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 24 static 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 47 static 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 94 static 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 132 static 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 170 static 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 409 static 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 (void) new (&thiz->mCallbackProtector) 461 android::sp<android::CallbackProtector>(); 462 thiz->mRecordSource = AUDIO_SOURCE_DEFAULT; 463 #endif 464 465 // Check the source and sink parameters, and make a local copy of all parameters 466 result = checkDataSource("pAudioSrc", pAudioSrc, &thiz->mDataSource, 467 DATALOCATOR_MASK_IODEVICE, DATAFORMAT_MASK_NULL); 468 if (SL_RESULT_SUCCESS != result) { 469 break; 470 } 471 result = checkDataSink("pAudioSnk", pAudioSnk, &thiz->mDataSink, 472 DATALOCATOR_MASK_URI 473 #ifdef ANDROID 474 | DATALOCATOR_MASK_ANDROIDSIMPLEBUFFERQUEUE 475 #endif 476 , DATAFORMAT_MASK_MIME | DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX 477 ); 478 if (SL_RESULT_SUCCESS != result) { 479 break; 480 } 481 482 // It would be unsafe to ever refer to the application pointers again 483 pAudioSrc = NULL; 484 pAudioSnk = NULL; 485 486 // check the audio source and sink parameters against platform support 487 #ifdef ANDROID 488 result = android_audioRecorder_checkSourceSinkSupport(thiz); 489 if (SL_RESULT_SUCCESS != result) { 490 SL_LOGE("Cannot create AudioRecorder: invalid source or sink"); 491 break; 492 } 493 #endif 494 495 #ifdef ANDROID 496 // Allocate memory for buffer queue 497 SLuint32 locatorType = thiz->mDataSink.mLocator.mLocatorType; 498 if (locatorType == SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE) { 499 thiz->mBufferQueue.mNumBuffers = 500 thiz->mDataSink.mLocator.mBufferQueue.numBuffers; 501 // inline allocation of circular Buffer Queue mArray, up to a typical max 502 if (BUFFER_HEADER_TYPICAL >= thiz->mBufferQueue.mNumBuffers) { 503 thiz->mBufferQueue.mArray = thiz->mBufferQueue.mTypical; 504 } else { 505 // Avoid possible integer overflow during multiplication; this arbitrary 506 // maximum is big enough to not interfere with real applications, but 507 // small enough to not overflow. 508 if (thiz->mBufferQueue.mNumBuffers >= 256) { 509 result = SL_RESULT_MEMORY_FAILURE; 510 break; 511 } 512 thiz->mBufferQueue.mArray = (BufferHeader *) malloc((thiz->mBufferQueue. 513 mNumBuffers + 1) * sizeof(BufferHeader)); 514 if (NULL == thiz->mBufferQueue.mArray) { 515 result = SL_RESULT_MEMORY_FAILURE; 516 break; 517 } 518 } 519 thiz->mBufferQueue.mFront = thiz->mBufferQueue.mArray; 520 thiz->mBufferQueue.mRear = thiz->mBufferQueue.mArray; 521 } 522 #endif 523 524 // platform-specific initialization 525 #ifdef ANDROID 526 android_audioRecorder_create(thiz); 527 #endif 528 529 } while (0); 530 531 if (SL_RESULT_SUCCESS != result) { 532 IObject_Destroy(&thiz->mObject.mItf); 533 } else { 534 IObject_Publish(&thiz->mObject); 535 // return the new audio recorder object 536 *pRecorder = &thiz->mObject.mItf; 537 } 538 } 539 540 } 541 542 } 543 #else 544 result = SL_RESULT_FEATURE_UNSUPPORTED; 545 #endif 546 547 SL_LEAVE_INTERFACE 548 } 549 550 551 static SLresult IEngine_CreateMidiPlayer(SLEngineItf self, SLObjectItf *pPlayer, 552 SLDataSource *pMIDISrc, SLDataSource *pBankSrc, SLDataSink *pAudioOutput, 553 SLDataSink *pVibra, SLDataSink *pLEDArray, SLuint32 numInterfaces, 554 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 555 { 556 SL_ENTER_INTERFACE 557 558 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_PHONE) 559 if ((NULL == pPlayer) || (NULL == pMIDISrc) || (NULL == pAudioOutput)) { 560 result = SL_RESULT_PARAMETER_INVALID; 561 } else { 562 *pPlayer = NULL; 563 unsigned exposedMask; 564 const ClassTable *pCMidiPlayer_class = objectIDtoClass(SL_OBJECTID_MIDIPLAYER); 565 if (NULL == pCMidiPlayer_class) { 566 result = SL_RESULT_FEATURE_UNSUPPORTED; 567 } else { 568 result = checkInterfaces(pCMidiPlayer_class, numInterfaces, 569 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL); 570 } 571 if (SL_RESULT_SUCCESS == result) { 572 CMidiPlayer *thiz = (CMidiPlayer *) construct(pCMidiPlayer_class, exposedMask, self); 573 if (NULL == thiz) { 574 result = SL_RESULT_MEMORY_FAILURE; 575 } else { 576 #if 0 577 "pMIDISrc", pMIDISrc, URI | MIDIBUFFERQUEUE, NONE 578 "pBankSrc", pBanksrc, NULL | URI | ADDRESS, NULL 579 "pAudioOutput", pAudioOutput, OUTPUTMIX, NULL 580 "pVibra", pVibra, NULL | IODEVICE, NULL 581 "pLEDArray", pLEDArray, NULL | IODEVICE, NULL 582 #endif 583 // a fake value - why not use value from IPlay_init? what does CT check for? 584 thiz->mPlay.mDuration = 0; 585 IObject_Publish(&thiz->mObject); 586 // return the new MIDI player object 587 *pPlayer = &thiz->mObject.mItf; 588 } 589 } 590 } 591 #else 592 result = SL_RESULT_FEATURE_UNSUPPORTED; 593 #endif 594 595 SL_LEAVE_INTERFACE 596 } 597 598 599 static SLresult IEngine_CreateListener(SLEngineItf self, SLObjectItf *pListener, 600 SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 601 { 602 SL_ENTER_INTERFACE 603 604 #if USE_PROFILES & USE_PROFILES_GAME 605 if (NULL == pListener) { 606 result = SL_RESULT_PARAMETER_INVALID; 607 } else { 608 *pListener = NULL; 609 unsigned exposedMask; 610 const ClassTable *pCListener_class = objectIDtoClass(SL_OBJECTID_LISTENER); 611 if (NULL == pCListener_class) { 612 result = SL_RESULT_FEATURE_UNSUPPORTED; 613 } else { 614 result = checkInterfaces(pCListener_class, numInterfaces, 615 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL); 616 } 617 if (SL_RESULT_SUCCESS == result) { 618 CListener *thiz = (CListener *) construct(pCListener_class, exposedMask, self); 619 if (NULL == thiz) { 620 result = SL_RESULT_MEMORY_FAILURE; 621 } else { 622 IObject_Publish(&thiz->mObject); 623 // return the new 3D listener object 624 *pListener = &thiz->mObject.mItf; 625 } 626 } 627 } 628 #else 629 result = SL_RESULT_FEATURE_UNSUPPORTED; 630 #endif 631 632 SL_LEAVE_INTERFACE 633 } 634 635 636 static SLresult IEngine_Create3DGroup(SLEngineItf self, SLObjectItf *pGroup, SLuint32 numInterfaces, 637 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 638 { 639 SL_ENTER_INTERFACE 640 641 #if USE_PROFILES & USE_PROFILES_GAME 642 if (NULL == pGroup) { 643 result = SL_RESULT_PARAMETER_INVALID; 644 } else { 645 *pGroup = NULL; 646 unsigned exposedMask; 647 const ClassTable *pC3DGroup_class = objectIDtoClass(SL_OBJECTID_3DGROUP); 648 if (NULL == pC3DGroup_class) { 649 result = SL_RESULT_FEATURE_UNSUPPORTED; 650 } else { 651 result = checkInterfaces(pC3DGroup_class, numInterfaces, 652 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL); 653 } 654 if (SL_RESULT_SUCCESS == result) { 655 C3DGroup *thiz = (C3DGroup *) construct(pC3DGroup_class, exposedMask, self); 656 if (NULL == thiz) { 657 result = SL_RESULT_MEMORY_FAILURE; 658 } else { 659 thiz->mMemberMask = 0; 660 IObject_Publish(&thiz->mObject); 661 // return the new 3D group object 662 *pGroup = &thiz->mObject.mItf; 663 } 664 } 665 } 666 #else 667 result = SL_RESULT_FEATURE_UNSUPPORTED; 668 #endif 669 670 SL_LEAVE_INTERFACE 671 } 672 673 674 static SLresult IEngine_CreateOutputMix(SLEngineItf self, SLObjectItf *pMix, SLuint32 numInterfaces, 675 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 676 { 677 SL_ENTER_INTERFACE 678 679 if (NULL == pMix) { 680 result = SL_RESULT_PARAMETER_INVALID; 681 } else { 682 *pMix = NULL; 683 unsigned exposedMask; 684 const ClassTable *pCOutputMix_class = objectIDtoClass(SL_OBJECTID_OUTPUTMIX); 685 assert(NULL != pCOutputMix_class); 686 result = checkInterfaces(pCOutputMix_class, numInterfaces, 687 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL); 688 if (SL_RESULT_SUCCESS == result) { 689 COutputMix *thiz = (COutputMix *) construct(pCOutputMix_class, exposedMask, self); 690 if (NULL == thiz) { 691 result = SL_RESULT_MEMORY_FAILURE; 692 } else { 693 #ifdef ANDROID 694 android_outputMix_create(thiz); 695 #endif 696 #ifdef USE_SDL 697 IEngine *thisEngine = &thiz->mObject.mEngine->mEngine; 698 interface_lock_exclusive(thisEngine); 699 bool unpause = false; 700 if (NULL == thisEngine->mOutputMix) { 701 thisEngine->mOutputMix = thiz; 702 unpause = true; 703 } 704 interface_unlock_exclusive(thisEngine); 705 #endif 706 IObject_Publish(&thiz->mObject); 707 #ifdef USE_SDL 708 if (unpause) { 709 // Enable SDL_callback to be called periodically by SDL's internal thread 710 SDL_PauseAudio(0); 711 } 712 #endif 713 // return the new output mix object 714 *pMix = &thiz->mObject.mItf; 715 } 716 } 717 } 718 719 SL_LEAVE_INTERFACE 720 } 721 722 723 static SLresult IEngine_CreateMetadataExtractor(SLEngineItf self, SLObjectItf *pMetadataExtractor, 724 SLDataSource *pDataSource, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, 725 const SLboolean *pInterfaceRequired) 726 { 727 SL_ENTER_INTERFACE 728 729 #if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC) 730 if (NULL == pMetadataExtractor) { 731 result = SL_RESULT_PARAMETER_INVALID; 732 } else { 733 *pMetadataExtractor = NULL; 734 unsigned exposedMask; 735 const ClassTable *pCMetadataExtractor_class = 736 objectIDtoClass(SL_OBJECTID_METADATAEXTRACTOR); 737 if (NULL == pCMetadataExtractor_class) { 738 result = SL_RESULT_FEATURE_UNSUPPORTED; 739 } else { 740 result = checkInterfaces(pCMetadataExtractor_class, numInterfaces, 741 pInterfaceIds, pInterfaceRequired, &exposedMask, NULL); 742 } 743 if (SL_RESULT_SUCCESS == result) { 744 CMetadataExtractor *thiz = (CMetadataExtractor *) 745 construct(pCMetadataExtractor_class, exposedMask, self); 746 if (NULL == thiz) { 747 result = SL_RESULT_MEMORY_FAILURE; 748 } else { 749 #if 0 750 "pDataSource", pDataSource, NONE, NONE 751 #endif 752 IObject_Publish(&thiz->mObject); 753 // return the new metadata extractor object 754 *pMetadataExtractor = &thiz->mObject.mItf; 755 result = SL_RESULT_SUCCESS; 756 } 757 } 758 } 759 #else 760 result = SL_RESULT_FEATURE_UNSUPPORTED; 761 #endif 762 763 SL_LEAVE_INTERFACE 764 } 765 766 767 static SLresult IEngine_CreateExtensionObject(SLEngineItf self, SLObjectItf *pObject, 768 void *pParameters, SLuint32 objectID, SLuint32 numInterfaces, 769 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 770 { 771 SL_ENTER_INTERFACE 772 773 if (NULL == pObject) { 774 result = SL_RESULT_PARAMETER_INVALID; 775 } else { 776 *pObject = NULL; 777 result = SL_RESULT_FEATURE_UNSUPPORTED; 778 } 779 780 SL_LEAVE_INTERFACE 781 } 782 783 784 static SLresult IEngine_QueryNumSupportedInterfaces(SLEngineItf self, 785 SLuint32 objectID, SLuint32 *pNumSupportedInterfaces) 786 { 787 SL_ENTER_INTERFACE 788 789 if (NULL == pNumSupportedInterfaces) { 790 result = SL_RESULT_PARAMETER_INVALID; 791 } else { 792 const ClassTable *clazz = objectIDtoClass(objectID); 793 if (NULL == clazz) { 794 result = SL_RESULT_FEATURE_UNSUPPORTED; 795 } else { 796 SLuint32 count = 0; 797 SLuint32 i; 798 for (i = 0; i < clazz->mInterfaceCount; ++i) { 799 switch (clazz->mInterfaces[i].mInterface) { 800 case INTERFACE_IMPLICIT: 801 case INTERFACE_IMPLICIT_PREREALIZE: 802 case INTERFACE_EXPLICIT: 803 case INTERFACE_EXPLICIT_PREREALIZE: 804 case INTERFACE_DYNAMIC: 805 ++count; 806 break; 807 case INTERFACE_UNAVAILABLE: 808 break; 809 default: 810 assert(false); 811 break; 812 } 813 } 814 *pNumSupportedInterfaces = count; 815 result = SL_RESULT_SUCCESS; 816 } 817 } 818 819 SL_LEAVE_INTERFACE; 820 } 821 822 823 static SLresult IEngine_QuerySupportedInterfaces(SLEngineItf self, 824 SLuint32 objectID, SLuint32 index, SLInterfaceID *pInterfaceId) 825 { 826 SL_ENTER_INTERFACE 827 828 if (NULL == pInterfaceId) { 829 result = SL_RESULT_PARAMETER_INVALID; 830 } else { 831 *pInterfaceId = NULL; 832 const ClassTable *clazz = objectIDtoClass(objectID); 833 if (NULL == clazz) { 834 result = SL_RESULT_FEATURE_UNSUPPORTED; 835 } else { 836 result = SL_RESULT_PARAMETER_INVALID; // will be reset later 837 SLuint32 i; 838 for (i = 0; i < clazz->mInterfaceCount; ++i) { 839 switch (clazz->mInterfaces[i].mInterface) { 840 case INTERFACE_IMPLICIT: 841 case INTERFACE_IMPLICIT_PREREALIZE: 842 case INTERFACE_EXPLICIT: 843 case INTERFACE_EXPLICIT_PREREALIZE: 844 case INTERFACE_DYNAMIC: 845 break; 846 case INTERFACE_UNAVAILABLE: 847 continue; 848 default: 849 assert(false); 850 break; 851 } 852 if (index == 0) { 853 *pInterfaceId = &SL_IID_array[clazz->mInterfaces[i].mMPH]; 854 result = SL_RESULT_SUCCESS; 855 break; 856 } 857 --index; 858 } 859 } 860 } 861 862 SL_LEAVE_INTERFACE 863 }; 864 865 866 static const char * const extensionNames[] = { 867 #ifdef ANDROID 868 #define _(n) #n 869 #define __(n) _(n) 870 "ANDROID_SDK_LEVEL_" __(PLATFORM_SDK_VERSION), 871 #undef _ 872 #undef __ 873 #else 874 "WILHELM_DESKTOP", 875 #endif 876 }; 877 878 879 static SLresult IEngine_QueryNumSupportedExtensions(SLEngineItf self, SLuint32 *pNumExtensions) 880 { 881 SL_ENTER_INTERFACE 882 883 if (NULL == pNumExtensions) { 884 result = SL_RESULT_PARAMETER_INVALID; 885 } else { 886 *pNumExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]); 887 result = SL_RESULT_SUCCESS; 888 } 889 890 SL_LEAVE_INTERFACE 891 } 892 893 894 static SLresult IEngine_QuerySupportedExtension(SLEngineItf self, 895 SLuint32 index, SLchar *pExtensionName, SLint16 *pNameLength) 896 { 897 SL_ENTER_INTERFACE 898 899 if (NULL == pNameLength) { 900 result = SL_RESULT_PARAMETER_INVALID; 901 } else { 902 size_t actualNameLength; 903 unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]); 904 if (index >= numExtensions) { 905 actualNameLength = 0; 906 result = SL_RESULT_PARAMETER_INVALID; 907 } else { 908 const char *extensionName = extensionNames[index]; 909 actualNameLength = strlen(extensionName) + 1; 910 if (NULL == pExtensionName) { 911 // application is querying the name length in order to allocate a buffer 912 result = SL_RESULT_SUCCESS; 913 } else { 914 SLint16 availableNameLength = *pNameLength; 915 if (0 >= availableNameLength) { 916 // there is not even room for the terminating NUL 917 result = SL_RESULT_BUFFER_INSUFFICIENT; 918 } else if (actualNameLength > (size_t) availableNameLength) { 919 // "no invalid strings are written. That is, the null-terminator always exists" 920 memcpy(pExtensionName, extensionName, (size_t) availableNameLength - 1); 921 pExtensionName[(size_t) availableNameLength - 1] = '\0'; 922 result = SL_RESULT_BUFFER_INSUFFICIENT; 923 } else { 924 memcpy(pExtensionName, extensionName, actualNameLength); 925 result = SL_RESULT_SUCCESS; 926 } 927 } 928 } 929 *pNameLength = actualNameLength; 930 } 931 932 SL_LEAVE_INTERFACE 933 } 934 935 936 static SLresult IEngine_IsExtensionSupported(SLEngineItf self, 937 const SLchar *pExtensionName, SLboolean *pSupported) 938 { 939 SL_ENTER_INTERFACE 940 941 if (NULL == pSupported) { 942 result = SL_RESULT_PARAMETER_INVALID; 943 } else { 944 SLboolean isSupported = SL_BOOLEAN_FALSE; 945 if (NULL == pExtensionName) { 946 result = SL_RESULT_PARAMETER_INVALID; 947 } else { 948 unsigned numExtensions = sizeof(extensionNames) / sizeof(extensionNames[0]); 949 unsigned i; 950 for (i = 0; i < numExtensions; ++i) { 951 if (!strcmp((const char *) pExtensionName, extensionNames[i])) { 952 isSupported = SL_BOOLEAN_TRUE; 953 break; 954 } 955 } 956 result = SL_RESULT_SUCCESS; 957 } 958 *pSupported = isSupported; 959 } 960 961 SL_LEAVE_INTERFACE 962 } 963 964 965 static const struct SLEngineItf_ IEngine_Itf = { 966 IEngine_CreateLEDDevice, 967 IEngine_CreateVibraDevice, 968 IEngine_CreateAudioPlayer, 969 IEngine_CreateAudioRecorder, 970 IEngine_CreateMidiPlayer, 971 IEngine_CreateListener, 972 IEngine_Create3DGroup, 973 IEngine_CreateOutputMix, 974 IEngine_CreateMetadataExtractor, 975 IEngine_CreateExtensionObject, 976 IEngine_QueryNumSupportedInterfaces, 977 IEngine_QuerySupportedInterfaces, 978 IEngine_QueryNumSupportedExtensions, 979 IEngine_QuerySupportedExtension, 980 IEngine_IsExtensionSupported 981 }; 982 983 void IEngine_init(void *self) 984 { 985 IEngine *thiz = (IEngine *) self; 986 thiz->mItf = &IEngine_Itf; 987 // mLossOfControlGlobal is initialized in slCreateEngine 988 #ifdef USE_SDL 989 thiz->mOutputMix = NULL; 990 #endif 991 thiz->mInstanceCount = 1; // ourself 992 thiz->mInstanceMask = 0; 993 thiz->mChangedMask = 0; 994 unsigned i; 995 for (i = 0; i < MAX_INSTANCE; ++i) { 996 thiz->mInstances[i] = NULL; 997 } 998 thiz->mShutdown = SL_BOOLEAN_FALSE; 999 thiz->mShutdownAck = SL_BOOLEAN_FALSE; 1000 } 1001 1002 void IEngine_deinit(void *self) 1003 { 1004 } 1005 1006 1007 // OpenMAX AL Engine 1008 1009 1010 static XAresult IEngine_CreateCameraDevice(XAEngineItf self, XAObjectItf *pDevice, 1011 XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 1012 const XAboolean *pInterfaceRequired) 1013 { 1014 XA_ENTER_INTERFACE 1015 1016 //IXAEngine *thiz = (IXAEngine *) self; 1017 result = SL_RESULT_FEATURE_UNSUPPORTED; 1018 1019 XA_LEAVE_INTERFACE 1020 } 1021 1022 1023 static XAresult IEngine_CreateRadioDevice(XAEngineItf self, XAObjectItf *pDevice, 1024 XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 1025 const XAboolean *pInterfaceRequired) 1026 { 1027 XA_ENTER_INTERFACE 1028 1029 //IXAEngine *thiz = (IXAEngine *) self; 1030 result = SL_RESULT_FEATURE_UNSUPPORTED; 1031 1032 XA_LEAVE_INTERFACE 1033 } 1034 1035 1036 static XAresult IXAEngine_CreateLEDDevice(XAEngineItf self, XAObjectItf *pDevice, XAuint32 deviceID, 1037 XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 1038 const XAboolean *pInterfaceRequired) 1039 { 1040 // forward to OpenSL ES 1041 return IEngine_CreateLEDDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 1042 (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds, 1043 (const SLboolean *) pInterfaceRequired); 1044 } 1045 1046 1047 static XAresult IXAEngine_CreateVibraDevice(XAEngineItf self, XAObjectItf *pDevice, 1048 XAuint32 deviceID, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 1049 const XAboolean *pInterfaceRequired) 1050 { 1051 // forward to OpenSL ES 1052 return IEngine_CreateVibraDevice(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 1053 (SLObjectItf *) pDevice, deviceID, numInterfaces, (const SLInterfaceID *) pInterfaceIds, 1054 (const SLboolean *) pInterfaceRequired); 1055 } 1056 1057 1058 static XAresult IEngine_CreateMediaPlayer(XAEngineItf self, XAObjectItf *pPlayer, 1059 XADataSource *pDataSrc, XADataSource *pBankSrc, XADataSink *pAudioSnk, 1060 XADataSink *pImageVideoSnk, XADataSink *pVibra, XADataSink *pLEDArray, 1061 XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 1062 const XAboolean *pInterfaceRequired) 1063 { 1064 XA_ENTER_INTERFACE 1065 1066 if (NULL == pPlayer) { 1067 result = XA_RESULT_PARAMETER_INVALID; 1068 } else { 1069 *pPlayer = NULL; 1070 unsigned exposedMask; 1071 const ClassTable *pCMediaPlayer_class = objectIDtoClass(XA_OBJECTID_MEDIAPLAYER); 1072 assert(NULL != pCMediaPlayer_class); 1073 result = checkInterfaces(pCMediaPlayer_class, numInterfaces, 1074 (const SLInterfaceID *) pInterfaceIds, pInterfaceRequired, &exposedMask, NULL); 1075 if (XA_RESULT_SUCCESS == result) { 1076 1077 // Construct our new MediaPlayer instance 1078 CMediaPlayer *thiz = (CMediaPlayer *) construct(pCMediaPlayer_class, exposedMask, 1079 &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf); 1080 if (NULL == thiz) { 1081 result = XA_RESULT_MEMORY_FAILURE; 1082 } else { 1083 1084 do { 1085 1086 // Initialize private fields not associated with an interface 1087 1088 // Default data source in case of failure in checkDataSource 1089 thiz->mDataSource.mLocator.mLocatorType = SL_DATALOCATOR_NULL; 1090 thiz->mDataSource.mFormat.mFormatType = XA_DATAFORMAT_NULL; 1091 1092 // Default andio and image sink in case of failure in checkDataSink 1093 thiz->mAudioSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL; 1094 thiz->mAudioSink.mFormat.mFormatType = XA_DATAFORMAT_NULL; 1095 thiz->mImageVideoSink.mLocator.mLocatorType = XA_DATALOCATOR_NULL; 1096 thiz->mImageVideoSink.mFormat.mFormatType = XA_DATAFORMAT_NULL; 1097 1098 // More default values, in case destructor needs to be called early 1099 thiz->mNumChannels = UNKNOWN_NUMCHANNELS; 1100 1101 #ifdef ANDROID 1102 // placement new (explicit constructor) 1103 // FIXME unnecessary once those fields are encapsulated in one class, rather 1104 // than a structure 1105 (void) new (&thiz->mAVPlayer) android::sp<android::GenericPlayer>(); 1106 (void) new (&thiz->mCallbackProtector) 1107 android::sp<android::CallbackProtector>(); 1108 // Android-specific POD fields are initialized in android_Player_create, 1109 // and assume calloc or memset 0 during allocation 1110 #endif 1111 1112 // Check the source and sink parameters against generic constraints 1113 1114 result = checkDataSource("pDataSrc", (const SLDataSource *) pDataSrc, 1115 &thiz->mDataSource, DATALOCATOR_MASK_URI 1116 #ifdef ANDROID 1117 | DATALOCATOR_MASK_ANDROIDFD 1118 | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE 1119 #endif 1120 , DATAFORMAT_MASK_MIME); 1121 if (XA_RESULT_SUCCESS != result) { 1122 break; 1123 } 1124 1125 result = checkDataSource("pBankSrc", (const SLDataSource *) pBankSrc, 1126 &thiz->mBankSource, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_URI | 1127 DATALOCATOR_MASK_ADDRESS, DATAFORMAT_MASK_NULL); 1128 if (XA_RESULT_SUCCESS != result) { 1129 break; 1130 } 1131 1132 result = checkDataSink("pAudioSnk", (const SLDataSink *) pAudioSnk, 1133 &thiz->mAudioSink, DATALOCATOR_MASK_OUTPUTMIX, DATAFORMAT_MASK_NULL); 1134 if (XA_RESULT_SUCCESS != result) { 1135 break; 1136 } 1137 1138 result = checkDataSink("pImageVideoSnk", (const SLDataSink *) pImageVideoSnk, 1139 &thiz->mImageVideoSink, 1140 DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_NATIVEDISPLAY, 1141 DATAFORMAT_MASK_NULL); 1142 if (XA_RESULT_SUCCESS != result) { 1143 break; 1144 } 1145 1146 result = checkDataSink("pVibra", (const SLDataSink *) pVibra, &thiz->mVibraSink, 1147 DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE, 1148 DATAFORMAT_MASK_NULL); 1149 if (XA_RESULT_SUCCESS != result) { 1150 break; 1151 } 1152 1153 result = checkDataSink("pLEDArray", (const SLDataSink *) pLEDArray, 1154 &thiz->mLEDArraySink, DATALOCATOR_MASK_NULL | DATALOCATOR_MASK_IODEVICE, 1155 DATAFORMAT_MASK_NULL); 1156 if (XA_RESULT_SUCCESS != result) { 1157 break; 1158 } 1159 1160 // Unsafe to ever refer to application pointers again 1161 pDataSrc = NULL; 1162 pBankSrc = NULL; 1163 pAudioSnk = NULL; 1164 pImageVideoSnk = NULL; 1165 pVibra = NULL; 1166 pLEDArray = NULL; 1167 1168 // Check that the requested interfaces are compatible with the data source 1169 // FIXME implement 1170 1171 // check the source and sink parameters against platform support 1172 #ifdef ANDROID 1173 result = android_Player_checkSourceSink(thiz); 1174 if (XA_RESULT_SUCCESS != result) { 1175 break; 1176 } 1177 #endif 1178 1179 #ifdef ANDROID 1180 // AndroidBufferQueue-specific initialization 1181 if (XA_DATALOCATOR_ANDROIDBUFFERQUEUE == 1182 thiz->mDataSource.mLocator.mLocatorType) { 1183 XAuint16 nbBuffers = (XAuint16) thiz->mDataSource.mLocator.mABQ.numBuffers; 1184 1185 // Avoid possible integer overflow during multiplication; this arbitrary 1186 // maximum is big enough to not interfere with real applications, but 1187 // small enough to not overflow. 1188 if (nbBuffers >= 256) { 1189 result = SL_RESULT_MEMORY_FAILURE; 1190 break; 1191 } 1192 1193 // initialize ABQ buffer type 1194 // assert below has been checked in android_audioPlayer_checkSourceSink 1195 assert(XA_DATAFORMAT_MIME == thiz->mDataSource.mFormat.mFormatType); 1196 if (XA_CONTAINERTYPE_MPEG_TS == 1197 thiz->mDataSource.mFormat.mMIME.containerType) { 1198 thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeMpeg2Ts; 1199 1200 // Set the container type for the StreamInformation interface 1201 XAMediaContainerInformation *containerInfo = 1202 (XAMediaContainerInformation*) 1203 // always storing container info at index 0, as per spec 1204 &(thiz->mStreamInfo.mStreamInfoTable.itemAt(0). 1205 containerInfo); 1206 containerInfo->containerType = XA_CONTAINERTYPE_MPEG_TS; 1207 // there are no streams at this stage 1208 containerInfo->numStreams = 0; 1209 1210 } else { 1211 thiz->mAndroidBufferQueue.mBufferType = kAndroidBufferTypeInvalid; 1212 SL_LOGE("Invalid buffer type in Android Buffer Queue"); 1213 result = SL_RESULT_CONTENT_UNSUPPORTED; 1214 } 1215 1216 // initialize ABQ memory 1217 thiz->mAndroidBufferQueue.mBufferArray = (AdvancedBufferHeader *) 1218 malloc( (nbBuffers + 1) * sizeof(AdvancedBufferHeader)); 1219 if (NULL == thiz->mAndroidBufferQueue.mBufferArray) { 1220 result = SL_RESULT_MEMORY_FAILURE; 1221 break; 1222 } else { 1223 thiz->mAndroidBufferQueue.mFront = 1224 thiz->mAndroidBufferQueue.mBufferArray; 1225 thiz->mAndroidBufferQueue.mRear = 1226 thiz->mAndroidBufferQueue.mBufferArray; 1227 } 1228 1229 thiz->mAndroidBufferQueue.mNumBuffers = nbBuffers; 1230 1231 } 1232 #endif 1233 1234 // used to store the data source of our audio player 1235 thiz->mDynamicSource.mDataSource = &thiz->mDataSource.u.mSource; 1236 1237 // platform-specific initialization 1238 #ifdef ANDROID 1239 android_Player_create(thiz); 1240 #endif 1241 1242 } while (0); 1243 1244 if (XA_RESULT_SUCCESS != result) { 1245 IObject_Destroy(&thiz->mObject.mItf); 1246 } else { 1247 IObject_Publish(&thiz->mObject); 1248 // return the new media player object 1249 *pPlayer = (XAObjectItf) &thiz->mObject.mItf; 1250 } 1251 1252 } 1253 } 1254 1255 } 1256 1257 XA_LEAVE_INTERFACE 1258 } 1259 1260 1261 static XAresult IEngine_CreateMediaRecorder(XAEngineItf self, XAObjectItf *pRecorder, 1262 XADataSource *pAudioSrc, XADataSource *pImageVideoSrc, 1263 XADataSink *pDataSnk, XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 1264 const XAboolean *pInterfaceRequired) 1265 { 1266 XA_ENTER_INTERFACE 1267 1268 //IXAEngine *thiz = (IXAEngine *) self; 1269 result = SL_RESULT_FEATURE_UNSUPPORTED; 1270 1271 #if 0 1272 "pAudioSrc", pAudioSrc, 1273 "pImageVideoSrc", pImageVideoSrc, 1274 "pDataSink", pDataSnk, 1275 #endif 1276 1277 XA_LEAVE_INTERFACE 1278 } 1279 1280 1281 static XAresult IXAEngine_CreateOutputMix(XAEngineItf self, XAObjectItf *pMix, 1282 XAuint32 numInterfaces, const XAInterfaceID *pInterfaceIds, 1283 const XAboolean *pInterfaceRequired) 1284 { 1285 // forward to OpenSL ES 1286 return IEngine_CreateOutputMix(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 1287 (SLObjectItf *) pMix, numInterfaces, (const SLInterfaceID *) pInterfaceIds, 1288 (const SLboolean *) pInterfaceRequired); 1289 } 1290 1291 1292 static XAresult IXAEngine_CreateMetadataExtractor(XAEngineItf self, XAObjectItf *pMetadataExtractor, 1293 XADataSource *pDataSource, XAuint32 numInterfaces, 1294 const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired) 1295 { 1296 // forward to OpenSL ES 1297 return IEngine_CreateMetadataExtractor(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 1298 (SLObjectItf *) pMetadataExtractor, (SLDataSource *) pDataSource, numInterfaces, 1299 (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired); 1300 } 1301 1302 1303 static XAresult IXAEngine_CreateExtensionObject(XAEngineItf self, XAObjectItf *pObject, 1304 void *pParameters, XAuint32 objectID, XAuint32 numInterfaces, 1305 const XAInterfaceID *pInterfaceIds, const XAboolean *pInterfaceRequired) 1306 { 1307 // forward to OpenSL ES 1308 return IEngine_CreateExtensionObject(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 1309 (SLObjectItf *) pObject, pParameters, objectID, numInterfaces, 1310 (const SLInterfaceID *) pInterfaceIds, (const SLboolean *) pInterfaceRequired); 1311 } 1312 1313 1314 static XAresult IEngine_GetImplementationInfo(XAEngineItf self, XAuint32 *pMajor, XAuint32 *pMinor, 1315 XAuint32 *pStep, /* XAuint32 nImplementationTextSize, */ const XAchar *pImplementationText) 1316 { 1317 XA_ENTER_INTERFACE 1318 1319 //IXAEngine *thiz = (IXAEngine *) self; 1320 result = SL_RESULT_FEATURE_UNSUPPORTED; 1321 1322 XA_LEAVE_INTERFACE 1323 } 1324 1325 1326 static XAresult IXAEngine_QuerySupportedProfiles(XAEngineItf self, XAint16 *pProfilesSupported) 1327 { 1328 XA_ENTER_INTERFACE 1329 1330 if (NULL == pProfilesSupported) { 1331 result = XA_RESULT_PARAMETER_INVALID; 1332 } else { 1333 #if 1 1334 *pProfilesSupported = 0; 1335 // the code below was copied from OpenSL ES and needs to be adapted for OpenMAX AL. 1336 #else 1337 // The generic implementation doesn't implement any of the profiles, they shouldn't be 1338 // declared as supported. Also exclude the fake profiles BASE and OPTIONAL. 1339 *pProfilesSupported = USE_PROFILES & 1340 (USE_PROFILES_GAME | USE_PROFILES_MUSIC | USE_PROFILES_PHONE); 1341 #endif 1342 result = XA_RESULT_SUCCESS; 1343 } 1344 1345 XA_LEAVE_INTERFACE 1346 } 1347 1348 1349 static XAresult IXAEngine_QueryNumSupportedInterfaces(XAEngineItf self, XAuint32 objectID, 1350 XAuint32 *pNumSupportedInterfaces) 1351 { 1352 // forward to OpenSL ES 1353 return IEngine_QueryNumSupportedInterfaces( 1354 &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, 1355 pNumSupportedInterfaces); 1356 } 1357 1358 1359 static XAresult IXAEngine_QuerySupportedInterfaces(XAEngineItf self, XAuint32 objectID, 1360 XAuint32 index, XAInterfaceID *pInterfaceId) 1361 { 1362 // forward to OpenSL ES 1363 return IEngine_QuerySupportedInterfaces( 1364 &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, objectID, index, 1365 (SLInterfaceID *) pInterfaceId); 1366 } 1367 1368 1369 static XAresult IXAEngine_QueryNumSupportedExtensions(XAEngineItf self, XAuint32 *pNumExtensions) 1370 { 1371 // forward to OpenSL ES 1372 return IEngine_QueryNumSupportedExtensions( 1373 &((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, pNumExtensions); 1374 } 1375 1376 1377 static XAresult IXAEngine_QuerySupportedExtension(XAEngineItf self, XAuint32 index, 1378 XAchar *pExtensionName, XAint16 *pNameLength) 1379 { 1380 // forward to OpenSL ES 1381 return IEngine_QuerySupportedExtension(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 1382 index, pExtensionName, (SLint16 *) pNameLength); 1383 } 1384 1385 1386 static XAresult IXAEngine_IsExtensionSupported(XAEngineItf self, const XAchar *pExtensionName, 1387 XAboolean *pSupported) 1388 { 1389 // forward to OpenSL ES 1390 return IEngine_IsExtensionSupported(&((CEngine *) ((IXAEngine *) self)->mThis)->mEngine.mItf, 1391 pExtensionName, pSupported); 1392 } 1393 1394 1395 static XAresult IXAEngine_QueryLEDCapabilities(XAEngineItf self, XAuint32 *pIndex, 1396 XAuint32 *pLEDDeviceID, XALEDDescriptor *pDescriptor) 1397 { 1398 // forward to OpenSL ES EngineCapabilities 1399 return (XAresult) IEngineCapabilities_QueryLEDCapabilities( 1400 &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex, 1401 pLEDDeviceID, (SLLEDDescriptor *) pDescriptor); 1402 } 1403 1404 1405 static XAresult IXAEngine_QueryVibraCapabilities(XAEngineItf self, XAuint32 *pIndex, 1406 XAuint32 *pVibraDeviceID, XAVibraDescriptor *pDescriptor) 1407 { 1408 // forward to OpenSL ES EngineCapabilities 1409 return (XAresult) IEngineCapabilities_QueryVibraCapabilities( 1410 &((CEngine *) ((IXAEngine *) self)->mThis)->mEngineCapabilities.mItf, pIndex, 1411 pVibraDeviceID, (SLVibraDescriptor *) pDescriptor); 1412 } 1413 1414 1415 // OpenMAX AL engine v-table 1416 1417 static const struct XAEngineItf_ IXAEngine_Itf = { 1418 IEngine_CreateCameraDevice, 1419 IEngine_CreateRadioDevice, 1420 IXAEngine_CreateLEDDevice, 1421 IXAEngine_CreateVibraDevice, 1422 IEngine_CreateMediaPlayer, 1423 IEngine_CreateMediaRecorder, 1424 IXAEngine_CreateOutputMix, 1425 IXAEngine_CreateMetadataExtractor, 1426 IXAEngine_CreateExtensionObject, 1427 IEngine_GetImplementationInfo, 1428 IXAEngine_QuerySupportedProfiles, 1429 IXAEngine_QueryNumSupportedInterfaces, 1430 IXAEngine_QuerySupportedInterfaces, 1431 IXAEngine_QueryNumSupportedExtensions, 1432 IXAEngine_QuerySupportedExtension, 1433 IXAEngine_IsExtensionSupported, 1434 IXAEngine_QueryLEDCapabilities, 1435 IXAEngine_QueryVibraCapabilities 1436 }; 1437 1438 1439 void IXAEngine_init(void *self) 1440 { 1441 IXAEngine *thiz = (IXAEngine *) self; 1442 thiz->mItf = &IXAEngine_Itf; 1443 } 1444 1445 1446 void IXAEngine_deinit(void *self) 1447 { 1448 } 1449