media: mfc: DRV4.0: fix buffer handling after encoding
authorAyoung Sim <a.sim@samsung.com>
Wed, 18 Apr 2018 10:29:57 +0000 (19:29 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:22:22 +0000 (20:22 +0300)
Buffers are dequeued such as below.
- Src buffer: whenever there is a encoded addr
- Dst buffer: whenever there are stream size

Change-Id: Ie5e63facdbcadd82acea39c348320fbd2b0a9362
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/s5p_mfc_irq.c
drivers/media/platform/exynos/mfc/s5p_mfc_nal_q.c

index bb4a421e0a7c16943de6a05eb16cb9b3802a991a..f6db2937aeb1f02f3e9168ed238671ad40f772f9 100644 (file)
@@ -745,93 +745,103 @@ static void mfc_handle_stream_copy_timestamp(struct s5p_mfc_ctx *ctx, struct s5p
                dst_mb->vb.vb2_buf.timestamp = new_timestamp;
 }
 
-static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type)
+static void mfc_handle_stream_input(struct s5p_mfc_ctx *ctx)
 {
        struct s5p_mfc_raw_info *raw;
        struct s5p_mfc_buf *ref_mb, *src_mb;
        dma_addr_t enc_addr[3] = { 0, 0, 0 };
-       int i;
+       int i, found_in_src_queue = 0;
        unsigned int index;
 
        raw = &ctx->raw_buf;
 
-       if (slice_type >= 0) {
-               if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
+       if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
                        ctx->state == MFCINST_RUNNING_BUF_FULL)
-                       s5p_mfc_change_state(ctx, MFCINST_RUNNING);
-
-               s5p_mfc_get_enc_frame_buffer(ctx, &enc_addr[0], raw->num_planes);
-
-               for (i = 0; i < raw->num_planes; i++)
-                       mfc_debug(2, "encoded[%d] addr: 0x%08llx\n",
-                                               i, enc_addr[i]);
-               if (enc_addr[0] == 0) {
-                       mfc_debug(3, "no encoded addr by B frame\n");
-                       return;
-               }
+               s5p_mfc_change_state(ctx, MFCINST_RUNNING);
 
-               if (IS_BUFFER_BATCH_MODE(ctx)) {
-                       src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
-                                       &ctx->src_buf_queue, enc_addr[0]);
-                       if (src_mb) {
-                               src_mb->done_index++;
-                               mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
+       s5p_mfc_get_enc_frame_buffer(ctx, &enc_addr[0], raw->num_planes);
+       if (enc_addr[0] == 0) {
+               mfc_debug(3, "no encoded src\n");
+               goto move_buf;
+       }
+       for (i = 0; i < raw->num_planes; i++)
+               mfc_debug(2, "encoded[%d] addr: 0x%08llx\n", i, enc_addr[i]);
 
-                               index = src_mb->vb.vb2_buf.index;
+       if (IS_BUFFER_BATCH_MODE(ctx)) {
+               src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_queue, enc_addr[0]);
+               if (src_mb) {
+                       found_in_src_queue = 1;
+                       src_mb->done_index++;
+                       mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
 
-                               if (call_cop(ctx, recover_buf_ctrls_val, ctx,
-                                                       &ctx->src_ctrls[index]) < 0)
-                                       mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+                       index = src_mb->vb.vb2_buf.index;
 
-                               mfc_handle_stream_copy_timestamp(ctx, src_mb);
+                       if (call_cop(ctx, recover_buf_ctrls_val, ctx,
+                                               &ctx->src_ctrls[index]) < 0)
+                               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
 
-                               /* single buffer || last image in a buffer container */
-                               if (!src_mb->num_bufs_in_vb || src_mb->done_index == src_mb->num_bufs_in_vb) {
-                                       src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                                                       &ctx->src_buf_queue, enc_addr[0]);
-                                       for (i = 0; i < raw->num_planes; i++)
-                                               s5p_mfc_bufcon_put_daddr(ctx, src_mb, i);
-                                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-                               }
+                       mfc_handle_stream_copy_timestamp(ctx, src_mb);
 
-                               /* encoder src buffer CFW UNPROT */
-                               if (ctx->is_drm)
-                                       s5p_mfc_raw_unprotect(ctx, src_mb, index);
+                       /* single buffer || last image in a buffer container */
+                       if (!src_mb->num_bufs_in_vb || src_mb->done_index == src_mb->num_bufs_in_vb) {
+                               src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                               &ctx->src_buf_queue, enc_addr[0]);
+                               for (i = 0; i < raw->num_planes; i++)
+                                       s5p_mfc_bufcon_put_daddr(ctx, src_mb, i);
+                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
                        }
-               } else {
-                       /* normal single buffer */
-                       src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                                       &ctx->src_buf_queue, enc_addr[0]);
-                       if (src_mb) {
-                               index = src_mb->vb.vb2_buf.index;
-                               if (call_cop(ctx, recover_buf_ctrls_val, ctx,
-                                                       &ctx->src_ctrls[index]) < 0)
-                                       mfc_err_ctx("failed in recover_buf_ctrls_val\n");
 
-                               mfc_debug(3, "find src buf in src_queue\n");
-                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                       /* encoder src buffer CFW UNPROT */
+                       if (ctx->is_drm)
+                               s5p_mfc_raw_unprotect(ctx, src_mb, index);
+               }
+       } else {
+               /* normal single buffer */
+               src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_queue, enc_addr[0]);
+               if (src_mb) {
+                       found_in_src_queue = 1;
+                       index = src_mb->vb.vb2_buf.index;
+                       if (call_cop(ctx, recover_buf_ctrls_val, ctx,
+                                               &ctx->src_ctrls[index]) < 0)
+                               mfc_err_ctx("failed in recover_buf_ctrls_val\n");
+
+                       mfc_debug(3, "find src buf in src_queue\n");
+                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+                       /* encoder src buffer CFW UNPROT */
+                       if (ctx->is_drm)
+                               s5p_mfc_raw_unprotect(ctx, src_mb, index);
+               } else {
+                       mfc_debug(3, "no src buf in src_queue\n");
+                       ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->ref_buf_queue, enc_addr[0]);
+                       if (ref_mb) {
+                               mfc_debug(3, "find src buf in ref_queue\n");
+                               vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
 
                                /* encoder src buffer CFW UNPROT */
-                               if (ctx->is_drm)
-                                       s5p_mfc_raw_unprotect(ctx, src_mb, index);
-                       } else {
-                               mfc_debug(3, "no src buf in src_queue\n");
-                               ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                                               &ctx->ref_buf_queue, enc_addr[0]);
-                               if (ref_mb) {
-                                       vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-
-                                       /* encoder src buffer CFW UNPROT */
-                                       if (ctx->is_drm) {
-                                               index = ref_mb->vb.vb2_buf.index;
-                                               s5p_mfc_raw_unprotect(ctx, ref_mb, index);
-                                       }
-                               } else {
-                                       mfc_err_ctx("couldn't find src buffer\n");
+                               if (ctx->is_drm) {
+                                       index = ref_mb->vb.vb2_buf.index;
+                                       s5p_mfc_raw_unprotect(ctx, ref_mb, index);
                                }
+                       } else {
+                               mfc_err_ctx("couldn't find src buffer\n");
                        }
                }
        }
