/*
 * 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.
 */

/* AndroidBufferQueue implementation */

//#define USE_LOG SLAndroidLogLevel_Verbose

#include "sles_allinclusive.h"
// for AAC ADTS verification on enqueue:
#include "android/include/AacBqToPcmCbRenderer.h"

/**
 * Determine the state of the audio player or media player associated with a buffer queue.
 *  Note that PLAYSTATE and RECORDSTATE values are equivalent (where PLAYING == RECORDING).
 */

static SLuint32 getAssociatedState(IAndroidBufferQueue *thiz)
{
    SLuint32 state;
    switch (InterfaceToObjectID(thiz)) {
      case XA_OBJECTID_MEDIAPLAYER:
        state = ((CMediaPlayer *) thiz->mThis)->mPlay.mState;
        break;
      case SL_OBJECTID_AUDIOPLAYER:
        state = ((CAudioPlayer *) thiz->mThis)->mPlay.mState;
        break;
      default:
        // unreachable, but just in case we will assume it is stopped
        assert(SL_BOOLEAN_FALSE);
        state = SL_PLAYSTATE_STOPPED;
        break;
    }
    return state;
}


/**
 * parse and set the items associated with the given buffer, based on the buffer type,
 * which determines the set of authorized items and format
 */
static SLresult setItems(SLuint32 dataLength,
        const SLAndroidBufferItem *pItems, SLuint32 itemsLength,
        SLuint16 bufferType, AdvancedBufferHeader *pBuff, bool *pEOS)
{
    // reset item structure based on type
    switch (bufferType) {
      case kAndroidBufferTypeMpeg2Ts:
        pBuff->mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
        pBuff->mItems.mTsCmdData.mPts = 0;
        break;
      case kAndroidBufferTypeAacadts:
        pBuff->mItems.mAdtsCmdData.mAdtsCmdCode = ANDROID_ADTSEVENT_NONE;
        break;
      case kAndroidBufferTypeInvalid:
      default:
        // shouldn't happen, but just in case clear out the item structure
        memset(&pBuff->mItems, 0, sizeof(AdvancedBufferItems));
        return SL_RESULT_INTERNAL_ERROR;
    }

    // process all items in the array; if no items then we break out of loop immediately
    while (itemsLength > 0) {

        // remaining length must be large enough for one full item without any associated data
        if (itemsLength < sizeof(SLAndroidBufferItem)) {
            SL_LOGE("Partial item at end of array");
            return SL_RESULT_PARAMETER_INVALID;
        }
        itemsLength -= sizeof(SLAndroidBufferItem);

        // remaining length must be large enough for data with current item and alignment padding
        SLuint32 itemDataSizeWithAlignmentPadding = (pItems->itemSize + 3) & ~3;
        if (itemsLength < itemDataSizeWithAlignmentPadding) {
            SL_LOGE("Partial item data at end of array");
            return SL_RESULT_PARAMETER_INVALID;
        }
        itemsLength -= itemDataSizeWithAlignmentPadding;

        // parse item data based on type
        switch (bufferType) {

          case kAndroidBufferTypeMpeg2Ts: {
            switch (pItems->itemKey) {

              case SL_ANDROID_ITEMKEY_EOS:
                pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_EOS;
                //SL_LOGD("Found EOS event=%d", pBuff->mItems.mTsCmdData.mTsCmdCode);
                if (pItems->itemSize != 0) {
                    SL_LOGE("Invalid item parameter size %u for EOS", pItems->itemSize);
                    return SL_RESULT_PARAMETER_INVALID;
                }
                break;

              case SL_ANDROID_ITEMKEY_DISCONTINUITY:
                if (pItems->itemSize == 0) {
                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_DISCONTINUITY;
                    //SL_LOGD("Found DISCONTINUITYevent=%d", pBuff->mItems.mTsCmdData.mTsCmdCode);
                } else if (pItems->itemSize == sizeof(SLAuint64)) {
                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_DISCON_NEWPTS;
                    memcpy(&pBuff->mItems.mTsCmdData.mPts, pItems->itemData, sizeof(SLAuint64));
                    //SL_LOGD("Found PTS=%lld", pBuff->mItems.mTsCmdData.mPts);
                } else {
                    SL_LOGE("Invalid item parameter size %u for MPEG-2 PTS", pItems->itemSize);
                    return SL_RESULT_PARAMETER_INVALID;
                }
                break;

              case SL_ANDROID_ITEMKEY_FORMAT_CHANGE:
                // distinguish between a "full" format change and one where it says what changed
                if (pItems->itemSize == 0) {
                    SL_LOGV("Received format change with no data == full format change");
                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL;
                } else if (pItems->itemSize == sizeof(SLuint32)) {
                    XAuint32 formatData;// = *((XAuint32*)pItems->itemData);
                    memcpy(&formatData, pItems->itemData, sizeof(XAuint32));
                    // intentionally only supporting video change when reading which specific
                    //    stream has changed, interpret other changes as full change
                    if (formatData == XA_ANDROID_FORMATCHANGE_ITEMDATA_VIDEO) {
                        pBuff->mItems.mTsCmdData.mTsCmdCode |=
                                ANDROID_MP2TSEVENT_FORMAT_CHANGE_VIDEO;
                        SL_LOGV("Received video format change");
                    } else {
                        // note that we don't support specifying
                        //    ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL by having all bits of
                        //    the data mask set, we default to it with unsupported masks
                        SL_LOGE("Received format change with unsupported data, ignoring data");
                        pBuff->mItems.mTsCmdData.mTsCmdCode |=
                                ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL;
                    }
                } else {
                    SL_LOGE("Received format change with invalid data size, ignoring data");
                    pBuff->mItems.mTsCmdData.mTsCmdCode |= ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL;
                }
                break;

              default:
                // unknown item key
                SL_LOGE("Unknown item key %u with size %u", pItems->itemKey, pItems->itemSize);
                return SL_RESULT_PARAMETER_INVALID;

            }// switch (pItems->itemKey)
          } break;

          case kAndroidBufferTypeAacadts: {
            switch (pItems->itemKey) {

              case SL_ANDROID_ITEMKEY_EOS:
                pBuff->mItems.mAdtsCmdData.mAdtsCmdCode |= ANDROID_ADTSEVENT_EOS;
                if (pItems->itemSize != 0) {
                    SL_LOGE("Invalid item parameter size %u for EOS", pItems->itemSize);
                    return SL_RESULT_PARAMETER_INVALID;
                }
                break;

              default:
                // unknown item key
                SL_LOGE("Unknown item key %u with size %u", pItems->itemKey, pItems->itemSize);
                return SL_RESULT_PARAMETER_INVALID;

            }// switch (pItems->itemKey)
          } break;

          case kAndroidBufferTypeInvalid:
          default:
            // not reachable as we checked this earlier
            return SL_RESULT_INTERNAL_ERROR;

        }// switch (bufferType)

        // skip past this item, including data with alignment padding
        pItems = (SLAndroidBufferItem *) ((char *) pItems +
                sizeof(SLAndroidBufferItem) + itemDataSizeWithAlignmentPadding);
    }

    // now check for invalid combinations of items
    switch (bufferType) {

      case kAndroidBufferTypeMpeg2Ts: {
        // supported Mpeg2Ts commands are mutually exclusive
        switch (pBuff->mItems.mTsCmdData.mTsCmdCode) {
          // single items are allowed
          case ANDROID_MP2TSEVENT_EOS:
            if (dataLength > 0) {
                SL_LOGE("Can't enqueue non-zero data with EOS");
                return SL_RESULT_PRECONDITIONS_VIOLATED;
            }
            *pEOS = true;
            break;
          case ANDROID_MP2TSEVENT_NONE:
          case ANDROID_MP2TSEVENT_DISCONTINUITY:
          case ANDROID_MP2TSEVENT_DISCON_NEWPTS:
          case ANDROID_MP2TSEVENT_FORMAT_CHANGE_FULL:
          case ANDROID_MP2TSEVENT_FORMAT_CHANGE_VIDEO:
            break;
          // no combinations are allowed
          default:
            SL_LOGE("Invalid combination of items");
            return SL_RESULT_PARAMETER_INVALID;
        }
      } break;

      case kAndroidBufferTypeAacadts: {
        // only one item supported, and thus no combination check needed
        if (pBuff->mItems.mAdtsCmdData.mAdtsCmdCode == ANDROID_ADTSEVENT_EOS) {
            if (dataLength > 0) {
                SL_LOGE("Can't enqueue non-zero data with EOS");
                return SL_RESULT_PRECONDITIONS_VIOLATED;
            }
            *pEOS = true;
        }
      } break;

      case kAndroidBufferTypeInvalid:
      default:
        // not reachable as we checked this earlier
        return SL_RESULT_INTERNAL_ERROR;
    }

    return SL_RESULT_SUCCESS;
}


