/* INTEL CONFIDENTIAL
* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
* Corporation or its suppliers or licensors.  Title to the
* Material remains with Intel Corporation or its suppliers and
* licensors.  The Material contains trade secrets and proprietary
* and confidential information of Intel or its suppliers and
* licensors. The Material is protected by worldwide copyright and
* trade secret laws and treaty provisions.  No part of the Material
* may be used, copied, reproduced, modified, published, uploaded,
* posted, transmitted, distributed, or disclosed in any way without
* Intel's prior express written permission.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you
* by disclosure or delivery of the Materials, either expressly, by
* implication, inducement, estoppel or otherwise. Any license
* under such intellectual property rights must be express and
* approved by Intel in writing.
*
*/

#include "VideoDecoderAVCSecure.h"
#include "VideoDecoderTrace.h"
#include <string.h>


#define STARTCODE_00                0x00
#define STARTCODE_01                0x01
#define STARTCODE_PREFIX_LEN        3
#define NALU_TYPE_MASK              0x1F


// mask for little endian, to mast the second and fourth bytes in the byte stream
#define STARTCODE_MASK0             0xFF000000 //0x00FF0000
#define STARTCODE_MASK1             0x0000FF00  //0x000000FF


typedef enum {
    NAL_UNIT_TYPE_unspecified0 = 0,
    NAL_UNIT_TYPE_SLICE,
    NAL_UNIT_TYPE_DPA,
    NAL_UNIT_TYPE_DPB,
    NAL_UNIT_TYPE_DPC,
    NAL_UNIT_TYPE_IDR,
    NAL_UNIT_TYPE_SEI,
    NAL_UNIT_TYPE_SPS,
    NAL_UNIT_TYPE_PPS,
    NAL_UNIT_TYPE_Acc_unit_delimiter,
    NAL_UNIT_TYPE_EOSeq,
    NAL_UNIT_TYPE_EOstream,
    NAL_UNIT_TYPE_filler_data,
    NAL_UNIT_TYPE_SPS_extension,
    NAL_UNIT_TYPE_Reserved14,
    NAL_UNIT_TYPE_Reserved15,
    NAL_UNIT_TYPE_Reserved16,
    NAL_UNIT_TYPE_Reserved17,
    NAL_UNIT_TYPE_Reserved18,
    NAL_UNIT_TYPE_ACP,
    NAL_UNIT_TYPE_Reserved20,
    NAL_UNIT_TYPE_Reserved21,
    NAL_UNIT_TYPE_Reserved22,
    NAL_UNIT_TYPE_Reserved23,
    NAL_UNIT_TYPE_unspecified24,
} NAL_UNIT_TYPE;

#ifndef min
#define min(X, Y)  ((X) <(Y) ? (X) : (Y))
#endif


static const uint8_t startcodePrefix[STARTCODE_PREFIX_LEN] = {0x00, 0x00, 0x01};


VideoDecoderAVCSecure::VideoDecoderAVCSecure(const char *mimeType)
    : VideoDecoderAVC(mimeType),
      mNaluHeaderBuffer(NULL),
      mInputBuffer(NULL) {

    memset(&mMetadata, 0, sizeof(NaluMetadata));
    memset(&mByteStream, 0, sizeof(NaluByteStream));
}

VideoDecoderAVCSecure::~VideoDecoderAVCSecure() {
}

Decode_Status VideoDecoderAVCSecure::start(VideoConfigBuffer *buffer) {
    Decode_Status status = VideoDecoderAVC::start(buffer);
    if (status != DECODE_SUCCESS) {
        return status;
    }

    mMetadata.naluInfo = new NaluInfo [MAX_NALU_NUMBER];
    mByteStream.byteStream = new uint8_t [MAX_NALU_HEADER_BUFFER];
    mNaluHeaderBuffer = new uint8_t [MAX_NALU_HEADER_BUFFER];

    if (mMetadata.naluInfo == NULL ||
        mByteStream.byteStream == NULL ||
        mNaluHeaderBuffer == NULL) {
        ETRACE("Failed to allocate memory.");
        // TODO: release all allocated memory
        return DECODE_MEMORY_FAIL;
    }
    return status;
}

void VideoDecoderAVCSecure::stop(void) {
    VideoDecoderAVC::stop();

    if (mMetadata.naluInfo) {
        delete [] mMetadata.naluInfo;
        mMetadata.naluInfo = NULL;
    }

    if (mByteStream.byteStream) {
        delete [] mByteStream.byteStream;
        mByteStream.byteStream = NULL;
    }

    if (mNaluHeaderBuffer) {
        delete [] mNaluHeaderBuffer;
        mNaluHeaderBuffer = NULL;
    }
}

