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