+
+move_buf:
+       /* move enqueued src buffer: src queue -> ref queue */
+       if (!found_in_src_queue && ctx->state != MFCINST_FINISHING) {
+               s5p_mfc_move_first_buf_used(&ctx->buf_queue_lock,
+                               &ctx->ref_buf_queue, &ctx->src_buf_queue, MFC_QUEUE_ADD_BOTTOM);
+
+               mfc_debug(2, "enc src_buf_queue(%d) -> ref_buf_queue(%d)\n",
+                               s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
+                               s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
+       }
 }
 
 static void mfc_handle_stream_output(struct s5p_mfc_ctx *ctx, int slice_type,
@@ -841,58 +851,56 @@ static void mfc_handle_stream_output(struct s5p_mfc_ctx *ctx, int slice_type,
        struct s5p_mfc_buf *dst_mb;
        unsigned int index;
 
-       if (strm_size > 0 || ctx->state == MFCINST_RUNNING_BUF_FULL) {
-               /* at least one more dest. buffers exist always  */
-               dst_mb = s5p_mfc_get_del_buf(&ctx->buf_queue_lock,
-                               &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
-               if (!dst_mb) {
-                       mfc_err_dev("no dst buffers.\n");
-                       return;
-               }
+       if (strm_size == 0) {
+               mfc_debug(3, "no encoded dst (reuse)\n");
+               return;
+       } else if (strm_size < 0) {
+               mfc_err_ctx("invalid stream size: %d\n", strm_size);
+               return;
+       }
 
-               dst_mb->vb.flags &=
-                       ~(V4L2_BUF_FLAG_KEYFRAME |
-                         V4L2_BUF_FLAG_PFRAME |
-                         V4L2_BUF_FLAG_BFRAME);
+       /* at least one more dest. buffers exist always  */
+       dst_mb = s5p_mfc_get_del_buf(&ctx->buf_queue_lock,
+                       &ctx->dst_buf_queue, MFC_BUF_NO_TOUCH_USED);
+       if (!dst_mb) {
+               mfc_err_ctx("no dst buffers.\n");
+               return;
+       }
 
-               switch (slice_type) {
-               case S5P_FIMV_E_SLICE_TYPE_I:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_KEYFRAME;
-                       break;
-               case S5P_FIMV_E_SLICE_TYPE_P:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_PFRAME;
-                       break;
-               case S5P_FIMV_E_SLICE_TYPE_B:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_BFRAME;
-                       break;
-               default:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_KEYFRAME;
-                       break;
-               }
-               mfc_debug(2, "Slice type : %d\n", dst_mb->vb.flags);
+       dst_mb->vb.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
+                               V4L2_BUF_FLAG_PFRAME |
+                               V4L2_BUF_FLAG_BFRAME);
+       switch (slice_type) {
+       case S5P_FIMV_E_SLICE_TYPE_I:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
+               break;
+       case S5P_FIMV_E_SLICE_TYPE_P:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_PFRAME;
+               break;
+       case S5P_FIMV_E_SLICE_TYPE_B:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_BFRAME;
+               break;
+       default:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
+               break;
+       }
+       mfc_debug(2, "Slice type flag: %d\n", dst_mb->vb.flags);
 
-               if (IS_BPG_ENC(ctx)) {
-                       strm_size += enc->header_size;
-                       mfc_debug(2, "bpg total stream size: %d\n", strm_size);
-               }
-               vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, strm_size);
+       if (IS_BPG_ENC(ctx)) {
+               strm_size += enc->header_size;
+               mfc_debug(2, "bpg total stream size: %d\n", strm_size);
+       }
+       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, strm_size);
 
-               index = dst_mb->vb.vb2_buf.index;
-               if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
-                       mfc_err_ctx("failed in get_buf_ctrls_val\n");
+       index = dst_mb->vb.vb2_buf.index;
+       if (call_cop(ctx, get_buf_ctrls_val, ctx, &ctx->dst_ctrls[index]) < 0)
+               mfc_err_ctx("failed in get_buf_ctrls_val\n");
 
-               vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+       vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
 
-               /* encoder dst buffer CFW UNPROT */
-               if (ctx->is_drm)
-                       s5p_mfc_stream_unprotect(ctx, dst_mb, index);
-       } else if (strm_size == 0 && slice_type == S5P_FIMV_E_SLICE_TYPE_SKIPPED) {
-               /* TO-DO: skipped frame should be handled */
-       }
+       /* encoder dst buffer CFW UNPROT */
+       if (ctx->is_drm)
+               s5p_mfc_stream_unprotect(ctx, dst_mb, index);
 }
 
 /* Handle frame encoding interrupt */