static SLresult IAndroidBufferQueue_RegisterCallback(SLAndroidBufferQueueItf self,
        slAndroidBufferQueueCallback callback, void *pContext)
{
    SL_ENTER_INTERFACE

    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;

    interface_lock_exclusive(thiz);

    // verify pre-condition that media object is in the SL_PLAYSTATE_STOPPED state
    if (SL_PLAYSTATE_STOPPED == getAssociatedState(thiz)) {
        thiz->mCallback = callback;
        thiz->mContext = pContext;
        result = SL_RESULT_SUCCESS;

    } else {
        result = SL_RESULT_PRECONDITIONS_VIOLATED;
    }

    interface_unlock_exclusive(thiz);

    SL_LEAVE_INTERFACE
}


static SLresult IAndroidBufferQueue_Clear(SLAndroidBufferQueueItf self)
{
    SL_ENTER_INTERFACE
    result = SL_RESULT_SUCCESS;

    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;

    interface_lock_exclusive(thiz);

    // reset the queue pointers
    thiz->mFront = &thiz->mBufferArray[0];
    thiz->mRear = &thiz->mBufferArray[0];
    // reset the queue state
    thiz->mState.count = 0;
    thiz->mState.index = 0;

    // object-specific behavior for a clear
    switch (InterfaceToObjectID(thiz)) {
    case SL_OBJECTID_AUDIOPLAYER:
        android_audioPlayer_androidBufferQueue_clear_l((CAudioPlayer*) thiz->mThis);
        break;
    case XA_OBJECTID_MEDIAPLAYER:
        android_Player_androidBufferQueue_clear_l((CMediaPlayer*) thiz->mThis);
        break;
    default:
        result = SL_RESULT_PARAMETER_INVALID;
    }

    interface_unlock_exclusive(thiz);

    SL_LEAVE_INTERFACE
}


