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
VideoDecoderAVCSecure(const char * mimeType)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
~VideoDecoderAVCSecure()78 VideoDecoderAVCSecure::~VideoDecoderAVCSecure() {
79 }
80
start(VideoConfigBuffer * buffer)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
stop(void)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
decode(VideoDecodeBuffer * buffer)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
decodeSlice(vbp_data_h264 * data,uint32_t picIndex,uint32_t sliceIndex)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.
findNalUnitOffset(uint8_t * stream,int32_t offset,int32_t length)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
copyNaluHeader(uint8_t * stream,NaluByteStream * naluStream)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
parseAnnexBStream(uint8_t * stream,int32_t length,NaluByteStream * naluStream)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