1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* Engine implementation */
18 
19 #include <endian.h>
20 #include "sles_allinclusive.h"
21 
22 
23 /* Utility functions */
24 
initializeBufferQueueMembers(CAudioPlayer * ap)25 static SLresult initializeBufferQueueMembers(CAudioPlayer *ap) {
26     // inline allocation of circular mArray, up to a typical max
27     if (BUFFER_HEADER_TYPICAL >= ap->mBufferQueue.mNumBuffers) {
28         ap->mBufferQueue.mArray = ap->mBufferQueue.mTypical;
29     } else {
30         // Avoid possible integer overflow during multiplication; this arbitrary
31         // maximum is big enough to not interfere with real applications, but
32         // small enough to not overflow.
33         if (ap->mBufferQueue.mNumBuffers >= 256) {
34             return SL_RESULT_MEMORY_FAILURE;
35         }
36         ap->mBufferQueue.mArray = (BufferHeader *)
37                 malloc((ap->mBufferQueue.mNumBuffers + 1) * sizeof(BufferHeader));
38         if (NULL == ap->mBufferQueue.mArray) {
39             return SL_RESULT_MEMORY_FAILURE;
40         }
41     }
42     ap->mBufferQueue.mFront = ap->mBufferQueue.mArray;
43     ap->mBufferQueue.mRear = ap->mBufferQueue.mArray;
44     return SL_RESULT_SUCCESS;
45 }
46 
47 #ifdef ANDROID
initializeAndroidBufferQueueMembers(CAudioPlayer * ap)48 static SLresult initializeAndroidBufferQueueMembers(CAudioPlayer *ap) {
49     // Avoid possible integer overflow during multiplication; this arbitrary
50     // maximum is big enough to not interfere with real applications, but
51     // small enough to not overflow.
52     if (ap->mAndroidBufferQueue.mNumBuffers >= 256) {
53         return SL_RESULT_MEMORY_FAILURE;
54     }
55     ap->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
56             malloc( (ap->mAndroidBufferQueue.mNumBuffers + 1) * sizeof(AdvancedBufferHeader));
57     if (NULL == ap->mAndroidBufferQueue.mBufferArray) {
58         return SL_RESULT_MEMORY_FAILURE;
59     } else {
60 
61         // initialize ABQ buffer type
62         // assert below has been checked in android_audioPlayer_checkSourceSink
63         assert(SL_DATAFORMAT_MIME == ap->mDataSource.mFormat.mFormatType);
64         switch (ap->mDataSource.mFormat.mMIME.containerType) {
65           case SL_CONTAINERTYPE_MPEG_TS:
66             ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
67             break;
68           case SL_CONTAINERTYPE_AAC:
69           case SL_CONTAINERTYPE_RAW: {
70             const char* mime = (char*)ap->mDataSource.mFormat.mMIME.mimeType;
71             if ((mime != NULL) && !(strcasecmp(mime, (const char *)SL_ANDROID_MIME_AACADTS) &&
72                     strcasecmp(mime, ANDROID_MIME_AACADTS_ANDROID_FRAMEWORK))) {
73                 ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeAacadts;
74             } else {
75                 ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
76                 SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
77                 return SL_RESULT_CONTENT_UNSUPPORTED;
78             }
79           } break;
80           default:
81             ap->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
82             SL_LOGE("CreateAudioPlayer: Invalid buffer type in Android Buffer Queue");
83             return SL_RESULT_CONTENT_UNSUPPORTED;
84         }
85 
86         ap->mAndroidBufferQueue.mFront = ap->mAndroidBufferQueue.mBufferArray;
87         ap->mAndroidBufferQueue.mRear  = ap->mAndroidBufferQueue.mBufferArray;
88     }
89 
90     return SL_RESULT_SUCCESS;
91 }
92 #endif
93 
94 
IEngine_CreateLEDDevice(SLEngineItf self,SLObjectItf * pDevice,SLuint32 deviceID,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)95 static SLresult IEngine_CreateLEDDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
96     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
97 {
98     SL_ENTER_INTERFACE
99 
100 #if USE_PROFILES & USE_PROFILES_OPTIONAL
101     if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_LED != deviceID)) {
102         result = SL_RESULT_PARAMETER_INVALID;
103     } else {
104         *pDevice = NULL;
105         unsigned exposedMask;
106         const ClassTable *pCLEDDevice_class = objectIDtoClass(SL_OBJECTID_LEDDEVICE);
107         if (NULL == pCLEDDevice_class) {
108             result = SL_RESULT_FEATURE_UNSUPPORTED;
109         } else {
110             result = checkInterfaces(pCLEDDevice_class, numInterfaces, pInterfaceIds,
111                 pInterfaceRequired, &exposedMask, NULL);
112         }
113         if (SL_RESULT_SUCCESS == result) {
114             CLEDDevice *thiz = (CLEDDevice *) construct(pCLEDDevice_class, exposedMask, self);
115             if (NULL == thiz) {
116                 result = SL_RESULT_MEMORY_FAILURE;
117             } else {
118                 thiz->mDeviceID = deviceID;
119                 IObject_Publish(&thiz->mObject);
120                 // return the new LED object
121                 *pDevice = &thiz->mObject.mItf;
122             }
123         }
124     }
125 #else
126     result = SL_RESULT_FEATURE_UNSUPPORTED;
127 #endif
128 
129     SL_LEAVE_INTERFACE
130 }
131 
132 
IEngine_CreateVibraDevice(SLEngineItf self,SLObjectItf * pDevice,SLuint32 deviceID,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)133 static SLresult IEngine_CreateVibraDevice(SLEngineItf self, SLObjectItf *pDevice, SLuint32 deviceID,
134     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
135 {
136     SL_ENTER_INTERFACE
137 
138 #if USE_PROFILES & USE_PROFILES_OPTIONAL
139     if ((NULL == pDevice) || (SL_DEFAULTDEVICEID_VIBRA != deviceID)) {
140         result = SL_RESULT_PARAMETER_INVALID;
141     } else {
142         *pDevice = NULL;
143         unsigned exposedMask;
144         const ClassTable *pCVibraDevice_class = objectIDtoClass(SL_OBJECTID_VIBRADEVICE);
145         if (NULL == pCVibraDevice_class) {
146             result = SL_RESULT_FEATURE_UNSUPPORTED;
147         } else {
148             result = checkInterfaces(pCVibraDevice_class, numInterfaces,
149                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
150         }
151         if (SL_RESULT_SUCCESS == result) {
152             CVibraDevice *thiz = (CVibraDevice *) construct(pCVibraDevice_class, exposedMask, self);
153             if (NULL == thiz) {
154                 result = SL_RESULT_MEMORY_FAILURE;
155             } else {
156                 thiz->mDeviceID = deviceID;
157                 IObject_Publish(&thiz->mObject);
158                 // return the new vibra object
159                 *pDevice = &thiz->mObject.mItf;
160             }
161         }
162     }
163 #else
164     result = SL_RESULT_FEATURE_UNSUPPORTED;
165 #endif
166 
167     SL_LEAVE_INTERFACE
168 }
169 
170 
IEngine_CreateAudioPlayer(SLEngineItf self,SLObjectItf * pPlayer,SLDataSource * pAudioSrc,SLDataSink * pAudioSnk,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)171 static SLresult IEngine_CreateAudioPlayer(SLEngineItf self, SLObjectItf *pPlayer,
172     SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
173     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
174 {
175     SL_ENTER_INTERFACE
176 
177     if (NULL == pPlayer) {
178        result = SL_RESULT_PARAMETER_INVALID;
179     } else {
180         *pPlayer = NULL;
181         unsigned exposedMask, requiredMask;
182         const ClassTable *pCAudioPlayer_class = objectIDtoClass(SL_OBJECTID_AUDIOPLAYER);
183         assert(NULL != pCAudioPlayer_class);
184         result = checkInterfaces(pCAudioPlayer_class, numInterfaces,
185             pInterfaceIds, pInterfaceRequired, &exposedMask, &requiredMask);
186         if (SL_RESULT_SUCCESS == result) {
187 
188             // Construct our new AudioPlayer instance
189             CAudioPlayer *thiz = (CAudioPlayer *) construct(pCAudioPlayer_class, exposedMask, self);
190             if (NULL == thiz) {
191                 result = SL_RESULT_MEMORY_FAILURE;
192             } else {
193 
194                 do {
195 
196                     // Initialize private fields not associated with an interface
197 
198                     // Default data source in case of failure in checkDataSource
199                     thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
200                     thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;
201 
202                     // Default data sink in case of failure in checkDataSink
203                     thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
204                     thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;
205 
206                     // Default is no per-channel mute or solo
207                     thiz->mMuteMask = 0;
208                     thiz->mSoloMask = 0;
209 
210                     // Will be set soon for PCM buffer queues, or later by platform-specific code
211                     // during Realize or Prefetch
212                     thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
213                     thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
214 
215                     // More default values, in case destructor needs to be called early
216                     thiz->mDirectLevel = 0; // no attenuation
217 #ifdef USE_OUTPUTMIXEXT
218                     thiz->mTrack = NULL;
219                     thiz->mGains[0] = 1.0f;
220                     thiz->mGains[1] = 1.0f;
221                     thiz->mDestroyRequested = SL_BOOLEAN_FALSE;
222 #endif
223 #ifdef USE_SNDFILE
224                     thiz->mSndFile.mPathname = NULL;
225                     thiz->mSndFile.mSNDFILE = NULL;
226                     memset(&thiz->mSndFile.mSfInfo, 0, sizeof(SF_INFO));
227                     memset(&thiz->mSndFile.mMutex, 0, sizeof(pthread_mutex_t));
228                     thiz->mSndFile.mEOF = SL_BOOLEAN_FALSE;
229                     thiz->mSndFile.mWhich = 0;
230                     memset(thiz->mSndFile.mBuffer, 0, sizeof(thiz->mSndFile.mBuffer));
231 #endif
232 #ifdef ANDROID
233                     // placement new (explicit constructor)
234                     // FIXME unnecessary once those fields are encapsulated in one class, rather
235                     //   than a structure
236                     //###(void) new (&thiz->mAudioTrack) android::sp<android::AudioTrack>();
237                     (void) new (&thiz->mTrackPlayer) android::sp<android::TrackPlayerBase>();
238                     (void) new (&thiz->mCallbackProtector)
239                             android::sp<android::CallbackProtector>();
240                     (void) new (&thiz->mAuxEffect) android::sp<android::AudioEffect>();
241                     (void) new (&thiz->mAPlayer) android::sp<android::GenericPlayer>();
242                     // Android-specific POD fields are initialized in android_audioPlayer_create,
243                     // and assume calloc or memset 0 during allocation
244 #endif
245 
246                     // Check the source and sink parameters against generic constraints,
247                     // and make a local copy of all parameters in case other application threads
248                     // change memory concurrently.
249 
250                     result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
251                             DATALOCATOR_MASK_URI | DATALOCATOR_MASK_ADDRESS |
252                             DATALOCATOR_MASK_BUFFERQUEUE
253 #ifdef ANDROID
254                             | DATALOCATOR_MASK_ANDROIDFD | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
255                             | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
256 #endif
257                             , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX);
258 
259                     if (SL_RESULT_SUCCESS != result) {
260                         break;
261                     }
262 
263                     result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
264                             DATALOCATOR_MASK_OUTPUTMIX                  // for playback
265 #ifdef ANDROID
266                             | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE // for decode to a BQ
267                             | DATALOCATOR_MASK_BUFFERQUEUE              // for decode to a BQ
268 #endif
269                             , DATAFORMAT_MASK_NULL
270 #ifdef ANDROID
271                             | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX  // for decode to PCM
272 #endif
273                             );
274                     if (SL_RESULT_SUCCESS != result) {
275                         break;
276                     }
277 
278                     // It would be unsafe to ever refer to the application pointers again
279                     pAudioSrc = NULL;
280                     pAudioSnk = NULL;
281 
282                     // Check that the requested interfaces are compatible with data source and sink
283                     result = checkSourceSinkVsInterfacesCompatibility(&thiz->mDataSource,
284                             &thiz->mDataSink, pCAudioPlayer_class, requiredMask);
285                     if (SL_RESULT_SUCCESS != result) {
286                         break;
287                     }
288 
289                     // copy the buffer queue count from source locator (for playback) / from the
290                     // sink locator (for decode on ANDROID build) to the buffer queue interface
291                     // we have already range-checked the value down to a smaller width
292                     SLuint16 nbBuffers = 0;
293                     bool usesAdvancedBufferHeaders = false;
294                     bool usesSimpleBufferQueue = false;
295                     // creating an AudioPlayer which decodes AAC ADTS buffers to a PCM buffer queue
296                     //  will cause usesAdvancedBufferHeaders and usesSimpleBufferQueue to be true
297                     switch (thiz->mDataSource.mLocator.mLocatorType) {
298                     case SL_DATALOCATOR_BUFFERQUEUE:
299 #ifdef ANDROID
300                     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
301 #endif
302                         usesSimpleBufferQueue = true;
303                         nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mBufferQueue.numBuffers;
304                         assert(SL_DATAFORMAT_PCM == thiz->mDataSource.mFormat.mFormatType
305                                 || SL_ANDROID_DATAFORMAT_PCM_EX
306                                     == thiz->mDataSource.mFormat.mFormatType);
307                         thiz->mNumChannels = thiz->mDataSource.mFormat.mPCM.numChannels;
308                         thiz->mSampleRateMilliHz = thiz->mDataSource.mFormat.mPCM.samplesPerSec;
309                         break;
310 #ifdef ANDROID
311                     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
312                         usesAdvancedBufferHeaders = true;
313                         nbBuffers = (SLuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
314                         thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
315                         break;
316 #endif
317                     default:
318                         nbBuffers = 0;
319                         break;
320                     }
321 #ifdef ANDROID
322                     switch (thiz->mDataSink.mLocator.mLocatorType) {
323                     case SL_DATALOCATOR_BUFFERQUEUE:
324                     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
325                         usesSimpleBufferQueue = true;
326                         nbBuffers = thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
327                         assert(SL_DATAFORMAT_PCM == thiz->mDataSink.mFormat.mFormatType
328                                 || SL_ANDROID_DATAFORMAT_PCM_EX
329                                     == thiz->mDataSink.mFormat.mFormatType);
330                         // FIXME The values specified by the app are meaningless. We get the
331                         // real values from the decoder.  But the data sink checks currently require
332                         // that the app specify these useless values.  Needs doc/fix.
333                         // Instead use the "unknown" values, as needed by prepare completion.
334                         // thiz->mNumChannels = thiz->mDataSink.mFormat.mPCM.numChannels;
335                         // thiz->mSampleRateMilliHz = thiz->mDataSink.mFormat.mPCM.samplesPerSec;
336                         thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
337                         thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
338                         break;
339                     default:
340                         // leave nbBuffers unchanged
341                         break;
342                     }
343 #endif
344                     thiz->mBufferQueue.mNumBuffers = nbBuffers;
345 
346                     // check the audio source and sink parameters against platform support
347 #ifdef ANDROID
348                     result = android_audioPlayer_checkSourceSink(thiz);
349                     if (SL_RESULT_SUCCESS != result) {
350                         break;
351                     }
352 #endif
353 
354 #ifdef USE_SNDFILE
355                     result = SndFile_checkAudioPlayerSourceSink(thiz);
356                     if (SL_RESULT_SUCCESS != result) {
357                         break;
358                     }
359 #endif
360 
361 #ifdef USE_OUTPUTMIXEXT
362                     result = IOutputMixExt_checkAudioPlayerSourceSink(thiz);
363                     if (SL_RESULT_SUCCESS != result) {
364                         break;
365                     }
366 #endif
367 
368                     // Allocate memory for buffer queue
369                     if (usesAdvancedBufferHeaders) {
370 #ifdef ANDROID
371                         // locator is SL_DATALOCATOR_ANDROIDBUFFERQUEUE
372                         result = initializeAndroidBufferQueueMembers(thiz);
373 #else
374                         assert(false);
375 #endif
376                     }
377 
378                     if (usesSimpleBufferQueue) {
379                         // locator is SL_DATALOCATOR_BUFFERQUEUE
380                         //         or SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
381                         result = initializeBufferQueueMembers(thiz);
382                     }
383 
384                     // used to store the data source of our audio player
385                     thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;
386 
387                     // platform-specific initialization
388 #ifdef ANDROID
389                     android_audioPlayer_create(thiz);
390 #endif
391 
392                 } while (0);
393 
394                 if (SL_RESULT_SUCCESS != result) {
395                     IObject_Destroy(&thiz->mObject.mItf);
396                 } else {
397                     IObject_Publish(&thiz->mObject);
398                     // return the new audio player object
399                     *pPlayer = &thiz->mObject.mItf;
400                 }
401 
402             }
403         }
404 
405     }
406 
407     SL_LEAVE_INTERFACE
408 }
409 
410 
IEngine_CreateAudioRecorder(SLEngineItf self,SLObjectItf * pRecorder,SLDataSource * pAudioSrc,SLDataSink * pAudioSnk,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)411 static SLresult IEngine_CreateAudioRecorder(SLEngineItf self, SLObjectItf *pRecorder,
412     SLDataSource *pAudioSrc, SLDataSink *pAudioSnk, SLuint32 numInterfaces,
413     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
414 {
415     SL_ENTER_INTERFACE
416 
417 #if (USE_PROFILES & USE_PROFILES_OPTIONAL) || defined(ANDROID)
418     if (NULL == pRecorder) {
419         result = SL_RESULT_PARAMETER_INVALID;
420     } else {
421         *pRecorder = NULL;
422         unsigned exposedMask;
423         const ClassTable *pCAudioRecorder_class = objectIDtoClass(SL_OBJECTID_AUDIORECORDER);
424         if (NULL == pCAudioRecorder_class) {
425             result = SL_RESULT_FEATURE_UNSUPPORTED;
426         } else {
427             result = checkInterfaces(pCAudioRecorder_class, numInterfaces,
428                     pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
429         }
430 
431         if (SL_RESULT_SUCCESS == result) {
432 
433             // Construct our new AudioRecorder instance
434             CAudioRecorder *thiz = (CAudioRecorder *) construct(pCAudioRecorder_class, exposedMask,
435                     self);
436             if (NULL == thiz) {
437                 result = SL_RESULT_MEMORY_FAILURE;
438             } else {
439 
440                 do {
441 
442                     // Initialize fields not associated with any interface
443 
444                     // Default data source in case of failure in checkDataSource
445                     thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
446                     thiz->mDataSource.mFormat.mFormatType = SL_DATAFORMAT_NULL;
447 
448                     // Default data sink in case of failure in checkDataSink
449                     thiz->mDataSink.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
450                     thiz->mDataSink.mFormat.mFormatType = SL_DATAFORMAT_NULL;
451 
452                     // These fields are set to real values by
453                     // android_audioRecorder_checkSourceSink.  Note that the data sink is
454                     // always PCM buffer queue, so we know the channel count and sample rate early.
455                     thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
456                     thiz->mSampleRateMilliHz = UNKNOWN_SAMPLERATE;
457 #ifdef ANDROID
458                     // placement new (explicit constructor)
459                     // FIXME unnecessary once those fields are encapsulated in one class, rather
460                     //   than a structure
461                     (void) new (&thiz->mAudioRecord) android::sp<android::AudioRecord>();
462                     (void) new (&thiz->mCallbackHandle) android::sp<android::AudioRecordCallback>();
463                     (void) new (&thiz->mCallbackProtector)
464                             android::sp<android::CallbackProtector>();
465                     thiz->mRecordSource = AUDIO_SOURCE_DEFAULT;
466 #endif
467 
468                     // Check the source and sink parameters, and make a local copy of all parameters
469                     result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
470                             DATALOCATOR_MASK_IODEVICE, DATAFORMAT_MASK_NULL);
471                     if (SL_RESULT_SUCCESS != result) {
472                         break;
473                     }
474                     result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
475                             DATALOCATOR_MASK_URI
476 #ifdef ANDROID
477                             | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
478 #endif
479                             , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX
480                     );
481                     if (SL_RESULT_SUCCESS != result) {
482                         break;
483                     }
484 
485                     // It would be unsafe to ever refer to the application pointers again
486                     pAudioSrc = NULL;
487                     pAudioSnk = NULL;
488 
489                     // check the audio source and sink parameters against platform support
490 #ifdef ANDROID
491                     result = android_audioRecorder_checkSourceSink(thiz);
492                     if (SL_RESULT_SUCCESS != result) {
493                         SL_LOGE("Cannot create AudioRecorder: invalid source or sink");
494                         break;
495                     }
496 #endif
497 
498 #ifdef ANDROID
499                     // Allocate memory for buffer queue
500                     SLuint32 locatorType = thiz->mDataSink.mLocator.mLocatorType;
501                     if (locatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE) {
502                         thiz->mBufferQueue.mNumBuffers =
503                             thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
504                         // inline allocation of circular Buffer Queue mArray, up to a typical max
505                         if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) {
506                             thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical;
507                         } else {
508                             // Avoid possible integer overflow during multiplication; this arbitrary
509                             // maximum is big enough to not interfere with real applications, but
510                             // small enough to not overflow.
511                             if (thiz->mBufferQueue.mNumBuffers >= 256) {
512                                 result = SL_RESULT_MEMORY_FAILURE;
513                                 break;
514                             }
515                             thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue.
516                                     mNumBuffers + 1) * sizeof(BufferHeader));
517                             if (NULL == thiz->mBufferQueue.mArray) {
518                                 result = SL_RESULT_MEMORY_FAILURE;
519                                 break;
520                             }
521                         }
522                         thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray;
523                         thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray;
524                     }
525 #endif
526 
527                     // platform-specific initialization
528 #ifdef ANDROID
529                     android_audioRecorder_create(thiz);
530 #endif
531 
532                 } while (0);
533 
534                 if (SL_RESULT_SUCCESS != result) {
535                     IObject_Destroy(&thiz->mObject.mItf);
536                 } else {
537                     IObject_Publish(&thiz->mObject);
538                     // return the new audio recorder object
539                     *pRecorder = &thiz->mObject.mItf;
540                 }
541             }
542 
543         }
544 
545     }
546 #else
547     result = SL_RESULT_FEATURE_UNSUPPORTED;
548 #endif
549 
550     SL_LEAVE_INTERFACE
551 }
552 
553 
IEngine_CreateMidiPlayer(SLEngineItf self,SLObjectItf * pPlayer,SLDataSource * pMIDISrc,SLDataSource * pBankSrc,SLDataSink * pAudioOutput,SLDataSink * pVibra,SLDataSink * pLEDArray,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)554 static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
555     SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
556     SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
557     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
558 {
559     SL_ENTER_INTERFACE
560 
561 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
562     if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) {
563         result = SL_RESULT_PARAMETER_INVALID;
564     } else {
565         *pPlayer = NULL;
566         unsigned exposedMask;
567         const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
568         if (NULL == pCMidiPlayer_class) {
569             result = SL_RESULT_FEATURE_UNSUPPORTED;
570         } else {
571             result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
572                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
573         }
574         if (SL_RESULT_SUCCESS == result) {
575             CMidiPlayer *thiz = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
576             if (NULL == thiz) {
577                 result = SL_RESULT_MEMORY_FAILURE;
578             } else {
579 #if 0
580                 "pMIDISrc", pMIDISrc, URI | MIDIBUFFERQUEUE, NONE
581                 "pBankSrc", pBanksrc, NULL | URI | ADDRESS, NULL
582                 "pAudioOutput", pAudioOutput, OUTPUTMIX, NULL
583                 "pVibra", pVibra, NULL | IODEVICE, NULL
584                 "pLEDArray", pLEDArray, NULL | IODEVICE, NULL
585 #endif
586                 // a fake value - why not use value from IPlay_init? what does CT check for?
587                 thiz->mPlay.mDuration = 0;
588                 IObject_Publish(&thiz->mObject);
589                 // return the new MIDI player object
590                 *pPlayer = &thiz->mObject.mItf;
591             }
592         }
593     }
594 #else
595     result = SL_RESULT_FEATURE_UNSUPPORTED;
596 #endif
597 
598     SL_LEAVE_INTERFACE
599 }
600 
601 
IEngine_CreateListener(SLEngineItf self,SLObjectItf * pListener,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)602 static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
603     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
604 {
605     SL_ENTER_INTERFACE
606 
607 #if USE_PROFILES & USE_PROFILES_GAME
608     if (NULL == pListener) {
609         result = SL_RESULT_PARAMETER_INVALID;
610     } else {
611         *pListener = NULL;
612         unsigned exposedMask;
613         const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
614         if (NULL == pCListener_class) {
615             result = SL_RESULT_FEATURE_UNSUPPORTED;
616         } else {
617             result = checkInterfaces(pCListener_class, numInterfaces,
618                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
619         }
620         if (SL_RESULT_SUCCESS == result) {
621             CListener *thiz = (CListener *) construct(pCListener_class, exposedMask, self);
622             if (NULL == thiz) {
623                 result = SL_RESULT_MEMORY_FAILURE;
624             } else {
625                 IObject_Publish(&thiz->mObject);
626                 // return the new 3D listener object
627                 *pListener = &thiz->mObject.mItf;
628             }
629         }
630     }
631 #else
632     result = SL_RESULT_FEATURE_UNSUPPORTED;
633 #endif
634 
635     SL_LEAVE_INTERFACE
636 }
637 
638 
IEngine_Create3DGroup(SLEngineItf self,SLObjectItf * pGroup,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)639 static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces,
640     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
641 {
642     SL_ENTER_INTERFACE
643 
644 #if USE_PROFILES & USE_PROFILES_GAME
645     if (NULL == pGroup) {
646         result = SL_RESULT_PARAMETER_INVALID;
647     } else {
648         *pGroup = NULL;
649         unsigned exposedMask;
650         const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
651         if (NULL == pC3DGroup_class) {
652             result = SL_RESULT_FEATURE_UNSUPPORTED;
653         } else {
654             result = checkInterfaces(pC3DGroup_class, numInterfaces,
655                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
656         }
657         if (SL_RESULT_SUCCESS == result) {
658             C3DGroup *thiz = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self);
659             if (NULL == thiz) {
660                 result = SL_RESULT_MEMORY_FAILURE;
661             } else {
662                 thiz->mMemberMask = 0;
663                 IObject_Publish(&thiz->mObject);
664                 // return the new 3D group object
665                 *pGroup = &thiz->mObject.mItf;
666             }
667         }
668     }
669 #else
670     result = SL_RESULT_FEATURE_UNSUPPORTED;
671 #endif
672 
673     SL_LEAVE_INTERFACE
674 }
675 
676 
IEngine_CreateOutputMix(SLEngineItf self,SLObjectItf * pMix,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)677 static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces,
678     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
679 {
680     SL_ENTER_INTERFACE
681 
682     if (NULL == pMix) {
683         result = SL_RESULT_PARAMETER_INVALID;
684     } else {
685         *pMix = NULL;
686         unsigned exposedMask;
687         const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
688         assert(NULL != pCOutputMix_class);
689         result = checkInterfaces(pCOutputMix_class, numInterfaces,
690             pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
691         if (SL_RESULT_SUCCESS == result) {
692             COutputMix *thiz = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
693             if (NULL == thiz) {
694                 result = SL_RESULT_MEMORY_FAILURE;
695             } else {
696 #ifdef ANDROID
697                 android_outputMix_create(thiz);
698 #endif
699 #ifdef USE_SDL
700                 IEngine *thisEngine = &thiz->mObject.mEngine->mEngine;
701                 interface_lock_exclusive(thisEngine);
702                 bool unpause = false;
703                 if (NULL == thisEngine->mOutputMix) {
704                     thisEngine->mOutputMix = thiz;
705                     unpause = true;
706                 }
707                 interface_unlock_exclusive(thisEngine);
708 #endif
709                 IObject_Publish(&thiz->mObject);
710 #ifdef USE_SDL
711                 if (unpause) {
712                     // Enable SDL_callback to be called periodically by SDL's internal thread
713                     SDL_PauseAudio(0);
714                 }
715 #endif
716                 // return the new output mix object
717                 *pMix = &thiz->mObject.mItf;
718             }
719         }
720     }
721 
722     SL_LEAVE_INTERFACE
723 }
724 
725 
IEngine_CreateMetadataExtractor(SLEngineItf self,SLObjectItf * pMetadataExtractor,SLDataSource * pDataSource,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)726 static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor,
727     SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
728     const SLboolean *pInterfaceRequired)
729 {
730     SL_ENTER_INTERFACE
731 
732 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
733     if (NULL == pMetadataExtractor) {
734         result = SL_RESULT_PARAMETER_INVALID;
735     } else {
736         *pMetadataExtractor = NULL;
737         unsigned exposedMask;
738         const ClassTable *pCMetadataExtractor_class =
739             objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
740         if (NULL == pCMetadataExtractor_class) {
741             result = SL_RESULT_FEATURE_UNSUPPORTED;
742         } else {
743             result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
744                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
745         }
746         if (SL_RESULT_SUCCESS == result) {
747             CMetadataExtractor *thiz = (CMetadataExtractor *)
748                 construct(pCMetadataExtractor_class, exposedMask, self);
749             if (NULL == thiz) {
750                 result = SL_RESULT_MEMORY_FAILURE;
751             } else {
752 #if 0
753                 "pDataSource", pDataSource, NONE, NONE
754 #endif
755                 IObject_Publish(&thiz->mObject);
756                 // return the new metadata extractor object
757                 *pMetadataExtractor = &thiz->mObject.mItf;
758                 result = SL_RESULT_SUCCESS;
759             }
760         }
761     }
762 #else
763     result = SL_RESULT_FEATURE_UNSUPPORTED;
764 #endif
765 
766     SL_LEAVE_INTERFACE
767 }
768 
769 
IEngine_CreateExtensionObject(SLEngineItf self,SLObjectItf * pObject,void * pParameters,SLuint32 objectID,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)770 static SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject,
771     void *pParameters, SLuint32 objectID, SLuint32 numInterfaces,
772     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
773 {
774     SL_ENTER_INTERFACE
775 
776     if (NULL == pObject) {
777         result = SL_RESULT_PARAMETER_INVALID;
778     } else {
779         *pObject = NULL;
780         result = SL_RESULT_FEATURE_UNSUPPORTED;
781     }
782 
783     SL_LEAVE_INTERFACE
784 }
785 
786 
IEngine_QueryNumSupportedInterfaces(SLEngineItf self,SLuint32 objectID,SLuint32 * pNumSupportedInterfaces)787 static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
788     SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
789 {
790     SL_ENTER_INTERFACE
791 
792     if (NULL == pNumSupportedInterfaces) {
793         result = SL_RESULT_PARAMETER_INVALID;
794     } else {
795         const ClassTable *clazz = objectIDtoClass(objectID);
796         if (NULL == clazz) {
797             result = SL_RESULT_FEATURE_UNSUPPORTED;
798         } else {
799             SLuint32 count = 0;
800             SLuint32 i;
801             for (i = 0; i < clazz->mInterfaceCount; ++i) {
802                 switch (clazz->mInterfaces[i].mInterface) {
803                 case INTERFACE_IMPLICIT:
804                 case INTERFACE_IMPLICIT_PREREALIZE:
805                 case INTERFACE_EXPLICIT:
806                 case INTERFACE_EXPLICIT_PREREALIZE:
807                 case INTERFACE_DYNAMIC:
808                     ++count;
809                     break;
810                 case INTERFACE_UNAVAILABLE:
811                     break;
812                 default:
813                     assert(false);
814                     break;
815                 }
816             }
817             *pNumSupportedInterfaces = count;
818             result = SL_RESULT_SUCCESS;
819         }
820     }
821 
822     SL_LEAVE_INTERFACE;
823 }
824 
825 
IEngine_QuerySupportedInterfaces(SLEngineItf self,SLuint32 objectID,SLuint32 index,SLInterfaceID * pInterfaceId)826 static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
827     SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
828 {
829     SL_ENTER_INTERFACE
830 
831     if (NULL == pInterfaceId) {
832         result = SL_RESULT_PARAMETER_INVALID;
833     } else {
834         *pInterfaceId = NULL;
835         const ClassTable *clazz = objectIDtoClass(objectID);
836         if (NULL == clazz) {
837             result = SL_RESULT_FEATURE_UNSUPPORTED;
838         } else {
839             result = SL_RESULT_PARAMETER_INVALID; // will be reset later
840             SLuint32 i;
841             for (i = 0; i < clazz->mInterfaceCount; ++i) {
842                 switch (clazz->mInterfaces[i].mInterface) {
843                 case INTERFACE_IMPLICIT:
844                 case INTERFACE_IMPLICIT_PREREALIZE:
845                 case INTERFACE_EXPLICIT:
846                 case INTERFACE_EXPLICIT_PREREALIZE:
847                 case INTERFACE_DYNAMIC:
848                     break;
849                 case INTERFACE_UNAVAILABLE:
850                     continue;
851                 default:
852                     assert(false);
853                     break;
854                 }
855                 if (index == 0) {
856                     *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH];
857                     result = SL_RESULT_SUCCESS;
858                     break;
859                 }
860                 --index;
861             }
862         }
863     }
864 
865     SL_LEAVE_INTERFACE
866 };
867 
868 
869 static const char * const extensionNames[] = {
870 #ifdef ANDROID
871 #define _(n) #n
872 #define __(n) _(n)
873     "ANDROID_SDK_LEVEL_" __(PLATFORM_SDK_VERSION),
874 #undef _
875 #undef __
876 #else
877     "WILHELM_DESKTOP",
878 #endif
879 };
880 
881 
IEngine_QueryNumSupportedExtensions(SLEngineItf self,SLuint32 * pNumExtensions)882 static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions)
883 {
884     SL_ENTER_INTERFACE
885 
886     if (NULL == pNumExtensions) {
887         result = SL_RESULT_PARAMETER_INVALID;
888     } else {
889         *pNumExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
890         result = SL_RESULT_SUCCESS;
891     }
892 
893     SL_LEAVE_INTERFACE
894 }
895 
896 
IEngine_QuerySupportedExtension(SLEngineItf self,SLuint32 index,SLchar * pExtensionName,SLint16 * pNameLength)897 static SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
898     SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
899 {
900     SL_ENTER_INTERFACE
901 
902     if (NULL == pNameLength) {
903         result = SL_RESULT_PARAMETER_INVALID;
904     } else {
905         size_t actualNameLength;
906         unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
907         if (index >= numExtensions) {
908             actualNameLength = 0;
909             result = SL_RESULT_PARAMETER_INVALID;
910         } else {
911             const char *extensionName = extensionNames[index];
912             actualNameLength = strlen(extensionName) + 1;
913             if (NULL == pExtensionName) {
914                 // application is querying the name length in order to allocate a buffer
915                 result = SL_RESULT_SUCCESS;
916             } else {
917                 SLint16 availableNameLength = *pNameLength;
918                 if (0 >= availableNameLength) {
919                     // there is not even room for the terminating NUL
920                     result = SL_RESULT_BUFFER_INSUFFICIENT;
921                 } else if (actualNameLength > (size_t) availableNameLength) {
922                     // "no invalid strings are written. That is, the null-terminator always exists"
923                     memcpy(pExtensionName, extensionName, (size_t) availableNameLength - 1);
924                     pExtensionName[(size_t) availableNameLength - 1] = '\0';
925                     result = SL_RESULT_BUFFER_INSUFFICIENT;
926                 } else {
927                     memcpy(pExtensionName, extensionName, actualNameLength);
928                     result = SL_RESULT_SUCCESS;
929                 }
930             }
931         }
932         *pNameLength = actualNameLength;
933     }
934 
935     SL_LEAVE_INTERFACE
936 }
937 
938 
IEngine_IsExtensionSupported(SLEngineItf self,const SLchar * pExtensionName,SLboolean * pSupported)939 static SLresult IEngine_IsExtensionSupported(SLEngineItf self,
940     const SLchar *pExtensionName, SLboolean *pSupported)
941 {
942     SL_ENTER_INTERFACE
943 
944     if (NULL == pSupported) {
945         result = SL_RESULT_PARAMETER_INVALID;
946     } else {
947         SLboolean isSupported = SL_BOOLEAN_FALSE;
948         if (NULL == pExtensionName) {
949             result = SL_RESULT_PARAMETER_INVALID;
950         } else {
951             unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
952             unsigned i;
953             for (i = 0; i < numExtensions; ++i) {
954                 if (!strcmp((const char *) pExtensionName, extensionNames[i])) {
955                     isSupported = SL_BOOLEAN_TRUE;
956                     break;
957                 }
958             }
959             result = SL_RESULT_SUCCESS;
960         }
961         *pSupported = isSupported;
962     }
963 
964     SL_LEAVE_INTERFACE
965 }
966 
967 
968 static const struct SLEngineItf_ IEngine_Itf = {
969     IEngine_CreateLEDDevice,
970     IEngine_CreateVibraDevice,
971     IEngine_CreateAudioPlayer,
972     IEngine_CreateAudioRecorder,
973     IEngine_CreateMidiPlayer,
974     IEngine_CreateListener,
975     IEngine_Create3DGroup,
976     IEngine_CreateOutputMix,
977     IEngine_CreateMetadataExtractor,
978     IEngine_CreateExtensionObject,
979     IEngine_QueryNumSupportedInterfaces,
980     IEngine_QuerySupportedInterfaces,
981     IEngine_QueryNumSupportedExtensions,
982     IEngine_QuerySupportedExtension,
983     IEngine_IsExtensionSupported
984 };
985 
IEngine_init(void * self)986 void IEngine_init(void *self)
987 {
988     IEngine *thiz = (IEngine *) self;
989     thiz->mItf = &IEngine_Itf;
990     // mLossOfControlGlobal is initialized in slCreateEngine
991 #ifdef USE_SDL
992     thiz->mOutputMix = NULL;
993 #endif
994     thiz->mInstanceCount = 1; // ourself
995     thiz->mInstanceMask = 0;
996     thiz->mChangedMask = 0;
997     unsigned i;
998     for (i = 0; i < MAX_INSTANCE; ++i) {
999         thiz->mInstances[i] = NULL;
1000     }
1001     thiz->mShutdown = SL_BOOLEAN_FALSE;
1002     thiz->mShutdownAck = SL_BOOLEAN_FALSE;
1003 #if _BYTE_ORDER == _BIG_ENDIAN
1004     thiz->mNativeEndianness = SL_BYTEORDER_BIGENDIAN;
1005 #else
1006     thiz->mNativeEndianness = SL_BYTEORDER_LITTLEENDIAN;
1007 #endif
1008 }
1009 
IEngine_deinit(void * self)1010 void IEngine_deinit(void *self)
1011 {
1012 }
1013 
1014 
1015 // OpenMAX AL Engine
1016 
1017 
IEngine_CreateCameraDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 deviceID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1018 static XAresult IEngine_CreateCameraDevice(XAEngineItf self, XAObjectItf *pDevice,
1019         XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1020         const XAboolean *pInterfaceRequired)
1021 {
1022     XA_ENTER_INTERFACE
1023 
1024     //IXAEngine *thiz = (IXAEngine *) self;
1025     result = SL_RESULT_FEATURE_UNSUPPORTED;
1026 
1027     XA_LEAVE_INTERFACE
1028 }
1029 
1030 
IEngine_CreateRadioDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1031 static XAresult IEngine_CreateRadioDevice(XAEngineItf self, XAObjectItf *pDevice,
1032         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1033         const XAboolean *pInterfaceRequired)
1034 {
1035     XA_ENTER_INTERFACE
1036 
1037     //IXAEngine *thiz = (IXAEngine *) self;
1038     result = SL_RESULT_FEATURE_UNSUPPORTED;
1039 
1040     XA_LEAVE_INTERFACE
1041 }
1042 
1043 
IXAEngine_CreateLEDDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 deviceID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1044 static XAresult IXAEngine_CreateLEDDevice(XAEngineItf self, XAObjectItf *pDevice, XAuint32 deviceID,
1045         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1046         const XAboolean *pInterfaceRequired)
1047 {
1048     // forward to OpenSL ES
1049     return IEngine_CreateLEDDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1050             (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
1051             (const SLboolean *) pInterfaceRequired);
1052 }
1053 
1054 
IXAEngine_CreateVibraDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 deviceID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1055 static XAresult IXAEngine_CreateVibraDevice(XAEngineItf self, XAObjectItf *pDevice,
1056         XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1057         const XAboolean *pInterfaceRequired)
1058 {
1059     // forward to OpenSL ES
1060     return IEngine_CreateVibraDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1061             (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
1062             (const SLboolean *) pInterfaceRequired);
1063 }
1064 
1065 
IEngine_CreateMediaPlayer(XAEngineItf self,XAObjectItf * pPlayer,XADataSource * pDataSrc,XADataSource * pBankSrc,XADataSink * pAudioSnk,XADataSink * pImageVideoSnk,XADataSink * pVibra,XADataSink * pLEDArray,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1066 static XAresult IEngine_CreateMediaPlayer(XAEngineItf self, XAObjectItf *pPlayer,
1067         XADataSource *pDataSrc, XADataSource *pBankSrc, XADataSink *pAudioSnk,
1068         XADataSink *pImageVideoSnk, XADataSink *pVibra, XADataSink *pLEDArray,
1069         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1070         const XAboolean *pInterfaceRequired)
1071 {
1072     XA_ENTER_INTERFACE
1073 
1074     if (NULL == pPlayer) {
1075         result = XA_RESULT_PARAMETER_INVALID;
1076     } else {
1077         *pPlayer = NULL;
1078         unsigned exposedMask;
1079         const ClassTable *pCMediaPlayer_class = objectIDtoClass(XA_OBJECTID_MEDIAPLAYER);
1080         assert(NULL != pCMediaPlayer_class);
1081         result = checkInterfaces(pCMediaPlayer_class, numInterfaces,
1082                 (const SLInterfaceID *) pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
1083         if (XA_RESULT_SUCCESS == result) {
1084 
1085             // Construct our new MediaPlayer instance
1086             CMediaPlayer *thiz = (CMediaPlayer *) construct(pCMediaPlayer_class, exposedMask,
1087                     &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf);
1088             if (NULL == thiz) {
1089                 result = XA_RESULT_MEMORY_FAILURE;
1090             } else {
1091 
1092                 do {
1093 
1094                     // Initialize private fields not associated with an interface
1095 
1096                     // Default data source in case of failure in checkDataSource
1097                     thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
1098                     thiz->mDataSource.mFormat.mFormatType = XA_DATAFORMAT_NULL;
1099 
1100                     // Default andio and image sink in case of failure in checkDataSink
1101                     thiz->mAudioSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
1102                     thiz->mAudioSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
1103                     thiz->mImageVideoSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
1104                     thiz->mImageVideoSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
1105 
1106                     // More default values, in case destructor needs to be called early
1107                     thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
1108 
1109 #ifdef ANDROID
1110                     // placement new (explicit constructor)
1111                     // FIXME unnecessary once those fields are encapsulated in one class, rather
1112                     //   than a structure
1113                     (void) new (&thiz->mAVPlayer) android::sp<android::GenericPlayer>();
1114                     (void) new (&thiz->mCallbackProtector)
1115                             android::sp<android::CallbackProtector>();
1116                     // Android-specific POD fields are initialized in android_Player_create,
1117                     // and assume calloc or memset 0 during allocation
1118 #endif
1119 
1120                     // Check the source and sink parameters against generic constraints
1121 
1122                     result = checkDataSource("pDataSrc", (const SLDataSource *) pDataSrc,
1123                             &thiz->mDataSource, DATALOCATOR_MASK_URI
1124 #ifdef ANDROID
1125                             | DATALOCATOR_MASK_ANDROIDFD
1126                             | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
1127 #endif
1128                             , DATAFORMAT_MASK_MIME);
1129                     if (XA_RESULT_SUCCESS != result) {
1130                         break;
1131                     }
1132 
1133                     result = checkDataSource("pBankSrc", (const SLDataSource *) pBankSrc,
1134                             &thiz->mBankSource, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_URI |
1135                             DATALOCATOR_MASK_ADDRESS, DATAFORMAT_MASK_NULL);
1136                     if (XA_RESULT_SUCCESS != result) {
1137                         break;
1138                     }
1139 
1140                     result = checkDataSink("pAudioSnk", (const SLDataSink *) pAudioSnk,
1141                             &thiz->mAudioSink, DATALOCATOR_MASK_OUTPUTMIX, DATAFORMAT_MASK_NULL);
1142                     if (XA_RESULT_SUCCESS != result) {
1143                         break;
1144                     }
1145 
1146                     result = checkDataSink("pImageVideoSnk", (const SLDataSink *) pImageVideoSnk,
1147                             &thiz->mImageVideoSink,
1148                             DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_NATIVEDISPLAY,
1149                             DATAFORMAT_MASK_NULL);
1150                     if (XA_RESULT_SUCCESS != result) {
1151                         break;
1152                     }
1153 
1154                     result = checkDataSink("pVibra", (const SLDataSink *) pVibra, &thiz->mVibraSink,
1155                             DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
1156                             DATAFORMAT_MASK_NULL);
1157                     if (XA_RESULT_SUCCESS != result) {
1158                         break;
1159                     }
1160 
1161                     result = checkDataSink("pLEDArray", (const SLDataSink *) pLEDArray,
1162                             &thiz->mLEDArraySink, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
1163                             DATAFORMAT_MASK_NULL);
1164                     if (XA_RESULT_SUCCESS != result) {
1165                         break;
1166                     }
1167 
1168                     // Unsafe to ever refer to application pointers again
1169                     pDataSrc = NULL;
1170                     pBankSrc = NULL;
1171                     pAudioSnk = NULL;
1172                     pImageVideoSnk = NULL;
1173                     pVibra = NULL;
1174                     pLEDArray = NULL;
1175 
1176                     // Check that the requested interfaces are compatible with the data source
1177                     // FIXME implement
1178 
1179                     // check the source and sink parameters against platform support
1180 #ifdef ANDROID
1181                     result = android_Player_checkSourceSink(thiz);
1182                     if (XA_RESULT_SUCCESS != result) {
1183                         break;
1184                     }
1185 #endif
1186 
1187 #ifdef ANDROID
1188                     // AndroidBufferQueue-specific initialization
1189                     if (XA_DATALOCATOR_ANDROIDBUFFERQUEUE ==
1190                             thiz->mDataSource.mLocator.mLocatorType) {
1191                         XAuint16 nbBuffers = (XAuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
1192 
1193                         // Avoid possible integer overflow during multiplication; this arbitrary
1194                         // maximum is big enough to not interfere with real applications, but
1195                         // small enough to not overflow.
1196                         if (nbBuffers >= 256) {
1197                             result = SL_RESULT_MEMORY_FAILURE;
1198                             break;
1199                         }
1200 
1201                         // initialize ABQ buffer type
1202                         // assert below has been checked in android_audioPlayer_checkSourceSink
1203                         assert(XA_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType);
1204                         if (XA_CONTAINERTYPE_MPEG_TS ==
1205                                 thiz->mDataSource.mFormat.mMIME.containerType) {
1206                             thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
1207 
1208                             // Set the container type for the StreamInformation interface
1209                             XAMediaContainerInformation *containerInfo =
1210                                     (XAMediaContainerInformation*)
1211                                         // always storing container info at index 0, as per spec
1212                                         &thiz->mStreamInfo.mStreamInfoTable.itemAt(0).containerInfo;
1213                             containerInfo->containerType = XA_CONTAINERTYPE_MPEG_TS;
1214                             // there are no streams at this stage
1215                             containerInfo->numStreams = 0;
1216 
1217                         } else {
1218                             thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
1219                             SL_LOGE("Invalid buffer type in Android Buffer Queue");
1220                             result = SL_RESULT_CONTENT_UNSUPPORTED;
1221                         }
1222 
1223                         // initialize ABQ memory
1224                         thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
1225                                     malloc( (nbBuffers + 1) * sizeof(AdvancedBufferHeader));
1226                         if (NULL == thiz->mAndroidBufferQueue.mBufferArray) {
1227                             result = SL_RESULT_MEMORY_FAILURE;
1228                             break;
1229                         } else {
1230                             thiz->mAndroidBufferQueue.mFront =
1231                                     thiz->mAndroidBufferQueue.mBufferArray;
1232                             thiz->mAndroidBufferQueue.mRear =
1233                                     thiz->mAndroidBufferQueue.mBufferArray;
1234                         }
1235 
1236                         thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
1237 
1238                     }
1239 #endif
1240 
1241                     // used to store the data source of our audio player
1242                     thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;
1243 
1244                     // platform-specific initialization
1245 #ifdef ANDROID
1246                     android_Player_create(thiz);
1247 #endif
1248 
1249                 } while (0);
1250 
1251                 if (XA_RESULT_SUCCESS != result) {
1252                     IObject_Destroy(&thiz->mObject.mItf);
1253                 } else {
1254                     IObject_Publish(&thiz->mObject);
1255                     // return the new media player object
1256                     *pPlayer = (XAObjectItf) &thiz->mObject.mItf;
1257                 }
1258 
1259             }
1260         }
1261 
1262     }
1263 
1264     XA_LEAVE_INTERFACE
1265 }
1266 
1267 
IEngine_CreateMediaRecorder(XAEngineItf self,XAObjectItf * pRecorder,XADataSource * pAudioSrc,XADataSource * pImageVideoSrc,XADataSink * pDataSnk,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1268 static XAresult IEngine_CreateMediaRecorder(XAEngineItf self, XAObjectItf *pRecorder,
1269         XADataSource *pAudioSrc, XADataSource *pImageVideoSrc,
1270         XADataSink *pDataSnk, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1271         const XAboolean *pInterfaceRequired)
1272 {
1273     XA_ENTER_INTERFACE
1274 
1275     //IXAEngine *thiz = (IXAEngine *) self;
1276     result = SL_RESULT_FEATURE_UNSUPPORTED;
1277 
1278 #if 0
1279     "pAudioSrc", pAudioSrc,
1280     "pImageVideoSrc", pImageVideoSrc,
1281     "pDataSink", pDataSnk,
1282 #endif
1283 
1284     XA_LEAVE_INTERFACE
1285 }
1286 
1287 
IXAEngine_CreateOutputMix(XAEngineItf self,XAObjectItf * pMix,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1288 static XAresult IXAEngine_CreateOutputMix(XAEngineItf self, XAObjectItf *pMix,
1289         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1290         const XAboolean *pInterfaceRequired)
1291 {
1292     // forward to OpenSL ES
1293     return IEngine_CreateOutputMix(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1294             (SLObjectItf *) pMix, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
1295             (const SLboolean *) pInterfaceRequired);
1296 }
1297 
1298 
IXAEngine_CreateMetadataExtractor(XAEngineItf self,XAObjectItf * pMetadataExtractor,XADataSource * pDataSource,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1299 static XAresult IXAEngine_CreateMetadataExtractor(XAEngineItf self, XAObjectItf *pMetadataExtractor,
1300             XADataSource *pDataSource, XAuint32 numInterfaces,
1301             const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
1302 {
1303     // forward to OpenSL ES
1304     return IEngine_CreateMetadataExtractor(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1305             (SLObjectItf *) pMetadataExtractor, (SLDataSource *) pDataSource, numInterfaces,
1306             (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
1307 }
1308 
1309 
IXAEngine_CreateExtensionObject(XAEngineItf self,XAObjectItf * pObject,void * pParameters,XAuint32 objectID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1310 static XAresult IXAEngine_CreateExtensionObject(XAEngineItf self, XAObjectItf *pObject,
1311             void *pParameters, XAuint32 objectID, XAuint32 numInterfaces,
1312             const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
1313 {
1314     // forward to OpenSL ES
1315     return IEngine_CreateExtensionObject(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1316             (SLObjectItf *) pObject, pParameters, objectID, numInterfaces,
1317             (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
1318 }
1319 
1320 
IEngine_GetImplementationInfo(XAEngineItf self,XAuint32 * pMajor,XAuint32 * pMinor,XAuint32 * pStep,const XAchar * pImplementationText)1321 static XAresult IEngine_GetImplementationInfo(XAEngineItf self, XAuint32 *pMajor, XAuint32 *pMinor,
1322         XAuint32 *pStep, /* XAuint32 nImplementationTextSize, */ const XAchar *pImplementationText)
1323 {
1324     XA_ENTER_INTERFACE
1325 
1326     //IXAEngine *thiz = (IXAEngine *) self;
1327     result = SL_RESULT_FEATURE_UNSUPPORTED;
1328 
1329     XA_LEAVE_INTERFACE
1330 }
1331 
1332 
IXAEngine_QuerySupportedProfiles(XAEngineItf self,XAint16 * pProfilesSupported)1333 static XAresult IXAEngine_QuerySupportedProfiles(XAEngineItf self, XAint16 *pProfilesSupported)
1334 {
1335     XA_ENTER_INTERFACE
1336 
1337     if (NULL == pProfilesSupported) {
1338         result = XA_RESULT_PARAMETER_INVALID;
1339     } else {
1340 #if 1
1341         *pProfilesSupported = 0;
1342         // the code below was copied from OpenSL ES and needs to be adapted for OpenMAX AL.
1343 #else
1344         // The generic implementation doesn't implement any of the profiles, they shouldn't be
1345         // declared as supported. Also exclude the fake profiles BASE and OPTIONAL.
1346         *pProfilesSupported = USE_PROFILES &
1347                 (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE);
1348 #endif
1349         result = XA_RESULT_SUCCESS;
1350     }
1351 
1352     XA_LEAVE_INTERFACE
1353 }
1354 
1355 
IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self,XAuint32 objectID,XAuint32 * pNumSupportedInterfaces)1356 static XAresult IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self, XAuint32 objectID,
1357         XAuint32 *pNumSupportedInterfaces)
1358 {
1359     // forward to OpenSL ES
1360     return IEngine_QueryNumSupportedInterfaces(
1361             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID,
1362             pNumSupportedInterfaces);
1363 }
1364 
1365 
IXAEngine_QuerySupportedInterfaces(XAEngineItf self,XAuint32 objectID,XAuint32 index,XAInterfaceID * pInterfaceId)1366 static XAresult IXAEngine_QuerySupportedInterfaces(XAEngineItf self, XAuint32 objectID,
1367         XAuint32 index, XAInterfaceID *pInterfaceId)
1368 {
1369     // forward to OpenSL ES
1370     return IEngine_QuerySupportedInterfaces(
1371             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, index,
1372             (SLInterfaceID *) pInterfaceId);
1373 }
1374 
1375 
IXAEngine_QueryNumSupportedExtensions(XAEngineItf self,XAuint32 * pNumExtensions)1376 static XAresult IXAEngine_QueryNumSupportedExtensions(XAEngineItf self, XAuint32 *pNumExtensions)
1377 {
1378     // forward to OpenSL ES
1379     return IEngine_QueryNumSupportedExtensions(
1380             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, pNumExtensions);
1381 }
1382 
1383 
IXAEngine_QuerySupportedExtension(XAEngineItf self,XAuint32 index,XAchar * pExtensionName,XAint16 * pNameLength)1384 static XAresult IXAEngine_QuerySupportedExtension(XAEngineItf self, XAuint32 index,
1385         XAchar *pExtensionName, XAint16 *pNameLength)
1386 {
1387     // forward to OpenSL ES
1388     return IEngine_QuerySupportedExtension(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1389             index, pExtensionName, (SLint16 *) pNameLength);
1390 }
1391 
1392 
IXAEngine_IsExtensionSupported(XAEngineItf self,const XAchar * pExtensionName,XAboolean * pSupported)1393 static XAresult IXAEngine_IsExtensionSupported(XAEngineItf self, const XAchar *pExtensionName,
1394         XAboolean *pSupported)
1395 {
1396     // forward to OpenSL ES
1397     return IEngine_IsExtensionSupported(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1398             pExtensionName, pSupported);
1399 }
1400 
1401 
IXAEngine_QueryLEDCapabilities(XAEngineItf self,XAuint32 * pIndex,XAuint32 * pLEDDeviceID,XALEDDescriptor * pDescriptor)1402 static XAresult IXAEngine_QueryLEDCapabilities(XAEngineItf self, XAuint32 *pIndex,
1403         XAuint32 *pLEDDeviceID, XALEDDescriptor *pDescriptor)
1404 {
1405     // forward to OpenSL ES EngineCapabilities
1406     return (XAresult) IEngineCapabilities_QueryLEDCapabilities(
1407             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
1408             pLEDDeviceID, (SLLEDDescriptor *) pDescriptor);
1409 }
1410 
1411 
IXAEngine_QueryVibraCapabilities(XAEngineItf self,XAuint32 * pIndex,XAuint32 * pVibraDeviceID,XAVibraDescriptor * pDescriptor)1412 static XAresult IXAEngine_QueryVibraCapabilities(XAEngineItf self, XAuint32 *pIndex,
1413         XAuint32 *pVibraDeviceID, XAVibraDescriptor *pDescriptor)
1414 {
1415     // forward to OpenSL ES EngineCapabilities
1416     return (XAresult) IEngineCapabilities_QueryVibraCapabilities(
1417             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
1418             pVibraDeviceID, (SLVibraDescriptor *) pDescriptor);
1419 }
1420 
1421 
1422 // OpenMAX AL engine v-table
1423 
1424 static const struct XAEngineItf_ IXAEngine_Itf = {
1425     IEngine_CreateCameraDevice,
1426     IEngine_CreateRadioDevice,
1427     IXAEngine_CreateLEDDevice,
1428     IXAEngine_CreateVibraDevice,
1429     IEngine_CreateMediaPlayer,
1430     IEngine_CreateMediaRecorder,
1431     IXAEngine_CreateOutputMix,
1432     IXAEngine_CreateMetadataExtractor,
1433     IXAEngine_CreateExtensionObject,
1434     IEngine_GetImplementationInfo,
1435     IXAEngine_QuerySupportedProfiles,
1436     IXAEngine_QueryNumSupportedInterfaces,
1437     IXAEngine_QuerySupportedInterfaces,
1438     IXAEngine_QueryNumSupportedExtensions,
1439     IXAEngine_QuerySupportedExtension,
1440     IXAEngine_IsExtensionSupported,
1441     IXAEngine_QueryLEDCapabilities,
1442     IXAEngine_QueryVibraCapabilities
1443 };
1444 
1445 
IXAEngine_init(void * self)1446 void IXAEngine_init(void *self)
1447 {
1448     IXAEngine *thiz = (IXAEngine *) self;
1449     thiz->mItf = &IXAEngine_Itf;
1450 }
1451 
1452 
IXAEngine_deinit(void * self)1453 void IXAEngine_deinit(void *self)
1454 {
1455 }
1456