/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** Data locator, data format, data source, and data sink support */

#include "sles_allinclusive.h"
#ifdef ANDROID  // FIXME This file should be portable
#include "android/channels.h"
#endif


/** \brief Check a data locator and make local deep copy */

static SLresult checkDataLocator(const char *name, void *pLocator, DataLocator *pDataLocator,
        SLuint32 allowedDataLocatorMask)
{
    assert(NULL != name && NULL != pDataLocator);
    SLresult result = SL_RESULT_SUCCESS;

    SLuint32 locatorType;
    if (NULL == pLocator) {
        pDataLocator->mLocatorType = locatorType = SL_DATALOCATOR_NULL;
    } else {
        locatorType = *(SLuint32 *)pLocator;
        switch (locatorType) {

        case SL_DATALOCATOR_ADDRESS:
            pDataLocator->mAddress = *(SLDataLocator_Address *)pLocator;
            // if length is greater than zero, then the address must be non-NULL
            if ((0 < pDataLocator->mAddress.length) && (NULL == pDataLocator->mAddress.pAddress)) {
                SL_LOGE("%s: pAddress=NULL", name);
                result = SL_RESULT_PARAMETER_INVALID;
            }
            break;

        case SL_DATALOCATOR_BUFFERQUEUE:
#ifdef ANDROID
        // This is an alias that is _not_ converted; the rest of the code must check for both
        // locator types. That's because it is only an alias for audio players, not audio recorder
        // objects so we have to remember the distinction.
        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
#endif
            pDataLocator->mBufferQueue = *(SLDataLocator_BufferQueue *)pLocator;
            // number of buffers must be specified, there is no default value, and can't be too big
            if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
                (pDataLocator->mBufferQueue.numBuffers <= 255))) {
                SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mBufferQueue.numBuffers);
                result = SL_RESULT_PARAMETER_INVALID;
            }
            break;

        case SL_DATALOCATOR_IODEVICE:
            {
            pDataLocator->mIODevice = *(SLDataLocator_IODevice *)pLocator;
            SLuint32 deviceType = pDataLocator->mIODevice.deviceType;
            SLObjectItf device = pDataLocator->mIODevice.device;
            if (NULL != device) {
                pDataLocator->mIODevice.deviceID = 0;
                SLuint32 expectedObjectID;
                switch (deviceType) {
                case SL_IODEVICE_LEDARRAY:
                    expectedObjectID = SL_OBJECTID_LEDDEVICE;
                    break;
                case SL_IODEVICE_VIBRA:
                    expectedObjectID = SL_OBJECTID_VIBRADEVICE;
                    break;
                case XA_IODEVICE_CAMERA:
                    expectedObjectID = XA_OBJECTID_CAMERADEVICE;
                    break;
                case XA_IODEVICE_RADIO:
                    expectedObjectID = XA_OBJECTID_RADIODEVICE;
                    break;
                // audio input and audio output cannot be specified via objects
                case SL_IODEVICE_AUDIOINPUT:
                // case SL_IODEVICE_AUDIOOUTPUT:   // does not exist in 1.0.1, added in 1.1
                default:
                    SL_LOGE("%s: deviceType=%u", name, deviceType);
                    pDataLocator->mIODevice.device = NULL;
                    expectedObjectID = 0;
                    result = SL_RESULT_PARAMETER_INVALID;
                }
                if (result == SL_RESULT_SUCCESS) {
                    // check that device has the correct object ID and is realized,
                    // and acquire a strong reference to it
                    result = AcquireStrongRef((IObject *) device, expectedObjectID);
                    if (SL_RESULT_SUCCESS != result) {
                        SL_LOGE("%s: locatorType=IODEVICE, but device field %p has wrong " \
                            "object ID or is not realized", name, device);
                        pDataLocator->mIODevice.device = NULL;
                    }
                }
            } else {
                SLuint32 deviceID = pDataLocator->mIODevice.deviceID;
                switch (deviceType) {
                case SL_IODEVICE_LEDARRAY:
                    if (SL_DEFAULTDEVICEID_LED != deviceID) {
                        SL_LOGE("%s: invalid LED deviceID=%u", name, deviceID);
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_IODEVICE_VIBRA:
                    if (SL_DEFAULTDEVICEID_VIBRA != deviceID) {
                        SL_LOGE("%s: invalid vibra deviceID=%u", name, deviceID);
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_IODEVICE_AUDIOINPUT:
                    if (SL_DEFAULTDEVICEID_AUDIOINPUT != deviceID) {
                        SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID);
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case XA_IODEVICE_RADIO:
                    // no default device ID for radio; see Khronos bug XXXX
                    break;
                case XA_IODEVICE_CAMERA:
                    if (XA_DEFAULTDEVICEID_CAMERA != deviceID) {
                        SL_LOGE("%s: invalid audio input deviceID=%u", name, deviceID);
                        result = XA_RESULT_PARAMETER_INVALID;
                    }
                    break;
                // case SL_IODEVICE_AUDIOOUTPUT:
                    // does not exist in 1.0.1, added in 1.1
                    // break;
                default:
                    SL_LOGE("%s: deviceType=%u is invalid", name, deviceType);
                    result = SL_RESULT_PARAMETER_INVALID;
                }
            }
            }
            break;

        case SL_DATALOCATOR_MIDIBUFFERQUEUE:
            pDataLocator->mMIDIBufferQueue = *(SLDataLocator_MIDIBufferQueue *)pLocator;
            if (0 == pDataLocator->mMIDIBufferQueue.tpqn) {
                pDataLocator->mMIDIBufferQueue.tpqn = 192;
            }
            // number of buffers must be specified, there is no default value, and can't be too big
            if (!((1 <= pDataLocator->mMIDIBufferQueue.numBuffers) &&
                (pDataLocator->mMIDIBufferQueue.numBuffers <= 255))) {
                SL_LOGE("%s: SLDataLocator_MIDIBufferQueue.numBuffers=%d", name,
                        pDataLocator->mMIDIBufferQueue.numBuffers);
                result = SL_RESULT_PARAMETER_INVALID;
            }
            break;

        case SL_DATALOCATOR_OUTPUTMIX:
            pDataLocator->mOutputMix = *(SLDataLocator_OutputMix *)pLocator;
            // check that output mix object has the correct object ID and is realized,
            // and acquire a strong reference to it
            result = AcquireStrongRef((IObject *) pDataLocator->mOutputMix.outputMix,
                SL_OBJECTID_OUTPUTMIX);
            if (SL_RESULT_SUCCESS != result) {
                SL_LOGE("%s: locatorType=SL_DATALOCATOR_OUTPUTMIX, but outputMix field %p does " \
                    "not refer to an SL_OBJECTID_OUTPUTMIX or the output mix is not realized", \
                    name, pDataLocator->mOutputMix.outputMix);
                pDataLocator->mOutputMix.outputMix = NULL;
            }
            break;

        case XA_DATALOCATOR_NATIVEDISPLAY:
            pDataLocator->mNativeDisplay = *(XADataLocator_NativeDisplay *)pLocator;
            // hWindow is NDK C ANativeWindow * and hDisplay must be NULL
            if (pDataLocator->mNativeDisplay.hWindow == NULL) {
                SL_LOGE("%s: hWindow must be non-NULL ANativeWindow *", name);
                result = SL_RESULT_PARAMETER_INVALID;
            }
            if (pDataLocator->mNativeDisplay.hDisplay != NULL) {
                SL_LOGE("%s: hDisplay must be NULL, but is %p", name,
                        pDataLocator->mNativeDisplay.hDisplay);
                result = SL_RESULT_PARAMETER_INVALID;
            }
            break;

        case SL_DATALOCATOR_URI:
            {
            pDataLocator->mURI = *(SLDataLocator_URI *)pLocator;
            if (NULL == pDataLocator->mURI.URI) {
                SL_LOGE("%s: invalid URI=NULL", name);
                result = SL_RESULT_PARAMETER_INVALID;
            } else {
                // NTH verify URI address for validity
                size_t len = strlen((const char *) pDataLocator->mURI.URI);
                SLchar *myURI = (SLchar *) malloc(len + 1);
                if (NULL == myURI) {
                    result = SL_RESULT_MEMORY_FAILURE;
                } else {
                    memcpy(myURI, pDataLocator->mURI.URI, len + 1);
                    // Verify that another thread didn't change the NUL-terminator after we used it
                    // to determine length of string to copy. It's OK if the string became shorter.
                    if ('\0' != myURI[len]) {
                        free(myURI);
                        myURI = NULL;
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                }
                pDataLocator->mURI.URI = myURI;
            }
            }
            break;

#ifdef ANDROID
        case SL_DATALOCATOR_ANDROIDFD:
        {
            pDataLocator->mFD = *(SLDataLocator_AndroidFD *)pLocator;
            SL_LOGV("%s: fd=%d offset=%lld length=%lld", name, pDataLocator->mFD.fd,
                    pDataLocator->mFD.offset, pDataLocator->mFD.length);
            // NTH check against process fd limit
            if (0 > pDataLocator->mFD.fd) {
                SL_LOGE("%s: fd=%d\n", name, pDataLocator->mFD.fd);
                result = SL_RESULT_PARAMETER_INVALID;
            }
            break;
        }
        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
        {
            pDataLocator->mABQ = *(SLDataLocator_AndroidBufferQueue*)pLocator;
            // number of buffers must be specified, there is no default value, and can't be too big
            if (!((1 <= pDataLocator->mBufferQueue.numBuffers) &&
                    (pDataLocator->mBufferQueue.numBuffers <= 255))) {
                SL_LOGE("%s: numBuffers=%u", name, pDataLocator->mABQ.numBuffers);
                result = SL_RESULT_PARAMETER_INVALID;
            }
            break;
        }
#endif

        case SL_DATALOCATOR_NULL:   // a NULL pointer is allowed, but not a pointer to NULL
        default:
            SL_LOGE("%s: locatorType=%u", name, locatorType);
            result = SL_RESULT_PARAMETER_INVALID;
        }

        // Verify that another thread didn't change the locatorType field after we used it
        // to determine sizeof struct to copy.
        if ((SL_RESULT_SUCCESS == result) && (locatorType != pDataLocator->mLocatorType)) {
            SL_LOGE("%s: locatorType changed from %u to %u", name, locatorType,
                    pDataLocator->mLocatorType);
            result = SL_RESULT_PRECONDITIONS_VIOLATED;
        }

    }

    // Verify that the data locator type is allowed in this context
    if (SL_RESULT_SUCCESS == result) {
        SLuint32 actualMask;
        switch (locatorType) {
        case SL_DATALOCATOR_NULL:
        case SL_DATALOCATOR_URI:
        case SL_DATALOCATOR_ADDRESS:
        case SL_DATALOCATOR_IODEVICE:
        case SL_DATALOCATOR_OUTPUTMIX:
        case XA_DATALOCATOR_NATIVEDISPLAY:
        case SL_DATALOCATOR_BUFFERQUEUE:
        case SL_DATALOCATOR_MIDIBUFFERQUEUE:
            actualMask = 1L << locatorType;
            break;
#ifdef ANDROID
        case SL_DATALOCATOR_ANDROIDFD:
        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
        case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
            actualMask = 0x100L << (locatorType - SL_DATALOCATOR_ANDROIDFD);
            break;
#endif
        default:
            assert(false);
            actualMask = 0L;
            break;
        }
        if (!(allowedDataLocatorMask & actualMask)) {
            SL_LOGE("%s: data locator type 0x%x not allowed", name, locatorType);
            result = SL_RESULT_CONTENT_UNSUPPORTED;
        }
    }

    return result;
}


