• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "VideoDecoderAVC.h"
18 #include "VideoDecoderTrace.h"
19 #include <string.h>
20 #include <cutils/properties.h>
21 
22 // Macros for actual buffer needed calculation
23 #define WIDI_CONSUMED   6
24 #define HDMI_CONSUMED   2
25 #define NW_CONSUMED     2
26 #define POC_DEFAULT     0x7FFFFFFF
27 
VideoDecoderAVC(const char * mimeType)28 VideoDecoderAVC::VideoDecoderAVC(const char *mimeType)
29     : VideoDecoderBase(mimeType, VBP_H264),
30       mToggleDPB(0),
31       mErrorConcealment(false){
32 
33     invalidateDPB(0);
34     invalidateDPB(1);
35     mLastPictureFlags = VA_PICTURE_H264_INVALID;
36 }
37 
~VideoDecoderAVC()38 VideoDecoderAVC::~VideoDecoderAVC() {
39     stop();
40 }
41 
start(VideoConfigBuffer * buffer)42 Decode_Status VideoDecoderAVC::start(VideoConfigBuffer *buffer) {
43     Decode_Status status;
44 
45     status = VideoDecoderBase::start(buffer);
46     CHECK_STATUS("VideoDecoderBase::start");
47 
48     // We don't want base class to manage reference.
49     VideoDecoderBase::ManageReference(false);
50     // output by picture order count
51     VideoDecoderBase::setOutputMethod(OUTPUT_BY_POC);
52 
53     mErrorConcealment = buffer->flag & WANT_ERROR_CONCEALMENT;
54     if (buffer->data == NULL || buffer->size == 0) {
55         WTRACE("No config data to start VA.");
56         if ((buffer->flag & HAS_SURFACE_NUMBER) && (buffer->flag & HAS_VA_PROFILE)) {
57             ITRACE("Used client supplied profile and surface to start VA.");
58             return VideoDecoderBase::setupVA(buffer->surfaceNumber, buffer->profile);
59         }
60         return DECODE_SUCCESS;
61     }
62 
63     vbp_data_h264 *data = NULL;
64     status = VideoDecoderBase::parseBuffer(buffer->data, buffer->size, true, (void**)&data);
65     CHECK_STATUS("VideoDecoderBase::parseBuffer");
66 
67     status = startVA(data);
68     return status;
69 }
70 
stop(void)71 void VideoDecoderAVC::stop(void) {
72     // drop the last  frame and ignore return value
73     endDecodingFrame(true);
74     VideoDecoderBase::stop();
75     invalidateDPB(0);
76     invalidateDPB(1);
77     mToggleDPB = 0;
78     mErrorConcealment = false;
79     mLastPictureFlags = VA_PICTURE_H264_INVALID;
80 }
81 
flush(void)82 void VideoDecoderAVC::flush(void) {
83     // drop the frame and ignore return value
84     VideoDecoderBase::flush();
85     invalidateDPB(0);
86     invalidateDPB(1);
87     mToggleDPB = 0;
88     mLastPictureFlags = VA_PICTURE_H264_INVALID;
89 }
90 
decode(VideoDecodeBuffer * buffer)91 Decode_Status VideoDecoderAVC::decode(VideoDecodeBuffer *buffer) {
92     Decode_Status status;
93     vbp_data_h264 *data = NULL;
94     if (buffer == NULL) {
95         return DECODE_INVALID_DATA;
96     }
97     status =  VideoDecoderBase::parseBuffer(
98             buffer->data,
99             buffer->size,
100             false,
101             (void**)&data);
102     CHECK_STATUS("VideoDecoderBase::parseBuffer");
103 
104     if (!mVAStarted) {
105          if (data->has_sps && data->has_pps) {
106             status = startVA(data);
107             CHECK_STATUS("startVA");
108         } else {
109             WTRACE("Can't start VA as either SPS or PPS is still not available.");
110             return DECODE_SUCCESS;
111         }
112     }
113 
114     VideoDecoderBase::setRotationDegrees(buffer->rotationDegrees);
115 
116     status = decodeFrame(buffer, data);
117     if (status == DECODE_MULTIPLE_FRAME) {
118         buffer->ext = &mExtensionBuffer;
119         mExtensionBuffer.extType = PACKED_FRAME_TYPE;
120         mExtensionBuffer.extSize = sizeof(mPackedFrame);
121         mExtensionBuffer.extData = (uint8_t*)&mPackedFrame;
122     }
123     return status;
124 }
125 
decodeFrame(VideoDecodeBuffer * buffer,vbp_data_h264 * data)126 Decode_Status VideoDecoderAVC::decodeFrame(VideoDecodeBuffer *buffer, vbp_data_h264 *data) {
127     Decode_Status status;
128     if (data->has_sps == 0 || data->has_pps == 0) {
129         return DECODE_NO_CONFIG;
130     }
131 
132     mVideoFormatInfo.flags = 0;
133     uint32_t fieldFlags = 0;
134     for (unsigned int i = 0; i < data->num_pictures; i++) {
135         VAPictureH264 &pic = data->pic_data[i].pic_parms->CurrPic;
136         fieldFlags |= pic.flags;
137         // Don't remove the following codes, it can be enabled for debugging DPB.
138 #if 0
139         VTRACE("%d: decoding frame %.2f, poc top = %d, poc bottom = %d, flags = %d,  reference = %d",
140                 i,
141                 buffer->timeStamp/1E6,
142                 pic.TopFieldOrderCnt,
143                 pic.BottomFieldOrderCnt,
144                 pic.flags,
145                 (pic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
146                 (pic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE));
147 #endif
148     }
149     int32_t topField = fieldFlags & VA_PICTURE_H264_TOP_FIELD;
150     int32_t botField = fieldFlags & VA_PICTURE_H264_BOTTOM_FIELD;
151     if ((topField == 0 && botField != 0) || (topField != 0 && botField == 0)) {
152         mVideoFormatInfo.flags |= IS_SINGLE_FIELD;
153     }
154 
155     if (data->new_sps || data->new_pps) {
156         status = handleNewSequence(data);
157         CHECK_STATUS("handleNewSequence");
158     }
159 
160     if (isWiDiStatusChanged()) {
161         mSizeChanged = false;
162         flushSurfaceBuffers();
163         return DECODE_FORMAT_CHANGE;
164     }
165 
166     // first pic_data always exists, check if any slice is parsed
167     if (data->pic_data[0].num_slices == 0) {
168         ITRACE("No slice available for decoding.");
169         status = mSizeChanged ? DECODE_FORMAT_CHANGE : DECODE_SUCCESS;
170         mSizeChanged = false;
171         return status;
172     }
173 
174     uint64_t lastPTS = mCurrentPTS;
175     mCurrentPTS = buffer->timeStamp;
176     //if (lastPTS != mCurrentPTS) {
177     if (isNewFrame(data, lastPTS == mCurrentPTS)) {
178         if (mLowDelay) {
179             // start decoding a new frame
180             status = beginDecodingFrame(data);
181             if (status != DECODE_SUCCESS) {
182                 Decode_Status st = status;
183                 // finish decoding the last frame if
184                 // encounter error when decode the new frame
185                 status = endDecodingFrame(false);
186                 CHECK_STATUS("endDecodingFrame");
187                 return st;
188             }
189         }
190 
191         // finish decoding the last frame
192         status = endDecodingFrame(false);
193         CHECK_STATUS("endDecodingFrame");
194 
195         if (!mLowDelay) {
196             // start decoding a new frame
197             status = beginDecodingFrame(data);
198             CHECK_STATUS("beginDecodingFrame");
199         }
200     } else {
201         status = continueDecodingFrame(data);
202         CHECK_STATUS("continueDecodingFrame");
203     }
204 
205     // HAS_COMPLETE_FRAME is not reliable as it may indicate end of a field
206 #if 0
207     if (buffer->flag & HAS_COMPLETE_FRAME) {
208         // finish decoding current frame
209         status = endDecodingFrame(false);
210         CHECK_STATUS("endDecodingFrame");
211     }
212 #endif
213     return DECODE_SUCCESS;
214 }
215 
beginDecodingFrame(vbp_data_h264 * data)216 Decode_Status VideoDecoderAVC::beginDecodingFrame(vbp_data_h264 *data) {
217     Decode_Status status;
218 
219     status = acquireSurfaceBuffer();
220     CHECK_STATUS("acquireSurfaceBuffer");
221     VAPictureH264 *picture = &(data->pic_data[0].pic_parms->CurrPic);
222     if ((picture->flags  & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
223         (picture->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
224         mAcquiredBuffer->referenceFrame = true;
225     } else {
226         mAcquiredBuffer->referenceFrame = false;
227     }
228     // set asReference in updateDPB
229 
230     if (picture->flags & VA_PICTURE_H264_TOP_FIELD) {
231         mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD | VA_TOP_FIELD;
232     } else {
233         mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
234     }
235 
236     // TODO: Set the discontinuity flag
237     mAcquiredBuffer->renderBuffer.flag = 0;
238     mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
239     mAcquiredBuffer->pictureOrder = getPOC(picture);
240 
241     if (mSizeChanged) {
242         mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE;
243         mSizeChanged = false;
244     }
245 
246     status  = continueDecodingFrame(data);
247     // surface buffer is released if decode fails
248     return status;
249 }
250 
251 
continueDecodingFrame(vbp_data_h264 * data)252 Decode_Status VideoDecoderAVC::continueDecodingFrame(vbp_data_h264 *data) {
253     Decode_Status status;
254     vbp_picture_data_h264 *picData = data->pic_data;
255 
256     // TODO: remove these debugging codes
257     if (mAcquiredBuffer == NULL || mAcquiredBuffer->renderBuffer.surface == VA_INVALID_SURFACE) {
258         ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
259         return DECODE_FAIL;
260     }
261     for (uint32_t picIndex = 0; picIndex < data->num_pictures; picIndex++, picData++) {
262         // sanity check
263         if (picData == NULL || picData->pic_parms == NULL || picData->slc_data == NULL || picData->num_slices == 0) {
264             return DECODE_PARSER_FAIL;
265         }
266 
267         if (picIndex > 0 &&
268             (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
269             // it is a packed frame buffer
270             vbp_picture_data_h264 *lastPic = &data->pic_data[picIndex - 1];
271             vbp_slice_data_h264 *sliceData = &(lastPic->slc_data[lastPic->num_slices - 1]);
272             mPackedFrame.offSet = sliceData->slice_size + sliceData->slice_offset;
273             mPackedFrame.timestamp = mCurrentPTS; // use the current time stamp for the packed frame
274             ITRACE("slice data offset= %d, size = %d", sliceData->slice_offset, sliceData->slice_size);
275             return DECODE_MULTIPLE_FRAME;
276         }
277 
278         for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
279             status = decodeSlice(data, picIndex, sliceIndex);
280             if (status != DECODE_SUCCESS) {
281                 endDecodingFrame(true);
282                 // TODO: this is new code
283                 // remove current frame from DPB as it can't be decoded.
284                 removeReferenceFromDPB(picData->pic_parms);
285                 return status;
286             }
287         }
288     }
289     return DECODE_SUCCESS;
290 }
291 
decodeSlice(vbp_data_h264 * data,uint32_t picIndex,uint32_t sliceIndex)292 Decode_Status VideoDecoderAVC::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {
293     Decode_Status status;
294     VAStatus vaStatus;
295     uint32_t bufferIDCount = 0;
296     // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data
297     VABufferID bufferIDs[4];
298 
299     vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
300     vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
301     VAPictureParameterBufferH264 *picParam = picData->pic_parms;
302     VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);
303 
304     if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
305         // either condition indicates start of a new frame
306         if (sliceParam->first_mb_in_slice != 0) {
307             WTRACE("The first slice is lost.");
308             // TODO: handle the first slice lost
309         }
310         if (mDecodingFrame) {
311             // interlace content, complete decoding the first field
312             vaStatus = vaEndPicture(mVADisplay, mVAContext);
313             CHECK_VA_STATUS("vaEndPicture");
314 
315             // for interlace content, top field may be valid only after the second field is parsed
316             int32_t poc = getPOC(&(picParam->CurrPic));
317             if (poc < mAcquiredBuffer->pictureOrder) {
318                 mAcquiredBuffer->pictureOrder = poc;
319             }
320         }
321 
322         // Check there is no reference frame loss before decoding a frame
323 
324         // Update  the reference frames and surface IDs for DPB and current frame
325         status = updateDPB(picParam);
326         CHECK_STATUS("updateDPB");
327 
328 #ifndef USE_AVC_SHORT_FORMAT
329         //We have to provide a hacked DPB rather than complete DPB for libva as workaround
330         status = updateReferenceFrames(picData);
331         CHECK_STATUS("updateReferenceFrames");
332 #endif
333         vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
334         CHECK_VA_STATUS("vaBeginPicture");
335 
336         // start decoding a frame
337         mDecodingFrame = true;
338 
339         vaStatus = vaCreateBuffer(
340             mVADisplay,
341             mVAContext,
342             VAPictureParameterBufferType,
343             sizeof(VAPictureParameterBufferH264),
344             1,
345             picParam,
346             &bufferIDs[bufferIDCount]);
347         CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
348         bufferIDCount++;
349 
350         vaStatus = vaCreateBuffer(
351             mVADisplay,
352             mVAContext,
353             VAIQMatrixBufferType,
354             sizeof(VAIQMatrixBufferH264),
355             1,
356             data->IQ_matrix_buf,
357             &bufferIDs[bufferIDCount]);
358         CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
359         bufferIDCount++;
360     }
361 
362 #ifndef USE_AVC_SHORT_FORMAT
363 
364     status = setReference(sliceParam);
365     CHECK_STATUS("setReference");
366 
367     vaStatus = vaCreateBuffer(
368         mVADisplay,
369         mVAContext,
370         VASliceParameterBufferType,
371         sizeof(VASliceParameterBufferH264),
372         1,
373         sliceParam,
374         &bufferIDs[bufferIDCount]);
375 #else
376     vaStatus = vaCreateBuffer(
377         mVADisplay,
378         mVAContext,
379         VASliceParameterBufferType,
380         sizeof(VASliceParameterBufferH264Base),
381         1,
382         sliceParam,
383         &bufferIDs[bufferIDCount]);
384 #endif
385     CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
386     bufferIDCount++;
387 
388     vaStatus = vaCreateBuffer(
389         mVADisplay,
390         mVAContext,
391         VASliceDataBufferType,
392         sliceData->slice_size, //size
393         1,        //num_elements
394         sliceData->buffer_addr + sliceData->slice_offset,
395         &bufferIDs[bufferIDCount]);
396     CHECK_VA_STATUS("vaCreateSliceDataBuffer");
397     bufferIDCount++;
398 
399     vaStatus = vaRenderPicture(
400         mVADisplay,
401         mVAContext,
402         bufferIDs,
403         bufferIDCount);
404     CHECK_VA_STATUS("vaRenderPicture");
405 
406     return DECODE_SUCCESS;
407 }
408 
setReference(VASliceParameterBufferH264 * sliceParam)409 Decode_Status VideoDecoderAVC::setReference(VASliceParameterBufferH264 *sliceParam) {
410     int32_t numList = 1;
411     // TODO: set numList to 0 if it is I slice
412     if (sliceParam->slice_type == 1 || sliceParam->slice_type == 6) {
413         // B slice
414         numList = 2;
415     }
416 
417     int32_t activeMinus1 = sliceParam->num_ref_idx_l0_active_minus1;
418     VAPictureH264 *ref = sliceParam->RefPicList0;
419 
420     for (int32_t i = 0; i < numList; i++) {
421         if (activeMinus1 >= REF_LIST_SIZE) {
422             ETRACE("Invalid activeMinus1 (%d)", activeMinus1);
423             return DECODE_PARSER_FAIL;
424         }
425         for (int32_t j = 0; j <= activeMinus1; j++, ref++) {
426             if (!(ref->flags & VA_PICTURE_H264_INVALID)) {
427                 ref->picture_id = findSurface(ref);
428                 if (ref->picture_id == VA_INVALID_SURFACE) {
429                     // Error DecodeRefMissing is counted once even there're multiple
430                     mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 1;
431                     mAcquiredBuffer->renderBuffer.errBuf.errorArray[0].type = DecodeRefMissing;
432 
433                     if (mLastReference) {
434                         WTRACE("Reference frame %d is missing. Use last reference", getPOC(ref));
435                         ref->picture_id = mLastReference->renderBuffer.surface;
436                     } else {
437                         ETRACE("Reference frame %d is missing. Stop decoding.", getPOC(ref));
438                         return DECODE_NO_REFERENCE;
439                     }
440                 }
441             }
442         }
443         activeMinus1 = sliceParam->num_ref_idx_l1_active_minus1;
444         ref = sliceParam->RefPicList1;
445     }
446     return DECODE_SUCCESS;
447 }
448 
updateDPB(VAPictureParameterBufferH264 * picParam)449 Decode_Status VideoDecoderAVC::updateDPB(VAPictureParameterBufferH264 *picParam) {
450     clearAsReference(mToggleDPB);
451     // pointer to toggled DPB (new)
452     DecodedPictureBuffer *dpb = mDPBs[!mToggleDPB];
453     VAPictureH264 *ref = picParam->ReferenceFrames;
454 
455     // update current picture ID
456     picParam->CurrPic.picture_id = mAcquiredBuffer->renderBuffer.surface;
457 
458     // build new DPB
459     for (int32_t i = 0; i < MAX_REF_NUMBER; i++, ref++) {
460         if (ref->flags & VA_PICTURE_H264_INVALID) {
461             continue;
462         }
463 #ifdef USE_AVC_SHORT_FORMAT
464         ref->picture_id = findSurface(ref);
465 #endif
466         dpb->poc = getPOC(ref);
467         // looking for the latest ref frame in the DPB with specified POC, in case frames have same POC
468         dpb->surfaceBuffer = findRefSurfaceBuffer(ref);
469         if (dpb->surfaceBuffer == NULL) {
470             ETRACE("Reference frame %d is missing for current frame %d", dpb->poc, getPOC(&(picParam->CurrPic)));
471             // Error DecodeRefMissing is counted once even there're multiple
472             mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 1;
473             mAcquiredBuffer->renderBuffer.errBuf.errorArray[0].type = DecodeRefMissing;
474             if (dpb->poc == getPOC(&(picParam->CurrPic))) {
475                 WTRACE("updateDPB: Using the current picture for missing reference.");
476                 dpb->surfaceBuffer = mAcquiredBuffer;
477             } else if (mLastReference) {
478                 WTRACE("updateDPB: Use last reference frame %d for missing reference.", mLastReference->pictureOrder);
479                 // TODO: this is new code for error resilience
480                 dpb->surfaceBuffer = mLastReference;
481             } else {
482                 WTRACE("updateDPB: Unable to recover the missing reference frame.");
483                 // continue buillding DPB without updating dpb pointer.
484                 continue;
485                 // continue building DPB as this reference may not be actually used.
486                 // especially happen after seeking to a non-IDR I frame.
487                 //return DECODE_NO_REFERENCE;
488             }
489         }
490         if (dpb->surfaceBuffer) {
491             // this surface is used as reference
492             dpb->surfaceBuffer->asReferernce = true;
493         }
494         dpb++;
495     }
496 
497     // add current frame to DPB if it  is a reference frame
498     if ((picParam->CurrPic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
499         (picParam->CurrPic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
500         dpb->poc = getPOC(&(picParam->CurrPic));
501         dpb->surfaceBuffer = mAcquiredBuffer;
502         dpb->surfaceBuffer->asReferernce = true;
503     }
504     // invalidate the current used DPB
505     invalidateDPB(mToggleDPB);
506     mToggleDPB = !mToggleDPB;
507     return DECODE_SUCCESS;
508 }
509 
updateReferenceFrames(vbp_picture_data_h264 * picData)510 Decode_Status VideoDecoderAVC::updateReferenceFrames(vbp_picture_data_h264 *picData) {
511     bool found = false;
512     uint32_t flags = 0;
513     VAPictureParameterBufferH264 *picParam = picData->pic_parms;
514     VASliceParameterBufferH264 *sliceParam = NULL;
515     uint8_t activeMinus1 = 0;
516     VAPictureH264 *refList = NULL;
517     VAPictureH264 *dpb = picParam->ReferenceFrames;
518     VAPictureH264 *refFrame = NULL;
519 
520     for(int i = 0; i < picParam->num_ref_frames; i++) {
521         dpb->picture_id = findSurface(dpb);
522         dpb++;
523     }
524 
525     return DECODE_SUCCESS;
526 
527     // invalidate DPB in the picture buffer
528     memset(picParam->ReferenceFrames, 0xFF, sizeof(picParam->ReferenceFrames));
529     picParam->num_ref_frames = 0;
530 
531     // update DPB  from the reference list in each slice.
532     for (uint32_t slice = 0; slice < picData->num_slices; slice++) {
533         sliceParam = &(picData->slc_data[slice].slc_parms);
534 
535         for (int32_t list = 0; list < 2; list++) {
536             refList = (list == 0) ? sliceParam->RefPicList0 :
537                                     sliceParam->RefPicList1;
538             activeMinus1 = (list == 0) ? sliceParam->num_ref_idx_l0_active_minus1 :
539                                          sliceParam->num_ref_idx_l1_active_minus1;
540             if (activeMinus1 >= REF_LIST_SIZE) {
541                 return DECODE_PARSER_FAIL;
542             }
543             for (uint8_t item = 0; item < (uint8_t)(activeMinus1 + 1); item++, refList++) {
544                 if (refList->flags & VA_PICTURE_H264_INVALID) {
545                     break;
546                 }
547                 found = false;
548                 refFrame = picParam->ReferenceFrames;
549                 for (uint8_t frame = 0; frame < picParam->num_ref_frames; frame++, refFrame++) {
550                     if (refFrame->TopFieldOrderCnt == refList->TopFieldOrderCnt) {
551                         ///check for complementary field
552                         flags = refFrame->flags | refList->flags;
553                         //If both TOP and BOTTOM are set, we'll clear those flags
554                         if ((flags & VA_PICTURE_H264_TOP_FIELD) &&
555                             (flags & VA_PICTURE_H264_BOTTOM_FIELD)) {
556                             refFrame->flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
557                         }
558                         found = true;  //already in the DPB; will not add this one
559                         break;
560                     }
561                 }
562                 if (found == false) {
563                     // add a new reference to the DPB
564                     dpb->picture_id = findSurface(refList);
565                     if (dpb->picture_id == VA_INVALID_SURFACE) {
566                         if (mLastReference != NULL) {
567                             dpb->picture_id = mLastReference->renderBuffer.surface;
568                         } else {
569                             ETRACE("Reference frame %d is missing. Stop updating references frames.", getPOC(refList));
570                             return DECODE_NO_REFERENCE;
571                         }
572                     }
573                     dpb->flags = refList->flags;
574                     // if it's bottom field in dpb, there must have top field in DPB,
575                     // so clear the bottom flag, or will confuse VED to address top field
576                     if (dpb->flags & VA_PICTURE_H264_BOTTOM_FIELD)
577                         dpb->flags &= (~VA_PICTURE_H264_BOTTOM_FIELD);
578                     dpb->frame_idx = refList->frame_idx;
579                     dpb->TopFieldOrderCnt = refList->TopFieldOrderCnt;
580                     dpb->BottomFieldOrderCnt = refList->BottomFieldOrderCnt;
581                     dpb++;
582                     picParam->num_ref_frames++;
583                 }
584             }
585         }
586     }
587     return DECODE_SUCCESS;
588 }
589 
removeReferenceFromDPB(VAPictureParameterBufferH264 * picParam)590 void VideoDecoderAVC::removeReferenceFromDPB(VAPictureParameterBufferH264 *picParam) {
591     // remove the current frame from DPB as it can't be decoded.
592     if ((picParam->CurrPic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
593         (picParam->CurrPic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
594         DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
595         int32_t poc = getPOC(&(picParam->CurrPic));
596         for (int32_t i = 0; i < DPB_SIZE; i++, dpb++) {
597             if (poc == dpb->poc) {
598                 dpb->poc = (int32_t)POC_DEFAULT;
599                 if (dpb->surfaceBuffer) {
600                     dpb->surfaceBuffer->asReferernce = false;
601                 }
602                 dpb->surfaceBuffer = NULL;
603                 break;
604             }
605         }
606     }
607 }
608 
getPOC(VAPictureH264 * pic)609 int32_t VideoDecoderAVC::getPOC(VAPictureH264 *pic) {
610     if (pic->flags & VA_PICTURE_H264_BOTTOM_FIELD) {
611         return pic->BottomFieldOrderCnt;
612     }
613     return pic->TopFieldOrderCnt;
614 }
615 
findSurface(VAPictureH264 * pic)616 VASurfaceID VideoDecoderAVC::findSurface(VAPictureH264 *pic) {
617     VideoSurfaceBuffer *p = findSurfaceBuffer(pic);
618     if (p == NULL) {
619         ETRACE("Could not find surface for poc %d", getPOC(pic));
620         return VA_INVALID_SURFACE;
621     }
622     return p->renderBuffer.surface;
623 }
624 
findSurfaceBuffer(VAPictureH264 * pic)625 VideoSurfaceBuffer* VideoDecoderAVC::findSurfaceBuffer(VAPictureH264 *pic) {
626     DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
627     for (int32_t i = 0; i < DPB_SIZE; i++, dpb++) {
628         if (dpb->poc == pic->BottomFieldOrderCnt ||
629             dpb->poc == pic->TopFieldOrderCnt) {
630             // TODO: remove these debugging codes
631             if (dpb->surfaceBuffer == NULL) {
632                 ETRACE("Invalid surface buffer in the DPB for poc %d.", getPOC(pic));
633             }
634             return dpb->surfaceBuffer;
635         }
636     }
637     // ETRACE("Unable to find surface for poc %d", getPOC(pic));
638     return NULL;
639 }
640 
findRefSurfaceBuffer(VAPictureH264 * pic)641 VideoSurfaceBuffer* VideoDecoderAVC::findRefSurfaceBuffer(VAPictureH264 *pic) {
642     DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
643     // always looking for the latest one in the DPB, in case ref frames have same POC
644     dpb += (DPB_SIZE - 1);
645     for (int32_t i = DPB_SIZE; i > 0; i--, dpb--) {
646         if (dpb->poc == pic->BottomFieldOrderCnt ||
647             dpb->poc == pic->TopFieldOrderCnt) {
648             // TODO: remove these debugging codes
649             if (dpb->surfaceBuffer == NULL) {
650                 ETRACE("Invalid surface buffer in the DPB for poc %d.", getPOC(pic));
651             }
652             return dpb->surfaceBuffer;
653         }
654     }
655     ETRACE("Unable to find surface for poc %d", getPOC(pic));
656     return NULL;
657 }
658 
invalidateDPB(int toggle)659 void VideoDecoderAVC::invalidateDPB(int toggle) {
660     DecodedPictureBuffer* p = mDPBs[toggle];
661     for (int i = 0; i < DPB_SIZE; i++) {
662         p->poc = (int32_t) POC_DEFAULT;
663         p->surfaceBuffer = NULL;
664         p++;
665     }
666 }
667 
clearAsReference(int toggle)668 void VideoDecoderAVC::clearAsReference(int toggle) {
669     DecodedPictureBuffer* p = mDPBs[toggle];
670     for (int i = 0; i < DPB_SIZE; i++) {
671         if (p->surfaceBuffer) {
672             p->surfaceBuffer->asReferernce = false;
673         }
674         p++;
675     }
676 }
677 
startVA(vbp_data_h264 * data)678 Decode_Status VideoDecoderAVC::startVA(vbp_data_h264 *data) {
679     int32_t DPBSize = getDPBSize(data);
680 
681     //Use high profile for all kinds of H.264 profiles (baseline, main and high) except for constrained baseline
682     VAProfile vaProfile = VAProfileH264High;
683 
684     // TODO: determine when to use VAProfileH264ConstrainedBaseline, set only if we are told to do so
685     if ((data->codec_data->profile_idc == 66 || data->codec_data->constraint_set0_flag == 1) &&
686         data->codec_data->constraint_set1_flag == 1) {
687         if (mErrorConcealment) {
688             vaProfile = VAProfileH264ConstrainedBaseline;
689         }
690     }
691 
692     VideoDecoderBase::setOutputWindowSize(mConfigBuffer.flag & WANT_ADAPTIVE_PLAYBACK ? OUTPUT_WINDOW_SIZE : DPBSize);
693     updateFormatInfo(data);
694 
695    // for 1080p, limit the total surface to 19, according the hardware limitation
696    // change the max surface number from 19->10 to workaround memory shortage
697    // remove the workaround
698     if(mVideoFormatInfo.height == 1088 && DPBSize + AVC_EXTRA_SURFACE_NUMBER > 19) {
699         DPBSize = 19 - AVC_EXTRA_SURFACE_NUMBER;
700     }
701 
702     return VideoDecoderBase::setupVA(DPBSize + AVC_EXTRA_SURFACE_NUMBER, vaProfile);
703 }
704 
updateFormatInfo(vbp_data_h264 * data)705 void VideoDecoderAVC::updateFormatInfo(vbp_data_h264 *data) {
706     // new video size
707     uint32_t width = (data->pic_data[0].pic_parms->picture_width_in_mbs_minus1 + 1) * 16;
708     uint32_t height = (data->pic_data[0].pic_parms->picture_height_in_mbs_minus1 + 1) * 16;
709     ITRACE("updateFormatInfo: current size: %d x %d, new size: %d x %d",
710         mVideoFormatInfo.width, mVideoFormatInfo.height, width, height);
711 
712     if (mConfigBuffer.flag & WANT_ADAPTIVE_PLAYBACK) {
713         // When Adaptive playback is enabled, turn off low delay mode.
714         // Otherwise there may be a 240ms stuttering if the output mode is changed from LowDelay to Delay.
715         enableLowDelayMode(false);
716     } else {
717         // for baseline profile or constrained high profile, enable low delay mode automatically
718         enableLowDelayMode((data->codec_data->profile_idc == 66) || (data->codec_data->profile_idc == 100 && data->codec_data->constraint_set4_flag == 1 && data->codec_data->constraint_set5_flag == 1));
719     }
720 
721     if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
722         pthread_mutex_lock(&mFormatLock);
723     }
724 
725     if ((mVideoFormatInfo.width != width ||
726         mVideoFormatInfo.height != height) &&
727         width && height) {
728         if (VideoDecoderBase::alignMB(mVideoFormatInfo.width) != width ||
729             VideoDecoderBase::alignMB(mVideoFormatInfo.height) != height) {
730             mSizeChanged = true;
731             ITRACE("Video size is changed.");
732         }
733         mVideoFormatInfo.width = width;
734         mVideoFormatInfo.height = height;
735     }
736 
737     // video_range has default value of 0.
738     mVideoFormatInfo.videoRange = data->codec_data->video_full_range_flag;
739 
740     switch (data->codec_data->matrix_coefficients) {
741         case 1:
742             mVideoFormatInfo.colorMatrix = VA_SRC_BT709;
743             break;
744 
745         // ITU-R Recommendation BT.470-6 System B, G (MP4), same as
746         // SMPTE 170M/BT601
747         case 5:
748         case 6:
749             mVideoFormatInfo.colorMatrix = VA_SRC_BT601;
750             break;
751 
752         default:
753             // unknown color matrix, set to 0 so color space flag will not be set.
754             mVideoFormatInfo.colorMatrix = 0;
755             break;
756     }
757     mVideoFormatInfo.aspectX = data->codec_data->sar_width;
758     mVideoFormatInfo.aspectY = data->codec_data->sar_height;
759     mVideoFormatInfo.bitrate = data->codec_data->bit_rate;
760     mVideoFormatInfo.cropLeft = data->codec_data->crop_left;
761     mVideoFormatInfo.cropRight = data->codec_data->crop_right;
762     mVideoFormatInfo.cropTop = data->codec_data->crop_top;
763     mVideoFormatInfo.cropBottom = data->codec_data->crop_bottom;
764 
765     ITRACE("Cropping: left = %d, top = %d, right = %d, bottom = %d",
766         data->codec_data->crop_left,
767         data->codec_data->crop_top,
768         data->codec_data->crop_right,
769         data->codec_data->crop_bottom);
770 
771     if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
772         mVideoFormatInfo.actualBufferNeeded = mConfigBuffer.surfaceNumber;
773     } else {
774         // The number of actual buffer needed is
775         // outputQueue + nativewindow_owned + num_ref_frames + widi_need_max + 1(available buffer)
776         // while outputQueue = DPB < 8? DPB :8
777         mVideoFormatInfo.actualBufferNeeded = mOutputWindowSize + NW_CONSUMED /* Owned by native window */
778                                               + data->codec_data->num_ref_frames
779 #ifndef USE_GEN_HW
780                                               + HDMI_CONSUMED /* Two extra buffers are needed for native window buffer cycling */
781                                               + (mWiDiOn ? WIDI_CONSUMED : 0) /* WiDi maximum needs */
782 #endif
783                                               + 1;
784     }
785 
786     ITRACE("actualBufferNeeded =%d", mVideoFormatInfo.actualBufferNeeded);
787 
788     if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
789         if (mSizeChanged
790             || isWiDiStatusChanged()
791             || (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber)) {
792             mVideoFormatInfo.valid = false;
793         } else {
794             mVideoFormatInfo.valid = true;
795         }
796 
797         pthread_mutex_unlock(&mFormatLock);
798     } else {
799         mVideoFormatInfo.valid = true;
800     }
801 
802     setRenderRect();
803     setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange);
804 }
805 
isWiDiStatusChanged()806 bool VideoDecoderAVC::isWiDiStatusChanged() {
807 #ifndef USE_GEN_HW
808     if (mWiDiOn)
809         return false;
810 
811     if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION)
812         return false;
813 
814     if (!(mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER))
815         return false;
816 
817     char prop[PROPERTY_VALUE_MAX];
818     bool widi_on = (property_get("media.widi.enabled", prop, NULL) > 0) &&
819                     (!strcmp(prop, "1") || !strcasecmp(prop, "true"));
820     if (widi_on) {
821         mVideoFormatInfo.actualBufferNeeded += WIDI_CONSUMED;
822         mWiDiOn = true;
823         ITRACE("WiDi is enabled, actual buffer needed is %d", mVideoFormatInfo.actualBufferNeeded);
824         return true;
825     }
826     return false;
827 #else
828     return false;
829 #endif
830 }
831 
handleNewSequence(vbp_data_h264 * data)832 Decode_Status VideoDecoderAVC::handleNewSequence(vbp_data_h264 *data) {
833     Decode_Status status;
834     updateFormatInfo(data);
835 
836     bool rawDataMode = !(mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER);
837     if (rawDataMode && mSizeChanged) {
838         flushSurfaceBuffers();
839         mSizeChanged = false;
840         return DECODE_FORMAT_CHANGE;
841     }
842 
843     bool needFlush = false;
844     if (!rawDataMode) {
845         if (mStoreMetaData) {
846             needFlush = mSizeChanged
847                     || isWiDiStatusChanged()
848                     || (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber);
849         } else {
850             needFlush = (mVideoFormatInfo.width > mVideoFormatInfo.surfaceWidth)
851                     || (mVideoFormatInfo.height > mVideoFormatInfo.surfaceHeight)
852                     || isWiDiStatusChanged()
853                     || (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber);
854         }
855     }
856 
857     if (needFlush) {
858         if (mStoreMetaData) {
859             status = endDecodingFrame(false);
860             CHECK_STATUS("endDecodingFrame");
861         } else {
862             flushSurfaceBuffers();
863         }
864         mSizeChanged = false;
865         return DECODE_FORMAT_CHANGE;
866     } else
867         return DECODE_SUCCESS;
868 }
869 
isNewFrame(vbp_data_h264 * data,bool equalPTS)870 bool VideoDecoderAVC::isNewFrame(vbp_data_h264 *data, bool equalPTS) {
871     if (data->num_pictures == 0) {
872         ETRACE("num_pictures == 0");
873         return true;
874     }
875 
876     vbp_picture_data_h264* picData = data->pic_data;
877     if (picData->num_slices == 0) {
878         ETRACE("num_slices == 0");
879         return true;
880     }
881 
882     bool newFrame = false;
883     uint32_t fieldFlags = VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD;
884 
885     if (picData->slc_data[0].slc_parms.first_mb_in_slice != 0) {
886         // not the first slice, assume it is continuation of a partial frame
887         // TODO: check if it is new frame boundary as the first slice may get lost in streaming case.
888         WTRACE("first_mb_in_slice != 0");
889         if (!equalPTS) {
890             // return true if different timestamp, it is a workaround here for a streaming case
891             WTRACE("different PTS, treat it as a new frame");
892             return true;
893         }
894     } else {
895         if ((picData->pic_parms->CurrPic.flags & fieldFlags) == fieldFlags) {
896             ETRACE("Current picture has both odd field and even field.");
897         }
898         // current picture is a field or a frame, and buffer conains the first slice, check if the current picture and
899         // the last picture form an opposite field pair
900         if (((mLastPictureFlags | picData->pic_parms->CurrPic.flags) & fieldFlags) == fieldFlags) {
901             // opposite field
902             newFrame = false;
903             WTRACE("current picture is not at frame boundary.");
904             mLastPictureFlags = 0;
905         } else {
906             newFrame = true;
907             mLastPictureFlags = 0;
908             for (uint32_t i = 0; i < data->num_pictures; i++) {
909                 mLastPictureFlags |= data->pic_data[i].pic_parms->CurrPic.flags;
910             }
911             if ((mLastPictureFlags & fieldFlags) == fieldFlags) {
912                 // current buffer contains both odd field and even field.
913                 mLastPictureFlags = 0;
914             }
915         }
916     }
917 
918     return newFrame;
919 }
920 
getDPBSize(vbp_data_h264 * data)921 int32_t VideoDecoderAVC::getDPBSize(vbp_data_h264 *data) {
922     // 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 384 ), 16
923     struct DPBTable {
924         int32_t level;
925         float maxDPB;
926     } dpbTable[] = {
927         {9,  148.5},
928         {10, 148.5},
929         {11, 337.5},
930         {12, 891.0},
931         {13, 891.0},
932         {20, 891.0},
933         {21, 1782.0},
934         {22, 3037.5},
935         {30, 3037.5},
936         {31, 6750.0},
937         {32, 7680.0},
938         {40, 12288.0},
939         {41, 12288.0},
940         {42, 13056.0},
941         {50, 41400.0},
942         {51, 69120.0}
943     };
944 
945     int32_t count = sizeof(dpbTable)/sizeof(DPBTable);
946     float maxDPB = 0;
947     for (int32_t i = 0; i < count; i++)
948     {
949         if (dpbTable[i].level == data->codec_data->level_idc) {
950             maxDPB = dpbTable[i].maxDPB;
951             break;
952         }
953     }
954 
955     int32_t maxDPBSize = maxDPB * 1024 / (
956         (data->pic_data[0].pic_parms->picture_width_in_mbs_minus1 + 1) *
957         (data->pic_data[0].pic_parms->picture_height_in_mbs_minus1 + 1) *
958         384);
959 
960     if (maxDPBSize > 16) {
961         maxDPBSize = 16;
962     } else if (maxDPBSize == 0) {
963         maxDPBSize = 3;
964     }
965     if(maxDPBSize < data->codec_data->num_ref_frames) {
966         maxDPBSize = data->codec_data->num_ref_frames;
967     }
968 
969     // add one extra frame for current frame.
970     maxDPBSize += 1;
971     ITRACE("maxDPBSize = %d, num_ref_frame = %d", maxDPBSize, data->codec_data->num_ref_frames);
972     return maxDPBSize;
973 }
974 
checkHardwareCapability()975 Decode_Status VideoDecoderAVC::checkHardwareCapability() {
976 #ifndef USE_GEN_HW
977     VAStatus vaStatus;
978     VAConfigAttrib cfgAttribs[2];
979     cfgAttribs[0].type = VAConfigAttribMaxPictureWidth;
980     cfgAttribs[1].type = VAConfigAttribMaxPictureHeight;
981     vaStatus = vaGetConfigAttributes(mVADisplay, VAProfileH264High,
982             VAEntrypointVLD, cfgAttribs, 2);
983     CHECK_VA_STATUS("vaGetConfigAttributes");
984     if (cfgAttribs[0].value * cfgAttribs[1].value < (uint32_t)mVideoFormatInfo.width * (uint32_t)mVideoFormatInfo.height) {
985         ETRACE("hardware supports resolution %d * %d smaller than the clip resolution %d * %d",
986                 cfgAttribs[0].value, cfgAttribs[1].value, mVideoFormatInfo.width, mVideoFormatInfo.height);
987         return DECODE_DRIVER_FAIL;
988     }
989 #endif
990     return DECODE_SUCCESS;
991 }
992 
993 #ifdef USE_AVC_SHORT_FORMAT
getCodecSpecificConfigs(VAProfile profile,VAConfigID * config)994 Decode_Status VideoDecoderAVC::getCodecSpecificConfigs(
995     VAProfile profile, VAConfigID *config)
996 {
997     VAStatus vaStatus;
998     VAConfigAttrib attrib[2];
999 
1000     if (config == NULL) {
1001         ETRACE("Invalid parameter!");
1002         return DECODE_FAIL;
1003     }
1004 
1005     attrib[0].type = VAConfigAttribRTFormat;
1006     attrib[0].value = VA_RT_FORMAT_YUV420;
1007     attrib[1].type = VAConfigAttribDecSliceMode;
1008     attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
1009 
1010     vaStatus = vaGetConfigAttributes(mVADisplay,profile,VAEntrypointVLD, &attrib[1], 1);
1011 
1012     if (attrib[1].value & VA_DEC_SLICE_MODE_BASE) {
1013         ITRACE("AVC short format used");
1014         attrib[1].value = VA_DEC_SLICE_MODE_BASE;
1015     } else if (attrib[1].value & VA_DEC_SLICE_MODE_NORMAL) {
1016         ITRACE("AVC long format ssed");
1017         attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
1018     } else {
1019         ETRACE("Unsupported Decode Slice Mode!");
1020         return DECODE_FAIL;
1021     }
1022 
1023     vaStatus = vaCreateConfig(
1024             mVADisplay,
1025             profile,
1026             VAEntrypointVLD,
1027             &attrib[0],
1028             2,
1029             config);
1030     CHECK_VA_STATUS("vaCreateConfig");
1031 
1032     return DECODE_SUCCESS;
1033 }
1034 #endif
1035