libmix/videodecoder: Patches porting from R2 to R3
BZ: 18443
original patches:
27557 - libmix: fix issue when B frame number between 2 P frames is bigger than 2 (BZ: 17193)
26595 - decoder: expose VA context surfaces vie getInfo() (BZ: 14001)
24710 - libmix: if the frame is sync frame in container, skip the reference frame check (BZ: 8998)
24457 - Flush decoded buffer while resolution is changed. (BZ: 14251)
Signed-off-by: Weian Chen <weian.chen@intel.com>
Change-Id: Ic954d2a7972649e8e21021b6547b31c2e0d78e57
Reviewed-on: http://android.intel.com:8080/30008
Reviewed-by: Ding, Haitao <haitao.ding@intel.com>
Tested-by: Ding, Haitao <haitao.ding@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/videodecoder/VideoDecoderAVC.cpp b/videodecoder/VideoDecoderAVC.cpp
index 7ceb4a6..6613935 100644
--- a/videodecoder/VideoDecoderAVC.cpp
+++ b/videodecoder/VideoDecoderAVC.cpp
@@ -136,7 +136,7 @@
(pic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE));
}
#endif
- if (data->new_sps) {
+ if (data->new_sps || data->new_pps) {
status = handleNewSequence(data);
CHECK_STATUS("handleNewSequence");
}
@@ -144,7 +144,9 @@
// first pic_data always exists, check if any slice is parsed
if (data->pic_data[0].num_slices == 0) {
ITRACE("No slice available for decoding.");
- return DECODE_SUCCESS;
+ status = mSizeChanged ? DECODE_FORMAT_CHANGE : DECODE_SUCCESS;
+ mSizeChanged = false;
+ return status;
}
uint64_t lastPTS = mCurrentPTS;
@@ -674,7 +676,7 @@
} else {
WTRACE("Video size changed from %d x %d to %d x %d.", width, height,
mVideoFormatInfo.width, mVideoFormatInfo.height);
- flush();
+ flushSurfaceBuffers();
}
return DECODE_SUCCESS;
}
diff --git a/videodecoder/VideoDecoderBase.cpp b/videodecoder/VideoDecoderBase.cpp
index c71eff6..0f7f4ae 100644
--- a/videodecoder/VideoDecoderBase.cpp
+++ b/videodecoder/VideoDecoderBase.cpp
@@ -568,6 +568,19 @@
return DECODE_SUCCESS;
}
+void VideoDecoderBase::flushSurfaceBuffers(void) {
+ endDecodingFrame(true);
+ VideoSurfaceBuffer *p = NULL;
+ while (mOutputHead) {
+ mOutputHead->renderBuffer.renderDone = true;
+ p = mOutputHead;
+ mOutputHead = mOutputHead->next;
+ p->next = NULL;
+ }
+ mOutputHead = NULL;
+ mOutputTail = NULL;
+}
+
Decode_Status VideoDecoderBase::endDecodingFrame(bool dropFrame) {
Decode_Status status = DECODE_SUCCESS;
VAStatus vaStatus;
@@ -731,6 +744,7 @@
mVideoFormatInfo.surfaceWidth = mVideoFormatInfo.width;
mVideoFormatInfo.surfaceHeight = mVideoFormatInfo.height;
mVideoFormatInfo.surfaceNumber = mNumSurfaces;
+ mVideoFormatInfo.ctxSurfaces = mSurfaces;
if ((int32_t)profile != VAProfileSoftwareDecoding) {
vaStatus = vaCreateContext(
diff --git a/videodecoder/VideoDecoderBase.h b/videodecoder/VideoDecoderBase.h
index 3df3e3f..8cf4579 100644
--- a/videodecoder/VideoDecoderBase.h
+++ b/videodecoder/VideoDecoderBase.h
@@ -62,6 +62,8 @@
virtual Decode_Status outputSurfaceBuffer(void);
// acquired surface buffer is not used
virtual Decode_Status releaseSurfaceBuffer(void);
+ // flush all decoded but not rendered buffers
+ virtual void flushSurfaceBuffers(void);
virtual Decode_Status endDecodingFrame(bool dropFrame);
virtual VideoSurfaceBuffer* findOutputByPoc(bool draining = false);
virtual VideoSurfaceBuffer* findOutputByPct(bool draining = false);
diff --git a/videodecoder/VideoDecoderDefs.h b/videodecoder/VideoDecoderDefs.h
index 5f1eac4..92a5668 100644
--- a/videodecoder/VideoDecoderDefs.h
+++ b/videodecoder/VideoDecoderDefs.h
@@ -88,6 +88,9 @@
// indicate if it use graphic buffer.
USE_NATIVE_GRAPHIC_BUFFER = 0x2000,
+ // indicate whether it is a sync frame in container
+ IS_SYNC_FRAME = 0x4000,
+
} VIDEO_BUFFER_FLAG;
struct VideoDecodeBuffer {
@@ -146,6 +149,7 @@
int32_t surfaceWidth;
int32_t surfaceHeight;
int32_t surfaceNumber;
+ VASurfaceID *ctxSurfaces;
int32_t aspectX;
int32_t aspectY;
int32_t cropLeft;
diff --git a/videodecoder/VideoDecoderMPEG4.cpp b/videodecoder/VideoDecoderMPEG4.cpp
index 5975436..2abcf37 100644
--- a/videodecoder/VideoDecoderMPEG4.cpp
+++ b/videodecoder/VideoDecoderMPEG4.cpp
@@ -73,6 +73,11 @@
if (buffer == NULL) {
return DECODE_INVALID_DATA;
}
+ if (buffer->flag & IS_SYNC_FRAME) {
+ mIsSyncFrame = true;
+ } else {
+ mIsSyncFrame = false;
+ }
status = VideoDecoderBase::parseBuffer(
buffer->data,
buffer->size,
@@ -209,7 +214,7 @@
return DECODE_NO_REFERENCE;
}
} else if (codingType == MP4_VOP_TYPE_P || codingType == MP4_VOP_TYPE_S) {
- if (mLastReference == NULL) {
+ if (mLastReference == NULL&& mIsSyncFrame == false) {
return DECODE_NO_REFERENCE;
}
}
@@ -412,10 +417,14 @@
picParam->backward_reference_picture = VA_INVALID_SURFACE;
break;
case MP4_VOP_TYPE_P:
- if (mLastReference == NULL) {
+ if (mLastReference == NULL&& mIsSyncFrame == false) {
return DECODE_NO_REFERENCE;
}
- picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
+ if (mLastReference != NULL) {
+ picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
+ } else {
+ picParam->forward_reference_picture = VA_INVALID_SURFACE;
+ }
picParam->backward_reference_picture = VA_INVALID_SURFACE;
break;
case MP4_VOP_TYPE_B:
diff --git a/videodecoder/VideoDecoderMPEG4.h b/videodecoder/VideoDecoderMPEG4.h
index 79e5b99..300b583 100644
--- a/videodecoder/VideoDecoderMPEG4.h
+++ b/videodecoder/VideoDecoderMPEG4.h
@@ -64,6 +64,7 @@
bool mExpectingNVOP; // indicate if future n-vop is a placeholder of a packed frame
bool mSendIQMatrixBuf; // indicate if iq_matrix_buffer is sent to driver
int32_t mLastVOPCodingType;
+ bool mIsSyncFrame; // indicate if it is SyncFrame in container
};