media: amphion: initiate a drain of the capture queue in dynamic resolution change
authorMing Qian <ming.qian@nxp.com>
Sat, 6 May 2023 08:47:35 +0000 (16:47 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Jul 2023 14:21:50 +0000 (16:21 +0200)
[ Upstream commit 076b6289b2c12d76fab248659896682830fa7766 ]

The last buffer from before the change must be marked
with the V4L2_BUF_FLAG_LAST flag,
similarly to the Drain sequence above.

initiate a drain of the capture queue in dynamic resolution change

Fixes: 6de8d628df6e ("media: amphion: add v4l2 m2m vpu decoder stateful driver")
Signed-off-by: Ming Qian <ming.qian@nxp.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/media/platform/amphion/vdec.c
drivers/media/platform/amphion/venc.c
drivers/media/platform/amphion/vpu_v4l2.c
drivers/media/platform/amphion/vpu_v4l2.h

index 4918547..c08b5a2 100644 (file)
@@ -229,6 +229,7 @@ static void vdec_handle_resolution_change(struct vpu_inst *inst)
 
        vdec->source_change--;
        vpu_notify_source_change(inst);
+       vpu_set_last_buffer_dequeued(inst, false);
 }
 
 static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force)
@@ -264,7 +265,7 @@ static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
                return;
 
        if (vdec->eos_received) {
-               if (!vpu_set_last_buffer_dequeued(inst)) {
+               if (!vpu_set_last_buffer_dequeued(inst, true)) {
                        vdec->eos_received--;
                        vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
                }
@@ -517,7 +518,7 @@ static int vdec_drain(struct vpu_inst *inst)
                return 0;
 
        if (!vdec->params.frame_count) {
-               vpu_set_last_buffer_dequeued(inst);
+               vpu_set_last_buffer_dequeued(inst, true);
                return 0;
        }
 
@@ -556,7 +557,7 @@ static int vdec_cmd_stop(struct vpu_inst *inst)
        vpu_trace(inst->dev, "[%d]\n", inst->id);
 
        if (inst->state == VPU_CODEC_STATE_DEINIT) {
-               vpu_set_last_buffer_dequeued(inst);
+               vpu_set_last_buffer_dequeued(inst, true);
        } else {
                vdec->drain = 1;
                vdec_drain(inst);
index 37212f0..e8cb22d 100644 (file)
@@ -468,7 +468,7 @@ static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd
        vpu_inst_lock(inst);
        if (cmd->cmd == V4L2_ENC_CMD_STOP) {
                if (inst->state == VPU_CODEC_STATE_DEINIT)
-                       vpu_set_last_buffer_dequeued(inst);
+                       vpu_set_last_buffer_dequeued(inst, true);
                else
                        venc_request_eos(inst);
        }
@@ -888,7 +888,7 @@ static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
        struct venc_t *venc = inst->priv;
 
        if (venc->stopped && list_empty(&venc->frames))
-               vpu_set_last_buffer_dequeued(inst);
+               vpu_set_last_buffer_dequeued(inst, true);
 }
 
 static void venc_stop_done(struct vpu_inst *inst)
index 590d108..a749531 100644 (file)
@@ -100,7 +100,7 @@ int vpu_notify_source_change(struct vpu_inst *inst)
        return 0;
 }
 
-int vpu_set_last_buffer_dequeued(struct vpu_inst *inst)
+int vpu_set_last_buffer_dequeued(struct vpu_inst *inst, bool eos)
 {
        struct vb2_queue *q;
 
@@ -116,7 +116,8 @@ int vpu_set_last_buffer_dequeued(struct vpu_inst *inst)
        vpu_trace(inst->dev, "last buffer dequeued\n");
        q->last_buffer_dequeued = true;
        wake_up(&q->done_wq);
-       vpu_notify_eos(inst);
+       if (eos)
+               vpu_notify_eos(inst);
        return 0;
 }
 
index 795ca33..000af24 100644 (file)
@@ -26,7 +26,7 @@ struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32
 void vpu_v4l2_set_error(struct vpu_inst *inst);
 int vpu_notify_eos(struct vpu_inst *inst);
 int vpu_notify_source_change(struct vpu_inst *inst);
-int vpu_set_last_buffer_dequeued(struct vpu_inst *inst);
+int vpu_set_last_buffer_dequeued(struct vpu_inst *inst, bool eos);
 void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state);
 int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
 bool vpu_is_source_empty(struct vpu_inst *inst);