/*
 * 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"
#include "data.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, SLboolean isOutputFormat)
{
    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 {
                if (pDataFormat->mPCM.numChannels == 0) {
                    result = SL_RESULT_PARAMETER_INVALID;
                } else if (pDataFormat->mPCM.numChannels > SL_ANDROID_SPEAKER_COUNT_MAX) {
                    result = SL_RESULT_CONTENT_UNSUPPORTED;
                }
                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
                SL_LOGV("%s: Requested channel mask of 0x%x for %d channel audio",
                    name,
                    pDataFormat->mPCM.channelMask,
                    pDataFormat->mPCM.numChannels);

                if (pDataFormat->mPCM.channelMask == 0) {
                    // We can derive the channel mask from the channel count,
                    // but issue a warning--the automatic mask generation
                    // makes a lot of assumptions that may or may not be what
                    // the app was expecting.
                    SLuint32 mask = isOutputFormat
                            ? sles_channel_out_mask_from_count(pDataFormat->mPCM.numChannels)
                            : sles_channel_in_mask_from_count(pDataFormat->mPCM.numChannels);
                    if (mask == SL_ANDROID_UNKNOWN_CHANNELMASK) {
                        SL_LOGE("No channel mask specified and no default mapping for"
                                "requested speaker count of %u", pDataFormat->mPCM.numChannels);
                        result = SL_RESULT_PARAMETER_INVALID;
                    } else {
                        pDataFormat->mPCM.channelMask = mask;
                        SL_LOGW("No channel mask specified; Using mask %#x based on requested"
                                        "speaker count of %u",
                                pDataFormat->mPCM.channelMask,
                                pDataFormat->mPCM.numChannels);
                    }
                }

                SLuint32 mask = pDataFormat->mPCM.channelMask;
                SLuint32 count = sles_channel_count_from_mask(mask);
                if (count != pDataFormat->mPCM.numChannels) {
                    SL_LOGE("%s: requested %d channels but mask (0x%x) has %d channel bits set",
                        name,
                        pDataFormat->mPCM.numChannels,
                        mask,
                        count);
                    result = SL_RESULT_PARAMETER_INVALID;
                    break;
                }

                SL_LOGV("%s: final channel mask is 0x%x", name, pDataFormat->mPCM.channelMask);

                // 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,
                             SL_BOOLEAN_TRUE /*isOutputFormat*/);
    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,
            SL_BOOLEAN_FALSE /*isOutputFormat*/);

    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);
}
