• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include <va/va.h>
18 #include "VideoDecoderBase.h"
19 #include "VideoDecoderAVC.h"
20 #include "VideoDecoderTrace.h"
21 #include "vbp_loader.h"
22 #include "VideoDecoderAVCSecure.h"
23 #include "VideoFrameInfo.h"
24 
25 #define MAX_SLICEHEADER_BUFFER_SIZE 4096
26 #define STARTCODE_PREFIX_LEN        3
27 #define NALU_TYPE_MASK              0x1F
28 #define MAX_NALU_HEADER_BUFFER      8192
29 static const uint8_t startcodePrefix[STARTCODE_PREFIX_LEN] = {0x00, 0x00, 0x01};
30 
31 /* H264 start code values */
32 typedef enum _h264_nal_unit_type
33 {
34     h264_NAL_UNIT_TYPE_unspecified = 0,
35     h264_NAL_UNIT_TYPE_SLICE,
36     h264_NAL_UNIT_TYPE_DPA,
37     h264_NAL_UNIT_TYPE_DPB,
38     h264_NAL_UNIT_TYPE_DPC,
39     h264_NAL_UNIT_TYPE_IDR,
40     h264_NAL_UNIT_TYPE_SEI,
41     h264_NAL_UNIT_TYPE_SPS,
42     h264_NAL_UNIT_TYPE_PPS,
43     h264_NAL_UNIT_TYPE_Acc_unit_delimiter,
44     h264_NAL_UNIT_TYPE_EOSeq,
45     h264_NAL_UNIT_TYPE_EOstream,
46     h264_NAL_UNIT_TYPE_filler_data,
47     h264_NAL_UNIT_TYPE_SPS_extension,
48     h264_NAL_UNIT_TYPE_ACP = 19,
49     h264_NAL_UNIT_TYPE_Slice_extension = 20
50 } h264_nal_unit_type_t;
51 
VideoDecoderAVCSecure(const char * mimeType)52 VideoDecoderAVCSecure::VideoDecoderAVCSecure(const char *mimeType)
53     : VideoDecoderAVC(mimeType){
54     mFrameSize     = 0;
55     mFrameData     = NULL;
56     mIsEncryptData = 0;
57     mClearData     = NULL;
58     mCachedHeader  = NULL;
59     setParserType(VBP_H264SECURE);
60     mFrameIdx = 0;
61     mModularMode = 0;
62     mSliceNum = 0;
63 }
64 
start(VideoConfigBuffer * buffer)65 Decode_Status VideoDecoderAVCSecure::start(VideoConfigBuffer *buffer) {
66     VTRACE("VideoDecoderAVCSecure::start");
67 
68     Decode_Status status = VideoDecoderAVC::start(buffer);
69     if (status != DECODE_SUCCESS) {
70         return status;
71     }
72 
73     mClearData = new uint8_t [MAX_NALU_HEADER_BUFFER];
74     if (mClearData == NULL) {
75         ETRACE("Failed to allocate memory for mClearData");
76         return DECODE_MEMORY_FAIL;
77     }
78 
79     mCachedHeader= new uint8_t [MAX_SLICEHEADER_BUFFER_SIZE];
80     if (mCachedHeader == NULL) {
81         ETRACE("Failed to allocate memory for mCachedHeader");
82         return DECODE_MEMORY_FAIL;
83     }
84 
85     return status;
86 }
87 
stop(void)88 void VideoDecoderAVCSecure::stop(void) {
89     VTRACE("VideoDecoderAVCSecure::stop");
90     VideoDecoderAVC::stop();
91 
92     if (mClearData) {
93         delete [] mClearData;
94         mClearData = NULL;
95     }
96 
97     if (mCachedHeader) {
98         delete [] mCachedHeader;
99         mCachedHeader = NULL;
100     }
101 }
processModularInputBuffer(VideoDecodeBuffer * buffer,vbp_data_h264 ** data)102 Decode_Status VideoDecoderAVCSecure::processModularInputBuffer(VideoDecodeBuffer *buffer, vbp_data_h264 **data)
103 {
104     VTRACE("processModularInputBuffer +++");
105     Decode_Status status;
106     int32_t clear_data_size = 0;
107     uint8_t *clear_data = NULL;
108 
109     int32_t nalu_num = 0;
110     uint8_t nalu_type = 0;
111     int32_t nalu_offset = 0;
112     uint32_t nalu_size = 0;
113     uint8_t naluType = 0;
114     uint8_t *nalu_data = NULL;
115     uint32_t sliceidx = 0;
116 
117     frame_info_t *pFrameInfo = NULL;
118     mSliceNum = 0;
119     memset(&mSliceInfo, 0, sizeof(mSliceInfo));
120     mIsEncryptData = 0;
121 
122     if (buffer->flag & IS_SECURE_DATA) {
123         VTRACE("Decoding protected video ...");
124         pFrameInfo = (frame_info_t *) buffer->data;
125         if (pFrameInfo == NULL) {
126             ETRACE("Invalid parameter: pFrameInfo is NULL!");
127             return DECODE_MEMORY_FAIL;
128         }
129 
130         mFrameData = pFrameInfo->data;
131         mFrameSize = pFrameInfo->size;
132         VTRACE("mFrameData = %p, mFrameSize = %d", mFrameData, mFrameSize);
133 
134         nalu_num  = pFrameInfo->num_nalus;
135         VTRACE("nalu_num = %d", nalu_num);
136 
137         if (nalu_num <= 0 || nalu_num >= MAX_NUM_NALUS) {
138             ETRACE("Invalid parameter: nalu_num = %d", nalu_num);
139             return DECODE_MEMORY_FAIL;
140         }
141 
142         for (int32_t i = 0; i < nalu_num; i++) {
143 
144             nalu_size = pFrameInfo->nalus[i].length;
145             nalu_type = pFrameInfo->nalus[i].type;
146             nalu_offset = pFrameInfo->nalus[i].offset;
147             nalu_data = pFrameInfo->nalus[i].data;
148             naluType  = nalu_type & NALU_TYPE_MASK;
149 
150             VTRACE("nalu_type = 0x%x, nalu_size = %d, nalu_offset = 0x%x", nalu_type, nalu_size, nalu_offset);
151 
152             if (naluType >= h264_NAL_UNIT_TYPE_SLICE && naluType <= h264_NAL_UNIT_TYPE_IDR) {
153 
154                 mIsEncryptData = 1;
155                 VTRACE("slice idx = %d", sliceidx);
156                 mSliceInfo[sliceidx].sliceHeaderByte = nalu_type;
157                 mSliceInfo[sliceidx].sliceStartOffset = (nalu_offset >> 4) << 4;
158                 mSliceInfo[sliceidx].sliceByteOffset = nalu_offset - mSliceInfo[sliceidx].sliceStartOffset;
159                 mSliceInfo[sliceidx].sliceLength = mSliceInfo[sliceidx].sliceByteOffset + nalu_size;
160                 mSliceInfo[sliceidx].sliceSize = (mSliceInfo[sliceidx].sliceByteOffset + nalu_size + 0xF) & ~0xF;
161                 VTRACE("sliceHeaderByte = 0x%x", mSliceInfo[sliceidx].sliceHeaderByte);
162                 VTRACE("sliceStartOffset = %d", mSliceInfo[sliceidx].sliceStartOffset);
163                 VTRACE("sliceByteOffset = %d", mSliceInfo[sliceidx].sliceByteOffset);
164                 VTRACE("sliceSize = %d", mSliceInfo[sliceidx].sliceSize);
165                 VTRACE("sliceLength = %d", mSliceInfo[sliceidx].sliceLength);
166 
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 
processClassicInputBuffer(VideoDecodeBuffer * buffer,vbp_data_h264 ** data)218 Decode_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 
decode(VideoDecodeBuffer * buffer)297 Decode_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 
decodeFrame(VideoDecodeBuffer * buffer,vbp_data_h264 * data)342 Decode_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         parseModularSliceHeader(data);
385     }
386     else {
387         parseClassicSliceHeader(data);
388     }
389 
390     if (status != DECODE_SUCCESS) {
391         endDecodingFrame(true);
392         return status;
393     }
394 
395     status = beginDecodingFrame(data);
396     CHECK_STATUS("beginDecodingFrame");
397 
398    // finish decoding the last frame
399     status = endDecodingFrame(false);
400     CHECK_STATUS("endDecodingFrame");
401 
402     if (isNewFrame(data, lastPTS == mCurrentPTS) == 0) {
403         ETRACE("Can't handle interlaced frames yet");
404         return DECODE_FAIL;
405     }
406 
407     return DECODE_SUCCESS;
408 }
409 
beginDecodingFrame(vbp_data_h264 * data)410 Decode_Status VideoDecoderAVCSecure::beginDecodingFrame(vbp_data_h264 *data) {
411     VTRACE("VideoDecoderAVCSecure::beginDecodingFrame");
412     Decode_Status status;
413     VAPictureH264 *picture = &(data->pic_data[0].pic_parms->CurrPic);
414     if ((picture->flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
415         (picture->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
416         mAcquiredBuffer->referenceFrame = true;
417     } else {
418         mAcquiredBuffer->referenceFrame = false;
419     }
420 
421     if (picture->flags & VA_PICTURE_H264_TOP_FIELD) {
422         mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD | VA_TOP_FIELD;
423     } else {
424         mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
425     }
426 
427     mAcquiredBuffer->renderBuffer.flag = 0;
428     mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
429     mAcquiredBuffer->pictureOrder = getPOC(picture);
430 
431     if (mSizeChanged) {
432         mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE;
433         mSizeChanged = false;
434     }
435 
436     status  = continueDecodingFrame(data);
437     return status;
438 }
439 
continueDecodingFrame(vbp_data_h264 * data)440 Decode_Status VideoDecoderAVCSecure::continueDecodingFrame(vbp_data_h264 *data) {
441     VTRACE("VideoDecoderAVCSecure::continueDecodingFrame");
442     Decode_Status status;
443     vbp_picture_data_h264 *picData = data->pic_data;
444 
445     if (mAcquiredBuffer == NULL || mAcquiredBuffer->renderBuffer.surface == VA_INVALID_SURFACE) {
446         ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
447         return DECODE_FAIL;
448     }
449     VTRACE("data->num_pictures = %d", data->num_pictures);
450     for (uint32_t picIndex = 0; picIndex < data->num_pictures; picIndex++, picData++) {
451         if (picData == NULL || picData->pic_parms == NULL || picData->slc_data == NULL || picData->num_slices == 0) {
452             return DECODE_PARSER_FAIL;
453         }
454 
455         if (picIndex > 0 &&
456             (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
457             ETRACE("Packed frame is not supported yet!");
458             return DECODE_FAIL;
459         }
460         VTRACE("picData->num_slices = %d", picData->num_slices);
461         for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
462             status = decodeSlice(data, picIndex, sliceIndex);
463             if (status != DECODE_SUCCESS) {
464                 endDecodingFrame(true);
465                 // remove current frame from DPB as it can't be decoded.
466                 removeReferenceFromDPB(picData->pic_parms);
467                 return status;
468             }
469         }
470     }
471     mDecodingFrame = true;
472 
473     return DECODE_SUCCESS;
474 }
475 
parseClassicSliceHeader(vbp_data_h264 * data)476 Decode_Status VideoDecoderAVCSecure::parseClassicSliceHeader(vbp_data_h264 *data) {
477     Decode_Status status;
478     VAStatus vaStatus;
479 
480     VABufferID sliceheaderbufferID;
481     VABufferID pictureparameterparsingbufferID;
482     VABufferID mSlicebufferID;
483 
484     if (mFrameSize <= 0) {
485         return DECODE_SUCCESS;
486     }
487     vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
488     CHECK_VA_STATUS("vaBeginPicture");
489 
490     vaStatus = vaCreateBuffer(
491         mVADisplay,
492         mVAContext,
493         VAParseSliceHeaderGroupBufferType,
494         MAX_SLICEHEADER_BUFFER_SIZE,
495         1,
496         NULL,
497         &sliceheaderbufferID);
498     CHECK_VA_STATUS("vaCreateSliceHeaderGroupBuffer");
499 
500     void *sliceheaderbuf;
501     vaStatus = vaMapBuffer(
502         mVADisplay,
503         sliceheaderbufferID,
504         &sliceheaderbuf);
505     CHECK_VA_STATUS("vaMapBuffer");
506 
507     memset(sliceheaderbuf, 0, MAX_SLICEHEADER_BUFFER_SIZE);
508 
509     vaStatus = vaUnmapBuffer(
510         mVADisplay,
511         sliceheaderbufferID);
512     CHECK_VA_STATUS("vaUnmapBuffer");
513 
514 
515     vaStatus = vaCreateBuffer(
516         mVADisplay,
517         mVAContext,
518         VASliceDataBufferType,
519         mFrameSize, //size
520         1,        //num_elements
521         mFrameData,
522         &mSlicebufferID);
523     CHECK_VA_STATUS("vaCreateSliceDataBuffer");
524 
525     data->pic_parse_buffer->frame_buf_id = mSlicebufferID;
526     data->pic_parse_buffer->slice_headers_buf_id = sliceheaderbufferID;
527     data->pic_parse_buffer->frame_size = mFrameSize;
528     data->pic_parse_buffer->slice_headers_size = MAX_SLICEHEADER_BUFFER_SIZE;
529 
530 #if 0
531 
532     VTRACE("flags.bits.frame_mbs_only_flag = %d", data->pic_parse_buffer->flags.bits.frame_mbs_only_flag);
533     VTRACE("flags.bits.pic_order_present_flag = %d", data->pic_parse_buffer->flags.bits.pic_order_present_flag);
534     VTRACE("flags.bits.delta_pic_order_always_zero_flag = %d", data->pic_parse_buffer->flags.bits.delta_pic_order_always_zero_flag);
535     VTRACE("flags.bits.redundant_pic_cnt_present_flag = %d", data->pic_parse_buffer->flags.bits.redundant_pic_cnt_present_flag);
536     VTRACE("flags.bits.weighted_pred_flag = %d", data->pic_parse_buffer->flags.bits.weighted_pred_flag);
537     VTRACE("flags.bits.entropy_coding_mode_flag = %d", data->pic_parse_buffer->flags.bits.entropy_coding_mode_flag);
538     VTRACE("flags.bits.deblocking_filter_control_present_flag = %d", data->pic_parse_buffer->flags.bits.deblocking_filter_control_present_flag);
539     VTRACE("flags.bits.weighted_bipred_idc = %d", data->pic_parse_buffer->flags.bits.weighted_bipred_idc);
540 
541     VTRACE("pic_parse_buffer->expected_pic_parameter_set_id = %d", data->pic_parse_buffer->expected_pic_parameter_set_id);
542     VTRACE("pic_parse_buffer->num_slice_groups_minus1 = %d", data->pic_parse_buffer->num_slice_groups_minus1);
543     VTRACE("pic_parse_buffer->chroma_format_idc = %d", data->pic_parse_buffer->chroma_format_idc);
544     VTRACE("pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4 = %d", data->pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4);
545     VTRACE("pic_parse_buffer->pic_order_cnt_type = %d", data->pic_parse_buffer->pic_order_cnt_type);
546     VTRACE("pic_parse_buffer->residual_colour_transform_flag = %d", data->pic_parse_buffer->residual_colour_transform_flag);
547     VTRACE("pic_parse_buffer->num_ref_idc_l0_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l0_active_minus1);
548     VTRACE("pic_parse_buffer->num_ref_idc_l1_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l1_active_minus1);
549 #endif
550 
551     vaStatus = vaCreateBuffer(
552         mVADisplay,
553         mVAContext,
554         VAParsePictureParameterBufferType,
555         sizeof(VAParsePictureParameterBuffer),
556         1,
557         data->pic_parse_buffer,
558         &pictureparameterparsingbufferID);
559     CHECK_VA_STATUS("vaCreatePictureParameterParsingBuffer");
560 
561     vaStatus = vaRenderPicture(
562         mVADisplay,
563         mVAContext,
564         &pictureparameterparsingbufferID,
565         1);
566     CHECK_VA_STATUS("vaRenderPicture");
567 
568     vaStatus = vaMapBuffer(
569         mVADisplay,
570         sliceheaderbufferID,
571         &sliceheaderbuf);
572     CHECK_VA_STATUS("vaMapBuffer");
573 
574     status = updateSliceParameter(data,sliceheaderbuf);
575     CHECK_STATUS("processSliceHeader");
576 
577     vaStatus = vaUnmapBuffer(
578         mVADisplay,
579         sliceheaderbufferID);
580     CHECK_VA_STATUS("vaUnmapBuffer");
581 
582     return DECODE_SUCCESS;
583 }
584 
parseModularSliceHeader(vbp_data_h264 * data)585 Decode_Status VideoDecoderAVCSecure::parseModularSliceHeader(vbp_data_h264 *data) {
586     Decode_Status status;
587     VAStatus vaStatus;
588 
589     VABufferID sliceheaderbufferID;
590     VABufferID pictureparameterparsingbufferID;
591     VABufferID mSlicebufferID;
592     int32_t sliceIdx;
593 
594     vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
595     CHECK_VA_STATUS("vaBeginPicture");
596 
597     if (mFrameSize <= 0 || mSliceNum <=0) {
598         return DECODE_SUCCESS;
599     }
600     void *sliceheaderbuf;
601     memset(mCachedHeader, 0, MAX_SLICEHEADER_BUFFER_SIZE);
602     int32_t offset = 0;
603     int32_t size = 0;
604 
605     for (sliceIdx = 0; sliceIdx < mSliceNum; sliceIdx++) {
606         vaStatus = vaCreateBuffer(
607             mVADisplay,
608             mVAContext,
609             VAParseSliceHeaderGroupBufferType,
610             MAX_SLICEHEADER_BUFFER_SIZE,
611             1,
612             NULL,
613             &sliceheaderbufferID);
614         CHECK_VA_STATUS("vaCreateSliceHeaderGroupBuffer");
615 
616         vaStatus = vaMapBuffer(
617             mVADisplay,
618             sliceheaderbufferID,
619             &sliceheaderbuf);
620         CHECK_VA_STATUS("vaMapBuffer");
621 
622         memset(sliceheaderbuf, 0, MAX_SLICEHEADER_BUFFER_SIZE);
623 
624         vaStatus = vaUnmapBuffer(
625             mVADisplay,
626             sliceheaderbufferID);
627         CHECK_VA_STATUS("vaUnmapBuffer");
628 
629         vaStatus = vaCreateBuffer(
630             mVADisplay,
631             mVAContext,
632             VASliceDataBufferType,
633             mSliceInfo[sliceIdx].sliceSize, //size
634             1,        //num_elements
635             mFrameData + mSliceInfo[sliceIdx].sliceStartOffset,
636             &mSlicebufferID);
637         CHECK_VA_STATUS("vaCreateSliceDataBuffer");
638 
639         data->pic_parse_buffer->frame_buf_id = mSlicebufferID;
640         data->pic_parse_buffer->slice_headers_buf_id = sliceheaderbufferID;
641         data->pic_parse_buffer->frame_size = mSliceInfo[sliceIdx].sliceLength;
642         data->pic_parse_buffer->slice_headers_size = MAX_SLICEHEADER_BUFFER_SIZE;
643         data->pic_parse_buffer->nalu_header.value = mSliceInfo[sliceIdx].sliceHeaderByte;
644         data->pic_parse_buffer->slice_offset = mSliceInfo[sliceIdx].sliceByteOffset;
645 
646 #if 0
647         VTRACE("data->pic_parse_buffer->slice_offset = 0x%x", data->pic_parse_buffer->slice_offset);
648         VTRACE("pic_parse_buffer->nalu_header.value = %x", data->pic_parse_buffer->nalu_header.value = mSliceInfo[sliceIdx].sliceHeaderByte);
649         VTRACE("flags.bits.frame_mbs_only_flag = %d", data->pic_parse_buffer->flags.bits.frame_mbs_only_flag);
650         VTRACE("flags.bits.pic_order_present_flag = %d", data->pic_parse_buffer->flags.bits.pic_order_present_flag);
651         VTRACE("flags.bits.delta_pic_order_always_zero_flag = %d", data->pic_parse_buffer->flags.bits.delta_pic_order_always_zero_flag);
652         VTRACE("flags.bits.redundant_pic_cnt_present_flag = %d", data->pic_parse_buffer->flags.bits.redundant_pic_cnt_present_flag);
653         VTRACE("flags.bits.weighted_pred_flag = %d", data->pic_parse_buffer->flags.bits.weighted_pred_flag);
654         VTRACE("flags.bits.entropy_coding_mode_flag = %d", data->pic_parse_buffer->flags.bits.entropy_coding_mode_flag);
655         VTRACE("flags.bits.deblocking_filter_control_present_flag = %d", data->pic_parse_buffer->flags.bits.deblocking_filter_control_present_flag);
656         VTRACE("flags.bits.weighted_bipred_idc = %d", data->pic_parse_buffer->flags.bits.weighted_bipred_idc);
657         VTRACE("pic_parse_buffer->expected_pic_parameter_set_id = %d", data->pic_parse_buffer->expected_pic_parameter_set_id);
658         VTRACE("pic_parse_buffer->num_slice_groups_minus1 = %d", data->pic_parse_buffer->num_slice_groups_minus1);
659         VTRACE("pic_parse_buffer->chroma_format_idc = %d", data->pic_parse_buffer->chroma_format_idc);
660         VTRACE("pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4 = %d", data->pic_parse_buffer->log2_max_pic_order_cnt_lsb_minus4);
661         VTRACE("pic_parse_buffer->pic_order_cnt_type = %d", data->pic_parse_buffer->pic_order_cnt_type);
662         VTRACE("pic_parse_buffer->residual_colour_transform_flag = %d", data->pic_parse_buffer->residual_colour_transform_flag);
663         VTRACE("pic_parse_buffer->num_ref_idc_l0_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l0_active_minus1);
664         VTRACE("pic_parse_buffer->num_ref_idc_l1_active_minus1 = %d", data->pic_parse_buffer->num_ref_idc_l1_active_minus1);
665 #endif
666         vaStatus = vaCreateBuffer(
667             mVADisplay,
668             mVAContext,
669             VAParsePictureParameterBufferType,
670             sizeof(VAParsePictureParameterBuffer),
671             1,
672             data->pic_parse_buffer,
673             &pictureparameterparsingbufferID);
674         CHECK_VA_STATUS("vaCreatePictureParameterParsingBuffer");
675 
676         vaStatus = vaRenderPicture(
677             mVADisplay,
678             mVAContext,
679             &pictureparameterparsingbufferID,
680             1);
681         CHECK_VA_STATUS("vaRenderPicture");
682 
683         vaStatus = vaMapBuffer(
684             mVADisplay,
685             sliceheaderbufferID,
686             &sliceheaderbuf);
687         CHECK_VA_STATUS("vaMapBuffer");
688 
689         size = *(uint32 *)((uint8 *)sliceheaderbuf + 4) + 4;
690         VTRACE("slice header size = 0x%x, offset = 0x%x", size, offset);
691         if (offset + size <= MAX_SLICEHEADER_BUFFER_SIZE - 4) {
692             memcpy(mCachedHeader+offset, sliceheaderbuf, size);
693             offset += size;
694         } else {
695             WTRACE("Cached slice header is not big enough!");
696         }
697         vaStatus = vaUnmapBuffer(
698             mVADisplay,
699             sliceheaderbufferID);
700         CHECK_VA_STATUS("vaUnmapBuffer");
701     }
702     memset(mCachedHeader + offset, 0xFF, 4);
703     status = updateSliceParameter(data,mCachedHeader);
704     CHECK_STATUS("processSliceHeader");
705     return DECODE_SUCCESS;
706 }
707 
708 
updateSliceParameter(vbp_data_h264 * data,void * sliceheaderbuf)709 Decode_Status VideoDecoderAVCSecure::updateSliceParameter(vbp_data_h264 *data, void *sliceheaderbuf) {
710     VTRACE("VideoDecoderAVCSecure::updateSliceParameter");
711     Decode_Status status;
712     status =  VideoDecoderBase::updateBuffer(
713             (uint8_t *)sliceheaderbuf,
714             MAX_SLICEHEADER_BUFFER_SIZE,
715             (void**)&data);
716     CHECK_STATUS("updateBuffer");
717     return DECODE_SUCCESS;
718 }
719 
decodeSlice(vbp_data_h264 * data,uint32_t picIndex,uint32_t sliceIndex)720 Decode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {
721     Decode_Status status;
722     VAStatus vaStatus;
723     uint32_t bufferIDCount = 0;
724     // maximum 3 buffers to render a slice: picture parameter, IQMatrix, slice parameter
725     VABufferID bufferIDs[3];
726 
727     vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
728     vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
729     VAPictureParameterBufferH264 *picParam = picData->pic_parms;
730     VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);
731     uint32_t slice_data_size = 0;
732     uint8_t* slice_data_addr = NULL;
733 
734     if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
735         // either condition indicates start of a new frame
736         if (sliceParam->first_mb_in_slice != 0) {
737             WTRACE("The first slice is lost.");
738         }
739         VTRACE("Current frameidx = %d", mFrameIdx++);
740         // Update  the reference frames and surface IDs for DPB and current frame
741         status = updateDPB(picParam);
742         CHECK_STATUS("updateDPB");
743 
744         //We have to provide a hacked DPB rather than complete DPB for libva as workaround
745         status = updateReferenceFrames(picData);
746         CHECK_STATUS("updateReferenceFrames");
747 
748         mDecodingFrame = true;
749 
750         vaStatus = vaCreateBuffer(
751             mVADisplay,
752             mVAContext,
753             VAPictureParameterBufferType,
754             sizeof(VAPictureParameterBufferH264),
755             1,
756             picParam,
757             &bufferIDs[bufferIDCount]);
758         CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
759         bufferIDCount++;
760 
761         vaStatus = vaCreateBuffer(
762             mVADisplay,
763             mVAContext,
764             VAIQMatrixBufferType,
765             sizeof(VAIQMatrixBufferH264),
766             1,
767             data->IQ_matrix_buf,
768             &bufferIDs[bufferIDCount]);
769         CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
770         bufferIDCount++;
771     }
772 
773     status = setReference(sliceParam);
774     CHECK_STATUS("setReference");
775 
776     if (mModularMode) {
777         if (mIsEncryptData) {
778             sliceParam->slice_data_size = mSliceInfo[sliceIndex].sliceSize;
779             slice_data_size = mSliceInfo[sliceIndex].sliceSize;
780             slice_data_addr = mFrameData + mSliceInfo[sliceIndex].sliceStartOffset;
781         } else {
782             slice_data_size = sliceData->slice_size;
783             slice_data_addr = sliceData->buffer_addr + sliceData->slice_offset;
784         }
785     } else {
786         sliceParam->slice_data_size = mFrameSize;
787         slice_data_size = mFrameSize;
788         slice_data_addr = mFrameData;
789     }
790 
791     vaStatus = vaCreateBuffer(
792         mVADisplay,
793         mVAContext,
794         VASliceParameterBufferType,
795         sizeof(VASliceParameterBufferH264),
796         1,
797         sliceParam,
798         &bufferIDs[bufferIDCount]);
799     CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
800     bufferIDCount++;
801 
802     vaStatus = vaRenderPicture(
803         mVADisplay,
804         mVAContext,
805         bufferIDs,
806         bufferIDCount);
807     CHECK_VA_STATUS("vaRenderPicture");
808 
809     VABufferID slicebufferID;
810 
811     vaStatus = vaCreateBuffer(
812         mVADisplay,
813         mVAContext,
814         VASliceDataBufferType,
815         slice_data_size, //size
816         1,        //num_elements
817         slice_data_addr,
818         &slicebufferID);
819     CHECK_VA_STATUS("vaCreateSliceDataBuffer");
820 
821     vaStatus = vaRenderPicture(
822         mVADisplay,
823         mVAContext,
824         &slicebufferID,
825         1);
826     CHECK_VA_STATUS("vaRenderPicture");
827 
828     return DECODE_SUCCESS;
829 
830 }
831 
getCodecSpecificConfigs(VAProfile profile,VAConfigID * config)832 Decode_Status VideoDecoderAVCSecure::getCodecSpecificConfigs(
833     VAProfile profile, VAConfigID *config)
834 {
835     VAStatus vaStatus;
836     VAConfigAttrib attrib[2];
837 
838     if (config == NULL) {
839         ETRACE("Invalid parameter!");
840         return DECODE_FAIL;
841     }
842 
843     attrib[0].type = VAConfigAttribRTFormat;
844     attrib[0].value = VA_RT_FORMAT_YUV420;
845     attrib[1].type = VAConfigAttribDecSliceMode;
846     attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
847     if (mModularMode) {
848         attrib[1].value = VA_DEC_SLICE_MODE_SUBSAMPLE;
849     }
850 
851     vaStatus = vaCreateConfig(
852             mVADisplay,
853             profile,
854             VAEntrypointVLD,
855             &attrib[0],
856             2,
857             config);
858     CHECK_VA_STATUS("vaCreateConfig");
859 
860     return DECODE_SUCCESS;
861 }
862