Decode_Status VideoDecoderAVCSecure::decode(VideoDecodeBuffer *buffer) {
    Decode_Status status;
    int32_t sizeAccumulated = 0;
    int32_t sizeLeft = 0;
    uint8_t *pByteStream = NULL;
    NaluInfo *pNaluInfo = mMetadata.naluInfo;

    if (buffer->flag & IS_SECURE_DATA) {
        // NALU headers are appended to encrypted video bitstream
        // |...encrypted video bitstream (16 bytes aligned)...| 4 bytes of header size |...NALU headers..|
        pByteStream = buffer->data + buffer->size + 4;
        sizeLeft = *(int32_t *)(buffer->data + buffer->size);
        ITRACE("%s sizeLeft: %d buffer->size: %#x", __func__, sizeLeft, buffer->size);
        mInputBuffer = buffer->data;
    } else {
        status = parseAnnexBStream(buffer->data, buffer->size, &mByteStream);
        CHECK_STATUS("parseAnnexBStream");
        pByteStream = mByteStream.byteStream;
        sizeLeft = mByteStream.streamPos;
        mInputBuffer = buffer->data;
    }
    if (sizeLeft < 4) {
        ETRACE("Not enough data to read number of NALU.");
        return DECODE_INVALID_DATA;
    }

    // read number of NALU
    memcpy(&(mMetadata.naluNumber), pByteStream, sizeof(int32_t));
    pByteStream += 4;
    sizeLeft -= 4;

    if (mMetadata.naluNumber == 0) {
        WTRACE("Number of NALU is ZERO!");
        return DECODE_SUCCESS;
    }

    for (int32_t i = 0; i < mMetadata.naluNumber; i++) {
        if (sizeLeft < 12) {
            ETRACE("Not enough data to parse NALU offset, size, header length for NALU %d, left = %d", i, sizeLeft);
            return DECODE_INVALID_DATA;
        }
        sizeLeft -= 12;
        // read NALU offset
        memcpy(&(pNaluInfo->naluOffset), pByteStream, sizeof(int32_t));
        pByteStream += 4;

        // read NALU size
        memcpy(&(pNaluInfo->naluLen), pByteStream, sizeof(int32_t));
        pByteStream += 4;

        // read NALU header length
        memcpy(&(pNaluInfo->naluHeaderLen), pByteStream, sizeof(int32_t));
        pByteStream += 4;


        if (sizeLeft < pNaluInfo->naluHeaderLen) {
            ETRACE("Not enough data to copy NALU header for %d, left = %d, header len = %d", i, sizeLeft, pNaluInfo->naluHeaderLen);
            return DECODE_INVALID_DATA;
        }

        sizeLeft -=  pNaluInfo->naluHeaderLen;

        if (pNaluInfo->naluHeaderLen) {
            // copy start code prefix to buffer
            memcpy(mNaluHeaderBuffer + sizeAccumulated,
                startcodePrefix,
                STARTCODE_PREFIX_LEN);
            sizeAccumulated += STARTCODE_PREFIX_LEN;

            // copy NALU header
            memcpy(mNaluHeaderBuffer + sizeAccumulated, pByteStream, pNaluInfo->naluHeaderLen);
            pByteStream += pNaluInfo->naluHeaderLen;

            sizeAccumulated += pNaluInfo->naluHeaderLen;
        } else {
            WTRACE("header len is zero for NALU %d", i);
        }

        // for next NALU
        pNaluInfo++;
    }

    buffer->data = mNaluHeaderBuffer;
    buffer->size = sizeAccumulated;

    return VideoDecoderAVC::decode(buffer);
}


