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