Home | History | Annotate | Download | only in src
      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 /** Data locator, data format, data source, and data sink support */
     18 
     19 #include "sles_allinclusive.h"
     20 #ifdef ANDROID  // FIXME This file should be portable
     21 #include "android/channels.h"
     22 #include "data.h"
     23 #endif
     24 
     25 /** \brief Check a data locator and make local deep copy */
     26 
     27 static SLresult checkDataLocator(const char *name, void *pLocator, DataLocator *pDataLocator,
     28         SLuint32 allowedDataLocatorMask)
     29 {
     30     assert(NULL != name && NULL != pDataLocator);
     31     SLresult result = SL_RESULT_SUCCESS;
     32 
     33     SLuint32 locatorType;
     34     if (NULL == pLocator) {
     35         pDataLocator->mLocatorType = locatorType = SL_DATALOCATOR_NULL;
     36     } else {
     37         locatorType = *(SLuint32 *)pLocator;
     38         switch (locatorType) {
     39 
     40         case SL_DATALOCATOR_ADDRESS:
     41             pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator;
     42             // if length is greater than zero, then the address must be non-NULL
     43             if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) {
     44                 SL_LOGE("%s: pAddress=NULL", name);
     45                 result = SL_RESULT_PARAMETER_INVALID;
     46             }
     47             break;
     48 
     49         case SL_DATALOCATOR_BUFFERQUEUE:
     50 #ifdef ANDROID
     51         // This is an alias that is _not_ converted; the rest of the code must check for both
     52         // locator types. That's because it is only an alias for audio players, not audio recorder
     53         // objects so we have to remember the distinction.
     54         case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
     55 #endif
     56             pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator;
     57             // number of buffers must be specified, there is no default value, and can't be too big
     58             if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
     59                 (pDataLocator->mBufferQueue.numBuffers <= 255))) {
     60                 SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mBufferQueue.numBuffers);
     61                 result = SL_RESULT_PARAMETER_INVALID;
     62             }
     63             break;
     64 
     65         case SL_DATALOCATOR_IODEVICE:
     66             {
     67             pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator;
     68             SLuint32 deviceType = pDataLocator->mIODevice.deviceType;
     69             SLObjectItf device = pDataLocator->mIODevice.device;
     70             if (NULL != device) {
     71                 pDataLocator->mIODevice.deviceID = 0;
     72                 SLuint32 expectedObjectID;
     73                 switch (deviceType) {
     74                 case SL_IODEVICE_LEDARRAY:
     75                     expectedObjectID = SL_OBJECTID_LEDDEVICE;
     76                     break;
     77                 case SL_IODEVICE_VIBRA:
     78                     expectedObjectID = SL_OBJECTID_VIBRADEVICE;
     79                     break;
     80                 case XA_IODEVICE_CAMERA:
     81                     expectedObjectID = XA_OBJECTID_CAMERADEVICE;
     82                     break;
     83                 case XA_IODEVICE_RADIO:
     84                     expectedObjectID = XA_OBJECTID_RADIODEVICE;
     85                     break;
     86                 // audio input and audio output cannot be specified via objects
     87                 case SL_IODEVICE_AUDIOINPUT:
     88                 // case SL_IODEVICE_AUDIOOUTPUT:   // does not exist in 1.0.1, added in 1.1
     89                 default:
     90                     SL_LOGE("%s: deviceType=%u", name, deviceType);
     91                     pDataLocator->mIODevice.device = NULL;
     92                     expectedObjectID = 0;
     93                     result = SL_RESULT_PARAMETER_INVALID;
     94                 }
     95                 if (result == SL_RESULT_SUCCESS) {
     96                     // check that device has the correct object ID and is realized,
     97                     // and acquire a strong reference to it
     98                     result = AcquireStrongRef((IObject *) device, expectedObjectID);
     99                     if (SL_RESULT_SUCCESS != result) {
    100                         SL_LOGE("%s: locatorType=IODEVICE, but device field %p has wrong " \
    101                             "object ID or is not realized", name, device);
    102                         pDataLocator->mIODevice.device = NULL;
    103                     }
    104                 }
    105             } else {
    106                 SLuint32 deviceID = pDataLocator->mIODevice.deviceID;
    107                 switch (deviceType) {
    108                 case SL_IODEVICE_LEDARRAY:
    109                     if (SL_DEFAULTDEVICEID_LED != deviceID) {
    110                         SL_LOGE("%s: invalid LED deviceID=%u", name, deviceID);
    111                         result = SL_RESULT_PARAMETER_INVALID;
    112                     }
    113                     break;
    114                 case SL_IODEVICE_VIBRA:
    115                     if (SL_DEFAULTDEVICEID_VIBRA != deviceID) {
    116                         SL_LOGE("%s: invalid vibra deviceID=%u", name, deviceID);
    117                         result = SL_RESULT_PARAMETER_INVALID;
    118                     }
    119                     break;
    120                 case SL_IODEVICE_AUDIOINPUT:
    121                     if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) {
    122                         SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID);
    123                         result = SL_RESULT_PARAMETER_INVALID;
    124                     }
    125                     break;
    126                 case XA_IODEVICE_RADIO:
    127                     // no default device ID for radio; see Khronos bug XXXX
    128                     break;
    129                 case XA_IODEVICE_CAMERA:
    130                     if (XA_DEFAULTDEVICEID_CAMERA != deviceID) {
    131                         SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID);
    132                         result = XA_RESULT_PARAMETER_INVALID;
    133                     }
    134                     break;
    135                 // case SL_IODEVICE_AUDIOOUTPUT:
    136                     // does not exist in 1.0.1, added in 1.1
    137                     // break;
    138                 default:
    139                     SL_LOGE("%s: deviceType=%u is invalid", name, deviceType);
    140                     result = SL_RESULT_PARAMETER_INVALID;
    141                 }
    142             }
    143             }
    144             break;
    145 
    146         case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    147             pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator;
    148             if (0 == pDataLocator->mMIDIBufferQueue.tpqn) {
    149                 pDataLocator->mMIDIBufferQueue.tpqn = 192;
    150             }
    151             // number of buffers must be specified, there is no default value, and can't be too big
    152             if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) &&
    153                 (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) {
    154                 SL_LOGE("%s: SLDataLocator_MIDIBufferQueue.numBuffers=%d", name,
    155                         pDataLocator->mMIDIBufferQueue.numBuffers);
    156                 result = SL_RESULT_PARAMETER_INVALID;
    157             }
    158             break;
    159 
    160         case SL_DATALOCATOR_OUTPUTMIX:
    161             pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator;
    162             // check that output mix object has the correct object ID and is realized,
    163             // and acquire a strong reference to it
    164             result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix,
    165                 SL_OBJECTID_OUTPUTMIX);
    166             if (SL_RESULT_SUCCESS != result) {
    167                 SL_LOGE("%s: locatorType=SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does " \
    168                     "not refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \
    169                     name, pDataLocator->mOutputMix.outputMix);
    170                 pDataLocator->mOutputMix.outputMix = NULL;
    171             }
    172             break;
    173 
    174         case XA_DATALOCATOR_NATIVEDISPLAY:
    175             pDataLocator->mNativeDisplay = *(XADataLocator_NativeDisplay *)pLocator;
    176             // hWindow is NDK C ANativeWindow * and hDisplay must be NULL
    177             if (pDataLocator->mNativeDisplay.hWindow == NULL) {
    178                 SL_LOGE("%s: hWindow must be non-NULL ANativeWindow *", name);
    179                 result = SL_RESULT_PARAMETER_INVALID;
    180             }
    181             if (pDataLocator->mNativeDisplay.hDisplay != NULL) {
    182                 SL_LOGE("%s: hDisplay must be NULL, but is %p", name,
    183                         pDataLocator->mNativeDisplay.hDisplay);
    184                 result = SL_RESULT_PARAMETER_INVALID;
    185             }
    186             break;
    187 
    188         case SL_DATALOCATOR_URI:
    189             {
    190             pDataLocator->mURI = *(SLDataLocator_URI *)pLocator;
    191             if (NULL == pDataLocator->mURI.URI) {
    192                 SL_LOGE("%s: invalid URI=NULL", name);
    193                 result = SL_RESULT_PARAMETER_INVALID;
    194             } else {
    195                 // NTH verify URI address for validity
    196                 size_t len = strlen((const char *) pDataLocator->mURI.URI);
    197                 SLchar *myURI = (SLchar *) malloc(len + 1);
    198                 if (NULL == myURI) {
    199                     result = SL_RESULT_MEMORY_FAILURE;
    200                 } else {
    201                     memcpy(myURI, pDataLocator->mURI.URI, len + 1);
    202                     // Verify that another thread didn't change the NUL-terminator after we used it
    203                     // to determine length of string to copy. It's OK if the string became shorter.
    204                     if ('\0' != myURI[len]) {
    205                         free(myURI);
    206                         myURI = NULL;
    207                         result = SL_RESULT_PARAMETER_INVALID;
    208                     }
    209                 }
    210                 pDataLocator->mURI.URI = myURI;
    211             }
    212             }
    213             break;
    214 
    215 #ifdef ANDROID
    216         case SL_DATALOCATOR_ANDROIDFD:
    217         {
    218             pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator;
    219             SL_LOGV("%s: fd=%d offset=%lld length=%lld", name, pDataLocator->mFD.fd,
    220                     pDataLocator->mFD.offset, pDataLocator->mFD.length);
    221             // NTH check against process fd limit
    222             if (0 > pDataLocator->mFD.fd) {
    223                 SL_LOGE("%s: fd=%d\n", name, pDataLocator->mFD.fd);
    224                 result = SL_RESULT_PARAMETER_INVALID;
    225             }
    226             break;
    227         }
    228         case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    229         {
    230             pDataLocator->mABQ = *(SLDataLocator_AndroidBufferQueue*)pLocator;
    231             // number of buffers must be specified, there is no default value, and can't be too big
    232             if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
    233                     (pDataLocator->mBufferQueue.numBuffers <= 255))) {
    234                 SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mABQ.numBuffers);
    235                 result = SL_RESULT_PARAMETER_INVALID;
    236             }
    237             break;
    238         }
    239 #endif
    240 
    241         case SL_DATALOCATOR_NULL:   // a NULL pointer is allowed, but not a pointer to NULL
    242         default:
    243             SL_LOGE("%s: locatorType=%u", name, locatorType);
    244             result = SL_RESULT_PARAMETER_INVALID;
    245         }
    246 
    247         // Verify that another thread didn't change the locatorType field after we used it
    248         // to determine sizeof struct to copy.
    249         if ((SL_RESULT_SUCCESS == result) && (locatorType != pDataLocator->mLocatorType)) {
    250             SL_LOGE("%s: locatorType changed from %u to %u", name, locatorType,
    251                     pDataLocator->mLocatorType);
    252             result = SL_RESULT_PRECONDITIONS_VIOLATED;
    253         }
    254 
    255     }
    256 
    257     // Verify that the data locator type is allowed in this context
    258     if (SL_RESULT_SUCCESS == result) {
    259         SLuint32 actualMask;
    260         switch (locatorType) {
    261         case SL_DATALOCATOR_NULL:
    262         case SL_DATALOCATOR_URI:
    263         case SL_DATALOCATOR_ADDRESS:
    264         case SL_DATALOCATOR_IODEVICE:
    265         case SL_DATALOCATOR_OUTPUTMIX:
    266         case XA_DATALOCATOR_NATIVEDISPLAY:
    267         case SL_DATALOCATOR_BUFFERQUEUE:
    268         case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    269             actualMask = 1L << locatorType;
    270             break;
    271 #ifdef ANDROID
    272         case SL_DATALOCATOR_ANDROIDFD:
    273         case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    274         case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    275             actualMask = 0x100L << (locatorType - SL_DATALOCATOR_ANDROIDFD);
    276             break;
    277 #endif
    278         default:
    279             assert(false);
    280             actualMask = 0L;
    281             break;
    282         }
    283         if (!(allowedDataLocatorMask & actualMask)) {
    284             SL_LOGE("%s: data locator type 0x%x not allowed", name, locatorType);
    285             result = SL_RESULT_CONTENT_UNSUPPORTED;
    286         }
    287     }
    288 
    289     return result;
    290 }
    291 
    292 
    293 /** \brief Free the local deep copy of a data locator */
    294 
    295 static void freeDataLocator(DataLocator *pDataLocator)
    296 {
    297     switch (pDataLocator->mLocatorType) {
    298     case SL_DATALOCATOR_NULL:
    299     case SL_DATALOCATOR_ADDRESS:
    300     case SL_DATALOCATOR_BUFFERQUEUE:
    301     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    302     case XA_DATALOCATOR_NATIVEDISPLAY:
    303         break;
    304     case SL_DATALOCATOR_URI:
    305         if (NULL != pDataLocator->mURI.URI) {
    306             free(pDataLocator->mURI.URI);
    307             pDataLocator->mURI.URI = NULL;
    308         }
    309         pDataLocator->mURI.URI = NULL;
    310         break;
    311     case SL_DATALOCATOR_IODEVICE:
    312         if (NULL != pDataLocator->mIODevice.device) {
    313             ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device);
    314             pDataLocator->mIODevice.device = NULL;
    315         }
    316         break;
    317     case SL_DATALOCATOR_OUTPUTMIX:
    318         if (NULL != pDataLocator->mOutputMix.outputMix) {
    319             ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix);
    320             pDataLocator->mOutputMix.outputMix = NULL;
    321         }
    322         break;
    323 #ifdef ANDROID
    324     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    325     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    326     case SL_DATALOCATOR_ANDROIDFD:
    327         break;
    328 #endif
    329     default:
    330         // an invalid data locator is caught earlier when making the copy
    331         assert(false);
    332         break;
    333     }
    334 }
    335 
    336 
    337 /** \brief Check a data format and make local deep copy */
    338 
    339 static SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat,
    340         SLuint32 allowedDataFormatMask, SLboolean isOutputFormat)
    341 {
    342     assert(NULL != name && NULL != pDataFormat);
    343     SLresult result = SL_RESULT_SUCCESS;
    344     const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists
    345     SLuint32 formatType;
    346     if (NULL == pFormat) {
    347         pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL;
    348     } else {
    349         formatType = *(SLuint32 *)pFormat;
    350         switch (formatType) {
    351         case SL_ANDROID_DATAFORMAT_PCM_EX:
    352             pDataFormat->mPCMEx.representation =
    353                     ((SLAndroidDataFormat_PCM_EX *)pFormat)->representation;
    354             switch (pDataFormat->mPCMEx.representation) {
    355             case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT:
    356             case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT:
    357             case SL_ANDROID_PCM_REPRESENTATION_FLOAT:
    358                 df_representation = &pDataFormat->mPCMEx.representation;
    359                 break;
    360             default:
    361                 SL_LOGE("%s: unsupported representation: %d", name,
    362                         pDataFormat->mPCMEx.representation);
    363                 result = SL_RESULT_PARAMETER_INVALID;
    364                 break;
    365             }
    366             // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
    367             FALLTHROUGH_INTENDED;
    368         case SL_DATAFORMAT_PCM:
    369             pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
    370             do {
    371                 if (pDataFormat->mPCM.numChannels == 0) {
    372                     result = SL_RESULT_PARAMETER_INVALID;
    373                 } else if (pDataFormat->mPCM.numChannels > SL_ANDROID_SPEAKER_COUNT_MAX) {
    374                     result = SL_RESULT_CONTENT_UNSUPPORTED;
    375                 }
    376                 if (SL_RESULT_SUCCESS != result) {
    377                     SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels);
    378                     break;
    379                 }
    380 
    381                 // check the sampling rate
    382                 if (pDataFormat->mPCM.samplesPerSec == 0) {
    383                     result = SL_RESULT_PARAMETER_INVALID;
    384                 } else if (pDataFormat->mPCM.samplesPerSec < SL_SAMPLINGRATE_8 ||
    385                         pDataFormat->mPCM.samplesPerSec > SL_SAMPLINGRATE_192) {
    386                     result = SL_RESULT_CONTENT_UNSUPPORTED;
    387                 }
    388                 if (SL_RESULT_SUCCESS != result) {
    389                     SL_LOGE("%s: samplesPerSec=%u", name, pDataFormat->mPCM.samplesPerSec);
    390                     break;
    391                 }
    392 
    393                 // check the container bit depth and representation
    394                 switch (pDataFormat->mPCM.containerSize) {
    395                 case 8:
    396                     if (df_representation != NULL &&
    397                             *df_representation != SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT) {
    398                         result = SL_RESULT_PARAMETER_INVALID;
    399                     }
    400                     break;
    401                 case 16:
    402                 case 24:
    403                     if (df_representation != NULL &&
    404                             *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT) {
    405                         result = SL_RESULT_PARAMETER_INVALID;
    406                     }
    407                     break;
    408                 case 32:
    409                     if (df_representation != NULL
    410                             && *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT
    411                             && *df_representation != SL_ANDROID_PCM_REPRESENTATION_FLOAT) {
    412                         result = SL_RESULT_PARAMETER_INVALID;
    413                     }
    414                     break;
    415                 default:
    416                     result = SL_RESULT_PARAMETER_INVALID;
    417                     break;
    418                 }
    419                 if (SL_RESULT_SUCCESS != result) {
    420                     SL_LOGE("%s: containerSize=%u", name, pDataFormat->mPCM.containerSize);
    421                     break;
    422                 }
    423 
    424                 // sample size cannot be zero, and container size cannot be less than sample size
    425                 if (pDataFormat->mPCM.bitsPerSample == 0 ||
    426                         pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
    427                     result = SL_RESULT_PARAMETER_INVALID;
    428                 }
    429                 if (SL_RESULT_SUCCESS != result) {
    430                     SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name,
    431                             (unsigned) pDataFormat->mPCM.containerSize,
    432                             (unsigned) pDataFormat->mPCM.bitsPerSample);
    433                     break;
    434                 }
    435 
    436                 // check the channel mask
    437                 SL_LOGV("%s: Requested channel mask of 0x%x for %d channel audio",
    438                     name,
    439                     pDataFormat->mPCM.channelMask,
    440                     pDataFormat->mPCM.numChannels);
    441 
    442                 if (pDataFormat->mPCM.channelMask == 0) {
    443                     // We can derive the channel mask from the channel count,
    444                     // but issue a warning--the automatic mask generation
    445                     // makes a lot of assumptions that may or may not be what
    446                     // the app was expecting.
    447                     SLuint32 mask = isOutputFormat
    448                             ? sles_channel_out_mask_from_count(pDataFormat->mPCM.numChannels)
    449                             : sles_channel_in_mask_from_count(pDataFormat->mPCM.numChannels);
    450                     if (mask == SL_ANDROID_UNKNOWN_CHANNELMASK) {
    451                         SL_LOGE("No channel mask specified and no default mapping for"
    452                                 "requested speaker count of %u", pDataFormat->mPCM.numChannels);
    453                         result = SL_RESULT_PARAMETER_INVALID;
    454                     } else {
    455                         pDataFormat->mPCM.channelMask = mask;
    456                         SL_LOGW("No channel mask specified; Using mask %#x based on requested"
    457                                         "speaker count of %u",
    458                                 pDataFormat->mPCM.channelMask,
    459                                 pDataFormat->mPCM.numChannels);
    460                     }
    461                 }
    462 
    463                 SLuint32 mask = pDataFormat->mPCM.channelMask;
    464                 SLuint32 count = sles_channel_count_from_mask(mask);
    465                 if (count != pDataFormat->mPCM.numChannels) {
    466                     SL_LOGE("%s: requested %d channels but mask (0x%x) has %d channel bits set",
    467                         name,
    468                         pDataFormat->mPCM.numChannels,
    469                         mask,
    470                         count);
    471                     result = SL_RESULT_PARAMETER_INVALID;
    472                     break;
    473                 }
    474 
    475                 SL_LOGV("%s: final channel mask is 0x%x", name, pDataFormat->mPCM.channelMask);
    476 
    477                 // check the endianness / byte order
    478                 switch (pDataFormat->mPCM.endianness) {
    479                 case SL_BYTEORDER_LITTLEENDIAN:
    480                 case SL_BYTEORDER_BIGENDIAN:
    481                     break;
    482                 // native is proposed but not yet in spec
    483                 default:
    484                     result = SL_RESULT_PARAMETER_INVALID;
    485                     break;
    486                 }
    487                 if (SL_RESULT_SUCCESS != result) {
    488                     SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness);
    489                     break;
    490                 }
    491 
    492                 // here if all checks passed successfully
    493 
    494             } while(0);
    495             break;
    496 
    497         case SL_DATAFORMAT_MIME:
    498             pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
    499             if (NULL != pDataFormat->mMIME.mimeType) {
    500                 // NTH check address for validity
    501                 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
    502                 SLchar *myMIME = (SLchar *) malloc(len + 1);
    503                 if (NULL == myMIME) {
    504                     result = SL_RESULT_MEMORY_FAILURE;
    505                 } else {
    506                     memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
    507                     // make sure MIME string was not modified asynchronously
    508                     if ('\0' != myMIME[len]) {
    509                         free(myMIME);
    510                         myMIME = NULL;
    511                         result = SL_RESULT_PRECONDITIONS_VIOLATED;
    512                     }
    513                 }
    514                 pDataFormat->mMIME.mimeType = myMIME;
    515             }
    516             break;
    517 
    518         case XA_DATAFORMAT_RAWIMAGE:
    519             pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat;
    520             switch (pDataFormat->mRawImage.colorFormat) {
    521             case XA_COLORFORMAT_MONOCHROME:
    522             case XA_COLORFORMAT_8BITRGB332:
    523             case XA_COLORFORMAT_12BITRGB444:
    524             case XA_COLORFORMAT_16BITARGB4444:
    525             case XA_COLORFORMAT_16BITARGB1555:
    526             case XA_COLORFORMAT_16BITRGB565:
    527             case XA_COLORFORMAT_16BITBGR565:
    528             case XA_COLORFORMAT_18BITRGB666:
    529             case XA_COLORFORMAT_18BITARGB1665:
    530             case XA_COLORFORMAT_19BITARGB1666:
    531             case XA_COLORFORMAT_24BITRGB888:
    532             case XA_COLORFORMAT_24BITBGR888:
    533             case XA_COLORFORMAT_24BITARGB1887:
    534             case XA_COLORFORMAT_25BITARGB1888:
    535             case XA_COLORFORMAT_32BITBGRA8888:
    536             case XA_COLORFORMAT_32BITARGB8888:
    537             case XA_COLORFORMAT_YUV411PLANAR:
    538             case XA_COLORFORMAT_YUV420PLANAR:
    539             case XA_COLORFORMAT_YUV420SEMIPLANAR:
    540             case XA_COLORFORMAT_YUV422PLANAR:
    541             case XA_COLORFORMAT_YUV422SEMIPLANAR:
    542             case XA_COLORFORMAT_YCBYCR:
    543             case XA_COLORFORMAT_YCRYCB:
    544             case XA_COLORFORMAT_CBYCRY:
    545             case XA_COLORFORMAT_CRYCBY:
    546             case XA_COLORFORMAT_YUV444INTERLEAVED:
    547             case XA_COLORFORMAT_RAWBAYER8BIT:
    548             case XA_COLORFORMAT_RAWBAYER10BIT:
    549             case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED:
    550             case XA_COLORFORMAT_L2:
    551             case XA_COLORFORMAT_L4:
    552             case XA_COLORFORMAT_L8:
    553             case XA_COLORFORMAT_L16:
    554             case XA_COLORFORMAT_L24:
    555             case XA_COLORFORMAT_L32:
    556             case XA_COLORFORMAT_18BITBGR666:
    557             case XA_COLORFORMAT_24BITARGB6666:
    558             case XA_COLORFORMAT_24BITABGR6666:
    559                 break;
    560             case XA_COLORFORMAT_UNUSED:
    561             default:
    562                 result = XA_RESULT_PARAMETER_INVALID;
    563                 SL_LOGE("%s: unsupported color format %d", name,
    564                     pDataFormat->mRawImage.colorFormat);
    565                 break;
    566             }
    567             // no checks for height, width, or stride
    568             break;
    569 
    570         default:
    571             result = SL_RESULT_PARAMETER_INVALID;
    572             SL_LOGE("%s: formatType=%u", name, (unsigned) formatType);
    573             break;
    574 
    575         }
    576 
    577         // make sure format type was not modified asynchronously
    578         if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
    579             SL_LOGE("%s: formatType changed from %u to %u", name, formatType,
    580                     pDataFormat->mFormatType);
    581             result = SL_RESULT_PRECONDITIONS_VIOLATED;
    582         }
    583 
    584     }
    585 
    586     // Verify that the data format type is allowed in this context
    587     if (SL_RESULT_SUCCESS == result) {
    588         SLuint32 actualMask;
    589         switch (formatType) {
    590         case SL_DATAFORMAT_NULL:
    591         case SL_DATAFORMAT_MIME:
    592         case SL_DATAFORMAT_PCM:
    593         case SL_ANDROID_DATAFORMAT_PCM_EX:
    594         case XA_DATAFORMAT_RAWIMAGE:
    595             actualMask = 1L << formatType;
    596             break;
    597         default:
    598             assert(false);
    599             actualMask = 0L;
    600             break;
    601         }
    602         if (!(allowedDataFormatMask & actualMask)) {
    603             SL_LOGE("%s: data format %d not allowed", name, formatType);
    604             result = SL_RESULT_CONTENT_UNSUPPORTED;
    605         }
    606     }
    607 
    608     return result;
    609 }
    610 
    611 
    612 /** \brief Check interface ID compatibility with respect to a particular source
    613  *         and sink data locator format
    614  */
    615 
    616 SLresult checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat,
    617         const DataLocatorFormat *pSinkDataLocatorFormat,
    618         const ClassTable *clazz, unsigned requiredMask) {
    619     int index;
    620     switch (pSrcDataLocatorFormat->mLocator.mLocatorType) {
    621     case SL_DATALOCATOR_URI:
    622 #ifdef ANDROID
    623     case SL_DATALOCATOR_ANDROIDFD:
    624 #endif
    625         // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode
    626         // so we don't prevent the retrieval of the BufferQueue interfaces for those sources
    627         switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
    628         case SL_DATALOCATOR_BUFFERQUEUE:
    629 #ifdef ANDROID
    630         case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    631 #endif
    632             break;
    633         default:
    634             // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
    635             // if the data sink is not a buffer queue
    636             index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
    637 #ifdef ANDROID
    638             assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
    639 #endif
    640             if (0 <= index) {
    641                 if (requiredMask & (1 << index)) {
    642                     SL_LOGE("can't require SL_IID_BUFFERQUEUE "
    643 #ifdef ANDROID
    644                             "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
    645 #endif
    646                             "with a non-buffer queue data sink");
    647                     return SL_RESULT_FEATURE_UNSUPPORTED;
    648                 }
    649             }
    650             break;
    651         }
    652         break;
    653 
    654     case SL_DATALOCATOR_BUFFERQUEUE:
    655 #ifdef ANDROID
    656     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    657 #endif
    658         // can't require SLSeekItf if data source is a buffer queue
    659         index = clazz->mMPH_to_index[MPH_SEEK];
    660         if (0 <= index) {
    661             if (requiredMask & (1 << index)) {
    662                 SL_LOGE("can't require SL_IID_SEEK with a buffer queue data source");
    663                 return SL_RESULT_FEATURE_UNSUPPORTED;
    664             }
    665         }
    666         // can't require SLMuteSoloItf if data source is a mono buffer queue
    667         index = clazz->mMPH_to_index[MPH_MUTESOLO];
    668         if (0 <= index) {
    669             if ((requiredMask & (1 << index)) &&
    670                     (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) &&
    671                     (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) {
    672                 SL_LOGE("can't require SL_IID_MUTESOLO with a mono buffer queue data source");
    673                 return SL_RESULT_FEATURE_UNSUPPORTED;
    674             }
    675         }
    676         break;
    677 
    678 #ifdef ANDROID
    679     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    680         // can't require SLSeekItf if data source is an Android buffer queue
    681         index = clazz->mMPH_to_index[MPH_SEEK];
    682         if (0 <= index) {
    683             if (requiredMask & (1 << index)) {
    684                 SL_LOGE("can't require SL_IID_SEEK with a SL_DATALOCATOR_ANDROIDBUFFERQUEUE "\
    685                         "source");
    686                 return SL_RESULT_FEATURE_UNSUPPORTED;
    687             }
    688         }
    689         switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
    690         // for use-case AAC decode from SLAndroidBufferQueueItf with AAC ADTS data
    691         case SL_DATALOCATOR_BUFFERQUEUE:
    692         case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    693             break;
    694         // for use-case audio playback from SLAndroidBufferQueueItf with MP2TS data
    695         case SL_DATALOCATOR_OUTPUTMIX:
    696             break;
    697         default:
    698             SL_LOGE("Invalid sink for SL_DATALOCATOR_ANDROIDBUFFERQUEUE source");
    699             return SL_RESULT_FEATURE_UNSUPPORTED;
    700             break;
    701         }
    702         break;
    703 #endif
    704     case SL_DATALOCATOR_ADDRESS:
    705     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    706     case XA_DATALOCATOR_NATIVEDISPLAY:
    707         // any special checks here???
    708     default:
    709         // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
    710         // if the data source is not a buffer queue
    711         index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
    712 #ifdef ANDROID
    713         assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
    714 #endif
    715         if (0 <= index) {
    716             if (requiredMask & (1 << index)) {
    717                 SL_LOGE("can't require SL_IID_BUFFERQUEUE "
    718 #ifdef ANDROID
    719                         "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
    720 #endif
    721                         "with a non-buffer queue data source");
    722                 return SL_RESULT_FEATURE_UNSUPPORTED;
    723             }
    724         }
    725         break;
    726     }
    727     return SL_RESULT_SUCCESS;
    728 }
    729 
    730 
    731 /** \brief Free the local deep copy of a data format */
    732 
    733 static void freeDataFormat(DataFormat *pDataFormat)
    734 {
    735     switch (pDataFormat->mFormatType) {
    736     case SL_DATAFORMAT_MIME:
    737         if (NULL != pDataFormat->mMIME.mimeType) {
    738             free(pDataFormat->mMIME.mimeType);
    739             pDataFormat->mMIME.mimeType = NULL;
    740         }
    741         break;
    742     case SL_ANDROID_DATAFORMAT_PCM_EX:
    743     case SL_DATAFORMAT_PCM:
    744     case XA_DATAFORMAT_RAWIMAGE:
    745     case SL_DATAFORMAT_NULL:
    746         break;
    747     default:
    748         // an invalid data format is caught earlier during the copy
    749         assert(false);
    750         break;
    751     }
    752 }
    753 
    754 
    755 /** \brief Check a data source and make local deep copy */
    756 
    757 SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc,
    758         DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
    759         SLuint32 allowedDataFormatMask)
    760 {
    761     assert(NULL != name && NULL != pDataLocatorFormat);
    762     pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
    763     pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;
    764 
    765     if (NULL == pDataSrc) {
    766         pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    767         pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
    768         if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
    769                 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
    770             return SL_RESULT_SUCCESS;
    771         }
    772         SL_LOGE("%s: data source cannot be NULL", name);
    773         return SL_RESULT_PARAMETER_INVALID;
    774     }
    775     SLDataSource myDataSrc = *pDataSrc;
    776     SLresult result;
    777     result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator,
    778             allowedDataLocatorMask);
    779     if (SL_RESULT_SUCCESS != result) {
    780         return result;
    781     }
    782 
    783     switch (pDataLocatorFormat->mLocator.mLocatorType) {
    784     case SL_DATALOCATOR_URI:
    785         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
    786         break;
    787     case SL_DATALOCATOR_ADDRESS:
    788     case SL_DATALOCATOR_BUFFERQUEUE:
    789         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    790         break;
    791     // Per the spec, the pFormat field is ignored in some cases
    792     case SL_DATALOCATOR_IODEVICE:
    793         myDataSrc.pFormat = NULL;
    794         FALLTHROUGH_INTENDED;
    795     case SL_DATALOCATOR_NULL:
    796     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    797         allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
    798         break;
    799     case SL_DATALOCATOR_OUTPUTMIX:
    800     case XA_DATALOCATOR_NATIVEDISPLAY:
    801         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    802         break;
    803 #ifdef ANDROID
    804     case SL_DATALOCATOR_ANDROIDFD:
    805         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
    806         break;
    807     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    808         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    809         break;
    810     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    811         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;;
    812         break;
    813 #endif
    814     default:
    815         // invalid data locator type is caught earlier
    816         assert(false);
    817         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    818         break;
    819     }
    820 
    821     result = checkDataFormat(name,
    822                              myDataSrc.pFormat,
    823                              &pDataLocatorFormat->mFormat,
    824                              allowedDataFormatMask,
    825                              SL_BOOLEAN_TRUE /*isOutputFormat*/);
    826     if (SL_RESULT_SUCCESS != result) {
    827         freeDataLocator(&pDataLocatorFormat->mLocator);
    828         return result;
    829     }
    830 
    831     return SL_RESULT_SUCCESS;
    832 }
    833 
    834 
    835 /** \brief Check a data sink and make local deep copy */
    836 
    837 SLresult checkDataSink(const char *name, const SLDataSink *pDataSink,
    838         DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
    839         SLuint32 allowedDataFormatMask)
    840 {
    841     assert(NULL != name && NULL != pDataLocatorFormat);
    842     pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
    843     pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;
    844 
    845     if (NULL == pDataSink) {
    846         pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    847         pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
    848         if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
    849                 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
    850             return SL_RESULT_SUCCESS;
    851         }
    852         SL_LOGE("%s: data sink cannot be NULL", name);
    853         return SL_RESULT_PARAMETER_INVALID;
    854     }
    855     SLDataSink myDataSink = *pDataSink;
    856     SLresult result;
    857     result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator,
    858             allowedDataLocatorMask);
    859     if (SL_RESULT_SUCCESS != result) {
    860         return result;
    861     }
    862 
    863     switch (pDataLocatorFormat->mLocator.mLocatorType) {
    864     case SL_DATALOCATOR_URI:
    865         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
    866         break;
    867     case SL_DATALOCATOR_ADDRESS:
    868     case SL_DATALOCATOR_BUFFERQUEUE:
    869         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    870         break;
    871     // Per the spec, the pFormat field is ignored in some cases
    872     case SL_DATALOCATOR_IODEVICE:
    873     case SL_DATALOCATOR_OUTPUTMIX:
    874     case XA_DATALOCATOR_NATIVEDISPLAY:
    875         myDataSink.pFormat = NULL;
    876         FALLTHROUGH_INTENDED;
    877     case SL_DATALOCATOR_NULL:
    878     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    879         allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
    880         break;
    881 #ifdef ANDROID
    882     case SL_DATALOCATOR_ANDROIDFD:
    883         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    884         break;
    885     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    886         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    887         break;
    888     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    889         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    890         break;
    891 #endif
    892     default:
    893         // invalid data locator type is caught earlier
    894         assert(false);
    895         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    896         break;
    897     }
    898 
    899     result = checkDataFormat(name,
    900             myDataSink.pFormat,
    901             &pDataLocatorFormat->mFormat,
    902             allowedDataFormatMask,
    903             SL_BOOLEAN_FALSE /*isOutputFormat*/);
    904 
    905     if (SL_RESULT_SUCCESS != result) {
    906         freeDataLocator(&pDataLocatorFormat->mLocator);
    907         return result;
    908     }
    909 
    910     return SL_RESULT_SUCCESS;
    911 }
    912 
    913 
    914 /** \brief Free the local deep copy of a data locator format */
    915 
    916 void freeDataLocatorFormat(DataLocatorFormat *dlf)
    917 {
    918     assert(NULL != dlf);
    919     freeDataLocator(&dlf->mLocator);
    920     freeDataFormat(&dlf->mFormat);
    921 }
    922