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