182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON/*
282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Licensed under the Apache License, Version 2.0 (the "License");
582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* you may not use this file except in compliance with the License.
682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* You may obtain a copy of the License at
782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* http://www.apache.org/licenses/LICENSE-2.0
982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
1082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Unless required by applicable law or agreed to in writing, software
1182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* distributed under the License is distributed on an "AS IS" BASIS,
1282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* See the License for the specific language governing permissions and
1482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* limitations under the License.
1582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*/
1682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
1782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "va_private.h"
1882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderAVCSecure.h"
1982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderTrace.h"
2082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <string.h>
2182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define STARTCODE_PREFIX_LEN        3
2382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define NALU_TYPE_MASK              0x1F
2482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define MAX_NALU_HEADER_BUFFER      8192
2582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONstatic const uint8_t startcodePrefix[STARTCODE_PREFIX_LEN] = {0x00, 0x00, 0x01};
2682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderAVCSecure::VideoDecoderAVCSecure(const char *mimeType)
2882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    : VideoDecoderAVC(mimeType),
2982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mNaluHeaderBuffer(NULL),
3082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSliceHeaderBuffer(NULL) {
3182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setParserType(VBP_H264SECURE);
3282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
3382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderAVCSecure::~VideoDecoderAVCSecure() {
3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::start(VideoConfigBuffer *buffer) {
3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status = VideoDecoderAVC::start(buffer);
3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (status != DECODE_SUCCESS) {
4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return status;
4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mNaluHeaderBuffer = new uint8_t [MAX_NALU_HEADER_BUFFER];
4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mNaluHeaderBuffer == NULL) {
4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Failed to allocate memory for mNaluHeaderBuffer");
4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mSliceHeaderBuffer = new uint8_t [MAX_NALU_HEADER_BUFFER];
5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSliceHeaderBuffer == NULL) {
5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Failed to allocate memory for mSliceHeaderBuffer");
5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mNaluHeaderBuffer) {
5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            delete [] mNaluHeaderBuffer;
5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mNaluHeaderBuffer = NULL;
5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVCSecure::stop(void) {
6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderAVC::stop();
6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mNaluHeaderBuffer) {
6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mNaluHeaderBuffer;
6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mNaluHeaderBuffer = NULL;
6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSliceHeaderBuffer) {
7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        delete [] mSliceHeaderBuffer;
7382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSliceHeaderBuffer = NULL;
7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
7682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::decode(VideoDecodeBuffer *buffer) {
7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t sizeAccumulated = 0;
8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t sliceHeaderSize = 0;
8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t sizeLeft = 0;
8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t sliceIdx = 0;
8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t naluType;
8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    frame_info_t* pFrameInfo;
8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mFrameSize = 0;
8882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & IS_SECURE_DATA) {
8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("Decoding protected video ...");
9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mIsEncryptData = 1;
9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("Decoding clear video ...");
9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mIsEncryptData = 0;
9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return VideoDecoderAVC::decode(buffer);
9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->size != sizeof(frame_info_t)) {
9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Not enough data to read frame_info_t!");
9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
10182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    pFrameInfo = (frame_info_t*) buffer->data;
10282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
10382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mFrameSize = pFrameInfo->length;
10482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VTRACE("mFrameSize = %d", mFrameSize);
10582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
10682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memcpy(&mEncParam, pFrameInfo->pavp, sizeof(pavp_info_t));
10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < pFrameInfo->num_nalus; i++) {
10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        naluType = pFrameInfo->nalus[i].type & NALU_TYPE_MASK;
10982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (naluType >= h264_NAL_UNIT_TYPE_SLICE && naluType <= h264_NAL_UNIT_TYPE_IDR) {
11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(mSliceHeaderBuffer + sliceHeaderSize,
11182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &sliceIdx,
11282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sizeof(int32_t));
11382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceHeaderSize += 4;
11482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(mSliceHeaderBuffer + sliceHeaderSize,
11682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &pFrameInfo->data,
11782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sizeof(uint8_t*));
11882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceHeaderSize += sizeof(uint8_t*);
11982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(mSliceHeaderBuffer + sliceHeaderSize,
12182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &pFrameInfo->nalus[i].offset,
12282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sizeof(uint32_t));
12382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceHeaderSize += sizeof(uint32_t);
12482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(mSliceHeaderBuffer + sliceHeaderSize,
12682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &pFrameInfo->nalus[i].length,
12782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sizeof(uint32_t));
12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceHeaderSize += sizeof(uint32_t);
12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(mSliceHeaderBuffer + sliceHeaderSize,
13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                pFrameInfo->nalus[i].slice_header,
13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sizeof(slice_header_t));
13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceHeaderSize += sizeof(slice_header_t);
13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (pFrameInfo->nalus[i].type & 0x60) {
13582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                memcpy(mSliceHeaderBuffer+sliceHeaderSize, pFrameInfo->dec_ref_pic_marking, sizeof(dec_ref_pic_marking_t));
13682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
13782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                memset(mSliceHeaderBuffer+sliceHeaderSize, 0, sizeof(dec_ref_pic_marking_t));
13882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceHeaderSize += sizeof(dec_ref_pic_marking_t);
14082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceIdx++;
14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else if (naluType >= h264_NAL_UNIT_TYPE_SEI && naluType <= h264_NAL_UNIT_TYPE_PPS) {
14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(mNaluHeaderBuffer + sizeAccumulated,
14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                startcodePrefix,
14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                STARTCODE_PREFIX_LEN);
14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sizeAccumulated += STARTCODE_PREFIX_LEN;
14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(mNaluHeaderBuffer + sizeAccumulated,
14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                pFrameInfo->nalus[i].data,
14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                pFrameInfo->nalus[i].length);
14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sizeAccumulated += pFrameInfo->nalus[i].length;
15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Failure: DECODE_FRAME_DROPPED");
15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_FRAME_DROPPED;
15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_data_h264 *data = NULL;
15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int new_sequence_to_handle = 0;
15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (sizeAccumulated > 0) {
16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status =  VideoDecoderBase::parseBuffer(
16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mNaluHeaderBuffer,
16282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sizeAccumulated,
16382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                false,
16482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                (void**)&data);
16582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("VideoDecoderBase::parseBuffer");
16682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
16782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // [FIX DRC zoom issue] if one buffer contains more than one nalu
16882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // for example SPS+PPS+IDR, new_sps/new_pps flags set in parseBuffer
16982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // will be flushed in the following updateBuffer.
17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // So that handleNewSequence will not be handled in decodeFrame()
17182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (data->new_sps || data->new_pps) {
17282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            new_sequence_to_handle = 1;
17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (sliceHeaderSize > 0) {
17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        memset(mSliceHeaderBuffer + sliceHeaderSize, 0xFF, 4);
17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceHeaderSize += 4;
17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status =  VideoDecoderBase::updateBuffer(
18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSliceHeaderBuffer,
18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sliceHeaderSize,
18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                (void**)&data);
18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("VideoDecoderBase::updateBuffer");
18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // in case the flags were flushed but indeed new sequence needed to be handled.
18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((1 == new_sequence_to_handle) &&
18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ((data->new_sps == 0) || (data->new_pps == 0))) {
18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            data->new_sps = 1;
18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            data->new_pps = 1;
19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (data == NULL) {
19482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid data returned by parser!");
19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_MEMORY_FAIL;
19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mVAStarted) {
19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         if (data->has_sps && data->has_pps) {
20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = startVA(data);
20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_STATUS("startVA");
20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Can't start VA as either SPS or PPS is still not available.");
20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_SUCCESS;
20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = decodeFrame(buffer, data);
20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {
21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t bufferIDCount = 0;
21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data
21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VABufferID bufferIDs[5];
21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureParameterBufferH264 *picParam = picData->pic_parms;
22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);
22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAEncryptionParameterBuffer encryptParam;
22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // either condition indicates start of a new frame
22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (sliceParam->first_mb_in_slice != 0) {
22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("The first slice is lost.");
22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // TODO: handle the first slice lost
22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mDecodingFrame) {
23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // interlace content, complete decoding the first field
23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vaStatus = vaEndPicture(mVADisplay, mVAContext);
23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_VA_STATUS("vaEndPicture");
23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // for interlace content, top field may be valid only after the second field is parsed
23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->pictureOrder= picParam->CurrPic.TopFieldOrderCnt;
23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // Update  the reference frames and surface IDs for DPB and current frame
24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = updateDPB(picParam);
24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("updateDPB");
24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaBeginPicture");
24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // start decoding a frame
24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDecodingFrame = true;
24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateBuffer(
25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVAContext,
25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAPictureParameterBufferType,
25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sizeof(VAPictureParameterBufferH264),
25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,
25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam,
25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &bufferIDs[bufferIDCount]);
25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount++;
25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateBuffer(
26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVAContext,
26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAIQMatrixBufferType,
26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sizeof(VAIQMatrixBufferH264),
26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,
26682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            data->IQ_matrix_buf,
26782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &bufferIDs[bufferIDCount]);
26882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
26982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount++;
27082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mIsEncryptData) {
27282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memset(&encryptParam, 0, sizeof(VAEncryptionParameterBuffer));
27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            encryptParam.pavpCounterMode = 4;
27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            encryptParam.pavpEncryptionType = 2;
27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            encryptParam.hostEncryptMode = 2;
27682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            encryptParam.pavpHasBeenEnabled = 1;
27782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            encryptParam.app_id = 0;
27882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            memcpy(encryptParam.pavpAesCounter, mEncParam.iv, 16);
27982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
28082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vaStatus = vaCreateBuffer(
28182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVADisplay,
28282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mVAContext,
28382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                (VABufferType)VAEncryptionParameterBufferType,
28482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                sizeof(VAEncryptionParameterBuffer),
28582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                1,
28682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &encryptParam,
28782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                &bufferIDs[bufferIDCount]);
28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_VA_STATUS("vaCreateEncryptionParameterBuffer");
28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            bufferIDCount++;
29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateBuffer(
29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVAContext,
29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VASliceDataBufferType,
29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mFrameSize, //size
29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,        //num_elements
29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sliceData->buffer_addr + sliceData->slice_offset,
29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &bufferIDs[bufferIDCount]);
30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateSliceDataBuffer");
30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount++;
30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateBuffer(
30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASliceParameterBufferType,
30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sizeof(VASliceParameterBufferH264Base),
31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        1,
31182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceParam,
31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        &bufferIDs[bufferIDCount]);
31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bufferIDCount++;
31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaRenderPicture(
31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDs,
32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount);
32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaRenderPicture");
32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVCSecure::getCodecSpecificConfigs(
32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAProfile profile, VAConfigID *config)
32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAConfigAttrib attrib[2];
33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (config == NULL) {
33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid parameter!");
33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[0].type = VAConfigAttribRTFormat;
33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[0].value = VA_RT_FORMAT_YUV420;
34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[1].type = VAConfigAttribDecSliceMode;
34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaGetConfigAttributes(mVADisplay,profile,VAEntrypointVLD, &attrib[1], 1);
34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (attrib[1].value & VA_DEC_SLICE_MODE_BASE)
34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    {
34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("AVC short format used");
34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib[1].value = VA_DEC_SLICE_MODE_BASE;
34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else if (attrib[1].value & VA_DEC_SLICE_MODE_NORMAL) {
35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("AVC long format ssed");
35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Unsupported Decode Slice Mode!");
35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
35682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateConfig(
35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            profile,
36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAEntrypointVLD,
36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &attrib[0],
36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            2,
36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            config);
36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateConfig");
36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
368