@@ -912,6 +920,7 @@ static int mfc_handle_stream(struct s5p_mfc_ctx *ctx)
        mfc_debug(2, "encoded stream size: %d\n", strm_size);
        mfc_debug(2, "display order: %d\n", pic_count);
 
+       /* buffer full handling */
        if (enc->buf_full) {
                s5p_mfc_change_state(ctx, MFCINST_ABORT_INST);
                return 0;
@@ -929,31 +938,11 @@ static int mfc_handle_stream(struct s5p_mfc_ctx *ctx)
        }
 
        /* handle source buffer */
-       mfc_handle_stream_input(ctx, slice_type);
+       mfc_handle_stream_input(ctx);
 
        /* handle destination buffer */
        mfc_handle_stream_output(ctx, slice_type, strm_size);
 
-       if (IS_BUFFER_BATCH_MODE(ctx))
-               return 0;
-
-       if (s5p_mfc_is_queue_count_greater(&ctx->buf_queue_lock, &ctx->src_buf_queue, 0)) {
-               s5p_mfc_move_first_buf_used(&ctx->buf_queue_lock,
-                       &ctx->ref_buf_queue, &ctx->src_buf_queue, MFC_QUEUE_ADD_BOTTOM);
-
-               /*
-                * slice_type = 4 && strm_size = 0, skipped enable
-                * should be considered
-                */
-               if ((slice_type == -1) && (strm_size == 0))
-                       s5p_mfc_change_state(ctx, MFCINST_RUNNING_NO_OUTPUT);
-
-               mfc_debug(2, "slice_type: %d, ctx->state: %d\n", slice_type, ctx->state);
-               mfc_debug(2, "enc src count: %d, enc ref count: %d\n",
-                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_queue),
-                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
-       }
-
        return 0;
 }
 
