[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);