/** \brief Free the local deep copy of a data locator */

static void freeDataLocator(DataLocator *pDataLocator)
{
    switch (pDataLocator->mLocatorType) {
    case SL_DATALOCATOR_NULL:
    case SL_DATALOCATOR_ADDRESS:
    case SL_DATALOCATOR_BUFFERQUEUE:
    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    case XA_DATALOCATOR_NATIVEDISPLAY:
        break;
    case SL_DATALOCATOR_URI:
        if (NULL != pDataLocator->mURI.URI) {
            free(pDataLocator->mURI.URI);
            pDataLocator->mURI.URI = NULL;
        }
        pDataLocator->mURI.URI = NULL;
        break;
    case SL_DATALOCATOR_IODEVICE:
        if (NULL != pDataLocator->mIODevice.device) {
            ReleaseStrongRef((IObject *) pDataLocator->mIODevice.device);
            pDataLocator->mIODevice.device = NULL;
        }
        break;
    case SL_DATALOCATOR_OUTPUTMIX:
        if (NULL != pDataLocator->mOutputMix.outputMix) {
            ReleaseStrongRef((IObject *) pDataLocator->mOutputMix.outputMix);
            pDataLocator->mOutputMix.outputMix = NULL;
        }
        break;
#ifdef ANDROID
    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
    case SL_DATALOCATOR_ANDROIDFD:
        break;
#endif
    default:
        // an invalid data locator is caught earlier when making the copy
        assert(false);
        break;
    }
}


