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