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