/** \brief Check a data format and make local deep copy */

static SLresult checkDataFormat(const char *name, void *pFormat, DataFormat *pDataFormat,
        SLuint32 allowedDataFormatMask)
{
    assert(NULL != name && NULL != pDataFormat);
    SLresult result = SL_RESULT_SUCCESS;
    const SLuint32 *df_representation = NULL; // pointer to representation field, if it exists
    SLuint32 formatType;
    if (NULL == pFormat) {
        pDataFormat->mFormatType = formatType = SL_DATAFORMAT_NULL;
    } else {
        formatType = *(SLuint32 *)pFormat;
        switch (formatType) {
        case SL_ANDROID_DATAFORMAT_PCM_EX:
            pDataFormat->mPCMEx.representation =
                    ((SLAndroidDataFormat_PCM_EX *)pFormat)->representation;
            switch (pDataFormat->mPCMEx.representation) {
            case SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT:
            case SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT:
            case SL_ANDROID_PCM_REPRESENTATION_FLOAT:
                df_representation = &pDataFormat->mPCMEx.representation;
                break;
            default:
                SL_LOGE("%s: unsupported representation: %d", name,
                        pDataFormat->mPCMEx.representation);
                result = SL_RESULT_PARAMETER_INVALID;
                break;
            }
            // SL_ANDROID_DATAFORMAT_PCM_EX - fall through to next test.
        case SL_DATAFORMAT_PCM:
            pDataFormat->mPCM = *(SLDataFormat_PCM *)pFormat;
            do {

                // check the channel count
                // FIXME FCC_8 Android and 8-channel positional assumptions here
                switch (pDataFormat->mPCM.numChannels) {
                case 1:     // mono
                case 2:     // stereo
                case 3:     // stereo + front center
                case 4:     // QUAD
                case 5:     // QUAD + front center
                case 6:     // 5.1
                case 7:     // 5.1 + back center
                case 8:     // 7.1
                    break;
                case 0:     // unknown
                    result = SL_RESULT_PARAMETER_INVALID;
                    break;
                default:    // multi-channel
                    result = SL_RESULT_CONTENT_UNSUPPORTED;
                    break;
                }
                if (SL_RESULT_SUCCESS != result) {
                    SL_LOGE("%s: numChannels=%u", name, (unsigned) pDataFormat->mPCM.numChannels);
                    break;
                }

                // check the sampling rate
                if (pDataFormat->mPCM.samplesPerSec == 0) {
                    result = SL_RESULT_PARAMETER_INVALID;
                } else if (pDataFormat->mPCM.samplesPerSec < SL_SAMPLINGRATE_8 ||
                        pDataFormat->mPCM.samplesPerSec > SL_SAMPLINGRATE_192) {
                    result = SL_RESULT_CONTENT_UNSUPPORTED;
                }
                if (SL_RESULT_SUCCESS != result) {
                    SL_LOGE("%s: samplesPerSec=%u", name, pDataFormat->mPCM.samplesPerSec);
                    break;
                }

                // check the container bit depth and representation
                switch (pDataFormat->mPCM.containerSize) {
                case 8:
                    if (df_representation != NULL &&
                            *df_representation != SL_ANDROID_PCM_REPRESENTATION_UNSIGNED_INT) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case 16:
                case 24:
                    if (df_representation != NULL &&
                            *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case 32:
                    if (df_representation != NULL
                            && *df_representation != SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT
                            && *df_representation != SL_ANDROID_PCM_REPRESENTATION_FLOAT) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                default:
                    result = SL_RESULT_PARAMETER_INVALID;
                    break;
                }
                if (SL_RESULT_SUCCESS != result) {
                    SL_LOGE("%s: containerSize=%u", name, pDataFormat->mPCM.containerSize);
                    break;
                }

                // sample size cannot be zero, and container size cannot be less than sample size
                if (pDataFormat->mPCM.bitsPerSample == 0 ||
                        pDataFormat->mPCM.containerSize < pDataFormat->mPCM.bitsPerSample) {
                    result = SL_RESULT_PARAMETER_INVALID;
                }
                if (SL_RESULT_SUCCESS != result) {
                    SL_LOGE("%s: containerSize=%u, bitsPerSample=%u", name,
                            (unsigned) pDataFormat->mPCM.containerSize,
                            (unsigned) pDataFormat->mPCM.bitsPerSample);
                    break;
                }

                // check the channel mask
                // FIXME FCC_8 Android and 8-channel positional assumptions here
                switch (pDataFormat->mPCM.channelMask) {
                case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT:
                    if (2 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_SPEAKER_FRONT_LEFT:
                case SL_SPEAKER_FRONT_RIGHT:
                case SL_SPEAKER_FRONT_CENTER:
                    if (1 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
#ifdef ANDROID
                case SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER:
                    if (3 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_ANDROID_SPEAKER_QUAD:
                    if (4 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER:
                    if (5 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_ANDROID_SPEAKER_5DOT1:
                    if (6 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER:
                    if (7 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
                case SL_ANDROID_SPEAKER_7DOT1:
                    if (8 != pDataFormat->mPCM.numChannels) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    }
                    break;
#endif
                case 0: {
                    // According to OpenSL ES 1.0.1 section 9.1.7 SLDataFormat_PCM, "a default
                    // setting of zero indicates stereo format (i.e. the setting is equivalent to
                    // SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT)."
                    //
                    // ANDROID SPECIFIC BEHAVIOR.
                    // We fill in the appropriate mask to the number indicated by numChannels.
                    // The default of front left rather than center for mono may be non-intuitive,
                    // but the left channel is the first channel for stereo or multichannel content.
                    SLuint32 mask = channelCountToMask(pDataFormat->mPCM.numChannels);
                    if (mask == UNKNOWN_CHANNELMASK) {
                        result = SL_RESULT_PARAMETER_INVALID;
                    } else {
                        pDataFormat->mPCM.channelMask = mask;
                    }
                } break;
                default:
                    result = SL_RESULT_PARAMETER_INVALID;
                    break;
                }
                if (SL_RESULT_SUCCESS != result) {
                    SL_LOGE("%s: channelMask=0x%x numChannels=%u", name,
                        pDataFormat->mPCM.channelMask, pDataFormat->mPCM.numChannels);
                    break;
                }

                // check the endianness / byte order
                switch (pDataFormat->mPCM.endianness) {
                case SL_BYTEORDER_LITTLEENDIAN:
                case SL_BYTEORDER_BIGENDIAN:
                    break;
                // native is proposed but not yet in spec
                default:
                    result = SL_RESULT_PARAMETER_INVALID;
                    break;
                }
                if (SL_RESULT_SUCCESS != result) {
                    SL_LOGE("%s: endianness=%u", name, (unsigned) pDataFormat->mPCM.endianness);
                    break;
                }

                // here if all checks passed successfully

            } while(0);
            break;

        case SL_DATAFORMAT_MIME:
            pDataFormat->mMIME = *(SLDataFormat_MIME *)pFormat;
            if (NULL != pDataFormat->mMIME.mimeType) {
                // NTH check address for validity
                size_t len = strlen((const char *) pDataFormat->mMIME.mimeType);
                SLchar *myMIME = (SLchar *) malloc(len + 1);
                if (NULL == myMIME) {
                    result = SL_RESULT_MEMORY_FAILURE;
                } else {
                    memcpy(myMIME, pDataFormat->mMIME.mimeType, len + 1);
                    // make sure MIME string was not modified asynchronously
                    if ('\0' != myMIME[len]) {
                        free(myMIME);
                        myMIME = NULL;
                        result = SL_RESULT_PRECONDITIONS_VIOLATED;
                    }
                }
                pDataFormat->mMIME.mimeType = myMIME;
            }
            break;

        case XA_DATAFORMAT_RAWIMAGE:
            pDataFormat->mRawImage = *(XADataFormat_RawImage *)pFormat;
            switch (pDataFormat->mRawImage.colorFormat) {
            case XA_COLORFORMAT_MONOCHROME:
            case XA_COLORFORMAT_8BITRGB332:
            case XA_COLORFORMAT_12BITRGB444:
            case XA_COLORFORMAT_16BITARGB4444:
            case XA_COLORFORMAT_16BITARGB1555:
            case XA_COLORFORMAT_16BITRGB565:
            case XA_COLORFORMAT_16BITBGR565:
            case XA_COLORFORMAT_18BITRGB666:
            case XA_COLORFORMAT_18BITARGB1665:
            case XA_COLORFORMAT_19BITARGB1666:
            case XA_COLORFORMAT_24BITRGB888:
            case XA_COLORFORMAT_24BITBGR888:
            case XA_COLORFORMAT_24BITARGB1887:
            case XA_COLORFORMAT_25BITARGB1888:
            case XA_COLORFORMAT_32BITBGRA8888:
            case XA_COLORFORMAT_32BITARGB8888:
            case XA_COLORFORMAT_YUV411PLANAR:
            case XA_COLORFORMAT_YUV420PLANAR:
            case XA_COLORFORMAT_YUV420SEMIPLANAR:
            case XA_COLORFORMAT_YUV422PLANAR:
            case XA_COLORFORMAT_YUV422SEMIPLANAR:
            case XA_COLORFORMAT_YCBYCR:
            case XA_COLORFORMAT_YCRYCB:
            case XA_COLORFORMAT_CBYCRY:
            case XA_COLORFORMAT_CRYCBY:
            case XA_COLORFORMAT_YUV444INTERLEAVED:
            case XA_COLORFORMAT_RAWBAYER8BIT:
            case XA_COLORFORMAT_RAWBAYER10BIT:
            case XA_COLORFORMAT_RAWBAYER8BITCOMPRESSED:
            case XA_COLORFORMAT_L2:
            case XA_COLORFORMAT_L4:
            case XA_COLORFORMAT_L8:
            case XA_COLORFORMAT_L16:
            case XA_COLORFORMAT_L24:
            case XA_COLORFORMAT_L32:
            case XA_COLORFORMAT_18BITBGR666:
            case XA_COLORFORMAT_24BITARGB6666:
            case XA_COLORFORMAT_24BITABGR6666:
                break;
            case XA_COLORFORMAT_UNUSED:
            default:
                result = XA_RESULT_PARAMETER_INVALID;
                SL_LOGE("%s: unsupported color format %d", name,
                    pDataFormat->mRawImage.colorFormat);
                break;
            }
            // no checks for height, width, or stride
            break;

        default:
            result = SL_RESULT_PARAMETER_INVALID;
            SL_LOGE("%s: formatType=%u", name, (unsigned) formatType);
            break;

        }

        // make sure format type was not modified asynchronously
        if ((SL_RESULT_SUCCESS == result) && (formatType != pDataFormat->mFormatType)) {
            SL_LOGE("%s: formatType changed from %u to %u", name, formatType,
                    pDataFormat->mFormatType);
            result = SL_RESULT_PRECONDITIONS_VIOLATED;
        }

    }

    // Verify that the data format type is allowed in this context
    if (SL_RESULT_SUCCESS == result) {
        SLuint32 actualMask;
        switch (formatType) {
        case SL_DATAFORMAT_NULL:
        case SL_DATAFORMAT_MIME:
        case SL_DATAFORMAT_PCM:
        case SL_ANDROID_DATAFORMAT_PCM_EX:
        case XA_DATAFORMAT_RAWIMAGE:
            actualMask = 1L << formatType;
            break;
        default:
            assert(false);
            actualMask = 0L;
            break;
        }
        if (!(allowedDataFormatMask & actualMask)) {
            SL_LOGE("%s: data format %d not allowed", name, formatType);
            result = SL_RESULT_CONTENT_UNSUPPORTED;
        }
    }

    return result;
}


/** \brief Check interface ID compatibility with respect to a particular source
 *         and sink data locator format
 */

SLresult checkSourceSinkVsInterfacesCompatibility(const DataLocatorFormat *pSrcDataLocatorFormat,
        const DataLocatorFormat *pSinkDataLocatorFormat,
        const ClassTable *clazz, unsigned requiredMask) {
    int index;
    switch (pSrcDataLocatorFormat->mLocator.mLocatorType) {
    case SL_DATALOCATOR_URI:
#ifdef ANDROID
    case SL_DATALOCATOR_ANDROIDFD:
#endif
        // URIs and FD can be sources when "playing" to an OutputMix or a Buffer Queue for decode
        // so we don't prevent the retrieval of the BufferQueue interfaces for those sources
        switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
        case SL_DATALOCATOR_BUFFERQUEUE:
#ifdef ANDROID
        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
#endif
            break;
        default:
            // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
            // if the data sink is not a buffer queue
            index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
#ifdef ANDROID
            assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
#endif
            if (0 <= index) {
                if (requiredMask & (1 << index)) {
                    SL_LOGE("can't require SL_IID_BUFFERQUEUE "
#ifdef ANDROID
                            "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
#endif
                            "with a non-buffer queue data sink");
                    return SL_RESULT_FEATURE_UNSUPPORTED;
                }
            }
            break;
        }
        break;

    case SL_DATALOCATOR_BUFFERQUEUE:
#ifdef ANDROID
    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
#endif
        // can't require SLSeekItf if data source is a buffer queue
        index = clazz->mMPH_to_index[MPH_SEEK];
        if (0 <= index) {
            if (requiredMask & (1 << index)) {
                SL_LOGE("can't require SL_IID_SEEK with a buffer queue data source");
                return SL_RESULT_FEATURE_UNSUPPORTED;
            }
        }
        // can't require SLMuteSoloItf if data source is a mono buffer queue
        index = clazz->mMPH_to_index[MPH_MUTESOLO];
        if (0 <= index) {
            if ((requiredMask & (1 << index)) &&
                    (SL_DATAFORMAT_PCM == pSrcDataLocatorFormat->mFormat.mFormatType) &&
                    (1 == pSrcDataLocatorFormat->mFormat.mPCM.numChannels)) {
                SL_LOGE("can't require SL_IID_MUTESOLO with a mono buffer queue data source");
                return SL_RESULT_FEATURE_UNSUPPORTED;
            }
        }
        break;

#ifdef ANDROID
    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
        // can't require SLSeekItf if data source is an Android buffer queue
        index = clazz->mMPH_to_index[MPH_SEEK];
        if (0 <= index) {
            if (requiredMask & (1 << index)) {
                SL_LOGE("can't require SL_IID_SEEK with a SL_DATALOCATOR_ANDROIDBUFFERQUEUE "\
                        "source");
                return SL_RESULT_FEATURE_UNSUPPORTED;
            }
        }
        switch (pSinkDataLocatorFormat->mLocator.mLocatorType) {
        // for use-case AAC decode from SLAndroidBufferQueueItf with AAC ADTS data
        case SL_DATALOCATOR_BUFFERQUEUE:
        case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
            break;
        // for use-case audio playback from SLAndroidBufferQueueItf with MP2TS data
        case SL_DATALOCATOR_OUTPUTMIX:
            break;
        default:
            SL_LOGE("Invalid sink for SL_DATALOCATOR_ANDROIDBUFFERQUEUE source");
            return SL_RESULT_FEATURE_UNSUPPORTED;
            break;
        }
        break;
#endif
    case SL_DATALOCATOR_ADDRESS:
    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
    case XA_DATALOCATOR_NATIVEDISPLAY:
        // any special checks here???
    default:
        // can't require SLBufferQueueItf or its alias SLAndroidSimpleBufferQueueItf
        // if the data source is not a buffer queue
        index = clazz->mMPH_to_index[MPH_BUFFERQUEUE];
#ifdef ANDROID
        assert(index == clazz->mMPH_to_index[MPH_ANDROIDSIMPLEBUFFERQUEUE]);
#endif
        if (0 <= index) {
            if (requiredMask & (1 << index)) {
                SL_LOGE("can't require SL_IID_BUFFERQUEUE "
#ifdef ANDROID
                        "or SL_IID_ANDROIDSIMPLEBUFFERQUEUE "
#endif
                        "with a non-buffer queue data source");
                return SL_RESULT_FEATURE_UNSUPPORTED;
            }
        }
        break;
    }
    return SL_RESULT_SUCCESS;
}


/** \brief Free the local deep copy of a data format */

static void freeDataFormat(DataFormat *pDataFormat)
{
    switch (pDataFormat->mFormatType) {
    case SL_DATAFORMAT_MIME:
        if (NULL != pDataFormat->mMIME.mimeType) {
            free(pDataFormat->mMIME.mimeType);
            pDataFormat->mMIME.mimeType = NULL;
        }
        break;
    case SL_ANDROID_DATAFORMAT_PCM_EX:
    case SL_DATAFORMAT_PCM:
    case XA_DATAFORMAT_RAWIMAGE:
    case SL_DATAFORMAT_NULL:
        break;
    default:
        // an invalid data format is caught earlier during the copy
        assert(false);
        break;
    }
}


/** \brief Check a data source and make local deep copy */

SLresult checkDataSource(const char *name, const SLDataSource *pDataSrc,
        DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
        SLuint32 allowedDataFormatMask)
{
    assert(NULL != name && NULL != pDataLocatorFormat);
    pDataLocatorFormat->u.mSource.pLocator = &pDataLocatorFormat->mLocator;
    pDataLocatorFormat->u.mSource.pFormat = &pDataLocatorFormat->mFormat;

    if (NULL == pDataSrc) {
        pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
        pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
        if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
                (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
            return SL_RESULT_SUCCESS;
        }
        SL_LOGE("%s: data source cannot be NULL", name);
        return SL_RESULT_PARAMETER_INVALID;
    }
    SLDataSource myDataSrc = *pDataSrc;
    SLresult result;
    result = checkDataLocator(name, myDataSrc.pLocator, &pDataLocatorFormat->mLocator,
            allowedDataLocatorMask);
    if (SL_RESULT_SUCCESS != result) {
        return result;
    }

    switch (pDataLocatorFormat->mLocator.mLocatorType) {
    case SL_DATALOCATOR_URI:
        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
        break;
    case SL_DATALOCATOR_ADDRESS:
    case SL_DATALOCATOR_BUFFERQUEUE:
        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
        break;
    // Per the spec, the pFormat field is ignored in some cases
    case SL_DATALOCATOR_IODEVICE:
        myDataSrc.pFormat = NULL;
        // fall through
    case SL_DATALOCATOR_NULL:
    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
        allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
        break;
    case SL_DATALOCATOR_OUTPUTMIX:
    case XA_DATALOCATOR_NATIVEDISPLAY:
        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
        break;
#ifdef ANDROID
    case SL_DATALOCATOR_ANDROIDFD:
        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
        break;
    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
        break;
    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;;
        break;
#endif
    default:
        // invalid data locator type is caught earlier
        assert(false);
        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
        break;
    }

    result = checkDataFormat(name, myDataSrc.pFormat, &pDataLocatorFormat->mFormat,
            allowedDataFormatMask);
    if (SL_RESULT_SUCCESS != result) {
        freeDataLocator(&pDataLocatorFormat->mLocator);
        return result;
    }

    return SL_RESULT_SUCCESS;
}


/** \brief Check a data sink and make local deep copy */

SLresult checkDataSink(const char *name, const SLDataSink *pDataSink,
        DataLocatorFormat *pDataLocatorFormat, SLuint32 allowedDataLocatorMask,
        SLuint32 allowedDataFormatMask)
{
    assert(NULL != name && NULL != pDataLocatorFormat);
    pDataLocatorFormat->u.mSink.pLocator = &pDataLocatorFormat->mLocator;
    pDataLocatorFormat->u.mSink.pFormat = &pDataLocatorFormat->mFormat;

    if (NULL == pDataSink) {
        pDataLocatorFormat->mLocator.mLocatorType = SL_DATALOCATOR_NULL;
        pDataLocatorFormat->mFormat.mFormatType = SL_DATAFORMAT_NULL;
        if ((allowedDataLocatorMask & DATALOCATOR_MASK_NULL) &&
                (allowedDataFormatMask & DATAFORMAT_MASK_NULL)) {
            return SL_RESULT_SUCCESS;
        }
        SL_LOGE("%s: data sink cannot be NULL", name);
        return SL_RESULT_PARAMETER_INVALID;
    }
    SLDataSink myDataSink = *pDataSink;
    SLresult result;
    result = checkDataLocator(name, myDataSink.pLocator, &pDataLocatorFormat->mLocator,
            allowedDataLocatorMask);
    if (SL_RESULT_SUCCESS != result) {
        return result;
    }

    switch (pDataLocatorFormat->mLocator.mLocatorType) {
    case SL_DATALOCATOR_URI:
        allowedDataFormatMask &= DATAFORMAT_MASK_MIME;
        break;
    case SL_DATALOCATOR_ADDRESS:
    case SL_DATALOCATOR_BUFFERQUEUE:
        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
        break;
    // Per the spec, the pFormat field is ignored in some cases
    case SL_DATALOCATOR_IODEVICE:
    case SL_DATALOCATOR_OUTPUTMIX:
    case XA_DATALOCATOR_NATIVEDISPLAY:
        myDataSink.pFormat = NULL;
        // fall through
    case SL_DATALOCATOR_NULL:
    case SL_DATALOCATOR_MIDIBUFFERQUEUE:
        allowedDataFormatMask &= DATAFORMAT_MASK_NULL;
        break;
#ifdef ANDROID
    case SL_DATALOCATOR_ANDROIDFD:
        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
        break;
    case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE:
        allowedDataFormatMask &= DATAFORMAT_MASK_PCM | DATAFORMAT_MASK_PCM_EX;
        break;
    case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
        break;
#endif
    default:
        // invalid data locator type is caught earlier
        assert(false);
        allowedDataFormatMask = DATAFORMAT_MASK_NONE;
        break;
    }

    result = checkDataFormat(name, myDataSink.pFormat, &pDataLocatorFormat->mFormat,
            allowedDataFormatMask);
    if (SL_RESULT_SUCCESS != result) {
        freeDataLocator(&pDataLocatorFormat->mLocator);
        return result;
    }

    return SL_RESULT_SUCCESS;
}


/** \brief Free the local deep copy of a data locator format */

void freeDataLocatorFormat(DataLocatorFormat *dlf)
{
    assert(NULL != dlf);
    freeDataLocator(&dlf->mLocator);
    freeDataFormat(&dlf->mFormat);
}
