Commit 076b6289 authored by Ming Qian's avatar Ming Qian Committed by Hans Verkuil

media: amphion: initiate a drain of the capture queue in dynamic resolution change

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: 6de8d628 ("media: amphion: add v4l2 m2m vpu decoder stateful driver")
Signed-off-by: default avatarMing Qian <ming.qian@nxp.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
parent e75d25a0
...@@ -279,6 +279,7 @@ static void vdec_handle_resolution_change(struct vpu_inst *inst) ...@@ -279,6 +279,7 @@ static void vdec_handle_resolution_change(struct vpu_inst *inst)
vdec->source_change--; vdec->source_change--;
vpu_notify_source_change(inst); 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) static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force)
...@@ -314,7 +315,7 @@ static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst) ...@@ -314,7 +315,7 @@ static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
return; return;
if (vdec->eos_received) { if (vdec->eos_received) {
if (!vpu_set_last_buffer_dequeued(inst)) { if (!vpu_set_last_buffer_dequeued(inst, true)) {
vdec->eos_received--; vdec->eos_received--;
vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0); vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
} }
...@@ -569,7 +570,7 @@ static int vdec_drain(struct vpu_inst *inst) ...@@ -569,7 +570,7 @@ static int vdec_drain(struct vpu_inst *inst)
return 0; return 0;
if (!vdec->params.frame_count) { if (!vdec->params.frame_count) {
vpu_set_last_buffer_dequeued(inst); vpu_set_last_buffer_dequeued(inst, true);
return 0; return 0;
} }
...@@ -608,7 +609,7 @@ static int vdec_cmd_stop(struct vpu_inst *inst) ...@@ -608,7 +609,7 @@ static int vdec_cmd_stop(struct vpu_inst *inst)
vpu_trace(inst->dev, "[%d]\n", inst->id); vpu_trace(inst->dev, "[%d]\n", inst->id);
if (inst->state == VPU_CODEC_STATE_DEINIT) { if (inst->state == VPU_CODEC_STATE_DEINIT) {
vpu_set_last_buffer_dequeued(inst); vpu_set_last_buffer_dequeued(inst, true);
} else { } else {
vdec->drain = 1; vdec->drain = 1;
vdec_drain(inst); vdec_drain(inst);
......
...@@ -458,7 +458,7 @@ static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd ...@@ -458,7 +458,7 @@ static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd
vpu_inst_lock(inst); vpu_inst_lock(inst);
if (cmd->cmd == V4L2_ENC_CMD_STOP) { if (cmd->cmd == V4L2_ENC_CMD_STOP) {
if (inst->state == VPU_CODEC_STATE_DEINIT) if (inst->state == VPU_CODEC_STATE_DEINIT)
vpu_set_last_buffer_dequeued(inst); vpu_set_last_buffer_dequeued(inst, true);
else else
venc_request_eos(inst); venc_request_eos(inst);
} }
...@@ -878,7 +878,7 @@ static void venc_set_last_buffer_dequeued(struct vpu_inst *inst) ...@@ -878,7 +878,7 @@ static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
struct venc_t *venc = inst->priv; struct venc_t *venc = inst->priv;
if (venc->stopped && list_empty(&venc->frames)) 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) static void venc_stop_done(struct vpu_inst *inst)
......
...@@ -100,7 +100,7 @@ int vpu_notify_source_change(struct vpu_inst *inst) ...@@ -100,7 +100,7 @@ int vpu_notify_source_change(struct vpu_inst *inst)
return 0; 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; struct vb2_queue *q;
...@@ -116,7 +116,8 @@ int vpu_set_last_buffer_dequeued(struct vpu_inst *inst) ...@@ -116,7 +116,8 @@ int vpu_set_last_buffer_dequeued(struct vpu_inst *inst)
vpu_trace(inst->dev, "last buffer dequeued\n"); vpu_trace(inst->dev, "last buffer dequeued\n");
q->last_buffer_dequeued = true; q->last_buffer_dequeued = true;
wake_up(&q->done_wq); wake_up(&q->done_wq);
vpu_notify_eos(inst); if (eos)
vpu_notify_eos(inst);
return 0; return 0;
} }
......
...@@ -27,7 +27,7 @@ struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 ...@@ -27,7 +27,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); void vpu_v4l2_set_error(struct vpu_inst *inst);
int vpu_notify_eos(struct vpu_inst *inst); int vpu_notify_eos(struct vpu_inst *inst);
int vpu_notify_source_change(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); 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); int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
bool vpu_is_source_empty(struct vpu_inst *inst); bool vpu_is_source_empty(struct vpu_inst *inst);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment