Home | History | Annotate | Download | only in merrifield
      1 /*
      2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 #include <va/va.h>
     18 #include "VideoDecoderBase.h"
     19 #include "VideoDecoderAVC.h"
     20 #include "VideoDecoderTrace.h"
     21 #include "vbp_loader.h"
     22 #include "VideoDecoderAVCSecure.h"
     23 #include "VideoFrameInfo.h"
     24 
     25 #define MAX_SLICEHEADER_BUFFER_SIZE 4096
     26 #define STARTCODE_PREFIX_LEN        3
     27 #define NALU_TYPE_MASK              0x1F
     28 #define MAX_NALU_HEADER_BUFFER      8192
     29 static const uint8_t startcodePrefix[STARTCODE_PREFIX_LEN] = {0x00, 0x00, 0x01};
     30 
     31 /* H264 start code values */
     32 typedef enum _h264_nal_unit_type
     33 {
     34     h264_NAL_UNIT_TYPE_unspecified = 0,
     35     h264_NAL_UNIT_TYPE_SLICE,
     36     h264_NAL_UNIT_TYPE_DPA,
     37     h264_NAL_UNIT_TYPE_DPB,
     38     h264_NAL_UNIT_TYPE_DPC,
     39     h264_NAL_UNIT_TYPE_IDR,
     40     h264_NAL_UNIT_TYPE_SEI,
     41     h264_NAL_UNIT_TYPE_SPS,
     42     h264_NAL_UNIT_TYPE_PPS,
     43     h264_NAL_UNIT_TYPE_Acc_unit_delimiter,
     44     h264_NAL_UNIT_TYPE_EOSeq,
     45     h264_NAL_UNIT_TYPE_EOstream,
     46     h264_NAL_UNIT_TYPE_filler_data,
     47     h264_NAL_UNIT_TYPE_SPS_extension,
     48     h264_NAL_UNIT_TYPE_ACP = 19,
     49     h264_NAL_UNIT_TYPE_Slice_extension = 20
     50 } h264_nal_unit_type_t;
     51 
     52 VideoDecoderAVCSecure::VideoDecoderAVCSecure(const char *mimeType)
     53     : VideoDecoderAVC(mimeType){
     54     mFrameSize     = 0;
     55     mFrameData     = NULL;
     56     mIsEncryptData = 0;
     57     mClearData     = NULL;
     58     mCachedHeader  = NULL;
     59     setParserType(VBP_H264SECURE);
     60     mFrameIdx = 0;
     61     mModularMode = 0;
     62     mSliceNum = 0;
     63 }
     64 
     65 Decode_Status VideoDecoderAVCSecure::start(VideoConfigBuffer *buffer) {
     66     VTRACE("VideoDecoderAVCSecure::start");
     67 
     68     Decode_Status status = VideoDecoderAVC::start(buffer);
     69     if (status != DECODE_SUCCESS) {
     70         return status;
     71     }
     72 
     73     mClearData = new uint8_t [MAX_NALU_HEADER_BUFFER];
     74     if (mClearData == NULL) {
     75         ETRACE("Failed to allocate memory for mClearData");
     76         return DECODE_MEMORY_FAIL;
     77     }
     78 
     79     mCachedHeader= new uint8_t [MAX_SLICEHEADER_BUFFER_SIZE];
     80     if (mCachedHeader == NULL) {
     81         ETRACE("Failed to allocate memory for mCachedHeader");
     82         return DECODE_MEMORY_FAIL;
     83     }
     84 
     85     return status;
     86 }
     87 
     88 void VideoDecoderAVCSecure::stop(void) {
     89     VTRACE("VideoDecoderAVCSecure::stop");
     90     VideoDecoderAVC::stop();
     91 
     92     if (mClearData) {
     93         delete [] mClearData;
     94         mClearData = NULL;
     95     }
     96 
     97     if (mCachedHeader) {
     98         delete [] mCachedHeader;
     99         mCachedHeader = NULL;
    100     }
    101 }
    102 Decode_Status VideoDecoderAVCSecure::processModularInputBuffer(VideoDecodeBuffer *buffer, vbp_data_h264 **data)
    103 {
    104     VTRACE("processModularInputBuffer +++");
    105     Decode_Status status;
    106     int32_t clear_data_size = 0;
    107     uint8_t *clear_data = NULL;
    108 
    109     int32_t nalu_num = 0;
    110     uint8_t nalu_type = 0;
    111     int32_t nalu_offset = 0;
    112     uint32_t nalu_size = 0;
    113     uint8_t naluType = 0;
    114     uint8_t *nalu_data = NULL;
    115     uint32_t sliceidx = 0;
    116 
    117     frame_info_t *pFrameInfo = NULL;
    118     mSliceNum = 0;
    119     memset(&mSliceInfo, 0, sizeof(mSliceInfo));
    120     mIsEncryptData = 0;
    121 
    122     if (buffer->flag & IS_SECURE_DATA) {
    123         VTRACE("Decoding protected video ...");
    124         pFrameInfo = (frame_info_t *) buffer->data;
    125         if (pFrameInfo == NULL) {
    126             ETRACE("Invalid parameter: pFrameInfo is NULL!");
    127             return DECODE_MEMORY_FAIL;
    128         }
    129 
    130         mFrameData = pFrameInfo->data;
    131         mFrameSize = pFrameInfo->size;
    132         VTRACE("mFrameData = %p, mFrameSize = %d", mFrameData, mFrameSize);
    133 
    134         nalu_num  = pFrameInfo->num_nalus;
    135         VTRACE("nalu_num = %d", nalu_num);
    136 
    137         if (nalu_num <= 0 || nalu_num >= MAX_NUM_NALUS) {
    138             ETRACE("Invalid parameter: nalu_num = %d", nalu_num);
    139             return DECODE_MEMORY_FAIL;
    140         }
    141 
    142         for (int32_t i = 0; i < nalu_num; i++) {
    143 
    144             nalu_size = pFrameInfo->nalus[i].length;
    145             nalu_type = pFrameInfo->nalus[i].type;
    146             nalu_offset = pFrameInfo->nalus[i].offset;
    147             nalu_data = pFrameInfo->nalus[i].data;
    148             naluType  = nalu_type & NALU_TYPE_MASK;
    149 
    150             VTRACE("nalu_type = 0x%x, nalu_size = %d, nalu_offset = 0x%x", nalu_type, nalu_size, nalu_offset);
    151 
    152             if (naluType >= h264_NAL_UNIT_TYPE_SLICE && naluType <= h264_NAL_UNIT_TYPE_IDR) {
    153 
    154                 mIsEncryptData = 1;
    155                 VTRACE("slice idx = %d", sliceidx);
    156                 mSliceInfo[sliceidx].sliceHeaderByte = nalu_type;
    157                 mSliceInfo[sliceidx].sliceStartOffset = (nalu_offset >> 4) << 4;
    158                 mSliceInfo[sliceidx].sliceByteOffset = nalu_offset - mSliceInfo[sliceidx].sliceStartOffset;
    159                 mSliceInfo[sliceidx].sliceLength = mSliceInfo[sliceidx].sliceByteOffset + nalu_size;
    160                 mSliceInfo[sliceidx].sliceSize = (mSliceInfo[sliceidx].sliceByteOffset + nalu_size + 0xF) & ~0xF;
    161                 VTRACE("sliceHeaderByte = 0x%x", mSliceInfo[sliceidx].sliceHeaderByte);
    162                 VTRACE("sliceStartOffset = %d", mSliceInfo[sliceidx].sliceStartOffset);
    163                 VTRACE("sliceByteOffset = %d", mSliceInfo[sliceidx].sliceByteOffset);
    164                 VTRACE("sliceSize = %d", mSliceInfo[sliceidx].sliceSize);
    165                 VTRACE("sliceLength = %d", mSliceInfo[sliceidx].sliceLength);
    166 #if 0
    167                 uint32_t testsize;
    168                 uint8_t *testdata;
    169                 testsize = mSliceInfo[sliceidx].sliceSize > 64 ? 64 : mSliceInfo[sliceidx].sliceSize ;
    170                 testdata = (uint8_t *)(mFrameData);
    171                 for (int i = 0; i < testsize; i++) {
    172                     VTRACE("testdata[%d] = 0x%x", i, testdata[i]);
    173                 }
    174 #endif
    175                 sliceidx++;
    176 
    177             } else if (naluType == h264_NAL_UNIT_TYPE_SPS || naluType == h264_NAL_UNIT_TYPE_PPS) {
    178                 if (nalu_data == NULL) {
    179                     ETRACE("Invalid parameter: nalu_data = NULL for naluType 0x%x", naluType);
    180                     return DECODE_MEMORY_FAIL;
    181                 }
    182                 memcpy(mClearData + clear_data_size,
    183                     nalu_data,
    184                     nalu_size);
    185                 clear_data_size += nalu_size;
    186             } else {
    187                 ITRACE("Nalu type = 0x%x is skipped", naluType);
    188                 continue;
    189             }
    190         }
    191         clear_data = mClearData;
    192         mSliceNum = sliceidx;
    193 
    194     } else {
    195         VTRACE("Decoding clear video ...");
    196         mIsEncryptData = 0;
    197         mFrameSize = buffer->size;
    198         mFrameData = buffer->data;
    199         clear_data = buffer->data;
    200         clear_data_size = buffer->size;
    201     }
    202 
    203     if (clear_data_size > 0) {
    204         status =  VideoDecoderBase::parseBuffer(
    205                 clear_data,
    206                 clear_data_size,
    207                 false,
    208                 (void**)data);
    209         CHECK_STATUS("VideoDecoderBase::parseBuffer");
    210     } else {
    211         status =  VideoDecoderBase::queryBuffer((void**)data);
    212         CHECK_STATUS("VideoDecoderBase::queryBuffer");
    213     }
    214     return DECODE_SUCCESS;
    215 }
    216 
    217 Decode_Status VideoDecoderAVCSecure::processClassicInputBuffer(VideoDecodeBuffer *buffer, vbp_data_h264 **data)
    218 {
    219     Decode_Status status;
    220     int32_t clear_data_size = 0;
    221     uint8_t *clear_data = NULL;
    222     uint8_t naluType = 0;
    223 
    224     int32_t num_nalus;
    225     int32_t nalu_offset;
    226     int32_t offset;
    227     uint8_t *data_src;
    228     uint8_t *nalu_data;
    229     uint32_t nalu_size;
    230 
    231     if (buffer->flag & IS_SECURE_DATA) {
    232         VTRACE("Decoding protected video ...");
    233         mIsEncryptData = 1;
    234 
    235         mFrameData = buffer->data;
    236         mFrameSize = buffer->size;
    237         VTRACE("mFrameData = %p, mFrameSize = %d", mFrameData, mFrameSize);
    238         num_nalus  = *(uint32_t *)(buffer->data + buffer->size + sizeof(uint32_t));
    239         VTRACE("num_nalus = %d", num_nalus);
    240         offset = 4;
    241         for (int32_t i = 0; i < num_nalus; i++) {
    242             VTRACE("%d nalu, offset = %d", i, offset);
    243             data_src = buffer->data + buffer->size + sizeof(uint32_t) + offset;
    244             nalu_size = *(uint32_t *)(data_src + 2 * sizeof(uint32_t));
    245             nalu_size = (nalu_size + 0x03) & (~0x03);
    246 
    247             nalu_data = data_src + 3 *sizeof(uint32_t);
    248             naluType  = nalu_data[0] & NALU_TYPE_MASK;
    249             offset += nalu_size + 3 *sizeof(uint32_t);
    250             VTRACE("naluType = 0x%x", naluType);
    251             VTRACE("nalu_size = %d, nalu_data = %p", nalu_size, nalu_data);
    252 
    253             if (naluType >= h264_NAL_UNIT_TYPE_SLICE && naluType <= h264_NAL_UNIT_TYPE_IDR) {
    254                 ETRACE("Slice NALU received!");
    255                 return DECODE_INVALID_DATA;
    256             }
    257 
    258             else if (naluType >= h264_NAL_UNIT_TYPE_SEI && naluType <= h264_NAL_UNIT_TYPE_PPS) {
    259                 memcpy(mClearData + clear_data_size,
    260                     startcodePrefix,
    261                     STARTCODE_PREFIX_LEN);
    262                 clear_data_size += STARTCODE_PREFIX_LEN;
    263                 memcpy(mClearData + clear_data_size,
    264                     nalu_data,
    265                     nalu_size);
    266                 clear_data_size += nalu_size;
    267             } else {
    268                 ETRACE("Failure: DECODE_FRAME_DROPPED");
    269                 return DECODE_FRAME_DROPPED;
    270             }
    271         }
    272         clear_data = mClearData;
    273     } else {
    274         VTRACE("Decoding clear video ...");
    275         mIsEncryptData = 0;
    276         mFrameSize = buffer->size;
    277         mFrameData = buffer->data;
    278         clear_data = buffer->data;
    279         clear_data_size = buffer->size;
    280     }
    281 
    282     if (clear_data_size > 0) {
    283         status =  VideoDecoderBase::parseBuffer(
    284                 clear_data,
    285                 clear_data_size,
    286                 false,
    287                 (void**)data);
    288         CHECK_STATUS("VideoDecoderBase::parseBuffer");
    289     } else {
    290         status =  VideoDecoderBase::queryBuffer((void**)data);
    291         CHECK_STATUS("VideoDecoderBase::queryBuffer");
    292     }
    293     return DECODE_SUCCESS;
    294 }
    295 
    296 Decode_Status VideoDecoderAVCSecure::decode(VideoDecodeBuffer *buffer) {
    297     VTRACE("VideoDecoderAVCSecure::decode");
    298     Decode_Status status;
    299     vbp_data_h264 *data = NULL;
    300     if (buffer == NULL) {
    301         return DECODE_INVALID_DATA;
    302     }
    303 
    304 #if 0
    305     uint32_t testsize;
    306     uint8_t *testdata;
    307     testsize = buffer->size > 16 ? 16:buffer->size ;
    308     testdata = (uint8_t *)(buffer->data);
    309     for (int i = 0; i < 16; i++) {
    310         VTRACE("testdata[%d] = 0x%x", i, testdata[i]);
    311     }
    312 #endif
    313     if (buffer->flag & IS_SUBSAMPLE_ENCRYPTION) {
    314         mModularMode = 1;
    315     }
    316 
    317     if (mModularMode) {
    318         status = processModularInputBuffer(buffer,&data);
    319         CHECK_STATUS("processModularInputBuffer");
    320     }
    321     else {
    322         status = processClassicInputBuffer(buffer,&data);
    323         CHECK_STATUS("processClassicInputBuffer");
    324     }
    325 
    326     if (!mVAStarted) {
    327          if (data->has_sps && data->has_pps) {
    328             status = startVA(data);
    329             CHECK_STATUS("startVA");
    330         } else {
    331             WTRACE("Can't start VA as either SPS or PPS is still not available.");
    332             return DECODE_SUCCESS;
    333         }
    334     }
    335 
    336     status = decodeFrame(buffer, data);
    337 
    338     return status;
    339 }
    340 
    341 Decode_Status VideoDecoderAVCSecure::decodeFrame(VideoDecodeBuffer *buffer, vbp_data_h264 *data) {
    342     VTRACE("VideoDecoderAVCSecure::decodeFrame");
    343     Decode_Status status;
    344     VTRACE("data->has_sps = %d, data->has_pps = %d", data->has_sps, data->has_pps);
    345 
    346 #if 0
    347     // Don't remove the following codes, it can be enabled for debugging DPB.
    348     for (unsigned int i = 0; i < data->num_pictures; i++) {
    349         VAPictureH264 &pic = data->pic_data[i].pic_parms->CurrPic;
    350         VTRACE("%d: decoding frame %.2f, poc top = %d, poc bottom = %d, flags = %d,  reference = %d",
    351                 i,
    352                 buffer->timeStamp/1E6,
    353                 pic.TopFieldOrderCnt,
    354                 pic.BottomFieldOrderCnt,
    355                 pic.flags,
    356                 (pic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
    357                 (pic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE));
    358     }
    359 #endif
    360 
    361     if (data->new_sps || data->new_pps) {
    362         status = handleNewSequence(data);
    363         CHECK_STATUS("handleNewSequence");
    364     }
    365 
    366     if (mModularMode && (!mIsEncryptData)) {
    367         if (data->pic_data[0].num_slices == 0) {
    368             ITRACE("No slice available for decoding.");
    369             status = mSizeChanged ? DECODE_FORMAT_CHANGE : DECODE_SUCCESS;
    370             mSizeChanged = false;
    371             return status;
    372         }
    373     }
    374 
    375     uint64_t lastPTS = mCurrentPTS;
    376     mCurrentPTS = buffer->timeStamp;
    377 
    378     // start decoding a new frame
    379     status = acquireSurfaceBuffer();
    380     CHECK_STATUS("acquireSurfaceBuffer");
    381 
    382     if (mModularMode) {
    383         parseModularSliceHeader(buffer,data);
    384     }
    385     else {
    386         parseClassicSliceHeader(buffer,data);
    387     }
    388 
    389     if (status != DECODE_SUCCESS) {
    390         endDecodingFrame(true);
    391         return status;
    392     }
    393 
    394     status = beginDecodingFrame(data);
    395     CHECK_STATUS("beginDecodingFrame");
    396 
    397    // finish decoding the last frame
    398     status = endDecodingFrame(false);
    399     CHECK_STATUS("endDecodingFrame");
    400 
    401     if (isNewFrame(data, lastPTS == mCurrentPTS) == 0) {
    402         ETRACE("Can't handle interlaced frames yet");
    403         return DECODE_FAIL;
    404     }
    405 
    406     return DECODE_SUCCESS;
    407 }
    408 
    409 Decode_Status VideoDecoderAVCSecure::beginDecodingFrame(vbp_data_h264 *data) {
    410     VTRACE("VideoDecoderAVCSecure::beginDecodingFrame");
    411     Decode_Status status;
    412     VAPictureH264 *picture = &(data->pic_data[0].pic_parms->CurrPic);
    413     if ((picture->flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
    414         (picture->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
    415         mAcquiredBuffer->referenceFrame = true;
    416     } else {
    417         mAcquiredBuffer->referenceFrame = false;
    418     }
    419 
    420     if (picture->flags & VA_PICTURE_H264_TOP_FIELD) {
    421         mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD | VA_TOP_FIELD;
    422     } else {
    423         mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
    424     }
    425 
    426     mAcquiredBuffer->renderBuffer.flag = 0;
    427     mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
    428     mAcquiredBuffer->pictureOrder = getPOC(picture);
    429 
    430     if (mSizeChanged) {
    431         mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE;
    432         mSizeChanged = false;
    433     }
    434 
    435     status  = continueDecodingFrame(data);
    436     return status;
    437 }
    438 
    439 Decode_Status VideoDecoderAVCSecure::continueDecodingFrame(vbp_data_h264 *data) {
    440     VTRACE("VideoDecoderAVCSecure::continueDecodingFrame");
    441     Decode_Status status;
    442     vbp_picture_data_h264 *picData = data->pic_data;
    443 
    444     if (mAcquiredBuffer == NULL || mAcquiredBuffer->renderBuffer.surface == VA_INVALID_SURFACE) {
    445         ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
    446         return DECODE_FAIL;
    447     }
    448     VTRACE("data->num_pictures = %d", data->num_pictures);
    449     for (uint32_t picIndex = 0; picIndex < data->num_pictures; picIndex++, picData++) {
    450         if (picData == NULL || picData->pic_parms == NULL || picData->slc_data == NULL || picData->num_slices == 0) {
    451             return DECODE_PARSER_FAIL;
    452         }
    453 
    454         if (picIndex > 0 &&
    455             (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
    456             ETRACE("Packed frame is not supported yet!");
    457             return DECODE_FAIL;
    458         }
    459         VTRACE("picData->num_slices = %d", picData->num_slices);
    460         for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
    461             status = decodeSlice(data, picIndex, sliceIndex);
    462             if (status != DECODE_SUCCESS) {
    463                 endDecodingFrame(true);
    464                 // remove current frame from DPB as it can't be decoded.
    465                 removeReferenceFromDPB(picData->pic_parms);
    466                 return status;
    467             }
    468         }
    469     }
    470     return DECODE_SUCCESS;
    471 }
    472 
    473 Decode_Status VideoDecoderAVCSecure::parseClassicSliceHeader(VideoDecodeBuffer *buffer, vbp_data_h264 *data) {
    474     Decode_Status status;
    475     VAStatus vaStatus;
    476 
    477     VABufferID sliceheaderbufferID;
    478     VABufferID pictureparameterparsingbufferID;
    479     VABufferID mSlicebufferID;
    480 
    481     if (mFrameSize <= 0) {
    482         return DECODE_SUCCESS;
    483     }
    484     vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
    485     CHECK_VA_STATUS("vaBeginPicture");
    486 
    487     vaStatus = vaCreateBuffer(
    488         mVADisplay,
    489         mVAContext,
    490         VAParseSliceHeaderGroupBufferType,
    491         MAX_SLICEHEADER_BUFFER_SIZE,
    492         1,
    493         NULL,
    494         &sliceheaderbufferID);
    495     CHECK_VA_STATUS("vaCreateSliceHeaderGroupBuffer");
    496 
    497     void *sliceheaderbuf;
    498     vaStatus = vaMapBuffer(
    499         mVADisplay,
    500         sliceheaderbufferID,
    501         &sliceheaderbuf);
    502     CHECK_VA_STATUS("vaMapBuffer");
    503 
    504     memset(sliceheaderbuf, 0, MAX_SLICEHEADER_BUFFER_SIZE);
    505 
    506     vaStatus = vaUnmapBuffer(
    507         mVADisplay,
    508         sliceheaderbufferID);
    509     CHECK_VA_STATUS("vaUnmapBuffer");
    510 
    511 
    512     vaStatus = vaCreateBuffer(
    513         mVADisplay,
    514         mVAContext,
    515         VASliceDataBufferType,
    516         mFrameSize, //size
    517         1,        //num_elements
    518         mFrameData,
    519         &mSlicebufferID);
    520     CHECK_VA_STATUS("vaCreateSliceDataBuffer");
    521 
    522     data->pic_parse_buffer->frame_buf_id = mSlicebufferID;
    523     data->pic_parse_buffer->slice_headers_buf_id = sliceheaderbufferID;
    524     data->pic_parse_buffer->frame_size = mFrameSize;
    525     data->pic_parse_buffer->slice_headers_size = MAX_SLICEHEADER_BUFFER_SIZE;
    526 
    527 #if 0
    528 
    529     VTRACE("flags.bits.frame_mbs_only_flag = %d", data->pic_parse_buffer->flags.bits.frame_mbs_only_flag);
    530     VTRACE("flags.bits.pic_order_present_flag = %d", data->pic_parse_buffer->flags.bits.pic_order_present_flag);
    531     VTRACE("flags.bits.delta_pic_order_always_zero_flag = %d", data->pic_parse_buffer->flags.bits.delta_pic_order_always_zero_flag);
    532     VTRACE("flags.bits.redundant_pic_cnt_present_flag = %d", data->pic_parse_buffer->flags.bits.redundant_pic_cnt_present_flag);
    533     VTRACE("flags.bits.weighted_pred_flag = %d", data->pic_parse_buffer->flags.bits.weighted_pred_flag);
    534     VTRACE("flags.bits.entropy_coding_mode_flag = %d", data->pic_parse_buffer->flags.bits.entropy_coding_mode_flag);
    535     VTRACE("flags.bits.deblocking_filter_control_present_flag = %d", data->pic_parse_buffer->flags.bits.deblocking_filter_control_present_flag);
    536     VTRACE("flags.bits.weighted_bipred_idc = %d", data->pic_parse_buffer->flags.bits.weighted_bipred_idc);
    537 
    538     VTRACE("pic_parse_buffer->expected_pic_parameter_set_id = %d", data->pic_parse_buffer->expected_pic_parameter_set_id);
    539     VTRACE("pic_parse_buffer->num_slice_groups_minus1 = %d", data->pic_parse_buffer->num_slice_groups_minus1);
    540     VTRACE("pic_parse_buffer->chroma_format_idc = %d", data->pic_parse_buffer->chroma_format_idc);
    541     VTRACE("pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4 = %d", data->pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4);
    542     VTRACE("pic_parse_buffer->pic_order_cnt_type = %d", data->pic_parse_buffer->pic_order_cnt_type);
    543     VTRACE("pic_parse_buffer->residual_colour_transform_flag = %d", data->pic_parse_buffer->residual_colour_transform_flag);
    544     VTRACE("pic_parse_buffer->num_ref_idc_l0_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l0_active_minus1);
    545     VTRACE("pic_parse_buffer->num_ref_idc_l1_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l1_active_minus1);
    546 #endif
    547 
    548     vaStatus = vaCreateBuffer(
    549         mVADisplay,
    550         mVAContext,
    551         VAParsePictureParameterBufferType,
    552         sizeof(VAParsePictureParameterBuffer),
    553         1,
    554         data->pic_parse_buffer,
    555         &pictureparameterparsingbufferID);
    556     CHECK_VA_STATUS("vaCreatePictureParameterParsingBuffer");
    557 
    558     vaStatus = vaRenderPicture(
    559         mVADisplay,
    560         mVAContext,
    561         &pictureparameterparsingbufferID,
    562         1);
    563     CHECK_VA_STATUS("vaRenderPicture");
    564 
    565     vaStatus = vaMapBuffer(
    566         mVADisplay,
    567         sliceheaderbufferID,
    568         &sliceheaderbuf);
    569     CHECK_VA_STATUS("vaMapBuffer");
    570 
    571     status = updateSliceParameter(data,sliceheaderbuf);
    572     CHECK_STATUS("processSliceHeader");
    573 
    574     vaStatus = vaUnmapBuffer(
    575         mVADisplay,
    576         sliceheaderbufferID);
    577     CHECK_VA_STATUS("vaUnmapBuffer");
    578 
    579     return DECODE_SUCCESS;
    580 }
    581 
    582 Decode_Status VideoDecoderAVCSecure::parseModularSliceHeader(VideoDecodeBuffer *buffer, vbp_data_h264 *data) {
    583     Decode_Status status;
    584     VAStatus vaStatus;
    585 
    586     VABufferID sliceheaderbufferID;
    587     VABufferID pictureparameterparsingbufferID;
    588     VABufferID mSlicebufferID;
    589     int32_t sliceIdx;
    590 
    591     vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
    592     CHECK_VA_STATUS("vaBeginPicture");
    593 
    594     if (mFrameSize <= 0 || mSliceNum <=0) {
    595         return DECODE_SUCCESS;
    596     }
    597     void *sliceheaderbuf;
    598     memset(mCachedHeader, 0, MAX_SLICEHEADER_BUFFER_SIZE);
    599     int32_t offset = 0;
    600     int32_t size = 0;
    601 
    602     for (sliceIdx = 0; sliceIdx < mSliceNum; sliceIdx++) {
    603         vaStatus = vaCreateBuffer(
    604             mVADisplay,
    605             mVAContext,
    606             VAParseSliceHeaderGroupBufferType,
    607             MAX_SLICEHEADER_BUFFER_SIZE,
    608             1,
    609             NULL,
    610             &sliceheaderbufferID);
    611         CHECK_VA_STATUS("vaCreateSliceHeaderGroupBuffer");
    612 
    613         vaStatus = vaMapBuffer(
    614             mVADisplay,
    615             sliceheaderbufferID,
    616             &sliceheaderbuf);
    617         CHECK_VA_STATUS("vaMapBuffer");
    618 
    619         memset(sliceheaderbuf, 0, MAX_SLICEHEADER_BUFFER_SIZE);
    620 
    621         vaStatus = vaUnmapBuffer(
    622             mVADisplay,
    623             sliceheaderbufferID);
    624         CHECK_VA_STATUS("vaUnmapBuffer");
    625 
    626         vaStatus = vaCreateBuffer(
    627             mVADisplay,
    628             mVAContext,
    629             VASliceDataBufferType,
    630             mSliceInfo[sliceIdx].sliceSize, //size
    631             1,        //num_elements
    632             mFrameData + mSliceInfo[sliceIdx].sliceStartOffset,
    633             &mSlicebufferID);
    634         CHECK_VA_STATUS("vaCreateSliceDataBuffer");
    635 
    636         data->pic_parse_buffer->frame_buf_id = mSlicebufferID;
    637         data->pic_parse_buffer->slice_headers_buf_id = sliceheaderbufferID;
    638         data->pic_parse_buffer->frame_size = mSliceInfo[sliceIdx].sliceLength;
    639         data->pic_parse_buffer->slice_headers_size = MAX_SLICEHEADER_BUFFER_SIZE;
    640         data->pic_parse_buffer->nalu_header.value = mSliceInfo[sliceIdx].sliceHeaderByte;
    641         data->pic_parse_buffer->slice_offset = mSliceInfo[sliceIdx].sliceByteOffset;
    642 
    643 #if 0
    644         VTRACE("data->pic_parse_buffer->slice_offset = 0x%x", data->pic_parse_buffer->slice_offset);
    645         VTRACE("pic_parse_buffer->nalu_header.value = %x", data->pic_parse_buffer->nalu_header.value = mSliceInfo[sliceIdx].sliceHeaderByte);
    646         VTRACE("flags.bits.frame_mbs_only_flag = %d", data->pic_parse_buffer->flags.bits.frame_mbs_only_flag);
    647         VTRACE("flags.bits.pic_order_present_flag = %d", data->pic_parse_buffer->flags.bits.pic_order_present_flag);
    648         VTRACE("flags.bits.delta_pic_order_always_zero_flag = %d", data->pic_parse_buffer->flags.bits.delta_pic_order_always_zero_flag);
    649         VTRACE("flags.bits.redundant_pic_cnt_present_flag = %d", data->pic_parse_buffer->flags.bits.redundant_pic_cnt_present_flag);
    650         VTRACE("flags.bits.weighted_pred_flag = %d", data->pic_parse_buffer->flags.bits.weighted_pred_flag);
    651         VTRACE("flags.bits.entropy_coding_mode_flag = %d", data->pic_parse_buffer->flags.bits.entropy_coding_mode_flag);
    652         VTRACE("flags.bits.deblocking_filter_control_present_flag = %d", data->pic_parse_buffer->flags.bits.deblocking_filter_control_present_flag);
    653         VTRACE("flags.bits.weighted_bipred_idc = %d", data->pic_parse_buffer->flags.bits.weighted_bipred_idc);
    654         VTRACE("pic_parse_buffer->expected_pic_parameter_set_id = %d", data->pic_parse_buffer->expected_pic_parameter_set_id);
    655         VTRACE("pic_parse_buffer->num_slice_groups_minus1 = %d", data->pic_parse_buffer->num_slice_groups_minus1);
    656         VTRACE("pic_parse_buffer->chroma_format_idc = %d", data->pic_parse_buffer->chroma_format_idc);
    657         VTRACE("pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4 = %d", data->pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4);
    658         VTRACE("pic_parse_buffer->pic_order_cnt_type = %d", data->pic_parse_buffer->pic_order_cnt_type);
    659         VTRACE("pic_parse_buffer->residual_colour_transform_flag = %d", data->pic_parse_buffer->residual_colour_transform_flag);
    660         VTRACE("pic_parse_buffer->num_ref_idc_l0_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l0_active_minus1);
    661         VTRACE("pic_parse_buffer->num_ref_idc_l1_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l1_active_minus1);
    662 #endif
    663         vaStatus = vaCreateBuffer(
    664             mVADisplay,
    665             mVAContext,
    666             VAParsePictureParameterBufferType,
    667             sizeof(VAParsePictureParameterBuffer),
    668             1,
    669             data->pic_parse_buffer,
    670             &pictureparameterparsingbufferID);
    671         CHECK_VA_STATUS("vaCreatePictureParameterParsingBuffer");
    672 
    673         vaStatus = vaRenderPicture(
    674             mVADisplay,
    675             mVAContext,
    676             &pictureparameterparsingbufferID,
    677             1);
    678         CHECK_VA_STATUS("vaRenderPicture");
    679 
    680         vaStatus = vaMapBuffer(
    681             mVADisplay,
    682             sliceheaderbufferID,
    683             &sliceheaderbuf);
    684         CHECK_VA_STATUS("vaMapBuffer");
    685 
    686         size = *(uint32 *)((uint8 *)sliceheaderbuf + 4) + 4;
    687         VTRACE("slice header size = 0x%x, offset = 0x%x", size, offset);
    688         if (offset + size <= MAX_SLICEHEADER_BUFFER_SIZE - 4) {
    689             memcpy(mCachedHeader+offset, sliceheaderbuf, size);
    690             offset += size;
    691         } else {
    692             WTRACE("Cached slice header is not big enough!");
    693         }
    694         vaStatus = vaUnmapBuffer(
    695             mVADisplay,
    696             sliceheaderbufferID);
    697         CHECK_VA_STATUS("vaUnmapBuffer");
    698     }
    699     memset(mCachedHeader + offset, 0xFF, 4);
    700     status = updateSliceParameter(data,mCachedHeader);
    701     CHECK_STATUS("processSliceHeader");
    702     return DECODE_SUCCESS;
    703 }
    704 
    705 
    706 Decode_Status VideoDecoderAVCSecure::updateSliceParameter(vbp_data_h264 *data, void *sliceheaderbuf) {
    707     VTRACE("VideoDecoderAVCSecure::updateSliceParameter");
    708     Decode_Status status;
    709     status =  VideoDecoderBase::updateBuffer(
    710             (uint8_t *)sliceheaderbuf,
    711             MAX_SLICEHEADER_BUFFER_SIZE,
    712             (void**)&data);
    713     CHECK_STATUS("updateBuffer");
    714     return DECODE_SUCCESS;
    715 }
    716 
    717 Decode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {
    718     Decode_Status status;
    719     VAStatus vaStatus;
    720     uint32_t bufferIDCount = 0;
    721     // maximum 3 buffers to render a slice: picture parameter, IQMatrix, slice parameter
    722     VABufferID bufferIDs[3];
    723 
    724     vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
    725     vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
    726     VAPictureParameterBufferH264 *picParam = picData->pic_parms;
    727     VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);
    728     uint32_t slice_data_size = 0;
    729     uint8_t* slice_data_addr = NULL;
    730 
    731     if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
    732         // either condition indicates start of a new frame
    733         if (sliceParam->first_mb_in_slice != 0) {
    734             WTRACE("The first slice is lost.");
    735         }
    736         VTRACE("Current frameidx = %d", mFrameIdx++);
    737         // Update  the reference frames and surface IDs for DPB and current frame
    738         status = updateDPB(picParam);
    739         CHECK_STATUS("updateDPB");
    740 
    741         //We have to provide a hacked DPB rather than complete DPB for libva as workaround
    742         status = updateReferenceFrames(picData);
    743         CHECK_STATUS("updateReferenceFrames");
    744 
    745         mDecodingFrame = true;
    746 
    747         vaStatus = vaCreateBuffer(
    748             mVADisplay,
    749             mVAContext,
    750             VAPictureParameterBufferType,
    751             sizeof(VAPictureParameterBufferH264),
    752             1,
    753             picParam,
    754             &bufferIDs[bufferIDCount]);
    755         CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
    756         bufferIDCount++;
    757 
    758         vaStatus = vaCreateBuffer(
    759             mVADisplay,
    760             mVAContext,
    761             VAIQMatrixBufferType,
    762             sizeof(VAIQMatrixBufferH264),
    763             1,
    764             data->IQ_matrix_buf,
    765             &bufferIDs[bufferIDCount]);
    766         CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
    767         bufferIDCount++;
    768     }
    769 
    770     status = setReference(sliceParam);
    771     CHECK_STATUS("setReference");
    772 
    773     if (mModularMode) {
    774         if (mIsEncryptData) {
    775             sliceParam->slice_data_size = mSliceInfo[sliceIndex].sliceSize;
    776             slice_data_size = mSliceInfo[sliceIndex].sliceSize;
    777             slice_data_addr = mFrameData + mSliceInfo[sliceIndex].sliceStartOffset;
    778         } else {
    779             slice_data_size = sliceData->slice_size;
    780             slice_data_addr = sliceData->buffer_addr + sliceData->slice_offset;
    781         }
    782     } else {
    783         sliceParam->slice_data_size = mFrameSize;
    784         slice_data_size = mFrameSize;
    785         slice_data_addr = mFrameData;
    786     }
    787 
    788     vaStatus = vaCreateBuffer(
    789         mVADisplay,
    790         mVAContext,
    791         VASliceParameterBufferType,
    792         sizeof(VASliceParameterBufferH264),
    793         1,
    794         sliceParam,
    795         &bufferIDs[bufferIDCount]);
    796     CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
    797     bufferIDCount++;
    798 
    799     vaStatus = vaRenderPicture(
    800         mVADisplay,
    801         mVAContext,
    802         bufferIDs,
    803         bufferIDCount);
    804     CHECK_VA_STATUS("vaRenderPicture");
    805 
    806     VABufferID slicebufferID;
    807 
    808     vaStatus = vaCreateBuffer(
    809         mVADisplay,
    810         mVAContext,
    811         VASliceDataBufferType,
    812         slice_data_size, //size
    813         1,        //num_elements
    814         slice_data_addr,
    815         &slicebufferID);
    816     CHECK_VA_STATUS("vaCreateSliceDataBuffer");
    817 
    818     vaStatus = vaRenderPicture(
    819         mVADisplay,
    820         mVAContext,
    821         &slicebufferID,
    822         1);
    823     CHECK_VA_STATUS("vaRenderPicture");
    824 
    825     return DECODE_SUCCESS;
    826 
    827 }
    828 
    829 Decode_Status VideoDecoderAVCSecure::getCodecSpecificConfigs(
    830     VAProfile profile, VAConfigID *config)
    831 {
    832     VAStatus vaStatus;
    833     VAConfigAttrib attrib[2];
    834 
    835     if (config == NULL) {
    836         ETRACE("Invalid parameter!");
    837         return DECODE_FAIL;
    838     }
    839 
    840     attrib[0].type = VAConfigAttribRTFormat;
    841     attrib[0].value = VA_RT_FORMAT_YUV420;
    842     attrib[1].type = VAConfigAttribDecSliceMode;
    843     attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
    844     if (mModularMode) {
    845         attrib[1].value = VA_DEC_SLICE_MODE_SUBSAMPLE;
    846     }
    847 
    848     vaStatus = vaCreateConfig(
    849             mVADisplay,
    850             profile,
    851             VAEntrypointVLD,
    852             &attrib[0],
    853             2,
    854             config);
    855     CHECK_VA_STATUS("vaCreateConfig");
    856 
    857     return DECODE_SUCCESS;
    858 }
    859