index 7fb25738a9f3c08cbb294a5ccef1b23843e35cd9..05e1dd851879d119db8d4f5474a5a35c878b960f 100644 (file)
@@ -898,81 +898,90 @@ static void mfc_nal_q_handle_stream_copy_timestamp(struct s5p_mfc_ctx *ctx, stru
                dst_mb->vb.vb2_buf.timestamp = new_timestamp;
 }
 
-static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, int slice_type,
-                               unsigned int strm_size, EncoderOutputStr *pOutStr)
+static void mfc_nal_q_handle_stream_input(struct s5p_mfc_ctx *ctx, EncoderOutputStr *pOutStr)
 {
        struct s5p_mfc_buf *src_mb, *ref_mb;
        dma_addr_t enc_addr[3] = { 0, 0, 0 };
        struct s5p_mfc_raw_info *raw;
+       int found_in_src_queue = 0;
        unsigned int i;
 
        raw = &ctx->raw_buf;
 
-       if (slice_type >= 0) {
-               if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
+       if (ctx->state == MFCINST_RUNNING_NO_OUTPUT ||
                        ctx->state == MFCINST_RUNNING_BUF_FULL)
-                       ctx->state = MFCINST_RUNNING;
-
-               mfc_nal_q_get_enc_frame_buffer(ctx, &enc_addr[0],
-                                       raw->num_planes, pOutStr);
+               ctx->state = MFCINST_RUNNING;
 
-               for (i = 0; i < raw->num_planes; i++)
-                       mfc_debug(2, "NAL Q: encoded[%d] addr: 0x%08llx\n", i,
-                                       enc_addr[i]);
+       mfc_nal_q_get_enc_frame_buffer(ctx, &enc_addr[0], raw->num_planes, pOutStr);
+       if (enc_addr[0] == 0) {
+               mfc_debug(3, "NAL Q: no encoded src\n");
+               goto move_buf;
+       }
 
-               if (enc_addr[0] == 0) {
-                       mfc_debug(3, "NAL Q: no encoded addr by B frame\n");
-                       return;
-               }
+       for (i = 0; i < raw->num_planes; i++)
+               mfc_debug(2, "NAL Q: encoded[%d] addr: 0x%08llx\n", i, enc_addr[i]);
 
-               if (IS_BUFFER_BATCH_MODE(ctx)) {
+       if (IS_BUFFER_BATCH_MODE(ctx)) {
+               src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_queue, enc_addr[0]);
+               if (src_mb) {
+                       found_in_src_queue = 1;
+                       src_mb->done_index++;
+                       mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
+
+                       mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb);
+               } else {
                        src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
-                                       &ctx->src_buf_queue, enc_addr[0]);
+                                       &ctx->src_buf_nal_queue, enc_addr[0]);
                        if (src_mb) {
+                               found_in_src_queue = 1;
                                src_mb->done_index++;
                                mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
 
                                mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb);
-                       } else {
-                               src_mb = s5p_mfc_find_first_buf(&ctx->buf_queue_lock,
-                                               &ctx->src_buf_nal_queue, enc_addr[0]);
-                               if (src_mb) {
-                                       src_mb->done_index++;
-                                       mfc_debug(4, "batch buf done_index: %d\n", src_mb->done_index);
-
-                                       mfc_nal_q_handle_stream_copy_timestamp(ctx, src_mb);
-
-                                       /* last image in a buffer container */
-                                       if (src_mb->done_index == src_mb->num_bufs_in_vb) {
-                                               src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                                                               &ctx->src_buf_nal_queue, enc_addr[0]);
-                                               for (i = 0; i < raw->num_planes; i++)
-                                                       s5p_mfc_bufcon_put_daddr(ctx, src_mb, i);
-                                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-                                       }
+
+                               /* last image in a buffer container */
+                               if (src_mb->done_index == src_mb->num_bufs_in_vb) {
+                                       src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                                       &ctx->src_buf_nal_queue, enc_addr[0]);
+                                       for (i = 0; i < raw->num_planes; i++)
+                                               s5p_mfc_bufcon_put_daddr(ctx, src_mb, i);
+                                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
                                }
                        }
