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