v4l: optimize flow of reset for v4l codec. [1/1]
authorNanxin Qin <nanxin.qin@amlogic.com>
Mon, 23 Dec 2019 17:17:31 +0000 (01:17 +0800)
committerZhi Zhou <zhi.zhou@amlogic.com>
Fri, 27 Dec 2019 12:59:45 +0000 (05:59 -0700)
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 <nanxin.qin@amlogic.com>
drivers/amvdec_ports/aml_vcodec_adapt.c
drivers/amvdec_ports/aml_vcodec_dec.c
drivers/frame_provider/decoder/h264_multi/vmh264.c
drivers/frame_provider/decoder/h265/vh265.c
drivers/frame_provider/decoder/vp9/vvp9.c

index 9e4658bfb014b1a8f0590697d3c88c0f26cea56c..da5637d9ab65e20c5eae0634b6aa270396c12a01 100644 (file)
@@ -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;
index 5039ca7e2b94bd96eea68b6a1a8a287183cc66ea..ec6d6e39ba555a00e86ff5344fb0ffc8caab28b4 100644 (file)
@@ -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);
index c2a0f3890f845d6128de86d07a1f2d6aeb635b6c..c2e0e91ede9cc481a485f2337003e91a216345e5 100644 (file)
@@ -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;
                }
 
index fe582a99584f8ed9997330491aafc6585b4cc213..170cc224125ed65973121b43088e0827c1b03f92 100644 (file)
@@ -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;
                }
 
index a24a596df5fd73a7a6c5a6a57a5696226d521e93..6db0aa301564b91a721d5df462ffd25ad875b7b2 100644 (file)
@@ -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__);