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 /* OpenSL ES private and global functions not associated with an interface or class */ 18 19 #include "sles_allinclusive.h" 20 21 22 /** \brief Return true if the specified interface exists and has been initialized for this object. 23 * Returns false if the class does not support this kind of interface, or the class supports the 24 * interface but this particular object has not had the interface exposed at object creation time 25 * or by DynamicInterface::AddInterface. Note that the return value is not affected by whether 26 * the application has requested access to the interface with Object::GetInterface. Assumes on 27 * entry that the object is locked for either shared or exclusive access. 28 */ 29 30 bool IsInterfaceInitialized(IObject *this, unsigned MPH) 31 { 32 assert(NULL != this); 33 assert( /* (MPH_MIN <= MPH) && */ (MPH < (unsigned) MPH_MAX)); 34 const ClassTable *class__ = this->mClass; 35 assert(NULL != class__); 36 int index; 37 if (0 > (index = class__->mMPH_to_index[MPH])) { 38 return false; 39 } 40 assert(MAX_INDEX >= class__->mInterfaceCount); 41 assert(class__->mInterfaceCount > (unsigned) index); 42 switch (this->mInterfaceStates[index]) { 43 case INTERFACE_EXPOSED: 44 case INTERFACE_ADDED: 45 return true; 46 default: 47 return false; 48 } 49 } 50 51 52 /** \brief Map an IObject to it's "object ID" (which is really a class ID) */ 53 54 SLuint32 IObjectToObjectID(IObject *this) 55 { 56 assert(NULL != this); 57 return this->mClass->mObjectID; 58 } 59 60 61 /** \brief Acquire a strong reference to an object. 62 * Check that object has the specified "object ID" (which is really a class ID) and is in the 63 * realized state. If so, then acquire a strong reference to it and return true. 64 * Otherwise return false. 65 */ 66 67 SLresult AcquireStrongRef(IObject *object, SLuint32 expectedObjectID) 68 { 69 if (NULL == object) { 70 return SL_RESULT_PARAMETER_INVALID; 71 } 72 // NTH additional validity checks on address here 73 SLresult result; 74 object_lock_exclusive(object); 75 SLuint32 actualObjectID = IObjectToObjectID(object); 76 if (expectedObjectID != actualObjectID) { 77 SL_LOGE("object %p has object ID %lu but expected %lu", object, actualObjectID, 78 expectedObjectID); 79 result = SL_RESULT_PARAMETER_INVALID; 80 } else if (SL_OBJECT_STATE_REALIZED != object->mState) { 81 SL_LOGE("object %p with object ID %lu is not realized", object, actualObjectID); 82 result = SL_RESULT_PRECONDITIONS_VIOLATED; 83 } else { 84 ++object->mStrongRefCount; 85 result = SL_RESULT_SUCCESS; 86 } 87 object_unlock_exclusive(object); 88 return result; 89 } 90 91 92 /** \brief Release a strong reference to an object. 93 * Entry condition: the object is locked. 94 * Exit condition: the object is unlocked. 95 * Finishes the destroy if needed. 96 */ 97 98 void ReleaseStrongRefAndUnlockExclusive(IObject *object) 99 { 100 #ifdef USE_DEBUG 101 assert(pthread_equal(pthread_self(), object->mOwner)); 102 #endif 103 assert(0 < object->mStrongRefCount); 104 if ((0 == --object->mStrongRefCount) && (SL_OBJECT_STATE_DESTROYING == object->mState)) { 105 // FIXME do the destroy here - merge with IDestroy 106 // but can't do this until we move Destroy to the sync thread 107 // as Destroy is now a blocking operation, and to avoid a race 108 } else { 109 object_unlock_exclusive(object); 110 } 111 } 112 113 114 /** \brief Release a strong reference to an object. 115 * Entry condition: the object is unlocked. 116 * Exit condition: the object is unlocked. 117 * Finishes the destroy if needed. 118 */ 119 120 void ReleaseStrongRef(IObject *object) 121 { 122 assert(NULL != object); 123 object_lock_exclusive(object); 124 ReleaseStrongRefAndUnlockExclusive(object); 125 } 126 127 128 /** \brief Convert POSIX pthread error code to OpenSL ES result code */ 129 130 SLresult err_to_result(int err) 131 { 132 if (EAGAIN == err || ENOMEM == err) { 133 return SL_RESULT_RESOURCE_ERROR; 134 } 135 if (0 != err) { 136 return SL_RESULT_INTERNAL_ERROR; 137 } 138 return SL_RESULT_SUCCESS; 139 } 140 141 142 /** \brief Check the interface IDs passed into a Create operation */ 143 144 SLresult checkInterfaces(const ClassTable *class__, SLuint32 numInterfaces, 145 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired, unsigned *pExposedMask) 146 { 147 assert(NULL != class__ && NULL != pExposedMask); 148 // Initially no interfaces are exposed 149 unsigned exposedMask = 0; 150 const struct iid_vtable *interfaces = class__->mInterfaces; 151 SLuint32 interfaceCount = class__->mInterfaceCount; 152 SLuint32 i; 153 // Expose all implicit interfaces 154 for (i = 0; i < interfaceCount; ++i) { 155 switch (interfaces[i].mInterface) { 156 case INTERFACE_IMPLICIT: 157 case INTERFACE_IMPLICIT_PREREALIZE: 158 // there must be an initialization hook present 159 if (NULL != MPH_init_table[interfaces[i].mMPH].mInit) { 160 exposedMask |= 1 << i; 161 } 162 break; 163 case INTERFACE_EXPLICIT: 164 case INTERFACE_DYNAMIC: 165 case INTERFACE_UNAVAILABLE: 166 case INTERFACE_EXPLICIT_PREREALIZE: 167 break; 168 default: 169 assert(false); 170 break; 171 } 172 } 173 if (0 < numInterfaces) { 174 if (NULL == pInterfaceIds || NULL == pInterfaceRequired) { 175 return SL_RESULT_PARAMETER_INVALID; 176 } 177 bool anyRequiredButUnsupported = false; 178 // Loop for each requested interface 179 for (i = 0; i < numInterfaces; ++i) { 180 SLInterfaceID iid = pInterfaceIds[i]; 181 if (NULL == iid) { 182 return SL_RESULT_PARAMETER_INVALID; 183 } 184 int MPH, index; 185 if ((0 > (MPH = IID_to_MPH(iid))) || 186 // there must be an initialization hook present 187 (NULL == MPH_init_table[MPH].mInit) || 188 (0 > (index = class__->mMPH_to_index[MPH])) || 189 (INTERFACE_UNAVAILABLE == interfaces[index].mInterface)) { 190 // Here if interface was not found, or is not available for this object type 191 if (pInterfaceRequired[i]) { 192 // Application said it required the interface, so give up 193 SL_LOGE("class %s interface %lu required but unavailable MPH=%d", 194 class__->mName, i, MPH); 195 anyRequiredButUnsupported = true; 196 } 197 // Application said it didn't really need the interface, so ignore with warning 198 SL_LOGW("class %s interface %lu requested but unavailable MPH=%d", 199 class__->mName, i, MPH); 200 continue; 201 } 202 // The requested interface was both found and available, so expose it 203 exposedMask |= (1 << index); 204 // Note that we ignore duplicate requests, including equal and aliased IDs 205 } 206 if (anyRequiredButUnsupported) { 207 return SL_RESULT_FEATURE_UNSUPPORTED; 208 } 209 } 210 *pExposedMask = exposedMask; 211 return SL_RESULT_SUCCESS; 212 } 213 214 215 /** \brief Helper shared by decoder and encoder */ 216 217 SLresult GetCodecCapabilities(SLuint32 codecId, SLuint32 *pIndex, 218 SLAudioCodecDescriptor *pDescriptor, const CodecDescriptor *codecDescriptors) 219 { 220 if (NULL == pIndex) { 221 return SL_RESULT_PARAMETER_INVALID; 222 } 223 const CodecDescriptor *cd = codecDescriptors; 224 SLuint32 index; 225 if (NULL == pDescriptor) { 226 for (index = 0 ; NULL != cd->mDescriptor; ++cd) { 227 if (cd->mCodecID == codecId) { 228 ++index; 229 } 230 } 231 *pIndex = index; 232 return SL_RESULT_SUCCESS; 233 } 234 index = *pIndex; 235 for ( ; NULL != cd->mDescriptor; ++cd) { 236 if (cd->mCodecID == codecId) { 237 if (0 == index) { 238 *pDescriptor = *cd->mDescriptor; 239 #if 0 // Temporary workaround for Khronos bug 6331 240 if (0 < pDescriptor->numSampleRatesSupported) { 241 // The malloc is not in the 1.0.1 specification 242 SLmilliHertz *temp = (SLmilliHertz *) malloc(sizeof(SLmilliHertz) * 243 pDescriptor->numSampleRatesSupported); 244 assert(NULL != temp); 245 memcpy(temp, pDescriptor->pSampleRatesSupported, sizeof(SLmilliHertz) * 246 pDescriptor->numSampleRatesSupported); 247 pDescriptor->pSampleRatesSupported = temp; 248 } else { 249 pDescriptor->pSampleRatesSupported = NULL; 250 } 251 #endif 252 return SL_RESULT_SUCCESS; 253 } 254 --index; 255 } 256 } 257 return SL_RESULT_PARAMETER_INVALID; 258 } 259 260 261 /** \brief Check a data locator and make local deep copy */ 262 263 static SLresult checkDataLocator(void *pLocator, DataLocator *pDataLocator) 264 { 265 if (NULL == pLocator) { 266 pDataLocator->mLocatorType = SL_DATALOCATOR_NULL; 267 return SL_RESULT_SUCCESS; 268 } 269 SLresult result; 270 SLuint32 locatorType = *(SLuint32 *)pLocator; 271 switch (locatorType) { 272 273 case SL_DATALOCATOR_ADDRESS: 274 pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator; 275 // if length is greater than zero, then the address must be non-NULL 276 if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) { 277 SL_LOGE("pAddress is NULL"); 278 return SL_RESULT_PARAMETER_INVALID; 279 } 280 break; 281 282 case SL_DATALOCATOR_BUFFERQUEUE: 283 #ifdef ANDROID 284 // This is an alias that is _not_ converted; the rest of the code must check for both locator 285 // types. That's because it is only an alias for audio players, not audio recorder objects 286 // so we have to remember the distinction. 287 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 288 #endif 289 pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator; 290 // number of buffers must be specified, there is no default value, and must not be excessive 291 if (!((1 <= pDataLocator->mBufferQueue.numBuffers) && 292 (pDataLocator->mBufferQueue.numBuffers <= 255))) { 293 SL_LOGE("numBuffers=%u", (unsigned) pDataLocator->mBufferQueue.numBuffers); 294 return SL_RESULT_PARAMETER_INVALID; 295 } 296 break; 297 298 case SL_DATALOCATOR_IODEVICE: 299 { 300 pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator; 301 SLuint32 deviceType = pDataLocator->mIODevice.deviceType; 302 SLObjectItf device = pDataLocator->mIODevice.device; 303 if (NULL != device) { 304 pDataLocator->mIODevice.deviceID = 0; 305 SLuint32 expectedObjectID; 306 switch (deviceType) { 307 case SL_IODEVICE_LEDARRAY: 308 expectedObjectID = SL_OBJECTID_LEDDEVICE; 309 break; 310 case SL_IODEVICE_VIBRA: 311 expectedObjectID = SL_OBJECTID_VIBRADEVICE; 312 break; 313 // audio input and audio output cannot be specified via objects 314 case SL_IODEVICE_AUDIOINPUT: 315 // worse yet, an SL_IODEVICE enum constant for audio output does not exist yet 316 // case SL_IODEVICE_AUDIOOUTPUT: 317 default: 318 SL_LOGE("invalid deviceType %lu", deviceType); 319 pDataLocator->mIODevice.device = NULL; 320 return SL_RESULT_PARAMETER_INVALID; 321 } 322 // check that device has the correct object ID and is realized, 323 // and acquire a strong reference to it 324 result = AcquireStrongRef((IObject *) device, expectedObjectID); 325 if (SL_RESULT_SUCCESS != result) { 326 SL_LOGE("locator type is IODEVICE, but device field %p has wrong object ID or is " \ 327 "not realized", device); 328 pDataLocator->mIODevice.device = NULL; 329 return result; 330 } 331 } else { 332 SLuint32 deviceID = pDataLocator->mIODevice.deviceID; 333 switch (deviceType) { 334 case SL_IODEVICE_LEDARRAY: 335 if (SL_DEFAULTDEVICEID_LED != deviceID) { 336 SL_LOGE("invalid LED deviceID %lu", deviceID); 337 return SL_RESULT_PARAMETER_INVALID; 338 } 339 break; 340 case SL_IODEVICE_VIBRA: 341 if (SL_DEFAULTDEVICEID_VIBRA != deviceID) { 342 SL_LOGE("invalid vibra deviceID %lu", deviceID); 343 return SL_RESULT_PARAMETER_INVALID; 344 } 345 break; 346 case SL_IODEVICE_AUDIOINPUT: 347 if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) { 348 SL_LOGE("invalid audio input deviceID %lu", deviceID); 349 return SL_RESULT_PARAMETER_INVALID; 350 } 351 break; 352 default: 353 SL_LOGE("invalid deviceType %lu", deviceType); 354 return SL_RESULT_PARAMETER_INVALID; 355 } 356 } 357 } 358 break; 359 360 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 361 pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator; 362 if (0 == pDataLocator->mMIDIBufferQueue.tpqn) { 363 pDataLocator->mMIDIBufferQueue.tpqn = 192; 364 } 365 // number of buffers must be specified, there is no default value, and must not be excessive 366 if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) && 367 (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) { 368 SL_LOGE("invalid MIDI buffer queue"); 369 return SL_RESULT_PARAMETER_INVALID; 370 } 371 break; 372 373 case SL_DATALOCATOR_OUTPUTMIX: 374 pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator; 375 // check that output mix object has the correct object ID and is realized, 376 // and acquire a strong reference to it 377 result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix, 378 SL_OBJECTID_OUTPUTMIX); 379 if (SL_RESULT_SUCCESS != result) { 380 SL_LOGE("locatorType is SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does not " \ 381 "refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \ 382 pDataLocator->mOutputMix.outputMix); 383 pDataLocator->mOutputMix.outputMix = NULL; 384 return result; 385 } 386 break; 387 388 case SL_DATALOCATOR_URI: 389 { 390 pDataLocator->mURI = *(SLDataLocator_URI *)pLocator; 391 if (NULL == pDataLocator->mURI.URI) { 392 SL_LOGE("invalid URI"); 393 return SL_RESULT_PARAMETER_INVALID; 394 } 395 // NTH verify URI address for validity 396 size_t len = strlen((const char *) pDataLocator->mURI.URI); 397 SLchar *myURI = (SLchar *) malloc(len + 1); 398 if (NULL == myURI) { 399 pDataLocator->mURI.URI = NULL; 400 return SL_RESULT_MEMORY_FAILURE; 401 } 402 memcpy(myURI, pDataLocator->mURI.URI, len + 1); 403 // Verify that another thread didn't change the NUL-terminator after we used it 404 // to determine length of string to copy. It's OK if the string became shorter. 405 if ('\0' != myURI[len]) { 406 free(myURI); 407 pDataLocator->mURI.URI = NULL; 408 return SL_RESULT_PARAMETER_INVALID; 409 } 410 pDataLocator->mURI.URI = myURI; 411 } 412 break; 413 414 #ifdef ANDROID 415 case SL_DATALOCATOR_ANDROIDFD: 416 { 417 pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator; 418 SL_LOGV("Data locator FD: fd=%ld offset=%lld length=%lld", pDataLocator->mFD.fd, 419 pDataLocator->mFD.offset, pDataLocator->mFD.length); 420 // NTH check against process fd limit 421 if (0 > pDataLocator->mFD.fd) { 422 return SL_RESULT_PARAMETER_INVALID; 423 } 424 } 425 break; 426 #endif 427 428 default: 429 SL_LOGE("invalid locatorType %lu", locatorType); 430 return SL_RESULT_PARAMETER_INVALID; 431 } 432 433 // Verify that another thread didn't change the locatorType field after we used it 434 // to determine sizeof struct to copy. 435 if (locatorType != pDataLocator->mLocatorType) { 436 return SL_RESULT_PARAMETER_INVALID; 437 } 438 return SL_RESULT_SUCCESS; 439 } 440 441 442 /** \brief Free the local deep copy of a data locator */ 443 444 static void freeDataLocator(DataLocator *pDataLocator) 445 { 446 switch (pDataLocator->mLocatorType) { 447 case SL_DATALOCATOR_URI: 448 if (NULL != pDataLocator->mURI.URI) { 449 free(pDataLocator->mURI.URI); 450 pDataLocator->mURI.URI = NULL; 451 } 452 pDataLocator->mURI.URI = NULL; 453 break; 454 case SL_DATALOCATOR_IODEVICE: 455 if (NULL != pDataLocator->mIODevice.device) { 456 ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device); 457 pDataLocator->mIODevice.device = NULL; 458 } 459 break; 460 case SL_DATALOCATOR_OUTPUTMIX: 461 if (NULL != pDataLocator->mOutputMix.outputMix) { 462 ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix); 463 pDataLocator->mOutputMix.outputMix = NULL; 464 } 465 break; 466 default: 467 break; 468 } 469 } 470 471 472 /** \brief Check a data format and make local deep copy */ 473 474 static SLresult checkDataFormat(void *pFormat, DataFormat *pDataFormat) 475 { 476 SLresult result = SL_RESULT_SUCCESS; 477 478 if (NULL == pFormat) { 479 pDataFormat->mFormatType = SL_DATAFORMAT_NULL; 480 } else { 481 SLuint32 formatType = *(SLuint32 *)pFormat; 482 switch (formatType) { 483 484 case SL_DATAFORMAT_PCM: 485 pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat; 486 do { 487 488 // check the channel count 489 switch (pDataFormat->mPCM.numChannels) { 490 case 1: // mono 491 case 2: // stereo 492 break; 493 case 0: // unknown 494 result = SL_RESULT_PARAMETER_INVALID; 495 break; 496 default: // multi-channel 497 result = SL_RESULT_CONTENT_UNSUPPORTED; 498 break; 499 } 500 if (SL_RESULT_SUCCESS != result) { 501 SL_LOGE("numChannels=%u", (unsigned) pDataFormat->mPCM.numChannels); 502 break; 503 } 504 505 // check the sampling rate 506 switch (pDataFormat->mPCM.samplesPerSec) { 507 case SL_SAMPLINGRATE_8: 508 case SL_SAMPLINGRATE_11_025: 509 case SL_SAMPLINGRATE_12: 510 case SL_SAMPLINGRATE_16: 511 case SL_SAMPLINGRATE_22_05: 512 case SL_SAMPLINGRATE_24: 513 case SL_SAMPLINGRATE_32: 514 case SL_SAMPLINGRATE_44_1: 515 case SL_SAMPLINGRATE_48: 516 case SL_SAMPLINGRATE_64: 517 case SL_SAMPLINGRATE_88_2: 518 case SL_SAMPLINGRATE_96: 519 case SL_SAMPLINGRATE_192: 520 break; 521 case 0: 522 result = SL_RESULT_PARAMETER_INVALID; 523 break; 524 default: 525 result = SL_RESULT_CONTENT_UNSUPPORTED; 526 break; 527 } 528 if (SL_RESULT_SUCCESS != result) { 529 SL_LOGE("samplesPerSec=%u", (unsigned) pDataFormat->mPCM.samplesPerSec); 530 break; 531 } 532 533 // check the sample bit depth 534 switch (pDataFormat->mPCM.bitsPerSample) { 535 case SL_PCMSAMPLEFORMAT_FIXED_8: 536 case SL_PCMSAMPLEFORMAT_FIXED_16: 537 break; 538 case SL_PCMSAMPLEFORMAT_FIXED_20: 539 case SL_PCMSAMPLEFORMAT_FIXED_24: 540 case SL_PCMSAMPLEFORMAT_FIXED_28: 541 case SL_PCMSAMPLEFORMAT_FIXED_32: 542 result = SL_RESULT_CONTENT_UNSUPPORTED; 543 break; 544 default: 545 result = SL_RESULT_PARAMETER_INVALID; 546 break; 547 } 548 if (SL_RESULT_SUCCESS != result) { 549 SL_LOGE("bitsPerSample=%u", (unsigned) pDataFormat->mPCM.bitsPerSample); 550 break; 551 } 552 553 // check the container bit depth 554 if (pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) { 555 result = SL_RESULT_PARAMETER_INVALID; 556 } else if (pDataFormat->mPCM.containerSize != pDataFormat->mPCM.bitsPerSample) { 557 result = SL_RESULT_CONTENT_UNSUPPORTED; 558 } 559 if (SL_RESULT_SUCCESS != result) { 560 SL_LOGE("containerSize=%u, bitsPerSample=%u", 561 (unsigned) pDataFormat->mPCM.containerSize, 562 (unsigned) pDataFormat->mPCM.bitsPerSample); 563 break; 564 } 565 566 // check the channel mask 567 switch (pDataFormat->mPCM.channelMask) { 568 case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT: 569 if (2 != pDataFormat->mPCM.numChannels) { 570 result = SL_RESULT_PARAMETER_INVALID; 571 } 572 break; 573 case SL_SPEAKER_FRONT_LEFT: 574 case SL_SPEAKER_FRONT_RIGHT: 575 case SL_SPEAKER_FRONT_CENTER: 576 if (1 != pDataFormat->mPCM.numChannels) { 577 result = SL_RESULT_PARAMETER_INVALID; 578 } 579 break; 580 case 0: 581 pDataFormat->mPCM.channelMask = pDataFormat->mPCM.numChannels == 2 ? 582 SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT : SL_SPEAKER_FRONT_CENTER; 583 break; 584 default: 585 result = SL_RESULT_PARAMETER_INVALID; 586 break; 587 } 588 if (SL_RESULT_SUCCESS != result) { 589 SL_LOGE("channelMask=0x%lx numChannels=%lu", pDataFormat->mPCM.channelMask, 590 pDataFormat->mPCM.numChannels); 591 break; 592 } 593 594 // check the endianness / byte order 595 switch (pDataFormat->mPCM.endianness) { 596 case SL_BYTEORDER_LITTLEENDIAN: 597 case SL_BYTEORDER_BIGENDIAN: 598 break; 599 // native is proposed but not yet in spec 600 default: 601 result = SL_RESULT_PARAMETER_INVALID; 602 break; 603 } 604 if (SL_RESULT_SUCCESS != result) { 605 SL_LOGE("endianness=%u", (unsigned) pDataFormat->mPCM.endianness); 606 break; 607 } 608 609 // here if all checks passed successfully 610 611 } while(0); 612 break; 613 614 case SL_DATAFORMAT_MIME: 615 pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat; 616 if (NULL != pDataFormat->mMIME.mimeType) { 617 // NTH check address for validity 618 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType); 619 SLchar *myMIME = (SLchar *) malloc(len + 1); 620 if (NULL == myMIME) { 621 result = SL_RESULT_MEMORY_FAILURE; 622 } else { 623 memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1); 624 // make sure MIME string was not modified asynchronously 625 if ('\0' != myMIME[len]) { 626 free(myMIME); 627 myMIME = NULL; 628 result = SL_RESULT_PRECONDITIONS_VIOLATED; 629 } 630 } 631 pDataFormat->mMIME.mimeType = myMIME; 632 } 633 break; 634 635 default: 636 result = SL_RESULT_PARAMETER_INVALID; 637 SL_LOGE("formatType=%u", (unsigned) formatType); 638 break; 639 640 } 641 642 // make sure format type was not modified asynchronously 643 if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) { 644 result = SL_RESULT_PRECONDITIONS_VIOLATED; 645 } 646 647 } 648 649 return result; 650 } 651 652 653 /** \brief Check interface ID compatibility with respect to a particular data locator format */ 654 655 SLresult checkSourceFormatVsInterfacesCompatibility(const DataLocatorFormat *pDataLocatorFormat, 656 const ClassTable *class__, unsigned exposedMask) { 657 int index; 658 switch (pDataLocatorFormat->mLocator.mLocatorType) { 659 case SL_DATALOCATOR_BUFFERQUEUE: 660 #ifdef ANDROID 661 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 662 #endif 663 // can't request SLSeekItf if data source is a buffer queue 664 index = class__->mMPH_to_index[MPH_SEEK]; 665 if (0 <= index) { 666 if (exposedMask & (1 << index)) { 667 SL_LOGE("can't request SL_IID_SEEK with a buffer queue data source"); 668 return SL_RESULT_FEATURE_UNSUPPORTED; 669 } 670 } 671 // can't request SLMuteSoloItf if data source is a mono buffer queue 672 index = class__->mMPH_to_index[MPH_MUTESOLO]; 673 if (0 <= index) { 674 if ((exposedMask & (1 << index)) && 675 (SL_DATAFORMAT_PCM == pDataLocatorFormat->mFormat.mFormatType) && 676 (1 == pDataLocatorFormat->mFormat.mPCM.numChannels)) { 677 SL_LOGE("can't request SL_IID_MUTESOLO with a mono buffer queue data source"); 678 return SL_RESULT_FEATURE_UNSUPPORTED; 679 } 680 } 681 break; 682 default: 683 // can't request SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf 684 // if the data source is not a buffer queue 685 index = class__->mMPH_to_index[MPH_BUFFERQUEUE]; 686 #ifdef ANDROID 687 assert(index == class__->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]); 688 #endif 689 if (0 <= index) { 690 if (exposedMask & (1 << index)) { 691 SL_LOGE("can't request SL_IID_BUFFERQUEUE " 692 #ifdef ANDROID 693 "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE " 694 #endif 695 "with a non-buffer queue data source"); 696 return SL_RESULT_FEATURE_UNSUPPORTED; 697 } 698 } 699 break; 700 } 701 return SL_RESULT_SUCCESS; 702 } 703 704 705 /** \brief Free the local deep copy of a data format */ 706 707 static void freeDataFormat(DataFormat *pDataFormat) 708 { 709 switch (pDataFormat->mFormatType) { 710 case SL_DATAFORMAT_MIME: 711 if (NULL != pDataFormat->mMIME.mimeType) { 712 free(pDataFormat->mMIME.mimeType); 713 pDataFormat->mMIME.mimeType = NULL; 714 } 715 break; 716 default: 717 break; 718 } 719 } 720 721 722 /** \brief Check a data source and make local deep copy */ 723 724 SLresult checkDataSource(const SLDataSource *pDataSrc, DataLocatorFormat *pDataLocatorFormat) 725 { 726 if (NULL == pDataSrc) { 727 SL_LOGE("pDataSrc NULL"); 728 return SL_RESULT_PARAMETER_INVALID; 729 } 730 SLDataSource myDataSrc = *pDataSrc; 731 SLresult result; 732 result = checkDataLocator(myDataSrc.pLocator, &pDataLocatorFormat->mLocator); 733 if (SL_RESULT_SUCCESS != result) { 734 return result; 735 } 736 switch (pDataLocatorFormat->mLocator.mLocatorType) { 737 738 case SL_DATALOCATOR_URI: 739 case SL_DATALOCATOR_ADDRESS: 740 case SL_DATALOCATOR_BUFFERQUEUE: 741 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 742 #ifdef ANDROID 743 case SL_DATALOCATOR_ANDROIDFD: 744 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 745 #endif 746 result = checkDataFormat(myDataSrc.pFormat, &pDataLocatorFormat->mFormat); 747 if (SL_RESULT_SUCCESS != result) { 748 freeDataLocator(&pDataLocatorFormat->mLocator); 749 return result; 750 } 751 break; 752 753 case SL_DATALOCATOR_NULL: 754 case SL_DATALOCATOR_OUTPUTMIX: 755 default: 756 // invalid but fall through; the invalid locator will be caught later 757 SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 758 // keep going 759 760 case SL_DATALOCATOR_IODEVICE: 761 // for these data locator types, ignore the pFormat as it might be uninitialized 762 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 763 break; 764 } 765 766 pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator; 767 pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat; 768 return SL_RESULT_SUCCESS; 769 } 770 771 772 /** \brief Check a data sink and make local deep copy */ 773 774 SLresult checkDataSink(const SLDataSink *pDataSink, DataLocatorFormat *pDataLocatorFormat, 775 SLuint32 objType) 776 { 777 if (NULL == pDataSink) { 778 SL_LOGE("pDataSink NULL"); 779 return SL_RESULT_PARAMETER_INVALID; 780 } 781 SLDataSink myDataSink = *pDataSink; 782 SLresult result; 783 result = checkDataLocator(myDataSink.pLocator, &pDataLocatorFormat->mLocator); 784 if (SL_RESULT_SUCCESS != result) { 785 return result; 786 } 787 switch (pDataLocatorFormat->mLocator.mLocatorType) { 788 789 case SL_DATALOCATOR_URI: 790 case SL_DATALOCATOR_ADDRESS: 791 result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 792 if (SL_RESULT_SUCCESS != result) { 793 freeDataLocator(&pDataLocatorFormat->mLocator); 794 return result; 795 } 796 break; 797 798 case SL_DATALOCATOR_BUFFERQUEUE: 799 #ifdef ANDROID 800 case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: 801 #endif 802 if (SL_OBJECTID_AUDIOPLAYER == objType) { 803 SL_LOGE("buffer queue can't be used as data sink for audio player"); 804 result = SL_RESULT_PARAMETER_INVALID; 805 } else if (SL_OBJECTID_AUDIORECORDER == objType) { 806 #ifdef ANDROID 807 if (SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE != 808 pDataLocatorFormat->mLocator.mLocatorType) { 809 SL_LOGE("audio recorder source locator must be SL_DATALOCATOR_ANDROIDBUFFERQUEUE"); 810 result = SL_RESULT_PARAMETER_INVALID; 811 } else { 812 result = checkDataFormat(myDataSink.pFormat, &pDataLocatorFormat->mFormat); 813 } 814 #else 815 SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 816 result = SL_RESULT_PARAMETER_INVALID; 817 #endif 818 } 819 if (SL_RESULT_SUCCESS != result) { 820 freeDataLocator(&pDataLocatorFormat->mLocator); 821 return result; 822 } 823 break; 824 825 case SL_DATALOCATOR_NULL: 826 case SL_DATALOCATOR_MIDIBUFFERQUEUE: 827 default: 828 // invalid but fall through; the invalid locator will be caught later 829 SL_LOGE("mLocatorType=%u", (unsigned) pDataLocatorFormat->mLocator.mLocatorType); 830 // keep going 831 832 case SL_DATALOCATOR_IODEVICE: 833 case SL_DATALOCATOR_OUTPUTMIX: 834 // for these data locator types, ignore the pFormat as it might be uninitialized 835 pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL; 836 break; 837 } 838 839 pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator; 840 pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat; 841 return SL_RESULT_SUCCESS; 842 } 843 844 845 /** \brief Free the local deep copy of a data locator format */ 846 847 void freeDataLocatorFormat(DataLocatorFormat *dlf) 848 { 849 freeDataLocator(&dlf->mLocator); 850 freeDataFormat(&dlf->mFormat); 851 } 852 853 854 /* Interface initialization hooks */ 855 856 extern void 857 I3DCommit_init(void *), 858 I3DDoppler_init(void *), 859 I3DGrouping_init(void *), 860 I3DLocation_init(void *), 861 I3DMacroscopic_init(void *), 862 I3DSource_init(void *), 863 IAndroidConfiguration_init(void *), 864 IAndroidEffect_init(void *), 865 IAndroidEffectCapabilities_init(void *), 866 IAndroidEffectSend_init(void *), 867 IAudioDecoderCapabilities_init(void *), 868 IAudioEncoder_init(void *), 869 IAudioEncoderCapabilities_init(void *), 870 IAudioIODeviceCapabilities_init(void *), 871 IBassBoost_init(void *), 872 IBufferQueue_init(void *), 873 IDeviceVolume_init(void *), 874 IDynamicInterfaceManagement_init(void *), 875 IDynamicSource_init(void *), 876 IEffectSend_init(void *), 877 IEngine_init(void *), 878 IEngineCapabilities_init(void *), 879 IEnvironmentalReverb_init(void *), 880 IEqualizer_init(void *), 881 ILEDArray_init(void *), 882 IMIDIMessage_init(void *), 883 IMIDIMuteSolo_init(void *), 884 IMIDITempo_init(void *), 885 IMIDITime_init(void *), 886 IMetadataExtraction_init(void *), 887 IMetadataTraversal_init(void *), 888 IMuteSolo_init(void *), 889 IObject_init(void *), 890 IOutputMix_init(void *), 891 IOutputMixExt_init(void *), 892 IPitch_init(void *), 893 IPlay_init(void *), 894 IPlaybackRate_init(void *), 895 IPrefetchStatus_init(void *), 896 IPresetReverb_init(void *), 897 IRatePitch_init(void *), 898 IRecord_init(void *), 899 ISeek_init(void *), 900 IThreadSync_init(void *), 901 IVibra_init(void *), 902 IVirtualizer_init(void *), 903 IVisualization_init(void *), 904 IVolume_init(void *); 905 906 extern void 907 I3DGrouping_deinit(void *), 908 IAndroidEffect_deinit(void *), 909 IAndroidEffectCapabilities_deinit(void *), 910 IBassBoost_deinit(void *), 911 IBufferQueue_deinit(void *), 912 IEngine_deinit(void *), 913 IEnvironmentalReverb_deinit(void *), 914 IEqualizer_deinit(void *), 915 IObject_deinit(void *), 916 IPresetReverb_deinit(void *), 917 IThreadSync_deinit(void *), 918 IVirtualizer_deinit(void *); 919 920 extern bool 921 IAndroidEffectCapabilities_Expose(void *), 922 IBassBoost_Expose(void *), 923 IEnvironmentalReverb_Expose(void *), 924 IEqualizer_Expose(void *), 925 IPresetReverb_Expose(void *), 926 IVirtualizer_Expose(void *); 927 928 #if !(USE_PROFILES & USE_PROFILES_MUSIC) 929 #define IDynamicSource_init NULL 930 #define IMetadataExtraction_init NULL 931 #define IMetadataTraversal_init NULL 932 #define IVisualization_init NULL 933 #endif 934 935 #if !(USE_PROFILES & USE_PROFILES_GAME) 936 #define I3DCommit_init NULL 937 #define I3DDoppler_init NULL 938 #define I3DGrouping_init NULL 939 #define I3DLocation_init NULL 940 #define I3DMacroscopic_init NULL 941 #define I3DSource_init NULL 942 #define IMIDIMessage_init NULL 943 #define IMIDIMuteSolo_init NULL 944 #define IMIDITempo_init NULL 945 #define IMIDITime_init NULL 946 #define IPitch_init NULL 947 #define IRatePitch_init NULL 948 #define I3DGrouping_deinit NULL 949 #endif 950 951 #if !(USE_PROFILES & USE_PROFILES_BASE) 952 #define IAudioDecoderCapabilities_init NULL 953 #define IAudioEncoderCapabilities_init NULL 954 #define IAudioEncoder_init NULL 955 #define IAudioIODeviceCapabilities_init NULL 956 #define IDeviceVolume_init NULL 957 #define IEngineCapabilities_init NULL 958 #define IThreadSync_init NULL 959 #define IThreadSync_deinit NULL 960 #endif 961 962 #if !(USE_PROFILES & USE_PROFILES_OPTIONAL) 963 #define ILEDArray_init NULL 964 #define IVibra_init NULL 965 #endif 966 967 #ifndef ANDROID 968 #define IAndroidConfiguration_init NULL 969 #define IAndroidEffect_init NULL 970 #define IAndroidEffectCapabilities_init NULL 971 #define IAndroidEffectSend_init NULL 972 #define IAndroidEffect_deinit NULL 973 #define IAndroidEffectCapabilities_deinit NULL 974 #define IAndroidEffectCapabilities_Expose NULL 975 #endif 976 977 #ifndef USE_OUTPUTMIXEXT 978 #define IOutputMixExt_init NULL 979 #endif 980 981 982 /*static*/ const struct MPH_init MPH_init_table[MPH_MAX] = { 983 { /* MPH_3DCOMMIT, */ I3DCommit_init, NULL, NULL, NULL, NULL }, 984 { /* MPH_3DDOPPLER, */ I3DDoppler_init, NULL, NULL, NULL, NULL }, 985 { /* MPH_3DGROUPING, */ I3DGrouping_init, NULL, I3DGrouping_deinit, NULL, NULL }, 986 { /* MPH_3DLOCATION, */ I3DLocation_init, NULL, NULL, NULL, NULL }, 987 { /* MPH_3DMACROSCOPIC, */ I3DMacroscopic_init, NULL, NULL, NULL, NULL }, 988 { /* MPH_3DSOURCE, */ I3DSource_init, NULL, NULL, NULL, NULL }, 989 { /* MPH_AUDIODECODERCAPABILITIES, */ IAudioDecoderCapabilities_init, NULL, NULL, NULL, NULL }, 990 { /* MPH_AUDIOENCODER, */ IAudioEncoder_init, NULL, NULL, NULL, NULL }, 991 { /* MPH_AUDIOENCODERCAPABILITIES, */ IAudioEncoderCapabilities_init, NULL, NULL, NULL, NULL }, 992 { /* MPH_AUDIOIODEVICECAPABILITIES, */ IAudioIODeviceCapabilities_init, NULL, NULL, NULL, 993 NULL }, 994 { /* MPH_BASSBOOST, */ IBassBoost_init, NULL, IBassBoost_deinit, IBassBoost_Expose, NULL }, 995 { /* MPH_BUFFERQUEUE, */ IBufferQueue_init, NULL, IBufferQueue_deinit, NULL, NULL }, 996 { /* MPH_DEVICEVOLUME, */ IDeviceVolume_init, NULL, NULL, NULL, NULL }, 997 { /* MPH_DYNAMICINTERFACEMANAGEMENT, */ IDynamicInterfaceManagement_init, NULL, NULL, NULL, 998 NULL }, 999 { /* MPH_DYNAMICSOURCE, */ IDynamicSource_init, NULL, NULL, NULL, NULL }, 1000 { /* MPH_EFFECTSEND, */ IEffectSend_init, NULL, NULL, NULL, NULL }, 1001 { /* MPH_ENGINE, */ IEngine_init, NULL, IEngine_deinit, NULL, NULL }, 1002 { /* MPH_ENGINECAPABILITIES, */ IEngineCapabilities_init, NULL, NULL, NULL, NULL }, 1003 { /* MPH_ENVIRONMENTALREVERB, */ IEnvironmentalReverb_init, NULL, IEnvironmentalReverb_deinit, 1004 IEnvironmentalReverb_Expose, NULL }, 1005 { /* MPH_EQUALIZER, */ IEqualizer_init, NULL, IEqualizer_deinit, IEqualizer_Expose, NULL }, 1006 { /* MPH_LED, */ ILEDArray_init, NULL, NULL, NULL, NULL }, 1007 { /* MPH_METADATAEXTRACTION, */ IMetadataExtraction_init, NULL, NULL, NULL, NULL }, 1008 { /* MPH_METADATATRAVERSAL, */ IMetadataTraversal_init, NULL, NULL, NULL, NULL }, 1009 { /* MPH_MIDIMESSAGE, */ IMIDIMessage_init, NULL, NULL, NULL, NULL }, 1010 { /* MPH_MIDITIME, */ IMIDITime_init, NULL, NULL, NULL, NULL }, 1011 { /* MPH_MIDITEMPO, */ IMIDITempo_init, NULL, NULL, NULL, NULL }, 1012 { /* MPH_MIDIMUTESOLO, */ IMIDIMuteSolo_init, NULL, NULL, NULL, NULL }, 1013 { /* MPH_MUTESOLO, */ IMuteSolo_init, NULL, NULL, NULL, NULL }, 1014 { /* MPH_NULL, */ NULL, NULL, NULL, NULL, NULL }, 1015 { /* MPH_OBJECT, */ IObject_init, NULL, IObject_deinit, NULL, NULL }, 1016 { /* MPH_OUTPUTMIX, */ IOutputMix_init, NULL, NULL, NULL, NULL }, 1017 { /* MPH_PITCH, */ IPitch_init, NULL, NULL, NULL, NULL }, 1018 { /* MPH_PLAY, */ IPlay_init, NULL, NULL, NULL, NULL }, 1019 { /* MPH_PLAYBACKRATE, */ IPlaybackRate_init, NULL, NULL, NULL, NULL }, 1020 { /* MPH_PREFETCHSTATUS, */ IPrefetchStatus_init, NULL, NULL, NULL, NULL }, 1021 { /* MPH_PRESETREVERB, */ IPresetReverb_init, NULL, IPresetReverb_deinit, 1022 IPresetReverb_Expose, NULL }, 1023 { /* MPH_RATEPITCH, */ IRatePitch_init, NULL, NULL, NULL, NULL }, 1024 { /* MPH_RECORD, */ IRecord_init, NULL, NULL, NULL, NULL }, 1025 { /* MPH_SEEK, */ ISeek_init, NULL, NULL, NULL, NULL }, 1026 { /* MPH_THREADSYNC, */ IThreadSync_init, NULL, IThreadSync_deinit, NULL, NULL }, 1027 { /* MPH_VIBRA, */ IVibra_init, NULL, NULL, NULL, NULL }, 1028 { /* MPH_VIRTUALIZER, */ IVirtualizer_init, NULL, IVirtualizer_deinit, IVirtualizer_Expose, 1029 NULL }, 1030 { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL, NULL, NULL }, 1031 { /* MPH_VOLUME, */ IVolume_init, NULL, NULL, NULL, NULL }, 1032 { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL, NULL, NULL }, 1033 { /* MPH_ANDROIDEFFECT */ IAndroidEffect_init, NULL, IAndroidEffect_deinit, NULL, NULL }, 1034 { /* MPH_ANDROIDEFFECTCAPABILITIES */ IAndroidEffectCapabilities_init, NULL, 1035 IAndroidEffectCapabilities_deinit, IAndroidEffectCapabilities_Expose, NULL }, 1036 { /* MPH_ANDROIDEFFECTSEND */ IAndroidEffectSend_init, NULL, NULL, NULL, NULL }, 1037 { /* MPH_ANDROIDCONFIGURATION */ IAndroidConfiguration_init, NULL, NULL, NULL, NULL }, 1038 { /* MPH_ANDROIDSIMPLEBUFFERQUEUE, */ IBufferQueue_init /* alias */, NULL, NULL, NULL, NULL } 1039 }; 1040 1041 1042 /** \brief Construct a new instance of the specified class, exposing selected interfaces */ 1043 1044 IObject *construct(const ClassTable *class__, unsigned exposedMask, SLEngineItf engine) 1045 { 1046 IObject *this; 1047 // Do not change this to malloc; we depend on the object being memset to zero 1048 this = (IObject *) calloc(1, class__->mSize); 1049 if (NULL != this) { 1050 SL_LOGV("construct %s at %p", class__->mName, this); 1051 unsigned lossOfControlMask = 0; 1052 // a NULL engine means we are constructing the engine 1053 IEngine *thisEngine = (IEngine *) engine; 1054 if (NULL == thisEngine) { 1055 thisEngine = &((CEngine *) this)->mEngine; 1056 } else { 1057 interface_lock_exclusive(thisEngine); 1058 if (MAX_INSTANCE <= thisEngine->mInstanceCount) { 1059 SL_LOGE("Too many objects"); 1060 interface_unlock_exclusive(thisEngine); 1061 free(this); 1062 return NULL; 1063 } 1064 // pre-allocate a pending slot, but don't assign bit from mInstanceMask yet 1065 ++thisEngine->mInstanceCount; 1066 assert(((unsigned) ~0) != thisEngine->mInstanceMask); 1067 interface_unlock_exclusive(thisEngine); 1068 // const, no lock needed 1069 if (thisEngine->mLossOfControlGlobal) { 1070 lossOfControlMask = ~0; 1071 } 1072 } 1073 this->mLossOfControlMask = lossOfControlMask; 1074 this->mClass = class__; 1075 this->mEngine = thisEngine; 1076 const struct iid_vtable *x = class__->mInterfaces; 1077 SLuint8 *interfaceStateP = this->mInterfaceStates; 1078 SLuint32 index; 1079 for (index = 0; index < class__->mInterfaceCount; ++index, ++x, exposedMask >>= 1) { 1080 SLuint8 state; 1081 // initialize all interfaces with init hooks, even if not exposed 1082 const struct MPH_init *mi = &MPH_init_table[x->mMPH]; 1083 VoidHook init = mi->mInit; 1084 if (NULL != init) { 1085 void *self = (char *) this + x->mOffset; 1086 // IObject does not have an mThis, so [1] is not always defined 1087 if (index) { 1088 ((IObject **) self)[1] = this; 1089 } 1090 // call the initialization hook 1091 (*init)(self); 1092 // IObject does not require a call to GetInterface 1093 if (index) { 1094 // This trickery invalidates the v-table until GetInterface 1095 ((size_t *) self)[0] ^= ~0; 1096 } 1097 // if interface is exposed, also call the optional expose hook 1098 BoolHook expose; 1099 state = (exposedMask & 1) && ((NULL == (expose = mi->mExpose)) || (*expose)(self)) ? 1100 INTERFACE_EXPOSED : INTERFACE_INITIALIZED; 1101 // FIXME log or report to application if an expose hook on a 1102 // required explicit interface fails at creation time 1103 } else { 1104 state = INTERFACE_UNINITIALIZED; 1105 } 1106 *interfaceStateP++ = state; 1107 } 1108 // note that the new object is not yet published; creator must call IObject_Publish 1109 } 1110 return this; 1111 } 1112 1113 1114 /* This implementation supports at most one engine */ 1115 1116 static CEngine *theOneTrueEngine = NULL; 1117 static pthread_mutex_t theOneTrueMutex = PTHREAD_MUTEX_INITIALIZER; 1118 1119 1120 /** \brief Called by dlopen when .so is loaded */ 1121 1122 __attribute__((constructor)) static void onDlOpen(void) 1123 { 1124 } 1125 1126 1127 /** \brief Called by dlclose when .so is unloaded */ 1128 1129 __attribute__((destructor)) static void onDlClose(void) 1130 { 1131 if (NULL != theOneTrueEngine) { 1132 SL_LOGE("Object::Destroy omitted for engine %p", theOneTrueEngine); 1133 } 1134 } 1135 1136 /** \brief Called by IObject::Destroy after engine is destroyed. The parameter refers to the 1137 * previous engine, which is now undefined memory. 1138 */ 1139 1140 void CEngine_Destroyed(CEngine *self) 1141 { 1142 int ok; 1143 ok = pthread_mutex_lock(&theOneTrueMutex); 1144 assert(0 == ok); 1145 assert(self == theOneTrueEngine); 1146 theOneTrueEngine = NULL; 1147 ok = pthread_mutex_unlock(&theOneTrueMutex); 1148 assert(0 == ok); 1149 } 1150 1151 1152 /* Initial global entry points */ 1153 1154 1155 /** \brief slCreateEngine Function */ 1156 1157 SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions, 1158 const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, 1159 const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired) 1160 { 1161 SL_ENTER_GLOBAL 1162 1163 int ok; 1164 ok = pthread_mutex_lock(&theOneTrueMutex); 1165 assert(0 == ok); 1166 1167 do { 1168 1169 #ifdef ANDROID 1170 android::ProcessState::self()->startThreadPool(); 1171 #ifndef USE_BACKPORT 1172 android::DataSource::RegisterDefaultSniffers(); 1173 #endif 1174 #endif 1175 1176 if (NULL == pEngine) { 1177 result = SL_RESULT_PARAMETER_INVALID; 1178 break; 1179 } 1180 *pEngine = NULL; 1181 1182 if (NULL != theOneTrueEngine) { 1183 SL_LOGE("slCreateEngine while another engine %p is active", theOneTrueEngine); 1184 result = SL_RESULT_RESOURCE_ERROR; 1185 break; 1186 } 1187 1188 if ((0 < numOptions) && (NULL == pEngineOptions)) { 1189 SL_LOGE("numOptions=%lu and pEngineOptions=NULL", numOptions); 1190 result = SL_RESULT_PARAMETER_INVALID; 1191 break; 1192 } 1193 1194 // default values 1195 SLboolean threadSafe = SL_BOOLEAN_TRUE; 1196 SLboolean lossOfControlGlobal = SL_BOOLEAN_FALSE; 1197 1198 // process engine options 1199 SLuint32 i; 1200 const SLEngineOption *option = pEngineOptions; 1201 result = SL_RESULT_SUCCESS; 1202 for (i = 0; i < numOptions; ++i, ++option) { 1203 switch (option->feature) { 1204 case SL_ENGINEOPTION_THREADSAFE: 1205 threadSafe = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize 1206 break; 1207 case SL_ENGINEOPTION_LOSSOFCONTROL: 1208 lossOfControlGlobal = SL_BOOLEAN_FALSE != (SLboolean) option->data; // normalize 1209 break; 1210 default: 1211 SL_LOGE("unknown engine option: feature=%lu data=%lu", 1212 option->feature, option->data); 1213 result = SL_RESULT_PARAMETER_INVALID; 1214 break; 1215 } 1216 } 1217 if (SL_RESULT_SUCCESS != result) { 1218 break; 1219 } 1220 1221 unsigned exposedMask; 1222 const ClassTable *pCEngine_class = objectIDtoClass(SL_OBJECTID_ENGINE); 1223 assert(NULL != pCEngine_class); 1224 result = checkInterfaces(pCEngine_class, numInterfaces, 1225 pInterfaceIds, pInterfaceRequired, &exposedMask); 1226 if (SL_RESULT_SUCCESS != result) { 1227 break; 1228 } 1229 1230 CEngine *this = (CEngine *) construct(pCEngine_class, exposedMask, NULL); 1231 if (NULL == this) { 1232 result = SL_RESULT_MEMORY_FAILURE; 1233 break; 1234 } 1235 1236 // initialize fields not associated with an interface 1237 memset(&this->mSyncThread, 0, sizeof(pthread_t)); 1238 // initialize fields related to an interface 1239 this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0; 1240 this->mEngine.mLossOfControlGlobal = lossOfControlGlobal; 1241 this->mEngineCapabilities.mThreadSafe = threadSafe; 1242 IObject_Publish(&this->mObject); 1243 theOneTrueEngine = this; 1244 // return the new engine object 1245 *pEngine = &this->mObject.mItf; 1246 1247 } while(0); 1248 1249 ok = pthread_mutex_unlock(&theOneTrueMutex); 1250 assert(0 == ok); 1251 1252 SL_LEAVE_GLOBAL 1253 } 1254 1255 1256 /** \brief slQueryNumSupportedEngineInterfaces Function */ 1257 1258 SLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32 *pNumSupportedInterfaces) 1259 { 1260 SL_ENTER_GLOBAL 1261 1262 if (NULL == pNumSupportedInterfaces) { 1263 result = SL_RESULT_PARAMETER_INVALID; 1264 } else { 1265 const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE); 1266 assert(NULL != class__); 1267 SLuint32 count = 0; 1268 SLuint32 i; 1269 for (i = 0; i < class__->mInterfaceCount; ++i) { 1270 switch (class__->mInterfaces[i].mInterface) { 1271 case INTERFACE_IMPLICIT: 1272 case INTERFACE_IMPLICIT_PREREALIZE: 1273 case INTERFACE_EXPLICIT: 1274 case INTERFACE_EXPLICIT_PREREALIZE: 1275 case INTERFACE_DYNAMIC: 1276 ++count; 1277 break; 1278 case INTERFACE_UNAVAILABLE: 1279 break; 1280 default: 1281 assert(false); 1282 break; 1283 } 1284 } 1285 *pNumSupportedInterfaces = count; 1286 result = SL_RESULT_SUCCESS; 1287 } 1288 1289 SL_LEAVE_GLOBAL 1290 } 1291 1292 1293 /** \brief slQuerySupportedEngineInterfaces Function */ 1294 1295 SLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId) 1296 { 1297 SL_ENTER_GLOBAL 1298 1299 if (NULL == pInterfaceId) { 1300 result = SL_RESULT_PARAMETER_INVALID; 1301 } else { 1302 *pInterfaceId = NULL; 1303 const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE); 1304 assert(NULL != class__); 1305 result = SL_RESULT_PARAMETER_INVALID; // will be reset later 1306 SLuint32 i; 1307 for (i = 0; i < class__->mInterfaceCount; ++i) { 1308 switch (class__->mInterfaces[i].mInterface) { 1309 case INTERFACE_IMPLICIT: 1310 case INTERFACE_IMPLICIT_PREREALIZE: 1311 case INTERFACE_EXPLICIT: 1312 case INTERFACE_EXPLICIT_PREREALIZE: 1313 case INTERFACE_DYNAMIC: 1314 break; 1315 case INTERFACE_UNAVAILABLE: 1316 continue; 1317 default: 1318 assert(false); 1319 break; 1320 } 1321 if (index == 0) { 1322 // The engine has no aliases, but if it did, this would return only the primary 1323 *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH]; 1324 result = SL_RESULT_SUCCESS; 1325 break; 1326 } 1327 --index; 1328 } 1329 } 1330 1331 SL_LEAVE_GLOBAL 1332 } 1333