From b0424c3f32c05aa36abdf90251b8e96d59ff2681 Mon Sep 17 00:00:00 2001 From: Peng Yixin Date: Thu, 12 Nov 2020 14:20:56 +0800 Subject: [PATCH] h264: stream mode vpts lookup fail [1/1] PD#SWPL-35520 Problem: Because the stream will checkin one vpts every three frames, and some of the frames size is small, it will cause lookup pts is successful but it doesn't match, resulting playback unsmooth. Solution: When lookup fail is detected many times and the frame size is small, pts is computed using duration to solve the problem. Verify: SC2 Change-Id: Ib9319fc46e28006ccca173c87faf88b88288ba66 Signed-off-by: Peng Yixin --- .../decoder/h264_multi/h264_dpb.c | 3 +++ .../decoder/h264_multi/h264_dpb.h | 2 ++ .../decoder/h264_multi/vmh264.c | 19 +++++++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c index 523ce9f..2e5bae0 100644 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.c +++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.c @@ -1579,10 +1579,12 @@ static void dpb_combine_field(struct h264_dpb_stru *p_H264_Dpb, fs->pts64 = 0; } fs->offset_delimiter = fs->top_field->offset_delimiter; + fs->decoded_frame_size = fs->top_field->pic_size + fs->bottom_field->pic_size; } else if (fs->bottom_field) { fs->pts = fs->bottom_field->pts; fs->pts64 = fs->bottom_field->pts64; fs->offset_delimiter = fs->bottom_field->offset_delimiter; + fs->decoded_frame_size = fs->top_field->pic_size + fs->bottom_field->pic_size; } /* FIELD_CODING ;*/ } @@ -1644,6 +1646,7 @@ static void insert_picture_in_dpb(struct h264_dpb_stru *p_H264_Dpb, fs->slice_type = p->slice_type; fs->frame_size = p->frame_size; fs->offset_delimiter = p->offset_delimiter; + fs->decoded_frame_size = p->pic_size; if (p->used_for_reference) { fs->is_reference = 3; fs->is_orig_reference = 3; diff --git a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h index 1b34098..85ee158 100644 --- a/drivers/frame_provider/decoder/h264_multi/h264_dpb.h +++ b/drivers/frame_provider/decoder/h264_multi/h264_dpb.h @@ -740,6 +740,7 @@ struct StorablePicture { int max_mv; int min_mv; int avg_mv; + u32 pic_size; }; struct FrameStore { @@ -822,6 +823,7 @@ struct FrameStore { u32 frame_size2; // For recording the chunk->size in frame mode bool show_frame; struct fence *fence; + u32 decoded_frame_size; }; /* #define DPB_SIZE_MAX 16 */ diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c index 025a8e7..7e2fded 100644 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c @@ -345,6 +345,9 @@ static u32 without_display_mode; static int loop_playback_poc_threshold = 400; static int poc_threshold = 50; +static u32 lookup_check_conut = 30; + + /* *[3:0] 0: default use config from omx. * 1: force enable fence. @@ -923,6 +926,9 @@ struct vdec_h264_hw_s { bool discard_dv_data; int vdec_pg_enable_flag; u32 save_reg_f; + u32 start_bit_cnt; + u32 right_frame_count; + u32 wrong_frame_count; }; static u32 again_threshold; @@ -2763,11 +2769,18 @@ static int post_prepare_process(struct vdec_s *vdec, struct FrameStore *frame) if ((pts_lookup_offset_us64(PTS_TYPE_VIDEO, frame->offset_delimiter, &frame->pts, &frame->frame_size, 0, &frame->pts64) == 0)) { - hw->last_pts64 = frame->pts64; - hw->last_pts = frame->pts; + if ((lookup_check_conut && (hw->vf_pre_count > lookup_check_conut) && + (hw->wrong_frame_count > hw->right_frame_count)) && + ((frame->decoded_frame_size * 2 < frame->frame_size))) { + /*resolve many frame only one check in pts, cause playback unsmooth issue*/ + frame->pts64 = hw->last_pts64 +DUR2PTS(hw->frame_dur) ; + frame->pts = hw->last_pts + DUR2PTS(hw->frame_dur); + } + hw->right_frame_count++; } else { frame->pts64 = hw->last_pts64 +DUR2PTS(hw->frame_dur) ; frame->pts = hw->last_pts + DUR2PTS(hw->frame_dur); + hw->wrong_frame_count++; } } dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, @@ -6045,6 +6058,7 @@ static int vh264_pic_done_proc(struct vdec_s *vdec) struct StorablePicture *pic = p_H264_Dpb->mVideo.dec_picture; u32 offset = pic->offset_delimiter; + pic->pic_size = (hw->start_bit_cnt - READ_VREG(VIFF_BIT_CNT)) >> 3; if (pts_pickout_offset_us64(PTS_TYPE_VIDEO, offset, &pic->pts, 0, &pic->pts64)) { pic->pts = 0; @@ -9519,6 +9533,7 @@ static void run(struct vdec_s *vdec, unsigned long mask, WRITE_VREG(H264_DECODE_INFO, (1<<13)); WRITE_VREG(H264_DECODE_SIZE, size); WRITE_VREG(VIFF_BIT_CNT, size * 8); + hw->start_bit_cnt = size * 8; } config_aux_buf(hw); config_decode_mode(hw); -- 2.20.1