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 pByteStream = buffer->data; 129 sizeLeft = buffer->size; 130 mInputBuffer = NULL; 131 } else { 132 status = parseAnnexBStream(buffer->data, buffer->size, &mByteStream); 133 CHECK_STATUS("parseAnnexBStream"); 134 pByteStream = mByteStream.byteStream; 135 sizeLeft = mByteStream.streamPos; 136 mInputBuffer = buffer->data; 137 } 138 if (sizeLeft < 4) { 139 ETRACE("Not enough data to read number of NALU."); 140 return DECODE_INVALID_DATA; 141 } 142 143 // read number of NALU 144 memcpy(&(mMetadata.naluNumber), pByteStream, sizeof(int32_t)); 145 pByteStream += 4; 146 sizeLeft -= 4; 147 148 if (mMetadata.naluNumber == 0) { 149 WTRACE("Number of NALU is ZERO!"); 150 return DECODE_SUCCESS; 151 } 152 153 for (int32_t i = 0; i < mMetadata.naluNumber; i++) { 154 if (sizeLeft < 12) { 155 ETRACE("Not enough data to parse NALU offset, size, header length for NALU %d, left = %d", i, sizeLeft); 156 return DECODE_INVALID_DATA; 157 } 158 sizeLeft -= 12; 159 // read NALU offset 160 memcpy(&(pNaluInfo->naluOffset), pByteStream, sizeof(int32_t)); 161 pByteStream += 4; 162 163 // read NALU size 164 memcpy(&(pNaluInfo->naluLen), pByteStream, sizeof(int32_t)); 165 pByteStream += 4; 166 167 // read NALU header length 168 memcpy(&(pNaluInfo->naluHeaderLen), pByteStream, sizeof(int32_t)); 169 pByteStream += 4; 170 171 if (sizeLeft < pNaluInfo->naluHeaderLen) { 172 ETRACE("Not enough data to copy NALU header for %d, left = %d, header len = %d", i, sizeLeft, pNaluInfo->naluHeaderLen); 173 return DECODE_INVALID_DATA; 174 } 175 176 sizeLeft -= pNaluInfo->naluHeaderLen; 177 178 if (pNaluInfo->naluHeaderLen) { 179 // copy start code prefix to buffer 180 memcpy(mNaluHeaderBuffer + sizeAccumulated, 181 startcodePrefix, 182 STARTCODE_PREFIX_LEN); 183 sizeAccumulated += STARTCODE_PREFIX_LEN; 184 185 // copy NALU header 186 memcpy(mNaluHeaderBuffer + sizeAccumulated, pByteStream, pNaluInfo->naluHeaderLen); 187 pByteStream += pNaluInfo->naluHeaderLen; 188 189 sizeAccumulated += pNaluInfo->naluHeaderLen; 190 } else { 191 WTRACE("header len is zero for NALU %d", i); 192 } 193 194 // for next NALU 195 pNaluInfo++; 196 } 197 198 buffer->data = mNaluHeaderBuffer; 199 buffer->size = sizeAccumulated; 200 201 return VideoDecoderAVC::decode(buffer); 202 } 203 204 205 Decode_Status VideoDecoderAVCSecure::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) { 206 207 Decode_Status status; 208 VAStatus vaStatus; 209 uint32_t bufferIDCount = 0; 210 // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data 211 VABufferID bufferIDs[4]; 212 213 vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]); 214 vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]); 215 VAPictureParameterBufferH264 *picParam = picData->pic_parms; 216 VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms); 217 218 if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) { 219 // either condition indicates start of a new frame 220 if (sliceParam->first_mb_in_slice != 0) { 221 WTRACE("The first slice is lost."); 222 // TODO: handle the first slice lost 223 } 224 if (mDecodingFrame) { 225 // interlace content, complete decoding the first field 226 vaStatus = vaEndPicture(mVADisplay, mVAContext); 227 CHECK_VA_STATUS("vaEndPicture"); 228 229 // for interlace content, top field may be valid only after the second field is parsed 230 mAcquiredBuffer->pictureOrder= picParam->CurrPic.TopFieldOrderCnt; 231 } 232 233 // Check there is no reference frame loss before decoding a frame 234 235 // Update the reference frames and surface IDs for DPB and current frame 236 status = updateDPB(picParam); 237 CHECK_STATUS("updateDPB"); 238 239 //We have to provide a hacked DPB rather than complete DPB for libva as workaround 240 status = updateReferenceFrames(picData); 241 CHECK_STATUS("updateReferenceFrames"); 242 243 vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface); 244 CHECK_VA_STATUS("vaBeginPicture"); 245 246 // start decoding a frame 247 mDecodingFrame = true; 248 249 vaStatus = vaCreateBuffer( 250 mVADisplay, 251 mVAContext, 252 VAPictureParameterBufferType, 253 sizeof(VAPictureParameterBufferH264), 254 1, 255 picParam, 256 &bufferIDs[bufferIDCount]); 257 CHECK_VA_STATUS("vaCreatePictureParameterBuffer"); 258 bufferIDCount++; 259 260 vaStatus = vaCreateBuffer( 261 mVADisplay, 262 mVAContext, 263 VAIQMatrixBufferType, 264 sizeof(VAIQMatrixBufferH264), 265 1, 266 data->IQ_matrix_buf, 267 &bufferIDs[bufferIDCount]); 268 CHECK_VA_STATUS("vaCreateIQMatrixBuffer"); 269 bufferIDCount++; 270 } 271 272 status = setReference(sliceParam); 273 CHECK_STATUS("setReference"); 274 275 // find which naluinfo is correlated to current slice 276 int naluIndex = 0; 277 uint32_t accumulatedHeaderLen = 0; 278 uint32_t headerLen = 0; 279 for (; naluIndex < mMetadata.naluNumber; naluIndex++) { 280 headerLen = mMetadata.naluInfo[naluIndex].naluHeaderLen; 281 if (headerLen == 0) { 282 WTRACE("lenght of current NAL unit is 0."); 283 continue; 284 } 285 accumulatedHeaderLen += STARTCODE_PREFIX_LEN; 286 if (accumulatedHeaderLen + headerLen > sliceData->slice_offset) { 287 break; 288 } 289 accumulatedHeaderLen += headerLen; 290 } 291 292 if (sliceData->slice_offset != accumulatedHeaderLen) { 293 WTRACE("unexpected slice offset %d, accumulatedHeaderLen = %d", sliceData->slice_offset, accumulatedHeaderLen); 294 } 295 296 sliceParam->slice_data_size = mMetadata.naluInfo[naluIndex].naluLen; 297 sliceData->slice_size = sliceParam->slice_data_size; 298 299 // no need to update: 300 // sliceParam->slice_data_offset - 0 always 301 // sliceParam->slice_data_bit_offset - relative to sliceData->slice_offset 302 303 vaStatus = vaCreateBuffer( 304 mVADisplay, 305 mVAContext, 306 VASliceParameterBufferType, 307 sizeof(VASliceParameterBufferH264), 308 1, 309 sliceParam, 310 &bufferIDs[bufferIDCount]); 311 CHECK_VA_STATUS("vaCreateSliceParameterBuffer"); 312 bufferIDCount++; 313 314 // sliceData->slice_offset - accumulatedHeaderLen is the absolute offset to start codes of current NAL unit 315 // offset points to first byte of NAL unit 316 uint32_t sliceOffset = mMetadata.naluInfo[naluIndex].naluOffset; 317 if (mInputBuffer != NULL) { 318 vaStatus = vaCreateBuffer( 319 mVADisplay, 320 mVAContext, 321 VASliceDataBufferType, 322 sliceData->slice_size, //size 323 1, //num_elements 324 mInputBuffer + sliceOffset, 325 &bufferIDs[bufferIDCount]); 326 } else { 327 vaStatus = vaCreateBuffer( 328 mVADisplay, 329 mVAContext, 330 VAProtectedSliceDataBufferType, 331 sliceData->slice_size, //size 332 1, //num_elements 333 (uint8_t*)sliceOffset, // IMR offset 334 &bufferIDs[bufferIDCount]); 335 } 336 CHECK_VA_STATUS("vaCreateSliceDataBuffer"); 337 bufferIDCount++; 338 339 vaStatus = vaRenderPicture( 340 mVADisplay, 341 mVAContext, 342 bufferIDs, 343 bufferIDCount); 344 CHECK_VA_STATUS("vaRenderPicture"); 345 346 return DECODE_SUCCESS; 347 } 348 349 350 // Parse byte string pattern "0x000001" (3 bytes) in the current buffer. 351 // Returns offset of position following the pattern in the buffer if pattern is found or -1 if not found. 352 int32_t VideoDecoderAVCSecure::findNalUnitOffset(uint8_t *stream, int32_t offset, int32_t length) { 353 uint8_t *ptr; 354 uint32_t left = 0, data = 0, phase = 0; 355 uint8_t mask1 = 0, mask2 = 0; 356 357 /* Meaning of phase: 358 0: initial status, "0x000001" bytes are not found so far; 359 1: one "0x00" byte is found; 360 2: two or more consecutive "0x00" bytes" are found; 361 3: "0x000001" patten is found ; 362 4: if there is one more byte after "0x000001"; 363 */ 364 365 left = length; 366 ptr = (uint8_t *) (stream + offset); 367 phase = 0; 368 369 // parse until there is more data and start code not found 370 while ((left > 0) && (phase < 3)) { 371 // 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. 372 if (((((uint32_t)ptr) & 0x3) == 0) && (phase == 0)) { 373 while (left > 3) { 374 data = *((uint32_t *)ptr); 375 mask1 = (STARTCODE_00 != (data & STARTCODE_MASK0)); 376 mask2 = (STARTCODE_00 != (data & STARTCODE_MASK1)); 377 // If second byte and fourth byte are not zero's then we cannot have a start code here, 378 // as we need two consecutive zero bytes for a start code pattern. 379 if (mask1 && mask2) { 380 // skip 4 bytes and start over 381 ptr += 4; 382 left -=4; 383 continue; 384 } else { 385 break; 386 } 387 } 388 } 389 390 // At this point either data is not on a 32-bit boundary or phase > 0 so we look at one byte at a time 391 if (left > 0) { 392 if (*ptr == STARTCODE_00) { 393 phase++; 394 if (phase > 2) { 395 // more than 2 consecutive '0x00' bytes is found 396 phase = 2; 397 } 398 } else if ((*ptr == STARTCODE_01) && (phase == 2)) { 399 // start code is found 400 phase = 3; 401 } else { 402 // reset lookup 403 phase = 0; 404 } 405 ptr++; 406 left--; 407 } 408 } 409 410 if ((left > 0) && (phase == 3)) { 411 phase = 4; 412 // return offset of position following the pattern in the buffer which matches "0x000001" byte string 413 return (int32_t)(ptr - stream); 414 } 415 return -1; 416 } 417 418 419 Decode_Status VideoDecoderAVCSecure::copyNaluHeader(uint8_t *stream, NaluByteStream *naluStream) { 420 uint8_t naluType; 421 int32_t naluHeaderLen; 422 423 naluType = *(uint8_t *)(stream + naluStream->naluOffset); 424 naluType &= NALU_TYPE_MASK; 425 // first update nalu header length based on nalu type 426 if (naluType >= NAL_UNIT_TYPE_SLICE && naluType <= NAL_UNIT_TYPE_IDR) { 427 // coded slice, return only up to MAX_SLICE_HEADER_SIZE bytes 428 naluHeaderLen = min(naluStream->naluLen, MAX_SLICE_HEADER_SIZE); 429 } else if (naluType >= NAL_UNIT_TYPE_SEI && naluType <= NAL_UNIT_TYPE_PPS) { 430 //sps, pps, sei, etc, return the entire NAL unit in clear 431 naluHeaderLen = naluStream->naluLen; 432 } else { 433 return DECODE_FRAME_DROPPED; 434 } 435 436 memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluOffset), sizeof(int32_t)); 437 naluStream->streamPos += 4; 438 439 memcpy(naluStream->byteStream + naluStream->streamPos, &(naluStream->naluLen), sizeof(int32_t)); 440 naluStream->streamPos += 4; 441 442 memcpy(naluStream->byteStream + naluStream->streamPos, &naluHeaderLen, sizeof(int32_t)); 443 naluStream->streamPos += 4; 444 445 if (naluHeaderLen) { 446 memcpy(naluStream->byteStream + naluStream->streamPos, (uint8_t*)(stream + naluStream->naluOffset), naluHeaderLen); 447 naluStream->streamPos += naluHeaderLen; 448 } 449 return DECODE_SUCCESS; 450 } 451 452 453 // parse start-code prefixed stream, also knowns as Annex B byte stream, commonly used in AVI, ES, MPEG2 TS container 454 Decode_Status VideoDecoderAVCSecure::parseAnnexBStream(uint8_t *stream, int32_t length, NaluByteStream *naluStream) { 455 int32_t naluOffset, offset, left; 456 NaluInfo *info; 457 uint32_t ret = DECODE_SUCCESS; 458 459 naluOffset = 0; 460 offset = 0; 461 left = length; 462 463 // leave 4 bytes to copy nalu count 464 naluStream->streamPos = 4; 465 naluStream->naluCount = 0; 466 memset(naluStream->byteStream, 0, MAX_NALU_HEADER_BUFFER); 467 468 for (; ;) { 469 naluOffset = findNalUnitOffset(stream, offset, left); 470 if (naluOffset == -1) { 471 break; 472 } 473 474 if (naluStream->naluCount == 0) { 475 naluStream->naluOffset = naluOffset; 476 } else { 477 naluStream->naluLen = naluOffset - naluStream->naluOffset - STARTCODE_PREFIX_LEN; 478 ret = copyNaluHeader(stream, naluStream); 479 if (ret != DECODE_SUCCESS && ret != DECODE_FRAME_DROPPED) { 480 LOGW("copyNaluHeader returned %d", ret); 481 return ret; 482 } 483 // starting position for next NALU 484 naluStream->naluOffset = naluOffset; 485 } 486 487 if (ret == DECODE_SUCCESS) { 488 naluStream->naluCount++; 489 } 490 491 // update next lookup position and length 492 offset = naluOffset + 1; // skip one byte of NAL unit type 493 left = length - offset; 494 } 495 496 if (naluStream->naluCount > 0) { 497 naluStream->naluLen = length - naluStream->naluOffset; 498 memcpy(naluStream->byteStream, &(naluStream->naluCount), sizeof(int32_t)); 499 // ignore return value, either DECODE_SUCCESS or DECODE_FRAME_DROPPED 500 copyNaluHeader(stream, naluStream); 501 return DECODE_SUCCESS; 502 } 503 504 LOGW("number of valid NALU is 0!"); 505 return DECODE_SUCCESS; 506 } 507 508