static SLresult IAndroidBufferQueue_Enqueue(SLAndroidBufferQueueItf self,
        void *pBufferContext,
        void *pData,
        SLuint32 dataLength,
        const SLAndroidBufferItem *pItems,
        SLuint32 itemsLength)
{
    SL_ENTER_INTERFACE
    SL_LOGD("IAndroidBufferQueue_Enqueue pData=%p dataLength=%d", pData, dataLength);

    if ((dataLength > 0) && (NULL == pData)) {
        SL_LOGE("Enqueue failure: non-zero data length %u but NULL data pointer", dataLength);
        result = SL_RESULT_PARAMETER_INVALID;
    } else if ((itemsLength > 0) && (NULL == pItems)) {
        SL_LOGE("Enqueue failure: non-zero items length %u but NULL items pointer", itemsLength);
        result = SL_RESULT_PARAMETER_INVALID;
    } else if ((0 == dataLength) && (0 == itemsLength)) {
        // no data and no msg
        SL_LOGE("Enqueue failure: trying to enqueue buffer with no data and no items.");
        result = SL_RESULT_PARAMETER_INVALID;
    // Note that a non-NULL data pointer with zero data length is allowed.
    // We track that data pointer as it moves through the queue
    // to assist the application in accounting for data buffers.
    // A non-NULL items pointer with zero items length is also allowed, but has no value.
    } else {
        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;

        // buffer size check, can be done outside of lock because buffer type can't change
        switch (thiz->mBufferType) {
          case kAndroidBufferTypeMpeg2Ts:
            if (dataLength % MPEG2_TS_PACKET_SIZE == 0) {
                // The downstream Stagefright MPEG-2 TS parser is sensitive to format errors,
                // so do a quick sanity check beforehand on the first packet of the buffer.
                // We don't check all the packets to avoid thrashing the data cache.
                if ((dataLength > 0) && (*(SLuint8 *)pData != MPEG2_TS_PACKET_SYNC)) {
                    SL_LOGE("Error enqueueing MPEG-2 TS data: incorrect packet sync");
                    result = SL_RESULT_CONTENT_CORRUPTED;
                    SL_LEAVE_INTERFACE
                }
                break;
            }
            SL_LOGE("Error enqueueing MPEG-2 TS data: size must be a multiple of %d (packet size)",
                    MPEG2_TS_PACKET_SIZE);
            result = SL_RESULT_PARAMETER_INVALID;
            SL_LEAVE_INTERFACE
            break;
          case kAndroidBufferTypeAacadts:
            // zero dataLength is permitted in case of EOS command only
            if (dataLength > 0) {
                result = android::AacBqToPcmCbRenderer::validateBufferStartEndOnFrameBoundaries(
                    pData, dataLength);
                if (SL_RESULT_SUCCESS != result) {
                    SL_LOGE("Error enqueueing ADTS data: data must start and end on frame "
                            "boundaries");
                    SL_LEAVE_INTERFACE
                }
            }
            break;
          case kAndroidBufferTypeInvalid:
          default:
            result = SL_RESULT_PARAMETER_INVALID;
            SL_LEAVE_INTERFACE
        }

        interface_lock_exclusive(thiz);

        AdvancedBufferHeader *oldRear = thiz->mRear, *newRear;
        if ((newRear = oldRear + 1) == &thiz->mBufferArray[thiz->mNumBuffers + 1]) {
            newRear = thiz->mBufferArray;
        }
        if (thiz->mEOS) {
            SL_LOGE("Can't enqueue after EOS");
            result = SL_RESULT_PRECONDITIONS_VIOLATED;
        } else if (newRear == thiz->mFront) {
            result = SL_RESULT_BUFFER_INSUFFICIENT;
        } else {
            // set oldRear->mItems based on items
            result = setItems(dataLength, pItems, itemsLength, thiz->mBufferType, oldRear,
                    &thiz->mEOS);
            if (SL_RESULT_SUCCESS == result) {
                oldRear->mDataBuffer = pData;
                oldRear->mDataSize = dataLength;
                oldRear->mDataSizeConsumed = 0;
                oldRear->mBufferContext = pBufferContext;
                //oldRear->mBufferState = TBD;
                thiz->mRear = newRear;
                ++thiz->mState.count;
            }
        }
        // set enqueue attribute if state is PLAYING and the first buffer is enqueued
        interface_unlock_exclusive_attributes(thiz, ((SL_RESULT_SUCCESS == result) &&
                (1 == thiz->mState.count) && (SL_PLAYSTATE_PLAYING == getAssociatedState(thiz))) ?
                        ATTR_ABQ_ENQUEUE : ATTR_NONE);
    }

    SL_LEAVE_INTERFACE
}


