summaryrefslogtreecommitdiff
authormiaohong chen <miaohong.chen@amlogic.com>2020-04-30 07:41:29 (GMT)
committer Shen Liu <shen.liu@amlogic.com>2020-05-06 02:43:20 (GMT)
commit02808d6db3ae433d17733e5c6be8fa985252806e (patch)
treed99b951f00af0ceeeebfac29f10e280642d8a51f
parentfb8fe6e1ef0314160ce02a10ee7fe3a5d89d228e (diff)
downloadmedia_modules-02808d6db3ae433d17733e5c6be8fa985252806e.zip
media_modules-02808d6db3ae433d17733e5c6be8fa985252806e.tar.gz
media_modules-02808d6db3ae433d17733e5c6be8fa985252806e.tar.bz2
media_modules: vmh264 fast output optimization [1/1]
PD#SWPL-2682 Problem: there is issue in fast output handle Solution: optimaztion vmh264 dpb manangement to always output first decode I frame asap. all frames that poc less than the I will be discard. it is helpful for KPI of projects Verify: U212 Change-Id: I6e9f6b908a2321370a7c537032c898b266dcd6e9 Signed-off-by: miaohong chen <miaohong.chen@amlogic.com>
Diffstat
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.c51
-rw-r--r--drivers/frame_provider/decoder/h264_multi/h264_dpb.h9
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c7
3 files changed, 56 insertions, 11 deletions
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
index ff9e92f..23231af 100644
--- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
+++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c
@@ -2169,7 +2169,8 @@ static void get_smallest_poc(struct DecodedPictureBuffer *p_Dpb, int *poc,
/* rain */
if ((*poc > p_Dpb->fs[i]->poc) &&
(!p_Dpb->fs[i]->is_output) &&
- (!p_Dpb->fs[i]->pre_output)) {
+ (!p_Dpb->fs[i]->pre_output) &&
+ (p_Dpb->fs[i]->is_used == 3)) {
#else
if ((*poc > p_Dpb->fs[i]->poc) && (!p_Dpb->fs[i]->is_output)) {
#endif
@@ -2189,8 +2190,20 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
if (!flush_flag) {
for (i = 0; i < p_Dpb->used_size; i++) {
if ((!p_Dpb->fs[i]->is_output) &&
- (!p_Dpb->fs[i]->pre_output)) {
+ (!p_Dpb->fs[i]->pre_output) && (p_Dpb->fs[i]->is_used == 3)) {
none_displayed_num++;
+ if ((p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE ||
+ p_H264_Dpb->first_insert_frame == FirstInsertFrm_RESET)
+ && (p_Dpb->fs[i]->is_used == 3)
+ && (p_Dpb->last_output_poc == INT_MIN)) {
+ if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_IDLE)
+ fast_output_flag = 1;
+ p_H264_Dpb->first_insert_frame = FirstInsertFrm_OUT;
+ p_H264_Dpb->first_output_poc = p_Dpb->fs[i]->poc;
+ dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
+ "%s first insert frame i %d poc %d frame_num %x\n",
+ __func__, i, p_Dpb->fs[i]->poc, p_Dpb->fs[i]->frame_num);
+ }
/*check poc even/odd*/
if (p_H264_Dpb->poc_even_odd_flag == 0 &&
p_H264_Dpb->decode_pic_count >= 3)
@@ -2202,10 +2215,6 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
if ((p_H264_Dpb->fast_output_enable & 0x1) &&
(p_Dpb->fs[i]->data_flag & IDR_FLAG))
fast_output_flag = 1;
- if (p_H264_Dpb->fast_output_enable & 0x6
- && p_H264_Dpb->poc_even_odd_flag
- && p_Dpb->last_output_poc == INT_MIN)
- fast_output_flag = 1;
if ((p_H264_Dpb->fast_output_enable & 0x2) &&
((p_Dpb->fs[i]->poc -
p_Dpb->last_output_poc)
@@ -2213,6 +2222,7 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
fast_output_flag = 1;
if ((p_H264_Dpb->fast_output_enable & 0x4) &&
(p_H264_Dpb->poc_even_odd_flag == 2) &&
+ (p_Dpb->fs[i]->is_used == 3) &&
((p_Dpb->fs[i]->poc -
p_Dpb->last_output_poc)
== 2))
@@ -2234,6 +2244,19 @@ int output_frames(struct h264_dpb_stru *p_H264_Dpb, unsigned char flush_flag)
if (is_used_for_reference(p_Dpb->fs[pos]))
return 0;
#endif
+ if (p_H264_Dpb->first_insert_frame == FirstInsertFrm_OUT) {
+ dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
+ "%s pos %d pos->poc %d first_output_poc %d \n",
+ __func__, pos, p_Dpb->fs[pos]->poc, p_H264_Dpb->first_output_poc);
+
+ if (p_Dpb->fs[pos]->poc < p_H264_Dpb->first_output_poc)
+ p_Dpb->fs[pos]->data_flag |= NODISP_FLAG;
+ else if (p_Dpb->last_output_poc != INT_MIN)
+ p_H264_Dpb->first_insert_frame = FirstInsertFrm_SKIPDONE;
+
+ dpb_print(p_H264_Dpb->decoder_index, PRINT_FLAG_DPB_DETAIL,
+ "%s first_insert_frame %d \n", __func__, p_H264_Dpb->first_insert_frame);
+ }
if (prepare_display_buf(p_H264_Dpb->vdec, p_Dpb->fs[pos]) >= 0)
p_Dpb->fs[pos]->pre_output = 1;
else {
@@ -3501,8 +3524,7 @@ int store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
while (remove_unused_frame_from_dpb(p_H264_Dpb))
;
- while (output_frames(p_H264_Dpb,
- (p_H264_Dpb->fast_output_enable == H264_OUTPUT_MODE_FAST)))
+ while (output_frames(p_H264_Dpb, 0))
;
/* check for duplicate frame number in short term reference buffer */
@@ -3557,8 +3579,12 @@ int store_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb,
check_num_ref(p_Dpb);
- if (p_H264_Dpb->fast_output_enable == H264_OUTPUT_MODE_FAST) {
- while (output_frames(p_H264_Dpb, 1))
+ if (p_H264_Dpb->fast_output_enable == H264_OUTPUT_MODE_FAST)
+ i = 1;
+ else
+ i = 0;
+ if (i || (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE)) {
+ while (output_frames(p_H264_Dpb, i))
;
}
@@ -5801,6 +5827,11 @@ int dpb_check_ref_list_error(
int i;
/*int j;*/
struct Slice *currSlice = &p_H264_Dpb->mSlice;
+
+ /* in first output, ignore ref check */
+ if (p_H264_Dpb->first_insert_frame < FirstInsertFrm_SKIPDONE)
+ return 0;
+
if ((currSlice->slice_type != I_SLICE) &&
(currSlice->slice_type != SI_SLICE)) {
for (i = 0; i < currSlice->listXsize[0]; i++) {
diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
index 94cc3e0..e28a822 100644
--- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
+++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h
@@ -453,6 +453,13 @@ enum ProfileIDC {
STEREO_HIGH = 128 /*!< YUV 4:2:0/8 "Stereo High"*/
};
+enum FirstInsertFrm_State {
+ FirstInsertFrm_IDLE = 0,
+ FirstInsertFrm_OUT = 1,
+ FirstInsertFrm_RESET = 2,
+ FirstInsertFrm_SKIPDONE = 3,
+};
+
struct SPSParameters {
unsigned int profile_idc;
int pic_order_cnt_type;
@@ -856,6 +863,8 @@ struct h264_dpb_stru {
unsigned int dec_dpb_status;
unsigned char buf_alloc_fail;
unsigned int dpb_error_flag;
+ unsigned int first_insert_frame;
+ int first_output_poc;
};
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c
index 8fe5acb..aa8fdf3 100644
--- a/drivers/frame_provider/decoder/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -265,7 +265,7 @@ static unsigned int force_sliding_margin;
bit[15:8]: the max count of skip frames after first I
3, start playing from IDR
*/
-static unsigned int first_i_policy = (15 << 8) | 2;
+static unsigned int first_i_policy = 1;
/*
fast_output_enable:
@@ -6082,6 +6082,9 @@ static void vh264_local_init(struct vdec_h264_hw_s *hw)
if (i_only_flag & 0x100)
hw->i_only = i_only_flag & 0xff;
+ if (hw->i_only)
+ hw->dpb.first_insert_frame = FirstInsertFrm_SKIPDONE;
+
if ((unsigned long) hw->vh264_amstream_dec_info.param
& 0x08)
hw->no_poc_reorder_flag = 1;
@@ -7762,6 +7765,7 @@ static void h264_reset_bufmgr(struct vdec_s *vdec)
int i;
ulong timeout;
struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
+ struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
#if 0
struct h264_dpb_stru *p_H264_Dpb = &hw->dpb;
int actual_dpb_size, max_reference_size;
@@ -7858,6 +7862,7 @@ static void h264_reset_bufmgr(struct vdec_s *vdec)
hw->cfg_param3,
hw->cfg_param4) < 0)
hw->stat |= DECODER_FATAL_ERROR_SIZE_OVERFLOW;
+ p_H264_Dpb->first_insert_frame = FirstInsertFrm_RESET;
hw->init_flag = 1;
hw->reset_bufmgr_count++;
#endif