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