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