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