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