+               }
+       } else {
+               src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                               &ctx->src_buf_nal_queue, enc_addr[0]);
+               if (src_mb) {
+                       mfc_debug(3, "find src buf in src_queue\n");
+                       found_in_src_queue = 1;
+                       vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
                } else {
-                       src_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                                       &ctx->src_buf_nal_queue, enc_addr[0]);
-                       if (src_mb) {
-                               mfc_debug(3, "find src buf in src_queue\n");
-                               vb2_buffer_done(&src_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
+                       mfc_debug(3, "no src buf in src_queue\n");
+                       ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
+                                       &ctx->ref_buf_queue, enc_addr[0]);
+                       if (ref_mb) {
+                               mfc_debug(3, "find src buf in ref_queue\n");
+                               vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
                        } else {
-                               mfc_debug(3, "no src buf in src_queue\n");
-                               ref_mb = s5p_mfc_find_del_buf(&ctx->buf_queue_lock,
-                                               &ctx->ref_buf_queue, enc_addr[0]);
-                               if (ref_mb) {
-                                       mfc_debug(3, "find src buf in ref_queue\n");
-                                       vb2_buffer_done(&ref_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-                               } else {
-                                       mfc_err_dev("NAL Q: no src buffers\n");
-                                       return;
-                               }
+                               mfc_err_ctx("NAL Q: couldn't find src buffer\n");
                        }
                }
        }
 
