aboutsummaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorMing Qian2022-09-30 14:40:47 +0800
committerGreg Kroah-Hartman2022-12-31 13:32:03 +0100
commitfc6579f00506eced99cbd58b6cb24cc580251bd4 (patch)
treea41e9333e4a3204d8b77638eaeb3723164f7c81b /drivers/media
parente7d1e0b752641963be2586b0d8a563294e8dc2e4 (diff)
media: amphion: reset instance if it's aborted before codec header parsed
[ Upstream commit 3984ea32e83bcad06b4b034ddd4b0a934c1b2f91 ] there is hardware limitation that if it's aborted before the first codec header parsed, the codec may be stalled unless we do reset codec. and drop the source change event if it's triggered after reset. 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>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/amphion/vdec.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
index feb75dc204de..84c90ce265f2 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -753,6 +753,9 @@ static bool vdec_check_source_change(struct vpu_inst *inst)
if (!inst->fh.m2m_ctx)
return false;
+ if (vdec->reset_codec)
+ return false;
+
if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
return true;
fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
@@ -1088,7 +1091,8 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info
vdec->seq_tag = vdec->codec_info.tag;
if (vdec->is_source_changed) {
vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
- vpu_notify_source_change(inst);
+ vdec->source_change++;
+ vdec_handle_resolution_change(inst);
vdec->is_source_changed = false;
}
}
@@ -1335,6 +1339,8 @@ static void vdec_abort(struct vpu_inst *inst)
vdec->decoded_frame_count,
vdec->display_frame_count,
vdec->sequence);
+ if (!vdec->seq_hdr_found)
+ vdec->reset_codec = true;
vdec->params.end_flag = 0;
vdec->drain = 0;
vdec->params.frame_count = 0;
@@ -1342,6 +1348,7 @@ static void vdec_abort(struct vpu_inst *inst)
vdec->display_frame_count = 0;
vdec->sequence = 0;
vdec->aborting = false;
+ inst->extra_size = 0;
}
static void vdec_stop(struct vpu_inst *inst, bool free)
@@ -1464,8 +1471,7 @@ static int vdec_start_session(struct vpu_inst *inst, u32 type)
}
if (V4L2_TYPE_IS_OUTPUT(type)) {
- if (inst->state == VPU_CODEC_STATE_SEEK)
- vdec_update_state(inst, vdec->state, 1);
+ vdec_update_state(inst, vdec->state, 1);
vdec->eos_received = 0;
vpu_process_output_buffer(inst);
} else {
@@ -1629,6 +1635,7 @@ static int vdec_open(struct file *file)
return ret;
vdec->fixed_fmt = false;
+ vdec->state = VPU_CODEC_STATE_ACTIVE;
inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
inst->min_buffer_out = VDEC_MIN_BUFFER_OUT;
vdec_init(file);