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         // 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 
decodeSlice(vbp_data_h264 * data,uint32_t picIndex,uint32_t sliceIndex)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.
findNalUnitOffset(uint8_t * stream,int32_t offset,int32_t length)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 
copyNaluHeader(uint8_t * stream,NaluByteStream * naluStream)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
parseAnnexBStream(uint8_t * stream,int32_t length,NaluByteStream * naluStream)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