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->mCallbackProtector)
463                             android::sp<android::CallbackProtector>();
464                     thiz->mRecordSource = AUDIO_SOURCE_DEFAULT;
465 #endif
466 
467                     // Check the source and sink parameters, and make a local copy of all parameters
468                     result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource,
469                             DATALOCATOR_MASK_IODEVICE, DATAFORMAT_MASK_NULL);
470                     if (SL_RESULT_SUCCESS != result) {
471                         break;
472                     }
473                     result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink,
474                             DATALOCATOR_MASK_URI
475 #ifdef ANDROID
476                             | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE
477 #endif
478                             , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX
479                     );
480                     if (SL_RESULT_SUCCESS != result) {
481                         break;
482                     }
483 
484                     // It would be unsafe to ever refer to the application pointers again
485                     pAudioSrc = NULL;
486                     pAudioSnk = NULL;
487 
488                     // check the audio source and sink parameters against platform support
489 #ifdef ANDROID
490                     result = android_audioRecorder_checkSourceSink(thiz);
491                     if (SL_RESULT_SUCCESS != result) {
492                         SL_LOGE("Cannot create AudioRecorder: invalid source or sink");
493                         break;
494                     }
495 #endif
496 
497 #ifdef ANDROID
498                     // Allocate memory for buffer queue
499                     SLuint32 locatorType = thiz->mDataSink.mLocator.mLocatorType;
500                     if (locatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE) {
501                         thiz->mBufferQueue.mNumBuffers =
502                             thiz->mDataSink.mLocator.mBufferQueue.numBuffers;
503                         // inline allocation of circular Buffer Queue mArray, up to a typical max
504                         if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) {
505                             thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical;
506                         } else {
507                             // Avoid possible integer overflow during multiplication; this arbitrary
508                             // maximum is big enough to not interfere with real applications, but
509                             // small enough to not overflow.
510                             if (thiz->mBufferQueue.mNumBuffers >= 256) {
511                                 result = SL_RESULT_MEMORY_FAILURE;
512                                 break;
513                             }
514                             thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue.
515                                     mNumBuffers + 1) * sizeof(BufferHeader));
516                             if (NULL == thiz->mBufferQueue.mArray) {
517                                 result = SL_RESULT_MEMORY_FAILURE;
518                                 break;
519                             }
520                         }
521                         thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray;
522                         thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray;
523                     }
524 #endif
525 
526                     // platform-specific initialization
527 #ifdef ANDROID
528                     android_audioRecorder_create(thiz);
529 #endif
530 
531                 } while (0);
532 
533                 if (SL_RESULT_SUCCESS != result) {
534                     IObject_Destroy(&thiz->mObject.mItf);
535                 } else {
536                     IObject_Publish(&thiz->mObject);
537                     // return the new audio recorder object
538                     *pRecorder = &thiz->mObject.mItf;
539                 }
540             }
541 
542         }
543 
544     }
545 #else
546     result = SL_RESULT_FEATURE_UNSUPPORTED;
547 #endif
548 
549     SL_LEAVE_INTERFACE
550 }
551 
552 
IEngine_CreateMidiPlayer(SLEngineItf self,SLObjectItf * pPlayer,SLDataSource * pMIDISrc,SLDataSource * pBankSrc,SLDataSink * pAudioOutput,SLDataSink * pVibra,SLDataSink * pLEDArray,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)553 static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer,
554     SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput,
555     SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces,
556     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
557 {
558     SL_ENTER_INTERFACE
559 
560 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE)
561     if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) {
562         result = SL_RESULT_PARAMETER_INVALID;
563     } else {
564         *pPlayer = NULL;
565         unsigned exposedMask;
566         const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER);
567         if (NULL == pCMidiPlayer_class) {
568             result = SL_RESULT_FEATURE_UNSUPPORTED;
569         } else {
570             result = checkInterfaces(pCMidiPlayer_class, numInterfaces,
571                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
572         }
573         if (SL_RESULT_SUCCESS == result) {
574             CMidiPlayer *thiz = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self);
575             if (NULL == thiz) {
576                 result = SL_RESULT_MEMORY_FAILURE;
577             } else {
578 #if 0
579                 "pMIDISrc", pMIDISrc, URI | MIDIBUFFERQUEUE, NONE
580                 "pBankSrc", pBanksrc, NULL | URI | ADDRESS, NULL
581                 "pAudioOutput", pAudioOutput, OUTPUTMIX, NULL
582                 "pVibra", pVibra, NULL | IODEVICE, NULL
583                 "pLEDArray", pLEDArray, NULL | IODEVICE, NULL
584 #endif
585                 // a fake value - why not use value from IPlay_init? what does CT check for?
586                 thiz->mPlay.mDuration = 0;
587                 IObject_Publish(&thiz->mObject);
588                 // return the new MIDI player object
589                 *pPlayer = &thiz->mObject.mItf;
590             }
591         }
592     }
593 #else
594     result = SL_RESULT_FEATURE_UNSUPPORTED;
595 #endif
596 
597     SL_LEAVE_INTERFACE
598 }
599 
600 
IEngine_CreateListener(SLEngineItf self,SLObjectItf * pListener,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)601 static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener,
602     SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
603 {
604     SL_ENTER_INTERFACE
605 
606 #if USE_PROFILES & USE_PROFILES_GAME
607     if (NULL == pListener) {
608         result = SL_RESULT_PARAMETER_INVALID;
609     } else {
610         *pListener = NULL;
611         unsigned exposedMask;
612         const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER);
613         if (NULL == pCListener_class) {
614             result = SL_RESULT_FEATURE_UNSUPPORTED;
615         } else {
616             result = checkInterfaces(pCListener_class, numInterfaces,
617                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
618         }
619         if (SL_RESULT_SUCCESS == result) {
620             CListener *thiz = (CListener *) construct(pCListener_class, exposedMask, self);
621             if (NULL == thiz) {
622                 result = SL_RESULT_MEMORY_FAILURE;
623             } else {
624                 IObject_Publish(&thiz->mObject);
625                 // return the new 3D listener object
626                 *pListener = &thiz->mObject.mItf;
627             }
628         }
629     }
630 #else
631     result = SL_RESULT_FEATURE_UNSUPPORTED;
632 #endif
633 
634     SL_LEAVE_INTERFACE
635 }
636 
637 
IEngine_Create3DGroup(SLEngineItf self,SLObjectItf * pGroup,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)638 static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces,
639     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
640 {
641     SL_ENTER_INTERFACE
642 
643 #if USE_PROFILES & USE_PROFILES_GAME
644     if (NULL == pGroup) {
645         result = SL_RESULT_PARAMETER_INVALID;
646     } else {
647         *pGroup = NULL;
648         unsigned exposedMask;
649         const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP);
650         if (NULL == pC3DGroup_class) {
651             result = SL_RESULT_FEATURE_UNSUPPORTED;
652         } else {
653             result = checkInterfaces(pC3DGroup_class, numInterfaces,
654                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
655         }
656         if (SL_RESULT_SUCCESS == result) {
657             C3DGroup *thiz = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self);
658             if (NULL == thiz) {
659                 result = SL_RESULT_MEMORY_FAILURE;
660             } else {
661                 thiz->mMemberMask = 0;
662                 IObject_Publish(&thiz->mObject);
663                 // return the new 3D group object
664                 *pGroup = &thiz->mObject.mItf;
665             }
666         }
667     }
668 #else
669     result = SL_RESULT_FEATURE_UNSUPPORTED;
670 #endif
671 
672     SL_LEAVE_INTERFACE
673 }
674 
675 
IEngine_CreateOutputMix(SLEngineItf self,SLObjectItf * pMix,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)676 static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces,
677     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
678 {
679     SL_ENTER_INTERFACE
680 
681     if (NULL == pMix) {
682         result = SL_RESULT_PARAMETER_INVALID;
683     } else {
684         *pMix = NULL;
685         unsigned exposedMask;
686         const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX);
687         assert(NULL != pCOutputMix_class);
688         result = checkInterfaces(pCOutputMix_class, numInterfaces,
689             pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
690         if (SL_RESULT_SUCCESS == result) {
691             COutputMix *thiz = (COutputMix *) construct(pCOutputMix_class, exposedMask, self);
692             if (NULL == thiz) {
693                 result = SL_RESULT_MEMORY_FAILURE;
694             } else {
695 #ifdef ANDROID
696                 android_outputMix_create(thiz);
697 #endif
698 #ifdef USE_SDL
699                 IEngine *thisEngine = &thiz->mObject.mEngine->mEngine;
700                 interface_lock_exclusive(thisEngine);
701                 bool unpause = false;
702                 if (NULL == thisEngine->mOutputMix) {
703                     thisEngine->mOutputMix = thiz;
704                     unpause = true;
705                 }
706                 interface_unlock_exclusive(thisEngine);
707 #endif
708                 IObject_Publish(&thiz->mObject);
709 #ifdef USE_SDL
710                 if (unpause) {
711                     // Enable SDL_callback to be called periodically by SDL's internal thread
712                     SDL_PauseAudio(0);
713                 }
714 #endif
715                 // return the new output mix object
716                 *pMix = &thiz->mObject.mItf;
717             }
718         }
719     }
720 
721     SL_LEAVE_INTERFACE
722 }
723 
724 
IEngine_CreateMetadataExtractor(SLEngineItf self,SLObjectItf * pMetadataExtractor,SLDataSource * pDataSource,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)725 static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor,
726     SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds,
727     const SLboolean *pInterfaceRequired)
728 {
729     SL_ENTER_INTERFACE
730 
731 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
732     if (NULL == pMetadataExtractor) {
733         result = SL_RESULT_PARAMETER_INVALID;
734     } else {
735         *pMetadataExtractor = NULL;
736         unsigned exposedMask;
737         const ClassTable *pCMetadataExtractor_class =
738             objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR);
739         if (NULL == pCMetadataExtractor_class) {
740             result = SL_RESULT_FEATURE_UNSUPPORTED;
741         } else {
742             result = checkInterfaces(pCMetadataExtractor_class, numInterfaces,
743                 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
744         }
745         if (SL_RESULT_SUCCESS == result) {
746             CMetadataExtractor *thiz = (CMetadataExtractor *)
747                 construct(pCMetadataExtractor_class, exposedMask, self);
748             if (NULL == thiz) {
749                 result = SL_RESULT_MEMORY_FAILURE;
750             } else {
751 #if 0
752                 "pDataSource", pDataSource, NONE, NONE
753 #endif
754                 IObject_Publish(&thiz->mObject);
755                 // return the new metadata extractor object
756                 *pMetadataExtractor = &thiz->mObject.mItf;
757                 result = SL_RESULT_SUCCESS;
758             }
759         }
760     }
761 #else
762     result = SL_RESULT_FEATURE_UNSUPPORTED;
763 #endif
764 
765     SL_LEAVE_INTERFACE
766 }
767 
768 
IEngine_CreateExtensionObject(SLEngineItf self,SLObjectItf * pObject,void * pParameters,SLuint32 objectID,SLuint32 numInterfaces,const SLInterfaceID * pInterfaceIds,const SLboolean * pInterfaceRequired)769 static SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject,
770     void *pParameters, SLuint32 objectID, SLuint32 numInterfaces,
771     const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
772 {
773     SL_ENTER_INTERFACE
774 
775     if (NULL == pObject) {
776         result = SL_RESULT_PARAMETER_INVALID;
777     } else {
778         *pObject = NULL;
779         result = SL_RESULT_FEATURE_UNSUPPORTED;
780     }
781 
782     SL_LEAVE_INTERFACE
783 }
784 
785 
IEngine_QueryNumSupportedInterfaces(SLEngineItf self,SLuint32 objectID,SLuint32 * pNumSupportedInterfaces)786 static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self,
787     SLuint32 objectID, SLuint32 *pNumSupportedInterfaces)
788 {
789     SL_ENTER_INTERFACE
790 
791     if (NULL == pNumSupportedInterfaces) {
792         result = SL_RESULT_PARAMETER_INVALID;
793     } else {
794         const ClassTable *clazz = objectIDtoClass(objectID);
795         if (NULL == clazz) {
796             result = SL_RESULT_FEATURE_UNSUPPORTED;
797         } else {
798             SLuint32 count = 0;
799             SLuint32 i;
800             for (i = 0; i < clazz->mInterfaceCount; ++i) {
801                 switch (clazz->mInterfaces[i].mInterface) {
802                 case INTERFACE_IMPLICIT:
803                 case INTERFACE_IMPLICIT_PREREALIZE:
804                 case INTERFACE_EXPLICIT:
805                 case INTERFACE_EXPLICIT_PREREALIZE:
806                 case INTERFACE_DYNAMIC:
807                     ++count;
808                     break;
809                 case INTERFACE_UNAVAILABLE:
810                     break;
811                 default:
812                     assert(false);
813                     break;
814                 }
815             }
816             *pNumSupportedInterfaces = count;
817             result = SL_RESULT_SUCCESS;
818         }
819     }
820 
821     SL_LEAVE_INTERFACE;
822 }
823 
824 
IEngine_QuerySupportedInterfaces(SLEngineItf self,SLuint32 objectID,SLuint32 index,SLInterfaceID * pInterfaceId)825 static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self,
826     SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId)
827 {
828     SL_ENTER_INTERFACE
829 
830     if (NULL == pInterfaceId) {
831         result = SL_RESULT_PARAMETER_INVALID;
832     } else {
833         *pInterfaceId = NULL;
834         const ClassTable *clazz = objectIDtoClass(objectID);
835         if (NULL == clazz) {
836             result = SL_RESULT_FEATURE_UNSUPPORTED;
837         } else {
838             result = SL_RESULT_PARAMETER_INVALID; // will be reset later
839             SLuint32 i;
840             for (i = 0; i < clazz->mInterfaceCount; ++i) {
841                 switch (clazz->mInterfaces[i].mInterface) {
842                 case INTERFACE_IMPLICIT:
843                 case INTERFACE_IMPLICIT_PREREALIZE:
844                 case INTERFACE_EXPLICIT:
845                 case INTERFACE_EXPLICIT_PREREALIZE:
846                 case INTERFACE_DYNAMIC:
847                     break;
848                 case INTERFACE_UNAVAILABLE:
849                     continue;
850                 default:
851                     assert(false);
852                     break;
853                 }
854                 if (index == 0) {
855                     *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH];
856                     result = SL_RESULT_SUCCESS;
857                     break;
858                 }
859                 --index;
860             }
861         }
862     }
863 
864     SL_LEAVE_INTERFACE
865 };
866 
867 
868 static const char * const extensionNames[] = {
869 #ifdef ANDROID
870 #define _(n) #n
871 #define __(n) _(n)
872     "ANDROID_SDK_LEVEL_" __(PLATFORM_SDK_VERSION),
873 #undef _
874 #undef __
875 #else
876     "WILHELM_DESKTOP",
877 #endif
878 };
879 
880 
IEngine_QueryNumSupportedExtensions(SLEngineItf self,SLuint32 * pNumExtensions)881 static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions)
882 {
883     SL_ENTER_INTERFACE
884 
885     if (NULL == pNumExtensions) {
886         result = SL_RESULT_PARAMETER_INVALID;
887     } else {
888         *pNumExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
889         result = SL_RESULT_SUCCESS;
890     }
891 
892     SL_LEAVE_INTERFACE
893 }
894 
895 
IEngine_QuerySupportedExtension(SLEngineItf self,SLuint32 index,SLchar * pExtensionName,SLint16 * pNameLength)896 static SLresult IEngine_QuerySupportedExtension(SLEngineItf self,
897     SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength)
898 {
899     SL_ENTER_INTERFACE
900 
901     if (NULL == pNameLength) {
902         result = SL_RESULT_PARAMETER_INVALID;
903     } else {
904         size_t actualNameLength;
905         unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
906         if (index >= numExtensions) {
907             actualNameLength = 0;
908             result = SL_RESULT_PARAMETER_INVALID;
909         } else {
910             const char *extensionName = extensionNames[index];
911             actualNameLength = strlen(extensionName) + 1;
912             if (NULL == pExtensionName) {
913                 // application is querying the name length in order to allocate a buffer
914                 result = SL_RESULT_SUCCESS;
915             } else {
916                 SLint16 availableNameLength = *pNameLength;
917                 if (0 >= availableNameLength) {
918                     // there is not even room for the terminating NUL
919                     result = SL_RESULT_BUFFER_INSUFFICIENT;
920                 } else if (actualNameLength > (size_t) availableNameLength) {
921                     // "no invalid strings are written. That is, the null-terminator always exists"
922                     memcpy(pExtensionName, extensionName, (size_t) availableNameLength - 1);
923                     pExtensionName[(size_t) availableNameLength - 1] = '\0';
924                     result = SL_RESULT_BUFFER_INSUFFICIENT;
925                 } else {
926                     memcpy(pExtensionName, extensionName, actualNameLength);
927                     result = SL_RESULT_SUCCESS;
928                 }
929             }
930         }
931         *pNameLength = actualNameLength;
932     }
933 
934     SL_LEAVE_INTERFACE
935 }
936 
937 
IEngine_IsExtensionSupported(SLEngineItf self,const SLchar * pExtensionName,SLboolean * pSupported)938 static SLresult IEngine_IsExtensionSupported(SLEngineItf self,
939     const SLchar *pExtensionName, SLboolean *pSupported)
940 {
941     SL_ENTER_INTERFACE
942 
943     if (NULL == pSupported) {
944         result = SL_RESULT_PARAMETER_INVALID;
945     } else {
946         SLboolean isSupported = SL_BOOLEAN_FALSE;
947         if (NULL == pExtensionName) {
948             result = SL_RESULT_PARAMETER_INVALID;
949         } else {
950             unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]);
951             unsigned i;
952             for (i = 0; i < numExtensions; ++i) {
953                 if (!strcmp((const char *) pExtensionName, extensionNames[i])) {
954                     isSupported = SL_BOOLEAN_TRUE;
955                     break;
956                 }
957             }
958             result = SL_RESULT_SUCCESS;
959         }
960         *pSupported = isSupported;
961     }
962 
963     SL_LEAVE_INTERFACE
964 }
965 
966 
967 static const struct SLEngineItf_ IEngine_Itf = {
968     IEngine_CreateLEDDevice,
969     IEngine_CreateVibraDevice,
970     IEngine_CreateAudioPlayer,
971     IEngine_CreateAudioRecorder,
972     IEngine_CreateMidiPlayer,
973     IEngine_CreateListener,
974     IEngine_Create3DGroup,
975     IEngine_CreateOutputMix,
976     IEngine_CreateMetadataExtractor,
977     IEngine_CreateExtensionObject,
978     IEngine_QueryNumSupportedInterfaces,
979     IEngine_QuerySupportedInterfaces,
980     IEngine_QueryNumSupportedExtensions,
981     IEngine_QuerySupportedExtension,
982     IEngine_IsExtensionSupported
983 };
984 
IEngine_init(void * self)985 void IEngine_init(void *self)
986 {
987     IEngine *thiz = (IEngine *) self;
988     thiz->mItf = &IEngine_Itf;
989     // mLossOfControlGlobal is initialized in slCreateEngine
990 #ifdef USE_SDL
991     thiz->mOutputMix = NULL;
992 #endif
993     thiz->mInstanceCount = 1; // ourself
994     thiz->mInstanceMask = 0;
995     thiz->mChangedMask = 0;
996     unsigned i;
997     for (i = 0; i < MAX_INSTANCE; ++i) {
998         thiz->mInstances[i] = NULL;
999     }
1000     thiz->mShutdown = SL_BOOLEAN_FALSE;
1001     thiz->mShutdownAck = SL_BOOLEAN_FALSE;
1002 #if _BYTE_ORDER == _BIG_ENDIAN
1003     thiz->mNativeEndianness = SL_BYTEORDER_BIGENDIAN;
1004 #else
1005     thiz->mNativeEndianness = SL_BYTEORDER_LITTLEENDIAN;
1006 #endif
1007 }
1008 
IEngine_deinit(void * self)1009 void IEngine_deinit(void *self)
1010 {
1011 }
1012 
1013 
1014 // OpenMAX AL Engine
1015 
1016 
IEngine_CreateCameraDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 deviceID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1017 static XAresult IEngine_CreateCameraDevice(XAEngineItf self, XAObjectItf *pDevice,
1018         XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1019         const XAboolean *pInterfaceRequired)
1020 {
1021     XA_ENTER_INTERFACE
1022 
1023     //IXAEngine *thiz = (IXAEngine *) self;
1024     result = SL_RESULT_FEATURE_UNSUPPORTED;
1025 
1026     XA_LEAVE_INTERFACE
1027 }
1028 
1029 
IEngine_CreateRadioDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1030 static XAresult IEngine_CreateRadioDevice(XAEngineItf self, XAObjectItf *pDevice,
1031         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1032         const XAboolean *pInterfaceRequired)
1033 {
1034     XA_ENTER_INTERFACE
1035 
1036     //IXAEngine *thiz = (IXAEngine *) self;
1037     result = SL_RESULT_FEATURE_UNSUPPORTED;
1038 
1039     XA_LEAVE_INTERFACE
1040 }
1041 
1042 
IXAEngine_CreateLEDDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 deviceID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1043 static XAresult IXAEngine_CreateLEDDevice(XAEngineItf self, XAObjectItf *pDevice, XAuint32 deviceID,
1044         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1045         const XAboolean *pInterfaceRequired)
1046 {
1047     // forward to OpenSL ES
1048     return IEngine_CreateLEDDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1049             (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
1050             (const SLboolean *) pInterfaceRequired);
1051 }
1052 
1053 
IXAEngine_CreateVibraDevice(XAEngineItf self,XAObjectItf * pDevice,XAuint32 deviceID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1054 static XAresult IXAEngine_CreateVibraDevice(XAEngineItf self, XAObjectItf *pDevice,
1055         XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1056         const XAboolean *pInterfaceRequired)
1057 {
1058     // forward to OpenSL ES
1059     return IEngine_CreateVibraDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1060             (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
1061             (const SLboolean *) pInterfaceRequired);
1062 }
1063 
1064 
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)1065 static XAresult IEngine_CreateMediaPlayer(XAEngineItf self, XAObjectItf *pPlayer,
1066         XADataSource *pDataSrc, XADataSource *pBankSrc, XADataSink *pAudioSnk,
1067         XADataSink *pImageVideoSnk, XADataSink *pVibra, XADataSink *pLEDArray,
1068         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1069         const XAboolean *pInterfaceRequired)
1070 {
1071     XA_ENTER_INTERFACE
1072 
1073     if (NULL == pPlayer) {
1074         result = XA_RESULT_PARAMETER_INVALID;
1075     } else {
1076         *pPlayer = NULL;
1077         unsigned exposedMask;
1078         const ClassTable *pCMediaPlayer_class = objectIDtoClass(XA_OBJECTID_MEDIAPLAYER);
1079         assert(NULL != pCMediaPlayer_class);
1080         result = checkInterfaces(pCMediaPlayer_class, numInterfaces,
1081                 (const SLInterfaceID *) pInterfaceIds, pInterfaceRequired, &exposedMask, NULL);
1082         if (XA_RESULT_SUCCESS == result) {
1083 
1084             // Construct our new MediaPlayer instance
1085             CMediaPlayer *thiz = (CMediaPlayer *) construct(pCMediaPlayer_class, exposedMask,
1086                     &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf);
1087             if (NULL == thiz) {
1088                 result = XA_RESULT_MEMORY_FAILURE;
1089             } else {
1090 
1091                 do {
1092 
1093                     // Initialize private fields not associated with an interface
1094 
1095                     // Default data source in case of failure in checkDataSource
1096                     thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL;
1097                     thiz->mDataSource.mFormat.mFormatType = XA_DATAFORMAT_NULL;
1098 
1099                     // Default andio and image sink in case of failure in checkDataSink
1100                     thiz->mAudioSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
1101                     thiz->mAudioSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
1102                     thiz->mImageVideoSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL;
1103                     thiz->mImageVideoSink.mFormat.mFormatType = XA_DATAFORMAT_NULL;
1104 
1105                     // More default values, in case destructor needs to be called early
1106                     thiz->mNumChannels = UNKNOWN_NUMCHANNELS;
1107 
1108 #ifdef ANDROID
1109                     // placement new (explicit constructor)
1110                     // FIXME unnecessary once those fields are encapsulated in one class, rather
1111                     //   than a structure
1112                     (void) new (&thiz->mAVPlayer) android::sp<android::GenericPlayer>();
1113                     (void) new (&thiz->mCallbackProtector)
1114                             android::sp<android::CallbackProtector>();
1115                     // Android-specific POD fields are initialized in android_Player_create,
1116                     // and assume calloc or memset 0 during allocation
1117 #endif
1118 
1119                     // Check the source and sink parameters against generic constraints
1120 
1121                     result = checkDataSource("pDataSrc", (const SLDataSource *) pDataSrc,
1122                             &thiz->mDataSource, DATALOCATOR_MASK_URI
1123 #ifdef ANDROID
1124                             | DATALOCATOR_MASK_ANDROIDFD
1125                             | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
1126 #endif
1127                             , DATAFORMAT_MASK_MIME);
1128                     if (XA_RESULT_SUCCESS != result) {
1129                         break;
1130                     }
1131 
1132                     result = checkDataSource("pBankSrc", (const SLDataSource *) pBankSrc,
1133                             &thiz->mBankSource, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_URI |
1134                             DATALOCATOR_MASK_ADDRESS, DATAFORMAT_MASK_NULL);
1135                     if (XA_RESULT_SUCCESS != result) {
1136                         break;
1137                     }
1138 
1139                     result = checkDataSink("pAudioSnk", (const SLDataSink *) pAudioSnk,
1140                             &thiz->mAudioSink, DATALOCATOR_MASK_OUTPUTMIX, DATAFORMAT_MASK_NULL);
1141                     if (XA_RESULT_SUCCESS != result) {
1142                         break;
1143                     }
1144 
1145                     result = checkDataSink("pImageVideoSnk", (const SLDataSink *) pImageVideoSnk,
1146                             &thiz->mImageVideoSink,
1147                             DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_NATIVEDISPLAY,
1148                             DATAFORMAT_MASK_NULL);
1149                     if (XA_RESULT_SUCCESS != result) {
1150                         break;
1151                     }
1152 
1153                     result = checkDataSink("pVibra", (const SLDataSink *) pVibra, &thiz->mVibraSink,
1154                             DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
1155                             DATAFORMAT_MASK_NULL);
1156                     if (XA_RESULT_SUCCESS != result) {
1157                         break;
1158                     }
1159 
1160                     result = checkDataSink("pLEDArray", (const SLDataSink *) pLEDArray,
1161                             &thiz->mLEDArraySink, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE,
1162                             DATAFORMAT_MASK_NULL);
1163                     if (XA_RESULT_SUCCESS != result) {
1164                         break;
1165                     }
1166 
1167                     // Unsafe to ever refer to application pointers again
1168                     pDataSrc = NULL;
1169                     pBankSrc = NULL;
1170                     pAudioSnk = NULL;
1171                     pImageVideoSnk = NULL;
1172                     pVibra = NULL;
1173                     pLEDArray = NULL;
1174 
1175                     // Check that the requested interfaces are compatible with the data source
1176                     // FIXME implement
1177 
1178                     // check the source and sink parameters against platform support
1179 #ifdef ANDROID
1180                     result = android_Player_checkSourceSink(thiz);
1181                     if (XA_RESULT_SUCCESS != result) {
1182                         break;
1183                     }
1184 #endif
1185 
1186 #ifdef ANDROID
1187                     // AndroidBufferQueue-specific initialization
1188                     if (XA_DATALOCATOR_ANDROIDBUFFERQUEUE ==
1189                             thiz->mDataSource.mLocator.mLocatorType) {
1190                         XAuint16 nbBuffers = (XAuint16) thiz->mDataSource.mLocator.mABQ.numBuffers;
1191 
1192                         // Avoid possible integer overflow during multiplication; this arbitrary
1193                         // maximum is big enough to not interfere with real applications, but
1194                         // small enough to not overflow.
1195                         if (nbBuffers >= 256) {
1196                             result = SL_RESULT_MEMORY_FAILURE;
1197                             break;
1198                         }
1199 
1200                         // initialize ABQ buffer type
1201                         // assert below has been checked in android_audioPlayer_checkSourceSink
1202                         assert(XA_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType);
1203                         if (XA_CONTAINERTYPE_MPEG_TS ==
1204                                 thiz->mDataSource.mFormat.mMIME.containerType) {
1205                             thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts;
1206 
1207                             // Set the container type for the StreamInformation interface
1208                             XAMediaContainerInformation *containerInfo =
1209                                     (XAMediaContainerInformation*)
1210                                         // always storing container info at index 0, as per spec
1211                                         &thiz->mStreamInfo.mStreamInfoTable.itemAt(0).containerInfo;
1212                             containerInfo->containerType = XA_CONTAINERTYPE_MPEG_TS;
1213                             // there are no streams at this stage
1214                             containerInfo->numStreams = 0;
1215 
1216                         } else {
1217                             thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid;
1218                             SL_LOGE("Invalid buffer type in Android Buffer Queue");
1219                             result = SL_RESULT_CONTENT_UNSUPPORTED;
1220                         }
1221 
1222                         // initialize ABQ memory
1223                         thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *)
1224                                     malloc( (nbBuffers + 1) * sizeof(AdvancedBufferHeader));
1225                         if (NULL == thiz->mAndroidBufferQueue.mBufferArray) {
1226                             result = SL_RESULT_MEMORY_FAILURE;
1227                             break;
1228                         } else {
1229                             thiz->mAndroidBufferQueue.mFront =
1230                                     thiz->mAndroidBufferQueue.mBufferArray;
1231                             thiz->mAndroidBufferQueue.mRear =
1232                                     thiz->mAndroidBufferQueue.mBufferArray;
1233                         }
1234 
1235                         thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers;
1236 
1237                     }
1238 #endif
1239 
1240                     // used to store the data source of our audio player
1241                     thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource;
1242 
1243                     // platform-specific initialization
1244 #ifdef ANDROID
1245                     android_Player_create(thiz);
1246 #endif
1247 
1248                 } while (0);
1249 
1250                 if (XA_RESULT_SUCCESS != result) {
1251                     IObject_Destroy(&thiz->mObject.mItf);
1252                 } else {
1253                     IObject_Publish(&thiz->mObject);
1254                     // return the new media player object
1255                     *pPlayer = (XAObjectItf) &thiz->mObject.mItf;
1256                 }
1257 
1258             }
1259         }
1260 
1261     }
1262 
1263     XA_LEAVE_INTERFACE
1264 }
1265 
1266 
IEngine_CreateMediaRecorder(XAEngineItf self,XAObjectItf * pRecorder,XADataSource * pAudioSrc,XADataSource * pImageVideoSrc,XADataSink * pDataSnk,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1267 static XAresult IEngine_CreateMediaRecorder(XAEngineItf self, XAObjectItf *pRecorder,
1268         XADataSource *pAudioSrc, XADataSource *pImageVideoSrc,
1269         XADataSink *pDataSnk, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1270         const XAboolean *pInterfaceRequired)
1271 {
1272     XA_ENTER_INTERFACE
1273 
1274     //IXAEngine *thiz = (IXAEngine *) self;
1275     result = SL_RESULT_FEATURE_UNSUPPORTED;
1276 
1277 #if 0
1278     "pAudioSrc", pAudioSrc,
1279     "pImageVideoSrc", pImageVideoSrc,
1280     "pDataSink", pDataSnk,
1281 #endif
1282 
1283     XA_LEAVE_INTERFACE
1284 }
1285 
1286 
IXAEngine_CreateOutputMix(XAEngineItf self,XAObjectItf * pMix,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1287 static XAresult IXAEngine_CreateOutputMix(XAEngineItf self, XAObjectItf *pMix,
1288         XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds,
1289         const XAboolean *pInterfaceRequired)
1290 {
1291     // forward to OpenSL ES
1292     return IEngine_CreateOutputMix(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1293             (SLObjectItf *) pMix, numInterfaces, (const SLInterfaceID *) pInterfaceIds,
1294             (const SLboolean *) pInterfaceRequired);
1295 }
1296 
1297 
IXAEngine_CreateMetadataExtractor(XAEngineItf self,XAObjectItf * pMetadataExtractor,XADataSource * pDataSource,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1298 static XAresult IXAEngine_CreateMetadataExtractor(XAEngineItf self, XAObjectItf *pMetadataExtractor,
1299             XADataSource *pDataSource, XAuint32 numInterfaces,
1300             const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
1301 {
1302     // forward to OpenSL ES
1303     return IEngine_CreateMetadataExtractor(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1304             (SLObjectItf *) pMetadataExtractor, (SLDataSource *) pDataSource, numInterfaces,
1305             (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
1306 }
1307 
1308 
IXAEngine_CreateExtensionObject(XAEngineItf self,XAObjectItf * pObject,void * pParameters,XAuint32 objectID,XAuint32 numInterfaces,const XAInterfaceID * pInterfaceIds,const XAboolean * pInterfaceRequired)1309 static XAresult IXAEngine_CreateExtensionObject(XAEngineItf self, XAObjectItf *pObject,
1310             void *pParameters, XAuint32 objectID, XAuint32 numInterfaces,
1311             const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired)
1312 {
1313     // forward to OpenSL ES
1314     return IEngine_CreateExtensionObject(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1315             (SLObjectItf *) pObject, pParameters, objectID, numInterfaces,
1316             (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired);
1317 }
1318 
1319 
IEngine_GetImplementationInfo(XAEngineItf self,XAuint32 * pMajor,XAuint32 * pMinor,XAuint32 * pStep,const XAchar * pImplementationText)1320 static XAresult IEngine_GetImplementationInfo(XAEngineItf self, XAuint32 *pMajor, XAuint32 *pMinor,
1321         XAuint32 *pStep, /* XAuint32 nImplementationTextSize, */ const XAchar *pImplementationText)
1322 {
1323     XA_ENTER_INTERFACE
1324 
1325     //IXAEngine *thiz = (IXAEngine *) self;
1326     result = SL_RESULT_FEATURE_UNSUPPORTED;
1327 
1328     XA_LEAVE_INTERFACE
1329 }
1330 
1331 
IXAEngine_QuerySupportedProfiles(XAEngineItf self,XAint16 * pProfilesSupported)1332 static XAresult IXAEngine_QuerySupportedProfiles(XAEngineItf self, XAint16 *pProfilesSupported)
1333 {
1334     XA_ENTER_INTERFACE
1335 
1336     if (NULL == pProfilesSupported) {
1337         result = XA_RESULT_PARAMETER_INVALID;
1338     } else {
1339 #if 1
1340         *pProfilesSupported = 0;
1341         // the code below was copied from OpenSL ES and needs to be adapted for OpenMAX AL.
1342 #else
1343         // The generic implementation doesn't implement any of the profiles, they shouldn't be
1344         // declared as supported. Also exclude the fake profiles BASE and OPTIONAL.
1345         *pProfilesSupported = USE_PROFILES &
1346                 (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE);
1347 #endif
1348         result = XA_RESULT_SUCCESS;
1349     }
1350 
1351     XA_LEAVE_INTERFACE
1352 }
1353 
1354 
IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self,XAuint32 objectID,XAuint32 * pNumSupportedInterfaces)1355 static XAresult IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self, XAuint32 objectID,
1356         XAuint32 *pNumSupportedInterfaces)
1357 {
1358     // forward to OpenSL ES
1359     return IEngine_QueryNumSupportedInterfaces(
1360             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID,
1361             pNumSupportedInterfaces);
1362 }
1363 
1364 
IXAEngine_QuerySupportedInterfaces(XAEngineItf self,XAuint32 objectID,XAuint32 index,XAInterfaceID * pInterfaceId)1365 static XAresult IXAEngine_QuerySupportedInterfaces(XAEngineItf self, XAuint32 objectID,
1366         XAuint32 index, XAInterfaceID *pInterfaceId)
1367 {
1368     // forward to OpenSL ES
1369     return IEngine_QuerySupportedInterfaces(
1370             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, index,
1371             (SLInterfaceID *) pInterfaceId);
1372 }
1373 
1374 
IXAEngine_QueryNumSupportedExtensions(XAEngineItf self,XAuint32 * pNumExtensions)1375 static XAresult IXAEngine_QueryNumSupportedExtensions(XAEngineItf self, XAuint32 *pNumExtensions)
1376 {
1377     // forward to OpenSL ES
1378     return IEngine_QueryNumSupportedExtensions(
1379             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, pNumExtensions);
1380 }
1381 
1382 
IXAEngine_QuerySupportedExtension(XAEngineItf self,XAuint32 index,XAchar * pExtensionName,XAint16 * pNameLength)1383 static XAresult IXAEngine_QuerySupportedExtension(XAEngineItf self, XAuint32 index,
1384         XAchar *pExtensionName, XAint16 *pNameLength)
1385 {
1386     // forward to OpenSL ES
1387     return IEngine_QuerySupportedExtension(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1388             index, pExtensionName, (SLint16 *) pNameLength);
1389 }
1390 
1391 
IXAEngine_IsExtensionSupported(XAEngineItf self,const XAchar * pExtensionName,XAboolean * pSupported)1392 static XAresult IXAEngine_IsExtensionSupported(XAEngineItf self, const XAchar *pExtensionName,
1393         XAboolean *pSupported)
1394 {
1395     // forward to OpenSL ES
1396     return IEngine_IsExtensionSupported(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf,
1397             pExtensionName, pSupported);
1398 }
1399 
1400 
IXAEngine_QueryLEDCapabilities(XAEngineItf self,XAuint32 * pIndex,XAuint32 * pLEDDeviceID,XALEDDescriptor * pDescriptor)1401 static XAresult IXAEngine_QueryLEDCapabilities(XAEngineItf self, XAuint32 *pIndex,
1402         XAuint32 *pLEDDeviceID, XALEDDescriptor *pDescriptor)
1403 {
1404     // forward to OpenSL ES EngineCapabilities
1405     return (XAresult) IEngineCapabilities_QueryLEDCapabilities(
1406             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
1407             pLEDDeviceID, (SLLEDDescriptor *) pDescriptor);
1408 }
1409 
1410 
IXAEngine_QueryVibraCapabilities(XAEngineItf self,XAuint32 * pIndex,XAuint32 * pVibraDeviceID,XAVibraDescriptor * pDescriptor)1411 static XAresult IXAEngine_QueryVibraCapabilities(XAEngineItf self, XAuint32 *pIndex,
1412         XAuint32 *pVibraDeviceID, XAVibraDescriptor *pDescriptor)
1413 {
1414     // forward to OpenSL ES EngineCapabilities
1415     return (XAresult) IEngineCapabilities_QueryVibraCapabilities(
1416             &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex,
1417             pVibraDeviceID, (SLVibraDescriptor *) pDescriptor);
1418 }
1419 
1420 
1421 // OpenMAX AL engine v-table
1422 
1423 static const struct XAEngineItf_ IXAEngine_Itf = {
1424     IEngine_CreateCameraDevice,
1425     IEngine_CreateRadioDevice,
1426     IXAEngine_CreateLEDDevice,
1427     IXAEngine_CreateVibraDevice,
1428     IEngine_CreateMediaPlayer,
1429     IEngine_CreateMediaRecorder,
1430     IXAEngine_CreateOutputMix,
1431     IXAEngine_CreateMetadataExtractor,
1432     IXAEngine_CreateExtensionObject,
1433     IEngine_GetImplementationInfo,
1434     IXAEngine_QuerySupportedProfiles,
1435     IXAEngine_QueryNumSupportedInterfaces,
1436     IXAEngine_QuerySupportedInterfaces,
1437     IXAEngine_QueryNumSupportedExtensions,
1438     IXAEngine_QuerySupportedExtension,
1439     IXAEngine_IsExtensionSupported,
1440     IXAEngine_QueryLEDCapabilities,
1441     IXAEngine_QueryVibraCapabilities
1442 };
1443 
1444 
IXAEngine_init(void * self)1445 void IXAEngine_init(void *self)
1446 {
1447     IXAEngine *thiz = (IXAEngine *) self;
1448     thiz->mItf = &IXAEngine_Itf;
1449 }
1450 
1451 
IXAEngine_deinit(void * self)1452 void IXAEngine_deinit(void *self)
1453 {
1454 }
1455