Decode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {

    Decode_Status status;
    VAStatus vaStatus;
    uint32_t bufferIDCount = 0;
    // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data
    VABufferID bufferIDs[4];

    vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
    vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
    VAPictureParameterBufferH264 *picParam = picData->pic_parms;
    VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);

    if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
        // either condition indicates start of a new frame
        if (sliceParam->first_mb_in_slice != 0) {
            WTRACE("The first slice is lost.");
            // TODO: handle the first slice lost
        }
        if (mDecodingFrame) {
            // interlace content, complete decoding the first field
            vaStatus = vaEndPicture(mVADisplay, mVAContext);
            CHECK_VA_STATUS("vaEndPicture");

            // for interlace content, top field may be valid only after the second field is parsed
            mAcquiredBuffer->pictureOrder= picParam->CurrPic.TopFieldOrderCnt;
        }

        // Check there is no reference frame loss before decoding a frame

        // Update  the reference frames and surface IDs for DPB and current frame
        status = updateDPB(picParam);
        CHECK_STATUS("updateDPB");

        //We have to provide a hacked DPB rather than complete DPB for libva as workaround
        status = updateReferenceFrames(picData);
        CHECK_STATUS("updateReferenceFrames");

        vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
        CHECK_VA_STATUS("vaBeginPicture");

        // start decoding a frame
        mDecodingFrame = true;

        vaStatus = vaCreateBuffer(
            mVADisplay,
            mVAContext,
            VAPictureParameterBufferType,
            sizeof(VAPictureParameterBufferH264),
            1,
            picParam,
            &bufferIDs[bufferIDCount]);
        CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
        bufferIDCount++;

        vaStatus = vaCreateBuffer(
            mVADisplay,
            mVAContext,
            VAIQMatrixBufferType,
            sizeof(VAIQMatrixBufferH264),
            1,
            data->IQ_matrix_buf,
            &bufferIDs[bufferIDCount]);
        CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
        bufferIDCount++;
    }

    status = setReference(sliceParam);
    CHECK_STATUS("setReference");

    // find which naluinfo is correlated to current slice
    int naluIndex = 0;
    uint32_t accumulatedHeaderLen = 0;
    uint32_t headerLen = 0;
    for (; naluIndex < mMetadata.naluNumber; naluIndex++)  {
        headerLen = mMetadata.naluInfo[naluIndex].naluHeaderLen;
        if (headerLen == 0) {
            WTRACE("lenght of current NAL unit is 0.");
            continue;
        }
        accumulatedHeaderLen += STARTCODE_PREFIX_LEN;
        if (accumulatedHeaderLen + headerLen > sliceData->slice_offset) {
            break;
        }
        accumulatedHeaderLen += headerLen;
    }

    if (sliceData->slice_offset != accumulatedHeaderLen) {
        WTRACE("unexpected slice offset %d, accumulatedHeaderLen = %d", sliceData->slice_offset, accumulatedHeaderLen);
    }

    sliceParam->slice_data_size = mMetadata.naluInfo[naluIndex].naluLen;
    uint32_t sliceOffset = mMetadata.naluInfo[naluIndex].naluOffset;
    uint32_t slice_offset_shift =  sliceOffset % 16;
    sliceParam->slice_data_offset += slice_offset_shift;
    sliceParam->slice_data_size  += slice_offset_shift;
    sliceData->slice_size = (sliceParam->slice_data_size + 0xF) & ~0xF;

    vaStatus = vaCreateBuffer(
        mVADisplay,
        mVAContext,
        VASliceParameterBufferType,
        sizeof(VASliceParameterBufferH264),
        1,
        sliceParam,
        &bufferIDs[bufferIDCount]);
    CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
    bufferIDCount++;

    // sliceData->slice_offset - accumulatedHeaderLen is the absolute offset to start codes of current NAL unit
    // offset points to first byte of NAL unit

    if (mInputBuffer != NULL) {
        vaStatus = vaCreateBuffer(
            mVADisplay,
            mVAContext,
            VASliceDataBufferType,
            sliceData->slice_size,  //Slice size
            1,                      // num_elements
            mInputBuffer + sliceOffset - slice_offset_shift,
            &bufferIDs[bufferIDCount]);
    } else {
        vaStatus = vaCreateBuffer(
            mVADisplay,
            mVAContext,
            VAProtectedSliceDataBufferType,
            sliceData->slice_size, //size
            1,        //num_elements
            (uint8_t*)sliceOffset, // IMR offset
            &bufferIDs[bufferIDCount]);
    }
    CHECK_VA_STATUS("vaCreateSliceDataBuffer");
    bufferIDCount++;

    vaStatus = vaRenderPicture(
        mVADisplay,
        mVAContext,
        bufferIDs,
        bufferIDCount);
    CHECK_VA_STATUS("vaRenderPicture");

    return DECODE_SUCCESS;
}


// Parse byte string pattern "0x000001" (3 bytes)  in the current buffer.
// Returns offset of position following  the pattern in the buffer if pattern is found or -1 if not found.
int32_t VideoDecoderAVCSecure::findNalUnitOffset(uint8_t *stream, int32_t offset, int32_t length) {
    uint8_t *ptr;
    uint32_t left = 0, data = 0, phase = 0;
    uint8_t mask1 = 0, mask2 = 0;

    /* Meaning of phase:
        0: initial status, "0x000001" bytes are not found so far;
        1: one "0x00" byte is found;
        2: two or more consecutive "0x00" bytes" are found;
        3: "0x000001" patten is found ;
        4: if there is one more byte after "0x000001";
       */

    left = length;
    ptr = (uint8_t *) (stream + offset);
    phase = 0;

    // parse until there is more data and start code not found
    while ((left > 0) && (phase < 3)) {
        // Check if the address is 32-bit aligned & phase=0, if thats the case we can check 4 bytes instead of one byte at a time.
        if (((((uint32_t)ptr) & 0x3) == 0) && (phase == 0)) {
            while (left > 3) {
                data = *((uint32_t *)ptr);
                mask1 = (STARTCODE_00 != (data & STARTCODE_MASK0));
                mask2 = (STARTCODE_00 != (data & STARTCODE_MASK1));
                // If second byte and fourth byte are not zero's then we cannot have a start code here,
                //  as we need two consecutive zero bytes for a start code pattern.
                if (mask1 && mask2) {
                    // skip 4 bytes and start over
                    ptr += 4;
                    left -=4;
                    continue;
                } else {
                    break;
                }
            }
        }

        // At this point either data is not on a 32-bit boundary or phase > 0 so we look at one byte at a time
        if (left > 0) {
            if (*ptr == STARTCODE_00) {
                phase++;
                if (phase > 2) {
                    // more than 2 consecutive '0x00' bytes is found
                    phase = 2;
                }
            } else if ((*ptr == STARTCODE_01) && (phase == 2)) {
                // start code is found
                phase = 3;
            } else {
                // reset lookup
                phase = 0;
            }
            ptr++;
            left--;
        }
    }

    if ((left > 0) && (phase == 3)) {
        phase = 4;
        // return offset of position following the pattern in the buffer which matches "0x000001" byte string
        return (int32_t)(ptr - stream);
    }
    return -1;
}


