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