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