+move_buf:
+       /* move enqueued src buffer: src nal queue -> ref queue */
+       if (!found_in_src_queue) {
+               src_mb = s5p_mfc_get_move_buf_used(&ctx->buf_queue_lock,
+                               &ctx->ref_buf_queue, &ctx->src_buf_nal_queue);
+               if (!src_mb)
+                       mfc_err_dev("NAL Q: no src buffers\n");
+
+               mfc_debug(2, "NAL Q: enc src_buf_nal_queue(%d) -> ref_buf_queue(%d)\n",
+                               s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_nal_queue),
+                               s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
+       }
 }
 
 static void mfc_nal_q_handle_stream_output(struct s5p_mfc_ctx *ctx, int slice_type,
@@ -981,50 +990,11 @@ static void mfc_nal_q_handle_stream_output(struct s5p_mfc_ctx *ctx, int slice_ty
        struct s5p_mfc_buf *dst_mb;
        unsigned int index;
 
-       if (strm_size > 0) {
-               /* at least one more dest. buffers exist always  */
-               dst_mb = s5p_mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->dst_buf_nal_queue, MFC_BUF_NO_TOUCH_USED);
-               if (!dst_mb) {
-                       mfc_err_dev("NAL Q: no dst buffers\n");
-                       return;
-               }
-
-               dst_mb->vb.flags &=
-                       ~(V4L2_BUF_FLAG_KEYFRAME |
-                         V4L2_BUF_FLAG_PFRAME |
-                         V4L2_BUF_FLAG_BFRAME);
-
-               switch (slice_type) {
-               case S5P_FIMV_E_SLICE_TYPE_I:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_KEYFRAME;
-                               break;
-               case S5P_FIMV_E_SLICE_TYPE_P:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_PFRAME;
-                       break;
-               case S5P_FIMV_E_SLICE_TYPE_B:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_BFRAME;
-                       break;
-               default:
-                       dst_mb->vb.flags |=
-                               V4L2_BUF_FLAG_KEYFRAME;
-                       break;
-               }
-               mfc_debug(2, "NAL Q: Slice type : %d\n", dst_mb->vb.flags);
-
-               vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, strm_size);
-
-               index = dst_mb->vb.vb2_buf.index;
-               if (call_cop(ctx, get_buf_ctrls_val_nal_q_enc, ctx,
-                               &ctx->dst_ctrls[index], pOutStr) < 0)
-                       mfc_err_ctx("NAL Q: failed in get_buf_ctrls_val in nal q\n");
-
-               vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
-       } else if (strm_size == 0) {
+       if (strm_size == 0) {
+               mfc_debug(3, "NAL Q: no encoded dst (reuse)\n");
                dst_mb = s5p_mfc_get_move_buf(&ctx->buf_queue_lock,
-                               &ctx->dst_buf_queue, &ctx->dst_buf_nal_queue, MFC_BUF_RESET_USED, MFC_QUEUE_ADD_TOP);
+                               &ctx->dst_buf_queue, &ctx->dst_buf_nal_queue,
+                               MFC_BUF_RESET_USED, MFC_QUEUE_ADD_TOP);
                if (!dst_mb) {
                        mfc_err_dev("NAL Q: no dst buffers\n");
                        return;
@@ -1034,13 +1004,52 @@ static void mfc_nal_q_handle_stream_output(struct s5p_mfc_ctx *ctx, int slice_ty
                                s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_nal_queue),
                                s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->dst_buf_queue),
                                dst_mb->vb.vb2_buf.index);
