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