static SLresult IAndroidBufferQueue_GetState(SLAndroidBufferQueueItf self,
        SLAndroidBufferQueueState *pState)
{
    SL_ENTER_INTERFACE

    // Note that GetState while a Clear is pending is equivalent to GetState before the Clear

    if (NULL == pState) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;

        interface_lock_shared(thiz);

        pState->count = thiz->mState.count;
        pState->index = thiz->mState.index;

        interface_unlock_shared(thiz);

        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IAndroidBufferQueue_SetCallbackEventsMask(SLAndroidBufferQueueItf self,
        SLuint32 eventFlags)
{
    SL_ENTER_INTERFACE

    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
    interface_lock_exclusive(thiz);
    // FIXME only supporting SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED in this implementation
    if (!(~(SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED /* | others TBD */ ) & eventFlags)) {
        thiz->mCallbackEventsMask = eventFlags;
        result = SL_RESULT_SUCCESS;
    } else {
        result = SL_RESULT_FEATURE_UNSUPPORTED;
    }
    interface_unlock_exclusive(thiz);

    SL_LEAVE_INTERFACE
}


static SLresult IAndroidBufferQueue_GetCallbackEventsMask(SLAndroidBufferQueueItf self,
        SLuint32 *pEventFlags)
{
    SL_ENTER_INTERFACE

    if (NULL == pEventFlags) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
        interface_lock_shared(thiz);
        SLuint32 callbackEventsMask = thiz->mCallbackEventsMask;
        interface_unlock_shared(thiz);
        *pEventFlags = callbackEventsMask;
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static const struct SLAndroidBufferQueueItf_ IAndroidBufferQueue_Itf = {
    IAndroidBufferQueue_RegisterCallback,
    IAndroidBufferQueue_Clear,
    IAndroidBufferQueue_Enqueue,
    IAndroidBufferQueue_GetState,
    IAndroidBufferQueue_SetCallbackEventsMask,
    IAndroidBufferQueue_GetCallbackEventsMask
};


void IAndroidBufferQueue_init(void *self)
{
    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
    thiz->mItf = &IAndroidBufferQueue_Itf;

    thiz->mState.count = 0;
    thiz->mState.index = 0;

    thiz->mCallback = NULL;
    thiz->mContext = NULL;
    thiz->mCallbackEventsMask = SL_ANDROIDBUFFERQUEUEEVENT_PROCESSED;

    thiz->mBufferType = kAndroidBufferTypeInvalid;
    thiz->mBufferArray = NULL;
    thiz->mFront = NULL;
    thiz->mRear = NULL;
    thiz->mEOS = false;
}


void IAndroidBufferQueue_deinit(void *self)
{
    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;
    if (NULL != thiz->mBufferArray) {
        free(thiz->mBufferArray);
        thiz->mBufferArray = NULL;
    }
}


#if 0
// Dump the contents of an IAndroidBufferQueue to the log.  This is for debugging only,
// and is not a documented API.  The associated object is locked throughout for atomicity,
// but the log entries may be interspersed with unrelated logs.

void IAndroidBufferQueue_log(IAndroidBufferQueue *thiz)
{
    interface_lock_shared(thiz);
    SL_LOGI("IAndroidBufferQueue %p:", thiz);
    SL_LOGI("  mState.count=%u mState.index=%u mCallback=%p mContext=%p",
            thiz->mState.count, thiz->mState.index, thiz->mCallback, thiz->mContext);
    const char *bufferTypeString;
    switch (thiz->mBufferType) {
    case kAndroidBufferTypeInvalid:
        bufferTypeString = "kAndroidBufferTypeInvalid";
        break;
    case kAndroidBufferTypeMpeg2Ts:
        bufferTypeString = "kAndroidBufferTypeMpeg2Ts";
        break;
    case kAndroidBufferTypeAacadts:
        bufferTypeString = "kAndroidBufferTypeAacadts";
        break;
    default:
        bufferTypeString = "unknown";
        break;
    }
    SL_LOGI("  mCallbackEventsMask=0x%x, mBufferType=0x%x (%s), mEOS=%s",
            thiz->mCallbackEventsMask,
            thiz->mBufferType, bufferTypeString,
            thiz->mEOS ? "true" : "false");
    SL_LOGI("  mBufferArray=%p, mFront=%p (%u), mRear=%p (%u)",
            thiz->mBufferArray,
            thiz->mFront, thiz->mFront - thiz->mBufferArray,
            thiz->mRear, thiz->mRear - thiz->mBufferArray);
    SL_LOGI("  index mDataBuffer mDataSize mDataSizeConsumed mBufferContext mItems");
    const AdvancedBufferHeader *hdr;
    for (hdr = thiz->mFront; hdr != thiz->mRear; ) {
        SLuint32 i = hdr - thiz->mBufferArray;
        char itemString[32];
        switch (thiz->mBufferType) {
        case kAndroidBufferTypeMpeg2Ts:
            switch (hdr->mItems.mTsCmdData.mTsCmdCode) {
            case ANDROID_MP2TSEVENT_NONE:
                strcpy(itemString, "NONE");
                break;
            case ANDROID_MP2TSEVENT_EOS:
                strcpy(itemString, "EOS");
                break;
            case ANDROID_MP2TSEVENT_DISCONTINUITY:
                strcpy(itemString, "DISCONTINUITY");
                break;
            case ANDROID_MP2TSEVENT_DISCON_NEWPTS:
                snprintf(itemString, sizeof(itemString), "NEWPTS %llu",
                        hdr->mItems.mTsCmdData.mPts);
                break;
            case ANDROID_MP2TSEVENT_FORMAT_CHANGE:
                strcpy(itemString, "FORMAT_CHANGE");
                break;
            default:
                snprintf(itemString, sizeof(itemString), "0x%x", hdr->mItems.mTsCmdData.mTsCmdCode);
                break;
            }
            break;
        case kAndroidBufferTypeAacadts:
            switch (hdr->mItems.mAdtsCmdData.mAdtsCmdCode) {
            case ANDROID_ADTSEVENT_NONE:
                strcpy(itemString, "NONE");
                break;
            case ANDROID_ADTSEVENT_EOS:
                strcpy(itemString, "EOS");
                break;
            default:
                snprintf(itemString, sizeof(itemString), "0x%x",
                        hdr->mItems.mAdtsCmdData.mAdtsCmdCode);
                break;
            }
            break;
        default:
            strcpy(itemString, "");
            break;
        }
        SL_LOGI("  %5u %11p %9u %17u %14p %s",
                i, hdr->mDataBuffer, hdr->mDataSize, hdr->mDataSizeConsumed,
                hdr->mBufferContext, itemString);
                // mBufferState
        if (++hdr == &thiz->mBufferArray[thiz->mNumBuffers + 1]) {
            hdr = thiz->mBufferArray;
        }
    }
    interface_unlock_shared(thiz);
}

#endif
