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         case SL_DATAFORMAT_PCM:
    368             pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
    369             do {
    370                 if (pDataFormat->mPCM.numChannels == 0) {
    371                     result = SL_RESULT_PARAMETER_INVALID;
    372                 } else if (pDataFormat->mPCM.numChannels > SL_ANDROID_SPEAKER_COUNT_MAX) {
    373                     result = SL_RESULT_CONTENT_UNSUPPORTED;
    374                 }
    375                 if (SL_RESULT_SUCCESS != result) {
    376                     SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels);
    377                     break;
    378                 }
    379 
    380                 // check the sampling rate
    381                 if (pDataFormat->mPCM.samplesPerSec == 0) {
    382                     result = SL_RESULT_PARAMETER_INVALID;
    383                 } else if (pDataFormat->mPCM.samplesPerSec < SL_SAMPLINGRATE_8 ||
    384                         pDataFormat->mPCM.samplesPerSec > SL_SAMPLINGRATE_192) {
    385                     result = SL_RESULT_CONTENT_UNSUPPORTED;
    386                 }
    387                 if (SL_RESULT_SUCCESS != result) {
    388                     SL_LOGE("%s: samplesPerSec=%u", name, pDataFormat->mPCM.samplesPerSec);
    389                     break;
    390                 }
    391 
    392                 // check the container bit depth and representation
    393                 switch (pDataFormat->mPCM.containerSize) {
    394                 case 8:
    395                     if (df_representation != NULL &&
    396                             *df_representation != SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT) {
    397                         result = SL_RESULT_PARAMETER_INVALID;
    398                     }
    399                     break;
    400                 case 16:
    401                 case 24:
    402                     if (df_representation != NULL &&
    403                             *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT) {
    404                         result = SL_RESULT_PARAMETER_INVALID;
    405                     }
    406                     break;
    407                 case 32:
    408                     if (df_representation != NULL
    409                             && *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT
    410                             && *df_representation != SL_ANDROID_PCM_REPRESENTATION_FLOAT) {
    411                         result = SL_RESULT_PARAMETER_INVALID;
    412                     }
    413                     break;
    414                 default:
    415                     result = SL_RESULT_PARAMETER_INVALID;
    416                     break;
    417                 }
    418                 if (SL_RESULT_SUCCESS != result) {
    419                     SL_LOGE("%s: containerSize=%u", name, pDataFormat->mPCM.containerSize);
    420                     break;
    421                 }
    422 
    423                 // sample size cannot be zero, and container size cannot be less than sample size
    424                 if (pDataFormat->mPCM.bitsPerSample == 0 ||
    425                         pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
    426                     result = SL_RESULT_PARAMETER_INVALID;
    427                 }
    428                 if (SL_RESULT_SUCCESS != result) {
    429                     SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name,
    430                             (unsigned) pDataFormat->mPCM.containerSize,
    431                             (unsigned) pDataFormat->mPCM.bitsPerSample);
    432                     break;
    433                 }
    434 
    435                 // check the channel mask
    436                 SL_LOGV("%s: Requested channel mask of 0x%x for %d channel audio",
    437                     name,
    438                     pDataFormat->mPCM.channelMask,
    439                     pDataFormat->mPCM.numChannels);
    440 
    441                 if (pDataFormat->mPCM.channelMask == 0) {
    442                     // We can derive the channel mask from the channel count,
    443                     // but issue a warning--the automatic mask generation
    444                     // makes a lot of assumptions that may or may not be what
    445                     // the app was expecting.
    446                     SLuint32 mask = isOutputFormat
    447                             ? sles_channel_out_mask_from_count(pDataFormat->mPCM.numChannels)
    448                             : sles_channel_in_mask_from_count(pDataFormat->mPCM.numChannels);
    449                     if (mask == SL_ANDROID_UNKNOWN_CHANNELMASK) {
    450                         SL_LOGE("No channel mask specified and no default mapping for"
    451                                 "requested speaker count of %u", pDataFormat->mPCM.numChannels);
    452                         result = SL_RESULT_PARAMETER_INVALID;
    453                     } else {
    454                         pDataFormat->mPCM.channelMask = mask;
    455                         SL_LOGW("No channel mask specified; Using mask %#x based on requested"
    456                                         "speaker count of %u",
    457                                 pDataFormat->mPCM.channelMask,
    458                                 pDataFormat->mPCM.numChannels);
    459                     }
    460                 }
    461 
    462                 SLuint32 mask = pDataFormat->mPCM.channelMask;
    463                 SLuint32 count = sles_channel_count_from_mask(mask);
    464                 if (count != pDataFormat->mPCM.numChannels) {
    465                     SL_LOGE("%s: requested %d channels but mask (0x%x) has %d channel bits set",
    466                         name,
    467                         pDataFormat->mPCM.numChannels,
    468                         mask,
    469                         count);
    470                     result = SL_RESULT_PARAMETER_INVALID;
    471                     break;
    472                 }
    473 
    474                 SL_LOGV("%s: final channel mask is 0x%x", name, pDataFormat->mPCM.channelMask);
    475 
    476                 // check the endianness / byte order
    477                 switch (pDataFormat->mPCM.endianness) {
    478                 case SL_BYTEORDER_LITTLEENDIAN:
    479                 case SL_BYTEORDER_BIGENDIAN:
    480                     break;
    481                 // native is proposed but not yet in spec
    482                 default:
    483                     result = SL_RESULT_PARAMETER_INVALID;
    484                     break;
    485                 }
    486                 if (SL_RESULT_SUCCESS != result) {
    487                     SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness);
    488                     break;
    489                 }
    490 
    491                 // here if all checks passed successfully
    492 
    493             } while(0);
    494             break;
    495 
    496         case SL_DATAFORMAT_MIME:
    497             pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
    498             if (NULL != pDataFormat->mMIME.mimeType) {
    499                 // NTH check address for validity
    500                 size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
    501                 SLchar *myMIME = (SLchar *) malloc(len + 1);
    502                 if (NULL == myMIME) {
    503                     result = SL_RESULT_MEMORY_FAILURE;
    504                 } else {
    505                     memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
    506                     // make sure MIME string was not modified asynchronously
    507                     if ('\0' != myMIME[len]) {
    508                         free(myMIME);
    509                         myMIME = NULL;
    510                         result = SL_RESULT_PRECONDITIONS_VIOLATED;
    511                     }
    512                 }
    513                 pDataFormat->mMIME.mimeType = myMIME;
    514             }
    515             break;
    516 
    517         case XA_DATAFORMAT_RAWIMAGE:
    518             pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat;
    519             switch (pDataFormat->mRawImage.colorFormat) {
    520             case XA_COLORFORMAT_MONOCHROME:
    521             case XA_COLORFORMAT_8BITRGB332:
    522             case XA_COLORFORMAT_12BITRGB444:
    523             case XA_COLORFORMAT_16BITARGB4444:
    524             case XA_COLORFORMAT_16BITARGB1555:
    525             case XA_COLORFORMAT_16BITRGB565:
    526             case XA_COLORFORMAT_16BITBGR565:
    527             case XA_COLORFORMAT_18BITRGB666:
    528             case XA_COLORFORMAT_18BITARGB1665:
    529             case XA_COLORFORMAT_19BITARGB1666:
    530             case XA_COLORFORMAT_24BITRGB888:
    531             case XA_COLORFORMAT_24BITBGR888:
    532             case XA_COLORFORMAT_24BITARGB1887:
    533             case XA_COLORFORMAT_25BITARGB1888:
    534             case XA_COLORFORMAT_32BITBGRA8888:
    535             case XA_COLORFORMAT_32BITARGB8888:
    536             case XA_COLORFORMAT_YUV411PLANAR:
    537             case XA_COLORFORMAT_YUV420PLANAR:
    538             case XA_COLORFORMAT_YUV420SEMIPLANAR:
    539             case XA_COLORFORMAT_YUV422PLANAR:
    540             case XA_COLORFORMAT_YUV422SEMIPLANAR:
    541             case XA_COLORFORMAT_YCBYCR:
    542             case XA_COLORFORMAT_YCRYCB:
    543             case XA_COLORFORMAT_CBYCRY:
    544             case XA_COLORFORMAT_CRYCBY:
    545             case XA_COLORFORMAT_YUV444INTERLEAVED:
    546             case XA_COLORFORMAT_RAWBAYER8BIT:
    547             case XA_COLORFORMAT_RAWBAYER10BIT:
    548             case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED:
    549             case XA_COLORFORMAT_L2:
    550             case XA_COLORFORMAT_L4:
    551             case XA_COLORFORMAT_L8:
    552             case XA_COLORFORMAT_L16:
    553             case XA_COLORFORMAT_L24:
    554             case XA_COLORFORMAT_L32:
    555             case XA_COLORFORMAT_18BITBGR666:
    556             case XA_COLORFORMAT_24BITARGB6666:
    557             case XA_COLORFORMAT_24BITABGR6666:
    558                 break;
    559             case XA_COLORFORMAT_UNUSED:
    560             default:
    561                 result = XA_RESULT_PARAMETER_INVALID;
    562                 SL_LOGE("%s: unsupported color format %d", name,
    563                     pDataFormat->mRawImage.colorFormat);
    564                 break;
    565             }
    566             // no checks for height, width, or stride
    567             break;
    568 
    569         default:
    570             result = SL_RESULT_PARAMETER_INVALID;
    571             SL_LOGE("%s: formatType=%u", name, (unsigned) formatType);
    572             break;
    573 
    574         }
    575 
    576         // make sure format type was not modified asynchronously
    577         if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
    578             SL_LOGE("%s: formatType changed from %u to %u", name, formatType,
    579                     pDataFormat->mFormatType);
    580             result = SL_RESULT_PRECONDITIONS_VIOLATED;
    581         }
    582 
    583     }
    584 
    585     // Verify that the data format type is allowed in this context
    586     if (SL_RESULT_SUCCESS == result) {
    587         SLuint32 actualMask;
    588         switch (formatType) {
    589         case SL_DATAFORMAT_NULL:
    590         case SL_DATAFORMAT_MIME:
    591         case SL_DATAFORMAT_PCM:
    592         case SL_ANDROID_DATAFORMAT_PCM_EX:
    593         case XA_DATAFORMAT_RAWIMAGE:
    594             actualMask = 1L << formatType;
    595             break;
    596         default:
    597             assert(false);
    598             actualMask = 0L;
    599             break;
    600         }
    601         if (!(allowedDataFormatMask & actualMask)) {
    602             SL_LOGE("%s: data format %d not allowed", name, formatType);
    603             result = SL_RESULT_CONTENT_UNSUPPORTED;
    604         }
    605     }
    606 
    607     return result;
    608 }
    609 
    610 
    611 /** \brief Check interface ID compatibility with respect to a particular source
    612  *         and sink data locator format
    613  */
    614 
    615 SLresult checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat,
    616         const DataLocatorFormat *pSinkDataLocatorFormat,
    617         const ClassTable *clazz, unsigned requiredMask) {
    618     int index;
    619     switch (pSrcDataLocatorFormat->mLocator.mLocatorType) {
    620     case SL_DATALOCATOR_URI:
    621 #ifdef ANDROID
    622     case SL_DATALOCATOR_ANDROIDFD:
    623 #endif
    624         // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode
    625         // so we don't prevent the retrieval of the BufferQueue interfaces for those sources
    626         switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
    627         case SL_DATALOCATOR_BUFFERQUEUE:
    628 #ifdef ANDROID
    629         case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    630 #endif
    631             break;
    632         default:
    633             // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
    634             // if the data sink is not a buffer queue
    635             index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
    636 #ifdef ANDROID
    637             assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
    638 #endif
    639             if (0 <= index) {
    640                 if (requiredMask & (1 << index)) {
    641                     SL_LOGE("can't require SL_IID_BUFFERQUEUE "
    642 #ifdef ANDROID
    643                             "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
    644 #endif
    645                             "with a non-buffer queue data sink");
    646                     return SL_RESULT_FEATURE_UNSUPPORTED;
    647                 }
    648             }
    649             break;
    650         }
    651         break;
    652 
    653     case SL_DATALOCATOR_BUFFERQUEUE:
    654 #ifdef ANDROID
    655     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    656 #endif
    657         // can't require SLSeekItf if data source is a buffer queue
    658         index = clazz->mMPH_to_index[MPH_SEEK];
    659         if (0 <= index) {
    660             if (requiredMask & (1 << index)) {
    661                 SL_LOGE("can't require SL_IID_SEEK with a buffer queue data source");
    662                 return SL_RESULT_FEATURE_UNSUPPORTED;
    663             }
    664         }
    665         // can't require SLMuteSoloItf if data source is a mono buffer queue
    666         index = clazz->mMPH_to_index[MPH_MUTESOLO];
    667         if (0 <= index) {
    668             if ((requiredMask & (1 << index)) &&
    669                     (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) &&
    670                     (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) {
    671                 SL_LOGE("can't require SL_IID_MUTESOLO with a mono buffer queue data source");
    672                 return SL_RESULT_FEATURE_UNSUPPORTED;
    673             }
    674         }
    675         break;
    676 
    677 #ifdef ANDROID
    678     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    679         // can't require SLSeekItf if data source is an Android buffer queue
    680         index = clazz->mMPH_to_index[MPH_SEEK];
    681         if (0 <= index) {
    682             if (requiredMask & (1 << index)) {
    683                 SL_LOGE("can't require SL_IID_SEEK with a SL_DATALOCATOR_ANDROIDBUFFERQUEUE "\
    684                         "source");
    685                 return SL_RESULT_FEATURE_UNSUPPORTED;
    686             }
    687         }
    688         switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
    689         // for use-case AAC decode from SLAndroidBufferQueueItf with AAC ADTS data
    690         case SL_DATALOCATOR_BUFFERQUEUE:
    691         case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    692             break;
    693         // for use-case audio playback from SLAndroidBufferQueueItf with MP2TS data
    694         case SL_DATALOCATOR_OUTPUTMIX:
    695             break;
    696         default:
    697             SL_LOGE("Invalid sink for SL_DATALOCATOR_ANDROIDBUFFERQUEUE source");
    698             return SL_RESULT_FEATURE_UNSUPPORTED;
    699             break;
    700         }
    701         break;
    702 #endif
    703     case SL_DATALOCATOR_ADDRESS:
    704     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    705     case XA_DATALOCATOR_NATIVEDISPLAY:
    706         // any special checks here???
    707     default:
    708         // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
    709         // if the data source is not a buffer queue
    710         index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
    711 #ifdef ANDROID
    712         assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
    713 #endif
    714         if (0 <= index) {
    715             if (requiredMask & (1 << index)) {
    716                 SL_LOGE("can't require SL_IID_BUFFERQUEUE "
    717 #ifdef ANDROID
    718                         "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
    719 #endif
    720                         "with a non-buffer queue data source");
    721                 return SL_RESULT_FEATURE_UNSUPPORTED;
    722             }
    723         }
    724         break;
    725     }
    726     return SL_RESULT_SUCCESS;
    727 }
    728 
    729 
    730 /** \brief Free the local deep copy of a data format */
    731 
    732 static void freeDataFormat(DataFormat *pDataFormat)
    733 {
    734     switch (pDataFormat->mFormatType) {
    735     case SL_DATAFORMAT_MIME:
    736         if (NULL != pDataFormat->mMIME.mimeType) {
    737             free(pDataFormat->mMIME.mimeType);
    738             pDataFormat->mMIME.mimeType = NULL;
    739         }
    740         break;
    741     case SL_ANDROID_DATAFORMAT_PCM_EX:
    742     case SL_DATAFORMAT_PCM:
    743     case XA_DATAFORMAT_RAWIMAGE:
    744     case SL_DATAFORMAT_NULL:
    745         break;
    746     default:
    747         // an invalid data format is caught earlier during the copy
    748         assert(false);
    749         break;
    750     }
    751 }
    752 
    753 
    754 /** \brief Check a data source and make local deep copy */
    755 
    756 SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc,
    757         DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
    758         SLuint32 allowedDataFormatMask)
    759 {
    760     assert(NULL != name && NULL != pDataLocatorFormat);
    761     pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
    762     pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;
    763 
    764     if (NULL == pDataSrc) {
    765         pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    766         pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
    767         if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
    768                 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
    769             return SL_RESULT_SUCCESS;
    770         }
    771         SL_LOGE("%s: data source cannot be NULL", name);
    772         return SL_RESULT_PARAMETER_INVALID;
    773     }
    774     SLDataSource myDataSrc = *pDataSrc;
    775     SLresult result;
    776     result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator,
    777             allowedDataLocatorMask);
    778     if (SL_RESULT_SUCCESS != result) {
    779         return result;
    780     }
    781 
    782     switch (pDataLocatorFormat->mLocator.mLocatorType) {
    783     case SL_DATALOCATOR_URI:
    784         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
    785         break;
    786     case SL_DATALOCATOR_ADDRESS:
    787     case SL_DATALOCATOR_BUFFERQUEUE:
    788         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    789         break;
    790     // Per the spec, the pFormat field is ignored in some cases
    791     case SL_DATALOCATOR_IODEVICE:
    792         myDataSrc.pFormat = NULL;
    793         // fall through
    794     case SL_DATALOCATOR_NULL:
    795     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    796         allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
    797         break;
    798     case SL_DATALOCATOR_OUTPUTMIX:
    799     case XA_DATALOCATOR_NATIVEDISPLAY:
    800         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    801         break;
    802 #ifdef ANDROID
    803     case SL_DATALOCATOR_ANDROIDFD:
    804         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
    805         break;
    806     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    807         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    808         break;
    809     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    810         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;;
    811         break;
    812 #endif
    813     default:
    814         // invalid data locator type is caught earlier
    815         assert(false);
    816         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    817         break;
    818     }
    819 
    820     result = checkDataFormat(name,
    821                              myDataSrc.pFormat,
    822                              &pDataLocatorFormat->mFormat,
    823                              allowedDataFormatMask,
    824                              SL_BOOLEAN_TRUE /*isOutputFormat*/);
    825     if (SL_RESULT_SUCCESS != result) {
    826         freeDataLocator(&pDataLocatorFormat->mLocator);
    827         return result;
    828     }
    829 
    830     return SL_RESULT_SUCCESS;
    831 }
    832 
    833 
    834 /** \brief Check a data sink and make local deep copy */
    835 
    836 SLresult checkDataSink(const char *name, const SLDataSink *pDataSink,
    837         DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
    838         SLuint32 allowedDataFormatMask)
    839 {
    840     assert(NULL != name && NULL != pDataLocatorFormat);
    841     pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
    842     pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;
    843 
    844     if (NULL == pDataSink) {
    845         pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
    846         pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
    847         if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
    848                 (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
    849             return SL_RESULT_SUCCESS;
    850         }
    851         SL_LOGE("%s: data sink cannot be NULL", name);
    852         return SL_RESULT_PARAMETER_INVALID;
    853     }
    854     SLDataSink myDataSink = *pDataSink;
    855     SLresult result;
    856     result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator,
    857             allowedDataLocatorMask);
    858     if (SL_RESULT_SUCCESS != result) {
    859         return result;
    860     }
    861 
    862     switch (pDataLocatorFormat->mLocator.mLocatorType) {
    863     case SL_DATALOCATOR_URI:
    864         allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
    865         break;
    866     case SL_DATALOCATOR_ADDRESS:
    867     case SL_DATALOCATOR_BUFFERQUEUE:
    868         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    869         break;
    870     // Per the spec, the pFormat field is ignored in some cases
    871     case SL_DATALOCATOR_IODEVICE:
    872     case SL_DATALOCATOR_OUTPUTMIX:
    873     case XA_DATALOCATOR_NATIVEDISPLAY:
    874         myDataSink.pFormat = NULL;
    875         // fall through
    876     case SL_DATALOCATOR_NULL:
    877     case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    878         allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
    879         break;
    880 #ifdef ANDROID
    881     case SL_DATALOCATOR_ANDROIDFD:
    882         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    883         break;
    884     case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    885         allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
    886         break;
    887     case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    888         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    889         break;
    890 #endif
    891     default:
    892         // invalid data locator type is caught earlier
    893         assert(false);
    894         allowedDataFormatMask = DATAFORMAT_MASK_NONE;
    895         break;
    896     }
    897 
    898     result = checkDataFormat(name,
    899             myDataSink.pFormat,
    900             &pDataLocatorFormat->mFormat,
    901             allowedDataFormatMask,
    902             SL_BOOLEAN_FALSE /*isOutputFormat*/);
    903 
    904     if (SL_RESULT_SUCCESS != result) {
    905         freeDataLocator(&pDataLocatorFormat->mLocator);
    906         return result;
    907     }
    908 
    909     return SL_RESULT_SUCCESS;
    910 }
    911 
    912 
    913 /** \brief Free the local deep copy of a data locator format */
    914 
    915 void freeDataLocatorFormat(DataLocatorFormat *dlf)
    916 {
    917     assert(NULL != dlf);
    918     freeDataLocator(&dlf->mLocator);
    919     freeDataFormat(&dlf->mFormat);
    920 }
    921