VideoDecoderAVCSecure.cpp revision e5d3d0350319d2eac1c29ba10e86cb8c4784e97f
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
29static const uint8_t startcodePrefix[STARTCODE_PREFIX_LEN] = {0x00, 0x00, 0x01};
30
31/* H264 start code values */
32typedef 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
52VideoDecoderAVCSecure::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
65Decode_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
88void 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}
102Decode_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
167#if 0
168                uint32_t testsize;
169                uint8_t *testdata;
170                testsize = mSliceInfo[sliceidx].sliceSize > 64 ? 64 : mSliceInfo[sliceidx].sliceSize ;
171                testdata = (uint8_t *)(mFrameData);
172                for (int i = 0; i < testsize; i++) {
173                    VTRACE("testdata[%d] = 0x%x", i, testdata[i]);
174                }
175#endif
176                sliceidx++;
177
178            } else if (naluType == h264_NAL_UNIT_TYPE_SPS || naluType == h264_NAL_UNIT_TYPE_PPS) {
179                if (nalu_data == NULL) {
180                    ETRACE("Invalid parameter: nalu_data = NULL for naluType 0x%x", naluType);
181                    return DECODE_MEMORY_FAIL;
182                }
183                memcpy(mClearData + clear_data_size,
184                    nalu_data,
185                    nalu_size);
186                clear_data_size += nalu_size;
187            } else {
188                ITRACE("Nalu type = 0x%x is skipped", naluType);
189                continue;
190            }
191        }
192        clear_data = mClearData;
193        mSliceNum = sliceidx;
194
195    } else {
196        VTRACE("Decoding clear video ...");
197        mIsEncryptData = 0;
198        mFrameSize = buffer->size;
199        mFrameData = buffer->data;
200        clear_data = buffer->data;
201        clear_data_size = buffer->size;
202    }
203
204    if (clear_data_size > 0) {
205        status =  VideoDecoderBase::parseBuffer(
206                clear_data,
207                clear_data_size,
208                false,
209                (void**)data);
210        CHECK_STATUS("VideoDecoderBase::parseBuffer");
211    } else {
212        status =  VideoDecoderBase::queryBuffer((void**)data);
213        CHECK_STATUS("VideoDecoderBase::queryBuffer");
214    }
215    return DECODE_SUCCESS;
216}
217
218Decode_Status VideoDecoderAVCSecure::processClassicInputBuffer(VideoDecodeBuffer *buffer, vbp_data_h264 **data)
219{
220    Decode_Status status;
221    int32_t clear_data_size = 0;
222    uint8_t *clear_data = NULL;
223    uint8_t naluType = 0;
224
225    int32_t num_nalus;
226    int32_t nalu_offset;
227    int32_t offset;
228    uint8_t *data_src;
229    uint8_t *nalu_data;
230    uint32_t nalu_size;
231
232    if (buffer->flag & IS_SECURE_DATA) {
233        VTRACE("Decoding protected video ...");
234        mIsEncryptData = 1;
235
236        mFrameData = buffer->data;
237        mFrameSize = buffer->size;
238        VTRACE("mFrameData = %p, mFrameSize = %d", mFrameData, mFrameSize);
239        num_nalus  = *(uint32_t *)(buffer->data + buffer->size + sizeof(uint32_t));
240        VTRACE("num_nalus = %d", num_nalus);
241        offset = 4;
242        for (int32_t i = 0; i < num_nalus; i++) {
243            VTRACE("%d nalu, offset = %d", i, offset);
244            data_src = buffer->data + buffer->size + sizeof(uint32_t) + offset;
245            nalu_size = *(uint32_t *)(data_src + 2 * sizeof(uint32_t));
246            nalu_size = (nalu_size + 0x03) & (~0x03);
247
248            nalu_data = data_src + 3 *sizeof(uint32_t);
249            naluType  = nalu_data[0] & NALU_TYPE_MASK;
250            offset += nalu_size + 3 *sizeof(uint32_t);
251            VTRACE("naluType = 0x%x", naluType);
252            VTRACE("nalu_size = %d, nalu_data = %p", nalu_size, nalu_data);
253
254            if (naluType >= h264_NAL_UNIT_TYPE_SLICE && naluType <= h264_NAL_UNIT_TYPE_IDR) {
255                ETRACE("Slice NALU received!");
256                return DECODE_INVALID_DATA;
257            }
258
259            else if (naluType >= h264_NAL_UNIT_TYPE_SEI && naluType <= h264_NAL_UNIT_TYPE_PPS) {
260                memcpy(mClearData + clear_data_size,
261                    startcodePrefix,
262                    STARTCODE_PREFIX_LEN);
263                clear_data_size += STARTCODE_PREFIX_LEN;
264                memcpy(mClearData + clear_data_size,
265                    nalu_data,
266                    nalu_size);
267                clear_data_size += nalu_size;
268            } else {
269                ETRACE("Failure: DECODE_FRAME_DROPPED");
270                return DECODE_FRAME_DROPPED;
271            }
272        }
273        clear_data = mClearData;
274    } else {
275        VTRACE("Decoding clear video ...");
276        mIsEncryptData = 0;
277        mFrameSize = buffer->size;
278        mFrameData = buffer->data;
279        clear_data = buffer->data;
280        clear_data_size = buffer->size;
281    }
282
283    if (clear_data_size > 0) {
284        status =  VideoDecoderBase::parseBuffer(
285                clear_data,
286                clear_data_size,
287                false,
288                (void**)data);
289        CHECK_STATUS("VideoDecoderBase::parseBuffer");
290    } else {
291        status =  VideoDecoderBase::queryBuffer((void**)data);
292        CHECK_STATUS("VideoDecoderBase::queryBuffer");
293    }
294    return DECODE_SUCCESS;
295}
296
297Decode_Status VideoDecoderAVCSecure::decode(VideoDecodeBuffer *buffer) {
298    VTRACE("VideoDecoderAVCSecure::decode");
299    Decode_Status status;
300    vbp_data_h264 *data = NULL;
301    if (buffer == NULL) {
302        return DECODE_INVALID_DATA;
303    }
304
305#if 0
306    uint32_t testsize;
307    uint8_t *testdata;
308    testsize = buffer->size > 16 ? 16:buffer->size ;
309    testdata = (uint8_t *)(buffer->data);
310    for (int i = 0; i < 16; i++) {
311        VTRACE("testdata[%d] = 0x%x", i, testdata[i]);
312    }
313#endif
314    if (buffer->flag & IS_SUBSAMPLE_ENCRYPTION) {
315        mModularMode = 1;
316    }
317
318    if (mModularMode) {
319        status = processModularInputBuffer(buffer,&data);
320        CHECK_STATUS("processModularInputBuffer");
321    }
322    else {
323        status = processClassicInputBuffer(buffer,&data);
324        CHECK_STATUS("processClassicInputBuffer");
325    }
326
327    if (!mVAStarted) {
328         if (data->has_sps && data->has_pps) {
329            status = startVA(data);
330            CHECK_STATUS("startVA");
331        } else {
332            WTRACE("Can't start VA as either SPS or PPS is still not available.");
333            return DECODE_SUCCESS;
334        }
335    }
336
337    status = decodeFrame(buffer, data);
338
339    return status;
340}
341
342Decode_Status VideoDecoderAVCSecure::decodeFrame(VideoDecodeBuffer *buffer, vbp_data_h264 *data) {
343    VTRACE("VideoDecoderAVCSecure::decodeFrame");
344    Decode_Status status;
345    VTRACE("data->has_sps = %d, data->has_pps = %d", data->has_sps, data->has_pps);
346
347#if 0
348    // Don't remove the following codes, it can be enabled for debugging DPB.
349    for (unsigned int i = 0; i < data->num_pictures; i++) {
350        VAPictureH264 &pic = data->pic_data[i].pic_parms->CurrPic;
351        VTRACE("%d: decoding frame %.2f, poc top = %d, poc bottom = %d, flags = %d,  reference = %d",
352                i,
353                buffer->timeStamp/1E6,
354                pic.TopFieldOrderCnt,
355                pic.BottomFieldOrderCnt,
356                pic.flags,
357                (pic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
358                (pic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE));
359    }
360#endif
361
362    if (data->new_sps || data->new_pps) {
363        status = handleNewSequence(data);
364        CHECK_STATUS("handleNewSequence");
365    }
366
367    if (mModularMode && (!mIsEncryptData)) {
368        if (data->pic_data[0].num_slices == 0) {
369            ITRACE("No slice available for decoding.");
370            status = mSizeChanged ? DECODE_FORMAT_CHANGE : DECODE_SUCCESS;
371            mSizeChanged = false;
372            return status;
373        }
374    }
375
376    uint64_t lastPTS = mCurrentPTS;
377    mCurrentPTS = buffer->timeStamp;
378
379    // start decoding a new frame
380    status = acquireSurfaceBuffer();
381    CHECK_STATUS("acquireSurfaceBuffer");
382
383    if (mModularMode) {
384        status = parseModularSliceHeader(data);
385    }
386    else {
387        status = parseClassicSliceHeader(data);
388    }
389
390    if (status != DECODE_SUCCESS) {
391        endDecodingFrame(true);
392        if (status == DECODE_PARSER_FAIL) {
393            ETRACE("parse frame failed with DECODE_PARSER_FAIL");
394            status = DECODE_INVALID_DATA;
395        }
396        return status;
397    }
398
399    status = beginDecodingFrame(data);
400    CHECK_STATUS("beginDecodingFrame");
401
402   // finish decoding the last frame
403    status = endDecodingFrame(false);
404    CHECK_STATUS("endDecodingFrame");
405
406    if (isNewFrame(data, lastPTS == mCurrentPTS) == 0) {
407        ETRACE("Can't handle interlaced frames yet");
408        return DECODE_FAIL;
409    }
410
411    return DECODE_SUCCESS;
412}
413
414Decode_Status VideoDecoderAVCSecure::beginDecodingFrame(vbp_data_h264 *data) {
415    VTRACE("VideoDecoderAVCSecure::beginDecodingFrame");
416    Decode_Status status;
417    VAPictureH264 *picture = &(data->pic_data[0].pic_parms->CurrPic);
418    if ((picture->flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
419        (picture->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
420        mAcquiredBuffer->referenceFrame = true;
421    } else {
422        mAcquiredBuffer->referenceFrame = false;
423    }
424
425    if (picture->flags & VA_PICTURE_H264_TOP_FIELD) {
426        mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD | VA_TOP_FIELD;
427    } else {
428        mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
429    }
430
431    mAcquiredBuffer->renderBuffer.flag = 0;
432    mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
433    mAcquiredBuffer->pictureOrder = getPOC(picture);
434
435    if (mSizeChanged) {
436        mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE;
437        mSizeChanged = false;
438    }
439
440    status  = continueDecodingFrame(data);
441    return status;
442}
443
444Decode_Status VideoDecoderAVCSecure::continueDecodingFrame(vbp_data_h264 *data) {
445    VTRACE("VideoDecoderAVCSecure::continueDecodingFrame");
446    Decode_Status status;
447    vbp_picture_data_h264 *picData = data->pic_data;
448
449    if (mAcquiredBuffer == NULL || mAcquiredBuffer->renderBuffer.surface == VA_INVALID_SURFACE) {
450        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
451        return DECODE_FAIL;
452    }
453    VTRACE("data->num_pictures = %d", data->num_pictures);
454    for (uint32_t picIndex = 0; picIndex < data->num_pictures; picIndex++, picData++) {
455        if (picData == NULL || picData->pic_parms == NULL || picData->slc_data == NULL || picData->num_slices == 0) {
456            return DECODE_PARSER_FAIL;
457        }
458
459        if (picIndex > 0 &&
460            (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
461            ETRACE("Packed frame is not supported yet!");
462            return DECODE_FAIL;
463        }
464        VTRACE("picData->num_slices = %d", picData->num_slices);
465        for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
466            status = decodeSlice(data, picIndex, sliceIndex);
467            if (status != DECODE_SUCCESS) {
468                endDecodingFrame(true);
469                // remove current frame from DPB as it can't be decoded.
470                removeReferenceFromDPB(picData->pic_parms);
471                return status;
472            }
473        }
474    }
475    mDecodingFrame = true;
476
477    return DECODE_SUCCESS;
478}
479
480Decode_Status VideoDecoderAVCSecure::parseClassicSliceHeader(vbp_data_h264 *data) {
481    Decode_Status status;
482    VAStatus vaStatus;
483
484    VABufferID sliceheaderbufferID;
485    VABufferID pictureparameterparsingbufferID;
486    VABufferID mSlicebufferID;
487
488    if (mFrameSize <= 0) {
489        return DECODE_SUCCESS;
490    }
491    vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
492    CHECK_VA_STATUS("vaBeginPicture");
493
494    vaStatus = vaCreateBuffer(
495        mVADisplay,
496        mVAContext,
497        VAParseSliceHeaderGroupBufferType,
498        MAX_SLICEHEADER_BUFFER_SIZE,
499        1,
500        NULL,
501        &sliceheaderbufferID);
502    CHECK_VA_STATUS("vaCreateSliceHeaderGroupBuffer");
503
504    void *sliceheaderbuf;
505    vaStatus = vaMapBuffer(
506        mVADisplay,
507        sliceheaderbufferID,
508        &sliceheaderbuf);
509    CHECK_VA_STATUS("vaMapBuffer");
510
511    memset(sliceheaderbuf, 0, MAX_SLICEHEADER_BUFFER_SIZE);
512
513    vaStatus = vaUnmapBuffer(
514        mVADisplay,
515        sliceheaderbufferID);
516    CHECK_VA_STATUS("vaUnmapBuffer");
517
518
519    vaStatus = vaCreateBuffer(
520        mVADisplay,
521        mVAContext,
522        VASliceDataBufferType,
523        mFrameSize, //size
524        1,        //num_elements
525        mFrameData,
526        &mSlicebufferID);
527    CHECK_VA_STATUS("vaCreateSliceDataBuffer");
528
529    data->pic_parse_buffer->frame_buf_id = mSlicebufferID;
530    data->pic_parse_buffer->slice_headers_buf_id = sliceheaderbufferID;
531    data->pic_parse_buffer->frame_size = mFrameSize;
532    data->pic_parse_buffer->slice_headers_size = MAX_SLICEHEADER_BUFFER_SIZE;
533
534#if 0
535
536    VTRACE("flags.bits.frame_mbs_only_flag = %d", data->pic_parse_buffer->flags.bits.frame_mbs_only_flag);
537    VTRACE("flags.bits.pic_order_present_flag = %d", data->pic_parse_buffer->flags.bits.pic_order_present_flag);
538    VTRACE("flags.bits.delta_pic_order_always_zero_flag = %d", data->pic_parse_buffer->flags.bits.delta_pic_order_always_zero_flag);
539    VTRACE("flags.bits.redundant_pic_cnt_present_flag = %d", data->pic_parse_buffer->flags.bits.redundant_pic_cnt_present_flag);
540    VTRACE("flags.bits.weighted_pred_flag = %d", data->pic_parse_buffer->flags.bits.weighted_pred_flag);
541    VTRACE("flags.bits.entropy_coding_mode_flag = %d", data->pic_parse_buffer->flags.bits.entropy_coding_mode_flag);
542    VTRACE("flags.bits.deblocking_filter_control_present_flag = %d", data->pic_parse_buffer->flags.bits.deblocking_filter_control_present_flag);
543    VTRACE("flags.bits.weighted_bipred_idc = %d", data->pic_parse_buffer->flags.bits.weighted_bipred_idc);
544
545    VTRACE("pic_parse_buffer->expected_pic_parameter_set_id = %d", data->pic_parse_buffer->expected_pic_parameter_set_id);
546    VTRACE("pic_parse_buffer->num_slice_groups_minus1 = %d", data->pic_parse_buffer->num_slice_groups_minus1);
547    VTRACE("pic_parse_buffer->chroma_format_idc = %d", data->pic_parse_buffer->chroma_format_idc);
548    VTRACE("pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4 = %d", data->pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4);
549    VTRACE("pic_parse_buffer->pic_order_cnt_type = %d", data->pic_parse_buffer->pic_order_cnt_type);
550    VTRACE("pic_parse_buffer->residual_colour_transform_flag = %d", data->pic_parse_buffer->residual_colour_transform_flag);
551    VTRACE("pic_parse_buffer->num_ref_idc_l0_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l0_active_minus1);
552    VTRACE("pic_parse_buffer->num_ref_idc_l1_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l1_active_minus1);
553#endif
554
555    vaStatus = vaCreateBuffer(
556        mVADisplay,
557        mVAContext,
558        VAParsePictureParameterBufferType,
559        sizeof(VAParsePictureParameterBuffer),
560        1,
561        data->pic_parse_buffer,
562        &pictureparameterparsingbufferID);
563    CHECK_VA_STATUS("vaCreatePictureParameterParsingBuffer");
564
565    vaStatus = vaRenderPicture(
566        mVADisplay,
567        mVAContext,
568        &pictureparameterparsingbufferID,
569        1);
570    CHECK_VA_STATUS("vaRenderPicture");
571
572    vaStatus = vaMapBuffer(
573        mVADisplay,
574        sliceheaderbufferID,
575        &sliceheaderbuf);
576    CHECK_VA_STATUS("vaMapBuffer");
577
578    status = updateSliceParameter(data,sliceheaderbuf);
579    CHECK_STATUS("processSliceHeader");
580
581    vaStatus = vaUnmapBuffer(
582        mVADisplay,
583        sliceheaderbufferID);
584    CHECK_VA_STATUS("vaUnmapBuffer");
585
586    return DECODE_SUCCESS;
587}
588
589Decode_Status VideoDecoderAVCSecure::parseModularSliceHeader(vbp_data_h264 *data) {
590    Decode_Status status;
591    VAStatus vaStatus;
592
593    VABufferID sliceheaderbufferID;
594    VABufferID pictureparameterparsingbufferID;
595    VABufferID mSlicebufferID;
596    int32_t sliceIdx;
597
598    vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
599    CHECK_VA_STATUS("vaBeginPicture");
600
601    if (mFrameSize <= 0 || mSliceNum <=0) {
602        return DECODE_SUCCESS;
603    }
604    void *sliceheaderbuf;
605    memset(mCachedHeader, 0, MAX_SLICEHEADER_BUFFER_SIZE);
606    int32_t offset = 0;
607    int32_t size = 0;
608
609    for (sliceIdx = 0; sliceIdx < mSliceNum; sliceIdx++) {
610        vaStatus = vaCreateBuffer(
611            mVADisplay,
612            mVAContext,
613            VAParseSliceHeaderGroupBufferType,
614            MAX_SLICEHEADER_BUFFER_SIZE,
615            1,
616            NULL,
617            &sliceheaderbufferID);
618        CHECK_VA_STATUS("vaCreateSliceHeaderGroupBuffer");
619
620        vaStatus = vaMapBuffer(
621            mVADisplay,
622            sliceheaderbufferID,
623            &sliceheaderbuf);
624        CHECK_VA_STATUS("vaMapBuffer");
625
626        memset(sliceheaderbuf, 0, MAX_SLICEHEADER_BUFFER_SIZE);
627
628        vaStatus = vaUnmapBuffer(
629            mVADisplay,
630            sliceheaderbufferID);
631        CHECK_VA_STATUS("vaUnmapBuffer");
632
633        vaStatus = vaCreateBuffer(
634            mVADisplay,
635            mVAContext,
636            VASliceDataBufferType,
637            mSliceInfo[sliceIdx].sliceSize, //size
638            1,        //num_elements
639            mFrameData + mSliceInfo[sliceIdx].sliceStartOffset,
640            &mSlicebufferID);
641        CHECK_VA_STATUS("vaCreateSliceDataBuffer");
642
643        data->pic_parse_buffer->frame_buf_id = mSlicebufferID;
644        data->pic_parse_buffer->slice_headers_buf_id = sliceheaderbufferID;
645        data->pic_parse_buffer->frame_size = mSliceInfo[sliceIdx].sliceLength;
646        data->pic_parse_buffer->slice_headers_size = MAX_SLICEHEADER_BUFFER_SIZE;
647        data->pic_parse_buffer->nalu_header.value = mSliceInfo[sliceIdx].sliceHeaderByte;
648        data->pic_parse_buffer->slice_offset = mSliceInfo[sliceIdx].sliceByteOffset;
649
650#if 0
651        VTRACE("data->pic_parse_buffer->slice_offset = 0x%x", data->pic_parse_buffer->slice_offset);
652        VTRACE("pic_parse_buffer->nalu_header.value = %x", data->pic_parse_buffer->nalu_header.value = mSliceInfo[sliceIdx].sliceHeaderByte);
653        VTRACE("flags.bits.frame_mbs_only_flag = %d", data->pic_parse_buffer->flags.bits.frame_mbs_only_flag);
654        VTRACE("flags.bits.pic_order_present_flag = %d", data->pic_parse_buffer->flags.bits.pic_order_present_flag);
655        VTRACE("flags.bits.delta_pic_order_always_zero_flag = %d", data->pic_parse_buffer->flags.bits.delta_pic_order_always_zero_flag);
656        VTRACE("flags.bits.redundant_pic_cnt_present_flag = %d", data->pic_parse_buffer->flags.bits.redundant_pic_cnt_present_flag);
657        VTRACE("flags.bits.weighted_pred_flag = %d", data->pic_parse_buffer->flags.bits.weighted_pred_flag);
658        VTRACE("flags.bits.entropy_coding_mode_flag = %d", data->pic_parse_buffer->flags.bits.entropy_coding_mode_flag);
659        VTRACE("flags.bits.deblocking_filter_control_present_flag = %d", data->pic_parse_buffer->flags.bits.deblocking_filter_control_present_flag);
660        VTRACE("flags.bits.weighted_bipred_idc = %d", data->pic_parse_buffer->flags.bits.weighted_bipred_idc);
661        VTRACE("pic_parse_buffer->expected_pic_parameter_set_id = %d", data->pic_parse_buffer->expected_pic_parameter_set_id);
662        VTRACE("pic_parse_buffer->num_slice_groups_minus1 = %d", data->pic_parse_buffer->num_slice_groups_minus1);
663        VTRACE("pic_parse_buffer->chroma_format_idc = %d", data->pic_parse_buffer->chroma_format_idc);
664        VTRACE("pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4 = %d", data->pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4);
665        VTRACE("pic_parse_buffer->pic_order_cnt_type = %d", data->pic_parse_buffer->pic_order_cnt_type);
666        VTRACE("pic_parse_buffer->residual_colour_transform_flag = %d", data->pic_parse_buffer->residual_colour_transform_flag);
667        VTRACE("pic_parse_buffer->num_ref_idc_l0_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l0_active_minus1);
668        VTRACE("pic_parse_buffer->num_ref_idc_l1_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l1_active_minus1);
669#endif
670        vaStatus = vaCreateBuffer(
671            mVADisplay,
672            mVAContext,
673            VAParsePictureParameterBufferType,
674            sizeof(VAParsePictureParameterBuffer),
675            1,
676            data->pic_parse_buffer,
677            &pictureparameterparsingbufferID);
678        CHECK_VA_STATUS("vaCreatePictureParameterParsingBuffer");
679
680        vaStatus = vaRenderPicture(
681            mVADisplay,
682            mVAContext,
683            &pictureparameterparsingbufferID,
684            1);
685        CHECK_VA_STATUS("vaRenderPicture");
686
687        vaStatus = vaMapBuffer(
688            mVADisplay,
689            sliceheaderbufferID,
690            &sliceheaderbuf);
691        CHECK_VA_STATUS("vaMapBuffer");
692
693        size = *(uint32 *)((uint8 *)sliceheaderbuf + 4) + 4;
694        VTRACE("slice header size = 0x%x, offset = 0x%x", size, offset);
695        if (offset + size <= MAX_SLICEHEADER_BUFFER_SIZE - 4) {
696            memcpy(mCachedHeader+offset, sliceheaderbuf, size);
697            offset += size;
698        } else {
699            WTRACE("Cached slice header is not big enough!");
700        }
701        vaStatus = vaUnmapBuffer(
702            mVADisplay,
703            sliceheaderbufferID);
704        CHECK_VA_STATUS("vaUnmapBuffer");
705    }
706    memset(mCachedHeader + offset, 0xFF, 4);
707    status = updateSliceParameter(data,mCachedHeader);
708    CHECK_STATUS("processSliceHeader");
709    return DECODE_SUCCESS;
710}
711
712
713Decode_Status VideoDecoderAVCSecure::updateSliceParameter(vbp_data_h264 *data, void *sliceheaderbuf) {
714    VTRACE("VideoDecoderAVCSecure::updateSliceParameter");
715    Decode_Status status;
716    status =  VideoDecoderBase::updateBuffer(
717            (uint8_t *)sliceheaderbuf,
718            MAX_SLICEHEADER_BUFFER_SIZE,
719            (void**)&data);
720    CHECK_STATUS("updateBuffer");
721    return DECODE_SUCCESS;
722}
723
724Decode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {
725    Decode_Status status;
726    VAStatus vaStatus;
727    uint32_t bufferIDCount = 0;
728    // maximum 3 buffers to render a slice: picture parameter, IQMatrix, slice parameter
729    VABufferID bufferIDs[3];
730
731    vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
732    vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
733    VAPictureParameterBufferH264 *picParam = picData->pic_parms;
734    VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);
735    uint32_t slice_data_size = 0;
736    uint8_t* slice_data_addr = NULL;
737
738    if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
739        // either condition indicates start of a new frame
740        if (sliceParam->first_mb_in_slice != 0) {
741            WTRACE("The first slice is lost.");
742        }
743        VTRACE("Current frameidx = %d", mFrameIdx++);
744        // Update  the reference frames and surface IDs for DPB and current frame
745        status = updateDPB(picParam);
746        CHECK_STATUS("updateDPB");
747
748        //We have to provide a hacked DPB rather than complete DPB for libva as workaround
749        status = updateReferenceFrames(picData);
750        CHECK_STATUS("updateReferenceFrames");
751
752        mDecodingFrame = true;
753
754        vaStatus = vaCreateBuffer(
755            mVADisplay,
756            mVAContext,
757            VAPictureParameterBufferType,
758            sizeof(VAPictureParameterBufferH264),
759            1,
760            picParam,
761            &bufferIDs[bufferIDCount]);
762        CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
763        bufferIDCount++;
764
765        vaStatus = vaCreateBuffer(
766            mVADisplay,
767            mVAContext,
768            VAIQMatrixBufferType,
769            sizeof(VAIQMatrixBufferH264),
770            1,
771            data->IQ_matrix_buf,
772            &bufferIDs[bufferIDCount]);
773        CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
774        bufferIDCount++;
775    }
776
777    status = setReference(sliceParam);
778    CHECK_STATUS("setReference");
779
780    if (mModularMode) {
781        if (mIsEncryptData) {
782            sliceParam->slice_data_size = mSliceInfo[sliceIndex].sliceSize;
783            slice_data_size = mSliceInfo[sliceIndex].sliceSize;
784            slice_data_addr = mFrameData + mSliceInfo[sliceIndex].sliceStartOffset;
785        } else {
786            slice_data_size = sliceData->slice_size;
787            slice_data_addr = sliceData->buffer_addr + sliceData->slice_offset;
788        }
789    } else {
790        sliceParam->slice_data_size = mFrameSize;
791        slice_data_size = mFrameSize;
792        slice_data_addr = mFrameData;
793    }
794
795    vaStatus = vaCreateBuffer(
796        mVADisplay,
797        mVAContext,
798        VASliceParameterBufferType,
799        sizeof(VASliceParameterBufferH264),
800        1,
801        sliceParam,
802        &bufferIDs[bufferIDCount]);
803    CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
804    bufferIDCount++;
805
806    vaStatus = vaRenderPicture(
807        mVADisplay,
808        mVAContext,
809        bufferIDs,
810        bufferIDCount);
811    CHECK_VA_STATUS("vaRenderPicture");
812
813    VABufferID slicebufferID;
814
815    vaStatus = vaCreateBuffer(
816        mVADisplay,
817        mVAContext,
818        VASliceDataBufferType,
819        slice_data_size, //size
820        1,        //num_elements
821        slice_data_addr,
822        &slicebufferID);
823    CHECK_VA_STATUS("vaCreateSliceDataBuffer");
824
825    vaStatus = vaRenderPicture(
826        mVADisplay,
827        mVAContext,
828        &slicebufferID,
829        1);
830    CHECK_VA_STATUS("vaRenderPicture");
831
832    return DECODE_SUCCESS;
833
834}
835
836Decode_Status VideoDecoderAVCSecure::getCodecSpecificConfigs(
837    VAProfile profile, VAConfigID *config)
838{
839    VAStatus vaStatus;
840    VAConfigAttrib attrib[2];
841
842    if (config == NULL) {
843        ETRACE("Invalid parameter!");
844        return DECODE_FAIL;
845    }
846
847    attrib[0].type = VAConfigAttribRTFormat;
848    attrib[0].value = VA_RT_FORMAT_YUV420;
849    attrib[1].type = VAConfigAttribDecSliceMode;
850    attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
851    if (mModularMode) {
852        attrib[1].value = VA_DEC_SLICE_MODE_SUBSAMPLE;
853    }
854
855    vaStatus = vaCreateConfig(
856            mVADisplay,
857            profile,
858            VAEntrypointVLD,
859            &attrib[0],
860            2,
861            config);
862    CHECK_VA_STATUS("vaCreateConfig");
863
864    return DECODE_SUCCESS;
865}
866