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