Decode_Status VideoDecoderAVCSecure::copyNaluHeader(uint8_t *stream, NaluByteStream *naluStream) {
    uint8_t naluType;
    int32_t naluHeaderLen;

    naluType = *(uint8_t *)(stream + naluStream->naluOffset);
    naluType &= NALU_TYPE_MASK;
    // first update nalu header length based on nalu type
    if (naluType >= NAL_UNIT_TYPE_SLICE && naluType <= NAL_UNIT_TYPE_IDR) {
        // coded slice, return only up to MAX_SLICE_HEADER_SIZE bytes
        naluHeaderLen = min(naluStream->naluLen, MAX_SLICE_HEADER_SIZE);
    } else if (naluType >= NAL_UNIT_TYPE_SEI && naluType <= NAL_UNIT_TYPE_PPS) {
        //sps, pps, sei, etc, return the entire NAL unit in clear
        naluHeaderLen = naluStream->naluLen;
    } else {
        return DECODE_FRAME_DROPPED;
    }

    memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluOffset), sizeof(int32_t));
    naluStream->streamPos += 4;

    memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluLen), sizeof(int32_t));
    naluStream->streamPos += 4;

    memcpy(naluStream->byteStream + naluStream->streamPos, &naluHeaderLen, sizeof(int32_t));
    naluStream->streamPos += 4;

    if (naluHeaderLen) {
        memcpy(naluStream->byteStream + naluStream->streamPos, (uint8_t*)(stream + naluStream->naluOffset), naluHeaderLen);
        naluStream->streamPos += naluHeaderLen;
    }
    return DECODE_SUCCESS;
}


// parse start-code prefixed stream, also knowns as Annex B byte stream, commonly used in AVI, ES, MPEG2 TS container
Decode_Status VideoDecoderAVCSecure::parseAnnexBStream(uint8_t *stream, int32_t length, NaluByteStream *naluStream) {
    int32_t naluOffset, offset, left;
    NaluInfo *info;
    uint32_t ret = DECODE_SUCCESS;

    naluOffset = 0;
    offset = 0;
    left = length;

    // leave 4 bytes to copy nalu count
    naluStream->streamPos = 4;
    naluStream->naluCount = 0;
    memset(naluStream->byteStream, 0, MAX_NALU_HEADER_BUFFER);

    for (; ;) {
        naluOffset = findNalUnitOffset(stream, offset, left);
        if (naluOffset == -1) {
            break;
        }

        if (naluStream->naluCount == 0) {
            naluStream->naluOffset = naluOffset;
        } else {
            naluStream->naluLen = naluOffset - naluStream->naluOffset - STARTCODE_PREFIX_LEN;
            ret = copyNaluHeader(stream, naluStream);
            if (ret != DECODE_SUCCESS && ret != DECODE_FRAME_DROPPED) {
                LOGW("copyNaluHeader returned %d", ret);
                return ret;
            }
            // starting position for next NALU
            naluStream->naluOffset = naluOffset;
        }

        if (ret == DECODE_SUCCESS) {
            naluStream->naluCount++;
        }

        // update next lookup position and length
        offset = naluOffset + 1; // skip one byte of NAL unit type
        left = length - offset;
    }

    if (naluStream->naluCount > 0) {
        naluStream->naluLen = length - naluStream->naluOffset;
        memcpy(naluStream->byteStream, &(naluStream->naluCount), sizeof(int32_t));
        // ignore return value, either DECODE_SUCCESS or DECODE_FRAME_DROPPED
        copyNaluHeader(stream, naluStream);
        return DECODE_SUCCESS;
    }

    LOGW("number of valid NALU is 0!");
    return DECODE_SUCCESS;
}

