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