From: Nanxin Qin Date: Thu, 22 Oct 2020 06:23:55 +0000 (+0800) Subject: v4l: optimize the process of the resolution change. [1/1] X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=0baa899de596a1810cde8b1eb160d4d3fb4ac5a4;p=GitHub%2FLineageOS%2FG12%2Fandroid_hardware_amlogic_kernel-modules_media.git v4l: optimize the process of the resolution change. [1/1] PD#SWPL-34992 Problem: [RDK][Placto] H264 decoding error Solution: optimize the process of the resolution change. Verify: ab301 Change-Id: I1b70deb86e51169cc1d19f0ffb121d8053cc2957 Signed-off-by: Nanxin Qin --- diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c index b7c9046..29da0f1 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.c +++ b/drivers/amvdec_ports/aml_vcodec_dec.c @@ -1197,6 +1197,7 @@ static int vidioc_decoder_streamon(struct file *file, void *priv, mutex_unlock(&ctx->state_lock); ctx->is_stream_off = false; + ctx->v4l_resolution_change = false; } } else ctx->is_out_stream_off = false; @@ -2318,6 +2319,7 @@ static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) struct aml_vcodec_ctx *ctx = vb2_get_drv_priv(q); ctx->has_receive_eos = false; + v4l2_m2m_set_dst_buffered(ctx->fh.m2m_ctx, true); v4l_dbg(ctx, V4L_DEBUG_CODEC_PROT, diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h index f3ee0c5..e9195dc 100644 --- a/drivers/amvdec_ports/aml_vcodec_drv.h +++ b/drivers/amvdec_ports/aml_vcodec_drv.h @@ -408,6 +408,7 @@ struct aml_vdec_thread { * @param_change: indicate encode parameter type * @param_sets_from_ucode: if true indicate ps from ucode. * @v4l_codec_dpb_ready: queue buffer number greater than dpb. + # @v4l_resolution_change: indicate resolution change happend. * @comp: comp be used for sync picture information with decoder. * @config: used to set or get parms for application. * @picinfo: store picture info after header parsing. @@ -453,6 +454,7 @@ struct aml_vcodec_ctx { int dpb_size; bool param_sets_from_ucode; bool v4l_codec_dpb_ready; + bool v4l_resolution_change; struct completion comp; struct v4l2_config_parm config; struct vdec_pic_info picinfo; diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c index f441234..4390ccc 100644 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c @@ -906,7 +906,7 @@ struct vdec_h264_hw_s { unsigned int last_picture_slice_count; unsigned int first_pre_frame_num; #endif - unsigned int res_ch_flag; + u32 res_ch_flag; u32 b_frame_error_count; struct vdec_info gvs; u32 kpi_first_i_comming; @@ -937,6 +937,7 @@ static void set_frame_info(struct vdec_h264_hw_s *hw, struct vframe_s *vf, u32 index); static void release_aux_data(struct vdec_h264_hw_s *hw, int buf_spec_num); +static void clear_refer_bufs(struct vdec_h264_hw_s *hw); #ifdef ERROR_HANDLE_TEST static void h264_clear_dpb(struct vdec_h264_hw_s *hw); #endif @@ -2534,6 +2535,11 @@ unsigned char have_free_buf_spec(struct vdec_s *vdec) int allocated_count = 0; if (hw->is_used_v4l) { + struct h264_dpb_stru *dpb = &hw->dpb; + + if (dpb->mDPB.used_size >= dpb->mDPB.size - 1) + return 0; + for (i = 0; i < hw->dpb.mDPB.size; i++) { if (hw->buffer_spec[i].used == 0 && hw->buffer_spec[i].vf_ref == 0 && @@ -8734,6 +8740,7 @@ static int v4l_res_change(struct vdec_h264_hw_s *hw, vdec_v4l_set_ps_infos(ctx, &ps); vdec_v4l_res_ch_event(ctx); hw->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; amvdec_stop(); if (hw->mmu_enable) amhevc_stop(); @@ -8793,11 +8800,12 @@ static void vh264_work_implement(struct vdec_h264_hw_s *hw, } hw->v4l_params_parsed = true; vdec_v4l_set_ps_infos(ctx, &ps); + clear_refer_bufs(hw); + amvdec_stop(); if (hw->mmu_enable) amhevc_stop(); - } - else { + } else { if (vh264_set_params(hw, param1, param2, param3, param4, false) < 0) dpb_print(DECODE_ID(hw), 0, "set parameters error\n"); @@ -9237,10 +9245,11 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < run_ready_min_buf_num) ret = 0; + else if (ctx->v4l_codec_dpb_ready && + !is_buffer_available(vdec)) + ret = 0; } else { - if ((hw->res_ch_flag == 1) && - ((ctx->state <= AML_STATE_INIT) || - (ctx->state >= AML_STATE_FLUSHING))) + if (ctx->v4l_resolution_change) ret = 0; } } else if (!ctx->v4l_codec_dpb_ready) { @@ -9527,10 +9536,17 @@ static void run(struct vdec_s *vdec, unsigned long mask, static void clear_refer_bufs(struct vdec_h264_hw_s *hw) { int i; + ulong flags; - mutex_lock(&vmh264_mutex); - dealloc_buf_specs(hw, 1); - mutex_unlock(&vmh264_mutex); + if (hw->is_used_v4l) { + spin_lock_irqsave(&hw->bufspec_lock, flags); + for (i = 0; i < BUFSPEC_POOL_SIZE; i++) { + hw->buffer_spec[i].used = -1; + hw->buffer_spec[i].cma_alloc_addr = 0; + hw->buffer_spec[i].buf_adr = 0; + } + spin_unlock_irqrestore(&hw->bufspec_lock, flags); + } INIT_KFIFO(hw->display_q); INIT_KFIFO(hw->newframe_q); @@ -9565,11 +9581,7 @@ static void reset(struct vdec_s *vdec) } hw->eos = 0; hw->decode_pic_count = 0; - hw->dec_result = DEC_RESULT_NONE; - /* v4l will reset on every res change */ - hw->res_ch_flag = 0; - clear_refer_bufs(hw); reset_process_time(hw); h264_reset_bufmgr(vdec); @@ -9744,10 +9756,12 @@ static void h264_reset_bufmgr(struct vdec_s *vdec) /*hw->decode_pic_count = 0; hw->seq_info2 = 0;*/ - hw->cfg_param1 = READ_VREG(AV_SCRATCH_1); - hw->cfg_param2 = READ_VREG(AV_SCRATCH_2); - hw->cfg_param3 = READ_VREG(AV_SCRATCH_6); - hw->cfg_param4 = READ_VREG(AV_SCRATCH_B); + if (!hw->is_used_v4l) { + hw->cfg_param1 = READ_VREG(AV_SCRATCH_1); + hw->cfg_param2 = READ_VREG(AV_SCRATCH_2); + hw->cfg_param3 = READ_VREG(AV_SCRATCH_6); + hw->cfg_param4 = READ_VREG(AV_SCRATCH_B); + } if (vh264_set_params(hw, hw->cfg_param1, diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c index 132a3d0..257b779 100644 --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/drivers/frame_provider/decoder/h265/vh265.c @@ -1792,7 +1792,7 @@ struct hevc_state_s { u32 mem_map_mode; u32 performance_profile; struct vdec_info *gvs; - unsigned int res_ch_flag; + u32 res_ch_flag; bool ip_mode; u32 kpi_first_i_comming; u32 kpi_first_i_decoded; @@ -10081,6 +10081,7 @@ static int v4l_res_change(struct hevc_state_s *hevc, union param_u *rpm_param) vdec_v4l_res_ch_event(ctx); hevc->v4l_params_parsed = false; hevc->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; hevc->eos = 1; flush_output(hevc, NULL); //del_timer_sync(&hevc->timer); @@ -13187,9 +13188,7 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) run_ready_min_buf_num) ret = 0; } else { - if ((hevc->res_ch_flag == 1) && - ((ctx->state <= AML_STATE_INIT) || - (ctx->state >= AML_STATE_FLUSHING))) + if (ctx->v4l_resolution_change) ret = 0; } } else if (!ctx->v4l_codec_dpb_ready) { diff --git a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c index ba4c9f5..160ee6f 100644 --- a/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c +++ b/drivers/frame_provider/decoder/mjpeg/vmjpeg_multi.c @@ -227,7 +227,7 @@ struct vdec_mjpeg_hw_s { int dynamic_buf_num_margin; int sidebind_type; int sidebind_channel_id; - unsigned int res_ch_flag; + u32 res_ch_flag; u32 canvas_mode; u32 canvas_endian; }; @@ -319,6 +319,7 @@ static int v4l_res_change(struct vdec_mjpeg_hw_s *hw, int width, int height) vdec_v4l_res_ch_event(ctx); hw->v4l_params_parsed = false; hw->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; hw->eos = 1; notify_v4l_eos(hw_to_vdec(hw)); @@ -1281,9 +1282,7 @@ static unsigned long run_ready(struct vdec_s *vdec, run_ready_min_buf_num) return 0; } else { - if ((hw->res_ch_flag == 1) && - ((ctx->state <= AML_STATE_INIT) || - (ctx->state >= AML_STATE_FLUSHING))) + if (ctx->v4l_resolution_change) return 0; } } else if (!ctx->v4l_codec_dpb_ready) { diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index 59e096d..73925e9 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -326,7 +326,7 @@ struct vdec_mpeg12_hw_s { u32 dynamic_buf_num_margin; struct vdec_info gvs; struct vframe_qos_s vframe_qos; - unsigned int res_ch_flag; + u32 res_ch_flag; u32 i_only; u32 kpi_first_i_comming; u32 kpi_first_i_decoded; @@ -1818,6 +1818,7 @@ static int v4l_res_change(struct vdec_mpeg12_hw_s *hw, int width, int height) vdec_v4l_res_ch_event(ctx); hw->v4l_params_parsed = false; hw->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; hw->eos = 1; flush_output(hw); notify_v4l_eos(hw_to_vdec(hw)); @@ -3104,9 +3105,7 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) if (!ctx->v4l_codec_dpb_ready) return 0; } else { - if ((hw->res_ch_flag == 1) && - ((ctx->state <= AML_STATE_INIT) || - (ctx->state >= AML_STATE_FLUSHING))) + if (ctx->v4l_resolution_change) return 0; } } else if (!ctx->v4l_codec_dpb_ready) { diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 1ef8ced..1d34412 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -318,7 +318,7 @@ struct vdec_mpeg4_hw_s { u32 i_only; int sidebind_type; int sidebind_channel_id; - unsigned int res_ch_flag; + u32 res_ch_flag; unsigned int i_decoded_frames; unsigned int i_lost_frames; unsigned int i_concealed_frames; @@ -1015,6 +1015,7 @@ static int v4l_res_change(struct vdec_mpeg4_hw_s *hw, int width, int height) vdec_v4l_res_ch_event(ctx); hw->v4l_params_parsed = false; hw->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; hw->eos = 1; flush_output(hw); notify_v4l_eos(hw_to_vdec(hw)); @@ -2286,9 +2287,7 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) run_ready_min_buf_num) return 0; } else { - if ((hw->res_ch_flag == 1) && - ((ctx->state <= AML_STATE_INIT) || - (ctx->state >= AML_STATE_FLUSHING))) + if (ctx->v4l_resolution_change) return 0; } } else if (!ctx->v4l_codec_dpb_ready) { diff --git a/drivers/frame_provider/decoder/vav1/vav1.c b/drivers/frame_provider/decoder/vav1/vav1.c index c9e4cba..853c2e2 100644 --- a/drivers/frame_provider/decoder/vav1/vav1.c +++ b/drivers/frame_provider/decoder/vav1/vav1.c @@ -803,7 +803,7 @@ struct AV1HW_s { u32 mem_map_mode; u32 dynamic_buf_num_margin; struct vframe_s vframe_dummy; - unsigned int res_ch_flag; + u32 res_ch_flag; int buffer_wrap[FRAME_BUFFERS]; }; static void av1_dump_state(struct vdec_s *vdec); @@ -7850,6 +7850,7 @@ static int v4l_res_change(struct AV1HW_s *hw) vdec_v4l_res_ch_event(ctx); hw->v4l_params_parsed = false; hw->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; hw->eos = 1; //del_timer_sync(&pbi->timer); notify_v4l_eos(hw_to_vdec(hw)); @@ -9580,9 +9581,7 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) run_ready_min_buf_num) ret = 0; } else { - if ((hw->res_ch_flag == 1) && - ((ctx->state <= AML_STATE_INIT) || - (ctx->state >= AML_STATE_FLUSHING))) + if (ctx->v4l_resolution_change) ret = 0; } } else if (ctx->cap_pool.in < ctx->dpb_size) { diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c index 92fb605..0b81f1b 100644 --- a/drivers/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/frame_provider/decoder/vp9/vvp9.c @@ -1215,7 +1215,7 @@ struct VP9Decoder_s { u32 mem_map_mode; u32 dynamic_buf_num_margin; struct vframe_s vframe_dummy; - unsigned int res_ch_flag; + u32 res_ch_flag; /*struct VP9Decoder_s vp9_decoder;*/ union param_u vp9_param; int sidebind_type; @@ -7737,6 +7737,7 @@ int continue_decoding(struct VP9Decoder_s *pbi) if (pbi->is_used_v4l && ctx->param_sets_from_ucode) pbi->res_ch_flag = 0; + bit_depth_luma = pbi->vp9_param.p.bit_depth; bit_depth_chroma = pbi->vp9_param.p.bit_depth; @@ -8406,6 +8407,7 @@ static int v4l_res_change(struct VP9Decoder_s *pbi) vdec_v4l_res_ch_event(ctx); pbi->v4l_params_parsed = false; pbi->res_ch_flag = 1; + ctx->v4l_resolution_change = 1; pbi->eos = 1; vp9_bufmgr_postproc(pbi); //del_timer_sync(&pbi->timer); @@ -10208,9 +10210,7 @@ static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) pbi->run_ready_min_buf_num) ret = 0; } else { - if ((pbi->res_ch_flag == 1) && - ((ctx->state <= AML_STATE_INIT) || - (ctx->state >= AML_STATE_FLUSHING))) + if (ctx->v4l_resolution_change) ret = 0; } } else if (ctx->cap_pool.in < ctx->dpb_size) {