[PATCH 6.18 574/752] media: iris: Prevent output buffer queuing before stream-on completes

Sasha Levin
2026-02-28T17:56:25Z

From: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>

[ Upstream commit 2c73cfd0cfc44ffe331ccb81f6ac45fc399d9ddb ]

During normal playback, stream-on for input is followed by output, and
only after input stream-on does actual streaming begin. However, when
gst-play performs a seek, both input and output streams are stopped,
and on restart, output stream-on occurs first. At this point, firmware
has not yet started streaming. Queuing output buffers before the firmware
begins streaming causes it to process buffers in an invalid state, leading
to an error response. These buffers are returned to the driver as errors,
forcing the driver into an error state and stopping playback.

Fix this by deferring output buffer queuing until stream-on completes.
Input buffers can still be queued before stream-on as required.

Fixes: 92e007ca5ab6 ("media: iris: Add V4L2 streaming support for encoder video device")
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
Signed-off-by: Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
Reviewed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Cc: stable@vger.kernel.org
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/qcom/iris/iris_vb2.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c
index 139b821f7952f..bf0b8400996ec 100644
--- a/drivers/media/platform/qcom/iris/iris_vb2.c
+++ b/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -193,10 +193,14 @@ int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
buf_type = iris_v4l2_type_to_driver(q->type);

if (inst->domain == DECODER) {
- if (inst->state == IRIS_INST_STREAMING)
+ if (buf_type == BUF_INPUT)
+ ret = iris_queue_deferred_buffers(inst, BUF_INPUT);
+
+ if (!ret && inst->state == IRIS_INST_STREAMING) {
ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB);
- if (!ret)
- ret = iris_queue_deferred_buffers(inst, buf_type);
+ if (!ret)
+ ret = iris_queue_deferred_buffers(inst, BUF_OUTPUT);
+ }
} else {
if (inst->state == IRIS_INST_STREAMING) {
ret = iris_queue_deferred_buffers(inst, BUF_INPUT);
--
2.51.0