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 "VideoDecoderAVCSecure.h" 18 #include "VideoDecoderTrace.h" 19 #include <string.h> 20 21 22 #define STARTCODE_00 0x00 23 #define STARTCODE_01 0x01 24 #define STARTCODE_PREFIX_LEN 3 25 #define NALU_TYPE_MASK 0x1F 26 27 28 // mask for little endian, to mast the second and fourth bytes in the byte stream 29 #define STARTCODE_MASK0 0xFF000000 //0x00FF0000 30 #define STARTCODE_MASK1 0x0000FF00 //0x000000FF 31 32 33 typedef enum { 34 NAL_UNIT_TYPE_unspecified0 = 0, 35 NAL_UNIT_TYPE_SLICE, 36 NAL_UNIT_TYPE_DPA, 37 NAL_UNIT_TYPE_DPB, 38 NAL_UNIT_TYPE_DPC, 39 NAL_UNIT_TYPE_IDR, 40 NAL_UNIT_TYPE_SEI, 41 NAL_UNIT_TYPE_SPS, 42 NAL_UNIT_TYPE_PPS, 43 NAL_UNIT_TYPE_Acc_unit_delimiter, 44 NAL_UNIT_TYPE_EOSeq, 45 NAL_UNIT_TYPE_EOstream, 46 NAL_UNIT_TYPE_filler_data, 47 NAL_UNIT_TYPE_SPS_extension, 48 NAL_UNIT_TYPE_Reserved14, 49 NAL_UNIT_TYPE_Reserved15, 50 NAL_UNIT_TYPE_Reserved16, 51 NAL_UNIT_TYPE_Reserved17, 52 NAL_UNIT_TYPE_Reserved18, 53 NAL_UNIT_TYPE_ACP, 54 NAL_UNIT_TYPE_Reserved20, 55 NAL_UNIT_TYPE_Reserved21, 56 NAL_UNIT_TYPE_Reserved22, 57 NAL_UNIT_TYPE_Reserved23, 58 NAL_UNIT_TYPE_unspecified24, 59 } NAL_UNIT_TYPE; 60 61 #ifndef min 62 #define min(X, Y) ((X) <(Y) ? (X) : (Y)) 63 #endif 64 65 66 static const uint8_t startcodePrefix[STARTCODE_PREFIX_LEN] = {0x00, 0x00, 0x01}; 67 68 69 VideoDecoderAVCSecure::VideoDecoderAVCSecure(const char *mimeType) 70 : VideoDecoderAVC(mimeType), 71 mNaluHeaderBuffer(NULL), 72 mInputBuffer(NULL) { 73 74 memset(&mMetadata, 0, sizeof(NaluMetadata)); 75 memset(&mByteStream, 0, sizeof(NaluByteStream)); 76 } 77 78 VideoDecoderAVCSecure::~VideoDecoderAVCSecure() { 79 } 80 81 Decode_Status VideoDecoderAVCSecure::start(VideoConfigBuffer *buffer) { 82 Decode_Status status = VideoDecoderAVC::start(buffer); 83 if (status != DECODE_SUCCESS) { 84 return status; 85 } 86 87 mMetadata.naluInfo = new NaluInfo [MAX_NALU_NUMBER]; 88 mByteStream.byteStream = new uint8_t [MAX_NALU_HEADER_BUFFER]; 89 mNaluHeaderBuffer = new uint8_t [MAX_NALU_HEADER_BUFFER]; 90 91 if (mMetadata.naluInfo == NULL || 92 mByteStream.byteStream == NULL || 93 mNaluHeaderBuffer == NULL) { 94 ETRACE("Failed to allocate memory."); 95 // TODO: release all allocated memory 96 return DECODE_MEMORY_FAIL; 97 } 98 return status; 99 } 100 101 void VideoDecoderAVCSecure::stop(void) { 102 VideoDecoderAVC::stop(); 103 104 if (mMetadata.naluInfo) { 105 delete [] mMetadata.naluInfo; 106 mMetadata.naluInfo = NULL; 107 } 108 109 if (mByteStream.byteStream) { 110 delete [] mByteStream.byteStream; 111 mByteStream.byteStream = NULL; 112 } 113 114 if (mNaluHeaderBuffer) { 115 delete [] mNaluHeaderBuffer; 116 mNaluHeaderBuffer = NULL; 117 } 118 } 119 120 Decode_Status VideoDecoderAVCSecure::decode(VideoDecodeBuffer *buffer) { 121 Decode_Status status; 122 int32_t sizeAccumulated = 0; 123 int32_t sizeLeft = 0; 124 uint8_t *pByteStream = NULL; 125 NaluInfo *pNaluInfo = mMetadata.naluInfo; 126 127 if (buffer->flag & IS_SECURE_DATA) { 128 // NALU headers are appended to encrypted video bitstream 129 // |...encrypted video bitstream (16 bytes aligned)...| 4 bytes of header size |...NALU headers..| 130 pByteStream = buffer->data + buffer->size + 4; 131 sizeLeft = *(int32_t *)(buffer->data + buffer->size); 132 VTRACE("%s sizeLeft: %d buffer->size: %#x", __func__, sizeLeft, buffer->size); 133 mInputBuffer = buffer->data; 134 } else { 135 status = parseAnnexBStream(buffer->data, buffer->size, &mByteStream); 136 CHECK_STATUS("parseAnnexBStream"); 137 pByteStream = mByteStream.byteStream; 138 sizeLeft = mByteStream.streamPos; 139 mInputBuffer = buffer->data; 140 } 141 if (sizeLeft < 4) { 142 ETRACE("Not enough data to read number of NALU."); 143 return DECODE_INVALID_DATA; 144 } 145 146 // read number of NALU 147 memcpy(&(mMetadata.naluNumber), pByteStream, sizeof(int32_t)); 148 pByteStream += 4; 149 sizeLeft -= 4; 150 151 if (mMetadata.naluNumber == 0) { 152 WTRACE("Number of NALU is ZERO!"); 153 return DECODE_SUCCESS; 154 } 155 156 for (int32_t i = 0; i < mMetadata.naluNumber; i++) { 157 if (sizeLeft < 12) { 158 ETRACE("Not enough data to parse NALU offset, size, header length for NALU %d, left = %d", i, sizeLeft); 159 return DECODE_INVALID_DATA; 160 } 161 sizeLeft -= 12; 162 // read NALU offset 163 memcpy(&(pNaluInfo->naluOffset), pByteStream, sizeof(int32_t)); 164 pByteStream += 4; 165 166 // read NALU size 167 memcpy(&(pNaluInfo->naluLen), pByteStream, sizeof(int32_t)); 168 pByteStream += 4; 169 170 // read NALU header length 171 memcpy(&(pNaluInfo->naluHeaderLen), pByteStream, sizeof(int32_t)); 172 pByteStream += 4; 173 174 175 if (sizeLeft < pNaluInfo->naluHeaderLen) { 176 ETRACE("Not enough data to copy NALU header for %d, left = %d, header len = %d", i, sizeLeft, pNaluInfo->naluHeaderLen); 177 return DECODE_INVALID_DATA; 178 } 179 180 sizeLeft -= pNaluInfo->naluHeaderLen; 181 182 if (pNaluInfo->naluHeaderLen) { 183 // copy start code prefix to buffer 184 memcpy(mNaluHeaderBuffer + sizeAccumulated, 185 startcodePrefix, 186 STARTCODE_PREFIX_LEN); 187 sizeAccumulated += STARTCODE_PREFIX_LEN; 188 189 // copy NALU header 190 memcpy(mNaluHeaderBuffer + sizeAccumulated, pByteStream, pNaluInfo->naluHeaderLen); 191 pByteStream += pNaluInfo->naluHeaderLen; 192 193 sizeAccumulated += pNaluInfo->naluHeaderLen; 194 } else { 195 WTRACE("header len is zero for NALU %d", i); 196 } 197 198 // for next NALU 199 pNaluInfo++; 200 } 201 202 buffer->data = mNaluHeaderBuffer; 203 buffer->size = sizeAccumulated; 204 205 return VideoDecoderAVC::decode(buffer); 206 } 207 208 209 Decode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) { 210 211 Decode_Status status; 212 VAStatus vaStatus; 213 uint32_t bufferIDCount = 0; 214 // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data 215 VABufferID bufferIDs[4]; 216 217 vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]); 218 vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]); 219 VAPictureParameterBufferH264 *picParam = picData->pic_parms; 220 VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms); 221 222 if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) { 223 // either condition indicates start of a new frame 224 if (sliceParam->first_mb_in_slice != 0) { 225 WTRACE("The first slice is lost."); 226 // TODO: handle the first slice lost 227 } 228 if (mDecodingFrame) { 229 // interlace content, complete decoding the first field 230 vaStatus = vaEndPicture(mVADisplay, mVAContext); 231 CHECK_VA_STATUS("vaEndPicture"); 232 233 // for interlace content, top field may be valid only after the second field is parsed 234 mAcquiredBuffer->pictureOrder= picParam->CurrPic.TopFieldOrderCnt; 235 } 236 237 // Check there is no reference frame loss before decoding a frame 238 239 // Update the reference frames and surface IDs for DPB and current frame 240 status = updateDPB(picParam); 241 CHECK_STATUS("updateDPB"); 242 243 //We have to provide a hacked DPB rather than complete DPB for libva as workaround 244 status = updateReferenceFrames(picData); 245 CHECK_STATUS("updateReferenceFrames"); 246 247 vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface); 248 CHECK_VA_STATUS("vaBeginPicture"); 249 250 // start decoding a frame 251 mDecodingFrame = true; 252 253 vaStatus = vaCreateBuffer( 254 mVADisplay, 255 mVAContext, 256 VAPictureParameterBufferType, 257 sizeof(VAPictureParameterBufferH264), 258 1, 259 picParam, 260 &bufferIDs[bufferIDCount]); 261 CHECK_VA_STATUS("vaCreatePictureParameterBuffer"); 262 bufferIDCount++; 263 264 vaStatus = vaCreateBuffer( 265 mVADisplay, 266 mVAContext, 267 VAIQMatrixBufferType, 268 sizeof(VAIQMatrixBufferH264), 269 1, 270 data->IQ_matrix_buf, 271 &bufferIDs[bufferIDCount]); 272 CHECK_VA_STATUS("vaCreateIQMatrixBuffer"); 273 bufferIDCount++; 274 } 275 276 status = setReference(sliceParam); 277 CHECK_STATUS("setReference"); 278 279 // find which naluinfo is correlated to current slice 280 int naluIndex = 0; 281 uint32_t accumulatedHeaderLen = 0; 282 uint32_t headerLen = 0; 283 for (; naluIndex < mMetadata.naluNumber; naluIndex++) { 284 headerLen = mMetadata.naluInfo[naluIndex].naluHeaderLen; 285 if (headerLen == 0) { 286 WTRACE("lenght of current NAL unit is 0."); 287 continue; 288 } 289 accumulatedHeaderLen += STARTCODE_PREFIX_LEN; 290 if (accumulatedHeaderLen + headerLen > sliceData->slice_offset) { 291 break; 292 } 293 accumulatedHeaderLen += headerLen; 294 } 295 296 if (sliceData->slice_offset != accumulatedHeaderLen) { 297 WTRACE("unexpected slice offset %d, accumulatedHeaderLen = %d", sliceData->slice_offset, accumulatedHeaderLen); 298 } 299 300 sliceParam->slice_data_size = mMetadata.naluInfo[naluIndex].naluLen; 301 uint32_t sliceOffset = mMetadata.naluInfo[naluIndex].naluOffset; 302 uint32_t slice_offset_shift = sliceOffset % 16; 303 sliceParam->slice_data_offset += slice_offset_shift; 304 sliceData->slice_size = (sliceParam->slice_data_size + slice_offset_shift + 0xF) & ~0xF; 305 306 vaStatus = vaCreateBuffer( 307 mVADisplay, 308 mVAContext, 309 VASliceParameterBufferType, 310 sizeof(VASliceParameterBufferH264), 311 1, 312 sliceParam, 313 &bufferIDs[bufferIDCount]); 314 CHECK_VA_STATUS("vaCreateSliceParameterBuffer"); 315 bufferIDCount++; 316 317 // sliceData->slice_offset - accumulatedHeaderLen is the absolute offset to start codes of current NAL unit 318 // offset points to first byte of NAL unit 319 320 if (mInputBuffer != NULL) { 321 vaStatus = vaCreateBuffer( 322 mVADisplay, 323 mVAContext, 324 VASliceDataBufferType, 325 sliceData->slice_size, //Slice size 326 1, // num_elements 327 mInputBuffer + sliceOffset - slice_offset_shift, 328 &bufferIDs[bufferIDCount]); 329 } else { 330 vaStatus = vaCreateBuffer( 331 mVADisplay, 332 mVAContext, 333 VAProtectedSliceDataBufferType, 334 sliceData->slice_size, //size 335 1, //num_elements 336 (uint8_t*)sliceOffset, // IMR offset 337 &bufferIDs[bufferIDCount]); 338 } 339 CHECK_VA_STATUS("vaCreateSliceDataBuffer"); 340 bufferIDCount++; 341 342 vaStatus = vaRenderPicture( 343 mVADisplay, 344 mVAContext, 345 bufferIDs, 346 bufferIDCount); 347 CHECK_VA_STATUS("vaRenderPicture"); 348 349 return DECODE_SUCCESS; 350 } 351 352 353 // Parse byte string pattern "0x000001" (3 bytes) in the current buffer. 354 // Returns offset of position following the pattern in the buffer if pattern is found or -1 if not found. 355 int32_t VideoDecoderAVCSecure::findNalUnitOffset(uint8_t *stream, int32_t offset, int32_t length) { 356 uint8_t *ptr; 357 uint32_t left = 0, data = 0, phase = 0; 358 uint8_t mask1 = 0, mask2 = 0; 359 360 /* Meaning of phase: 361 0: initial status, "0x000001" bytes are not found so far; 362 1: one "0x00" byte is found; 363 2: two or more consecutive "0x00" bytes" are found; 364 3: "0x000001" patten is found ; 365 4: if there is one more byte after "0x000001"; 366 */ 367 368 left = length; 369 ptr = (uint8_t *) (stream + offset); 370 phase = 0; 371 372 // parse until there is more data and start code not found 373 while ((left > 0) && (phase < 3)) { 374 // Check if the address is 32-bit aligned & phase=0, if thats the case we can check 4 bytes instead of one byte at a time. 375 if (((((uint32_t)ptr) & 0x3) == 0) && (phase == 0)) { 376 while (left > 3) { 377 data = *((uint32_t *)ptr); 378 mask1 = (STARTCODE_00 != (data & STARTCODE_MASK0)); 379 mask2 = (STARTCODE_00 != (data & STARTCODE_MASK1)); 380 // If second byte and fourth byte are not zero's then we cannot have a start code here, 381 // as we need two consecutive zero bytes for a start code pattern. 382 if (mask1 && mask2) { 383 // skip 4 bytes and start over 384 ptr += 4; 385 left -=4; 386 continue; 387 } else { 388 break; 389 } 390 } 391 } 392 393 // At this point either data is not on a 32-bit boundary or phase > 0 so we look at one byte at a time 394 if (left > 0) { 395 if (*ptr == STARTCODE_00) { 396 phase++; 397 if (phase > 2) { 398 // more than 2 consecutive '0x00' bytes is found 399 phase = 2; 400 } 401 } else if ((*ptr == STARTCODE_01) && (phase == 2)) { 402 // start code is found 403 phase = 3; 404 } else { 405 // reset lookup 406 phase = 0; 407 } 408 ptr++; 409 left--; 410 } 411 } 412 413 if ((left > 0) && (phase == 3)) { 414 phase = 4; 415 // return offset of position following the pattern in the buffer which matches "0x000001" byte string 416 return (int32_t)(ptr - stream); 417 } 418 return -1; 419 } 420 421 422 Decode_Status VideoDecoderAVCSecure::copyNaluHeader(uint8_t *stream, NaluByteStream *naluStream) { 423 uint8_t naluType; 424 int32_t naluHeaderLen; 425 426 naluType = *(uint8_t *)(stream + naluStream->naluOffset); 427 naluType &= NALU_TYPE_MASK; 428 // first update nalu header length based on nalu type 429 if (naluType >= NAL_UNIT_TYPE_SLICE && naluType <= NAL_UNIT_TYPE_IDR) { 430 // coded slice, return only up to MAX_SLICE_HEADER_SIZE bytes 431 naluHeaderLen = min(naluStream->naluLen, MAX_SLICE_HEADER_SIZE); 432 } else if (naluType >= NAL_UNIT_TYPE_SEI && naluType <= NAL_UNIT_TYPE_PPS) { 433 //sps, pps, sei, etc, return the entire NAL unit in clear 434 naluHeaderLen = naluStream->naluLen; 435 } else { 436 return DECODE_FRAME_DROPPED; 437 } 438 439 memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluOffset), sizeof(int32_t)); 440 naluStream->streamPos += 4; 441 442 memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluLen), sizeof(int32_t)); 443 naluStream->streamPos += 4; 444 445 memcpy(naluStream->byteStream + naluStream->streamPos, &naluHeaderLen, sizeof(int32_t)); 446 naluStream->streamPos += 4; 447 448 if (naluHeaderLen) { 449 memcpy(naluStream->byteStream + naluStream->streamPos, (uint8_t*)(stream + naluStream->naluOffset), naluHeaderLen); 450 naluStream->streamPos += naluHeaderLen; 451 } 452 return DECODE_SUCCESS; 453 } 454 455 456 // parse start-code prefixed stream, also knowns as Annex B byte stream, commonly used in AVI, ES, MPEG2 TS container 457 Decode_Status VideoDecoderAVCSecure::parseAnnexBStream(uint8_t *stream, int32_t length, NaluByteStream *naluStream) { 458 int32_t naluOffset, offset, left; 459 NaluInfo *info; 460 uint32_t ret = DECODE_SUCCESS; 461 462 naluOffset = 0; 463 offset = 0; 464 left = length; 465 466 // leave 4 bytes to copy nalu count 467 naluStream->streamPos = 4; 468 naluStream->naluCount = 0; 469 memset(naluStream->byteStream, 0, MAX_NALU_HEADER_BUFFER); 470 471 for (; ;) { 472 naluOffset = findNalUnitOffset(stream, offset, left); 473 if (naluOffset == -1) { 474 break; 475 } 476 477 if (naluStream->naluCount == 0) { 478 naluStream->naluOffset = naluOffset; 479 } else { 480 naluStream->naluLen = naluOffset - naluStream->naluOffset - STARTCODE_PREFIX_LEN; 481 ret = copyNaluHeader(stream, naluStream); 482 if (ret != DECODE_SUCCESS && ret != DECODE_FRAME_DROPPED) { 483 LOGW("copyNaluHeader returned %d", ret); 484 return ret; 485 } 486 // starting position for next NALU 487 naluStream->naluOffset = naluOffset; 488 } 489 490 if (ret == DECODE_SUCCESS) { 491 naluStream->naluCount++; 492 } 493 494 // update next lookup position and length 495 offset = naluOffset + 1; // skip one byte of NAL unit type 496 left = length - offset; 497 } 498 499 if (naluStream->naluCount > 0) { 500 naluStream->naluLen = length - naluStream->naluOffset; 501 memcpy(naluStream->byteStream, &(naluStream->naluCount), sizeof(int32_t)); 502 // ignore return value, either DECODE_SUCCESS or DECODE_FRAME_DROPPED 503 copyNaluHeader(stream, naluStream); 504 return DECODE_SUCCESS; 505 } 506 507 LOGW("number of valid NALU is 0!"); 508 return DECODE_SUCCESS; 509 } 510 511