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