author | miaohong 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) |
commit | 02808d6db3ae433d17733e5c6be8fa985252806e (patch) | |
tree | d99b951f00af0ceeeebfac29f10e280642d8a51f | |
parent | fb8fe6e1ef0314160ce02a10ee7fe3a5d89d228e (diff) | |
download | media_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>
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/h264_dpb.c | 51 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/h264_dpb.h | 9 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h264_multi/vmh264.c | 7 |
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 |