+               return;
+       } else if (strm_size < 0) {
+               mfc_err_ctx("NAL Q: invalid stream size: %d\n", strm_size);
+               return;
+       }
+
+       /* at least one more dest. buffers exist always  */
+       dst_mb = s5p_mfc_get_del_buf(&ctx->buf_queue_lock, &ctx->dst_buf_nal_queue, MFC_BUF_NO_TOUCH_USED);
+       if (!dst_mb) {
+               mfc_err_dev("NAL Q: no dst buffers\n");
+               return;
+       }
+
+       dst_mb->vb.flags &= ~(V4L2_BUF_FLAG_KEYFRAME |
+                               V4L2_BUF_FLAG_PFRAME |
+                               V4L2_BUF_FLAG_BFRAME);
+
+       switch (slice_type) {
+       case S5P_FIMV_E_SLICE_TYPE_I:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
+               break;
+       case S5P_FIMV_E_SLICE_TYPE_P:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_PFRAME;
+               break;
+       case S5P_FIMV_E_SLICE_TYPE_B:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_BFRAME;
+               break;
+       default:
+               dst_mb->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
+               break;
        }
+       mfc_debug(2, "NAL Q: Slice type flag: %d\n", dst_mb->vb.flags);
+
+       vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, strm_size);
+
+       index = dst_mb->vb.vb2_buf.index;
+       if (call_cop(ctx, get_buf_ctrls_val_nal_q_enc, ctx,
+                               &ctx->dst_ctrls[index], pOutStr) < 0)
+               mfc_err_ctx("NAL Q: failed in get_buf_ctrls_val in nal q\n");
+
+       vb2_buffer_done(&dst_mb->vb.vb2_buf, VB2_BUF_STATE_DONE);
 }
 
 static void mfc_nal_q_handle_stream(struct s5p_mfc_ctx *ctx, EncoderOutputStr *pOutStr)
 {
        struct s5p_mfc_enc *enc = ctx->enc_priv;
-       struct s5p_mfc_buf *src_mb;
        int slice_type;
        unsigned int strm_size;
        unsigned int pic_count;
@@ -1054,46 +1063,17 @@ static void mfc_nal_q_handle_stream(struct s5p_mfc_ctx *ctx, EncoderOutputStr *p
        mfc_debug(2, "NAL Q: encoded slice type: %d\n", slice_type);
        mfc_debug(2, "NAL Q: encoded stream size: %d\n", strm_size);
        mfc_debug(2, "NAL Q: display order: %d\n", pic_count);
-/*
-       if (enc->buf_full) {
-               ctx->state = MFCINST_ABORT_INST;
-               return 0;
-       }
-*/
+
        /* set encoded frame type */
        enc->frame_type = slice_type;
        ctx->sequence++;
 
        /* handle input buffer */
-       mfc_nal_q_handle_stream_input(ctx, slice_type, strm_size, pOutStr);
+       mfc_nal_q_handle_stream_input(ctx, pOutStr);
 
        /* handle output buffer */
        mfc_nal_q_handle_stream_output(ctx, slice_type, strm_size, pOutStr);
 
-       if (IS_BUFFER_BATCH_MODE(ctx))
-               return;
-
-       if (s5p_mfc_is_queue_count_greater(&ctx->buf_queue_lock, &ctx->src_buf_nal_queue, 0)) {
-               src_mb = s5p_mfc_get_move_buf_used(&ctx->buf_queue_lock,
-                               &ctx->ref_buf_queue, &ctx->src_buf_nal_queue);
-               if (!src_mb) {
-                       mfc_err_dev("NAL Q: no src buffers\n");
-                       return;
-               }
-
-               /*
-                * slice_type = 4 && strm_size = 0, skipped enable
-                * should be considered
-                */
-               if ((slice_type == -1) && (strm_size == 0))
-                       ctx->state = MFCINST_RUNNING_NO_OUTPUT;
-
-               mfc_debug(2, "NAL Q: slice_type: %d, ctx->state: %d\n", slice_type, ctx->state);
-               mfc_debug(2, "NAL Q: enc src_buf_nal_queue(%d) -> ref_buf_nal_queue(%d)\n",
-                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->src_buf_nal_queue),
-                         s5p_mfc_get_queue_count(&ctx->buf_queue_lock, &ctx->ref_buf_queue));
-       }
-
        mfc_debug_leave();
 
        return;