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