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