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