[PORT FROM MAIN] VideoDecoderAVC: Flush DPB in VideoDecoderBase::flush()
BZ: 61843
Original libmixvbp_h264 didn't flush DPB when
VideoDecoderBase::flush() was called. For open-GOP
clips who has non-IDR keyframes, a B frame refering
to both the keyframe and the previous GOP may get
decode error.
Change-Id: I5ee2f8b091ac74ccdbb276f26145322bc72415e0
Signed-off-by: Cheng Yao <yao.cheng@intel.com>
Reviewed-on: http://android.intel.com:8080/76397
Tested-by: Tong, BoX <box.tong@intel.com>
Reviewed-by: Tong, BoX <box.tong@intel.com>
Reviewed-by: cactus <cactus@intel.com>
Tested-by: cactus <cactus@intel.com>
diff --git a/mix_vbp/viddec_fw/fw/codecs/h264/parser/viddec_h264_parse.c b/mix_vbp/viddec_fw/fw/codecs/h264/parser/viddec_h264_parse.c
index 2694f7d..473c64e 100644
--- a/mix_vbp/viddec_fw/fw/codecs/h264/parser/viddec_h264_parse.c
+++ b/mix_vbp/viddec_fw/fw/codecs/h264/parser/viddec_h264_parse.c
@@ -562,6 +562,37 @@
+ sizeof(int32_t) * MAX_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE;
}
+/* ------------------------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------------------------ */
+#ifdef VBP
+void viddec_h264_flush(void *parent, void *ctxt)
+#else
+static void viddec_h264_flush(void *parent, void *ctxt)
+#endif
+{
+ int i;
+ struct h264_viddec_parser* parser = ctxt;
+ h264_Info * pInfo = &(parser->info);
+
+ /* flush the dpb and output all */
+ h264_dpb_flush_dpb(pInfo, 1, pInfo->img.second_field, pInfo->active_SPS.num_ref_frames);
+
+ /* reset the dpb to the initial state, avoid parser store
+ wrong data to dpb in next slice parsing */
+ h264_DecodedPictureBuffer *p_dpb = &pInfo->dpb;
+ for (i = 0; i < NUM_DPB_FRAME_STORES; i++)
+ {
+ p_dpb->fs[i].fs_idc = MPD_DPB_FS_NULL_IDC;
+ p_dpb->fs_dpb_idc[i] = MPD_DPB_FS_NULL_IDC;
+ }
+ p_dpb->used_size = 0;
+ p_dpb->fs_dec_idc = MPD_DPB_FS_NULL_IDC;
+ p_dpb->fs_non_exist_idc = MPD_DPB_FS_NULL_IDC;
+
+ return;
+}
+
#ifndef VBP
void viddec_h264_get_ops(viddec_parser_ops_t *ops)
{
@@ -571,6 +602,7 @@
ops->get_cxt_size = viddec_h264_get_context_size;
ops->is_wkld_done = viddec_h264_wkld_done;
ops->is_frame_start = viddec_h264_is_frame_start;
+ ops->flush = viddec_h264_flush;
return;
}
#endif
diff --git a/mix_vbp/viddec_fw/fw/parser/include/viddec_parser_ops.h b/mix_vbp/viddec_fw/fw/parser/include/viddec_parser_ops.h
index 608c0e7..561b179 100644
--- a/mix_vbp/viddec_fw/fw/parser/include/viddec_parser_ops.h
+++ b/mix_vbp/viddec_fw/fw/parser/include/viddec_parser_ops.h
@@ -25,6 +25,8 @@
typedef uint32_t (*fn_is_frame_start)(void *ctxt);
typedef uint32_t (*fn_gen_contrib_tags)(void *parent, uint32_t ignore_partial);
typedef uint32_t (*fn_gen_assoc_tags)(void *parent);
+typedef void (*fn_flush_parser) (void *parent, void *ctxt);
+
typedef struct
{
@@ -36,6 +38,7 @@
fn_is_frame_start is_frame_start;
fn_gen_contrib_tags gen_contrib_tags;
fn_gen_assoc_tags gen_assoc_tags;
+ fn_flush_parser flush;
} viddec_parser_ops_t;
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
index 8592e64..c1ccef7 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
@@ -1,5 +1,5 @@
/* INTEL CONFIDENTIAL
-* Copyright (c) 2009 Intel Corporation. All rights reserved.
+* Copyright (c) 2009, 2012 Intel Corporation. All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
@@ -187,6 +187,14 @@
return VBP_LOAD;
}
#endif
+
+ pcontext->parser_ops->flush = dlsym(pcontext->fd_parser, "viddec_h264_flush");;
+ if (NULL == pcontext->parser_ops->flush)
+ {
+ ETRACE ("Failed to set entry point." );
+ return VBP_LOAD;
+ }
+
/* entry point not needed */
pcontext->parser_ops->is_frame_start = NULL;
return VBP_OK;
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_mp42_parser.c b/mix_vbp/viddec_fw/fw/parser/vbp_mp42_parser.c
index dfa536b..5e4c887 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_mp42_parser.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_mp42_parser.c
@@ -1,5 +1,5 @@
/* INTEL CONFIDENTIAL
-* Copyright (c) 2009 Intel Corporation. All rights reserved.
+* Copyright (c) 2009, 2012 Intel Corporation. All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
@@ -137,6 +137,10 @@
return VBP_LOAD;
}
#endif
+
+ /* entry point not needed */
+ pcontext->parser_ops->flush = NULL;
+
return VBP_OK;
}
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_utils.c b/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
index 83a38ac..3983387 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
@@ -1,5 +1,5 @@
/* INTEL CONFIDENTIAL
-* Copyright (c) 2009 Intel Corporation. All rights reserved.
+* Copyright (c) 2009, 2012 Intel Corporation. All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
@@ -571,11 +571,16 @@
/**
*
- * flush parsing buffer. Currently it is no op.
+ * flush parsing buffer. Currently always succeed.
*
*/
uint32 vbp_utils_flush(vbp_context *pcontext)
{
+ viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
+ viddec_parser_ops_t *ops = pcontext->parser_ops;
+ if (ops->flush != NULL) {
+ ops->flush((void *)cxt, (void *)&(cxt->codec_data[0]));
+ }
return VBP_OK;
}
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_vc1_parser.c b/mix_vbp/viddec_fw/fw/parser/vbp_vc1_parser.c
index 3ab3467..751227e 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_vc1_parser.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_vc1_parser.c
@@ -1,5 +1,5 @@
/* INTEL CONFIDENTIAL
-* Copyright (c) 2009 Intel Corporation. All rights reserved.
+* Copyright (c) 2009, 2012 Intel Corporation. All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
@@ -120,6 +120,9 @@
return VBP_LOAD;
}
+ /* entry point not needed */
+ pcontext->parser_ops->flush = NULL;
+
return VBP_OK;
}
diff --git a/videodecoder/VideoDecoderBase.cpp b/videodecoder/VideoDecoderBase.cpp
index c89b9b7..d5a47dd 100644
--- a/videodecoder/VideoDecoderBase.cpp
+++ b/videodecoder/VideoDecoderBase.cpp
@@ -1,5 +1,5 @@
/* INTEL CONFIDENTIAL
-* Copyright (c) 2009-2011 Intel Corporation. All rights reserved.
+* Copyright (c) 2009-2012 Intel Corporation. All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
@@ -200,6 +200,11 @@
mOutputTail = NULL;
mDecodingFrame = false;
+ // flush vbp parser
+ if (mParserHandle && (vbp_flush(mParserHandle) != VBP_OK)) {
+ WTRACE("Failed to flush parser. Continue");
+ }
+
// initialize surface buffer without resetting mapped/raw data
initSurfaceBuffer(false);