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