Home | History | Annotate | Download | only in libopensles
      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