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