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