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