From 49c06502c900f3fd27e878e04881d499b4788396 Mon Sep 17 00:00:00 2001 From: Nanxin Qin Date: Mon, 23 Dec 2019 17:17:31 +0000 Subject: v4l: optimize flow of reset for v4l codec. [1/1] PD#SWPL-18391 Problem: youtube playback drop amount of frames. Solution: 1. default config input size is 2M. 2. dont free vdec input buffer when have not frames in block. 3. vp9 mv buffer has not free when reset happend. Verify: u212 Change-Id: If907625d73cb2dce68047cb605efaa9e8d87d4f5 Signed-off-by: Nanxin Qin --- diff --git a/drivers/amvdec_ports/aml_vcodec_adapt.c b/drivers/amvdec_ports/aml_vcodec_adapt.c index 9e4658b..da5637d 100644 --- a/drivers/amvdec_ports/aml_vcodec_adapt.c +++ b/drivers/amvdec_ports/aml_vcodec_adapt.c @@ -120,7 +120,7 @@ static void set_default_params(struct aml_vdec_adapt *vdec) vdec->dec_prop.param = (void *)sync_mode; vdec->dec_prop.format = vdec->format; vdec->dec_prop.width = 1920; - vdec->dec_prop.height = 1080; + vdec->dec_prop.height = 1088; vdec->dec_prop.rate = 3200; } @@ -706,16 +706,22 @@ void aml_decoder_flush(struct aml_vdec_adapt *ada_ctx) vdec_set_eos(vdec, true); } -int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *flag) +int aml_codec_reset(struct aml_vdec_adapt *ada_ctx, int *mode) { struct vdec_s *vdec = ada_ctx->vdec; int ret = 0; if (vdec) { - if (*flag != 2) - vdec_set_eos(vdec, false); - ret = vdec_v4l2_reset(vdec, *flag); - *flag = 0; + vdec_set_eos(vdec, false); + + if (*mode == V4L_RESET_MODE_NORMAL && + vdec->input.have_frame_num == 0) + *mode = V4L_RESET_MODE_LIGHT; + + aml_v4l2_debug(2, "%s, reset mode: %d\n", __func__, *mode); + + ret = vdec_v4l2_reset(vdec, *mode); + *mode = V4L_RESET_MODE_NORMAL; } return ret; diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c index 5039ca7..ec6d6e3 100644 --- a/drivers/amvdec_ports/aml_vcodec_dec.c +++ b/drivers/amvdec_ports/aml_vcodec_dec.c @@ -559,17 +559,17 @@ static int get_display_buffer(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffe static void aml_check_dpb_ready(struct aml_vcodec_ctx *ctx) { if (!ctx->v4l_codec_dpb_ready) { - int buf_ready_num; - - /* is there enough dst bufs for decoding? */ - buf_ready_num = v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx); - if ((ctx->dpb_size) && - ((buf_ready_num + ctx->buf_used_count) >= ctx->dpb_size)) + /* + * make sure enough dst bufs for decoding, and + * the backend maybe hold 4 frms so need to minus 4. + */ + if ((ctx->dpb_size) && (ctx->cap_pool.in >= ctx->dpb_size - 4)) ctx->v4l_codec_dpb_ready = true; + aml_v4l2_debug(2, "[%d] %s() dpb: %d, ready: %d, used: %d, dpb is ready: %s", ctx->id, __func__, ctx->dpb_size, - buf_ready_num, ctx->buf_used_count, - ctx->v4l_codec_dpb_ready ? "yes" : "no"); + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx), + ctx->cap_pool.out, ctx->v4l_codec_dpb_ready ? "yes" : "no"); } } @@ -1047,7 +1047,7 @@ static int vidioc_decoder_streamon(struct file *file, void *priv, if ((ctx->state == AML_STATE_ACTIVE || ctx->state == AML_STATE_FLUSHING || ctx->state == AML_STATE_FLUSHED) || - (ctx->reset_flag == 2)) { + (ctx->reset_flag == V4L_RESET_MODE_LIGHT)) { ctx->state = AML_STATE_RESET; ATRACE_COUNTER("v4l2_state", ctx->state); ctx->v4l_codec_ready = false; @@ -1152,6 +1152,7 @@ void aml_vcodec_dec_set_default_params(struct aml_vcodec_ctx *ctx) q_data->bytesperline[0] = q_data->coded_width; q_data->sizeimage[1] = q_data->sizeimage[0] / 2; q_data->bytesperline[1] = q_data->coded_width; + ctx->reset_flag = V4L_RESET_MODE_NORMAL; ctx->state = AML_STATE_IDLE; ATRACE_COUNTER("v4l2_state", ctx->state); diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c index c2a0f38..c2e0e91 100644 --- a/drivers/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c @@ -2836,7 +2836,8 @@ int notify_v4l_eos(struct vdec_s *vdec) if (hw->is_used_v4l && hw->eos) { expires = jiffies + msecs_to_jiffies(2000); while (INVALID_IDX == (index = v4l_get_free_buf_idx(vdec))) { - if (time_after(jiffies, expires)) + if (time_after(jiffies, expires) || + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) break; } diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c index fe582a9..170cc22 100644 --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/drivers/frame_provider/decoder/h265/vh265.c @@ -9124,7 +9124,8 @@ static int notify_v4l_eos(struct vdec_s *vdec) if (hw->is_used_v4l && hw->eos) { expires = jiffies + msecs_to_jiffies(2000); while (INVALID_IDX == (index = get_free_buf_idx(hw))) { - if (time_after(jiffies, expires)) + if (time_after(jiffies, expires) || + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) break; } diff --git a/drivers/frame_provider/decoder/vp9/vvp9.c b/drivers/frame_provider/decoder/vp9/vvp9.c index a24a596..6db0aa3 100644 --- a/drivers/frame_provider/decoder/vp9/vvp9.c +++ b/drivers/frame_provider/decoder/vp9/vvp9.c @@ -1742,6 +1742,13 @@ static int alloc_mv_buf(struct VP9Decoder_s *pbi, int i, int size) { int ret = 0; + + if (pbi->m_mv_BUF[i].start_adr && + size > pbi->m_mv_BUF[i].size) { + dealloc_mv_bufs(pbi); + } else if (pbi->m_mv_BUF[i].start_adr) + return 0; + if (decoder_bmmu_box_alloc_buf_phy (pbi->bmmu_box, MV_BUFFER_IDX(i), size, @@ -7291,7 +7298,8 @@ static int notify_v4l_eos(struct vdec_s *vdec) if (hw->is_used_v4l && hw->eos) { expires = jiffies + msecs_to_jiffies(2000); while (INVALID_IDX == (index = v4l_get_free_fb(hw))) { - if (time_after(jiffies, expires)) + if (time_after(jiffies, expires) || + v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) break; } @@ -10165,7 +10173,6 @@ static void reset(struct vdec_s *vdec) } pbi->dec_result = DEC_RESULT_NONE; reset_process_time(pbi); - dealloc_mv_bufs(pbi); vp9_local_uninit(pbi); if (vvp9_local_init(pbi) < 0) vp9_print(pbi, 0, "%s local_init failed \r\n", __func__); -- cgit