Re: [PATCH 5/5] media: iris: Recycle decoder buffers for non-display pictures
From: Nicolas Dufresne
Date: Tue Nov 03 2026 - 17:25:45 EST
Le jeudi 29 octobre 2026 à 11:58 +0800, Xilin Wu a écrit :
> HFI gen2 reports non-display pictures with HFI_GEN2_PICTURE_NOSHOW, but
> Iris returns them as errors. For AV1, hidden and displayed pictures can
> share a timestamp, so GStreamer's v4l2av1dec drops the pending frame and
> loses the displayed picture.
>
> Recycle successful non-display buffers within the driver instead of
> returning them to userspace as errors. This also fixes VP9 streams using
> hidden alt-ref frames.
This change is expected to improve conformance, even though you still can't
display multiple time the same reference in V4L2 stateful. Can you run fluster
and share any conformance test that failed before and succeed today?
Nicolas
>
> Fixes: ac72ad9deafa ("media: iris: Add handling for no show frames")
> Signed-off-by: Xilin Wu <sophon@xxxxxxxxx>
> ---
> drivers/media/platform/qcom/iris/iris_hfi_gen2.h | 2 +
> .../platform/qcom/iris/iris_hfi_gen2_command.c | 11 ++++-
> .../platform/qcom/iris/iris_hfi_gen2_response.c | 47 ++++++++++++++++++++--
> 3 files changed, 55 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
> index 21ab58e0aa84..79aac2d4e500 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h
> @@ -20,6 +20,7 @@ struct iris_core;
> * @packet: HFI packet
> * @ipsc_properties_set: boolean to set ipsc properties to fw
> * @opsc_properties_set: boolean to set opsc properties to fw
> + * @output_stopping: capture STOP command is awaiting its response
> * @hfi_frame_info: structure of frame info
> * @src_subcr_params: subscription params to fw on input port
> * @dst_subcr_params: subscription params to fw on output port
> @@ -29,6 +30,7 @@ struct iris_inst_hfi_gen2 {
> struct iris_hfi_header *packet;
> bool ipsc_properties_set;
> bool opsc_properties_set;
> + bool output_stopping;
> struct iris_hfi_frame_info hfi_frame_info;
> struct hfi_subscription_params src_subcr_params;
> struct hfi_subscription_params dst_subcr_params;
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
> index a285e6fc8728..77ea153bf2d7 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
> @@ -1172,7 +1172,16 @@ static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
> if (ret)
> return ret;
>
> - return iris_wait_for_session_response(inst, false);
> + /* The response wait drops inst->lock, allowing buffers to be returned. */
> + if (plane == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
> + inst_hfi_gen2->output_stopping = true;
> +
> + ret = iris_wait_for_session_response(inst, false);
> +
> + if (plane == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
> + inst_hfi_gen2->output_stopping = false;
> +
> + return ret;
> }
>
> static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
> diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> index f0782c4b1e6e..a545410d1e8d 100644
> --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> @@ -101,9 +101,7 @@ static int iris_hfi_gen2_get_driver_buffer_flags(struct iris_inst *inst, u32 hfi
> HFI_GEN2_PICTURE_CRA | HFI_GEN2_PICTURE_BLA;
> u32 driver_flags = 0;
>
> - if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_NOSHOW)
> - driver_flags |= V4L2_BUF_FLAG_ERROR;
> - else if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe)
> + if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe)
> driver_flags |= V4L2_BUF_FLAG_KEYFRAME;
> else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_P)
> driver_flags |= V4L2_BUF_FLAG_PFRAME;
> @@ -345,9 +343,40 @@ static int iris_hfi_gen2_handle_input_buffer(struct iris_inst *inst,
> return 0;
> }
>
> +static int iris_hfi_gen2_requeue_output_buffer(struct iris_inst *inst,
> + struct iris_buffer *buf)
> +{
> + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
> + u64 timestamp = buf->timestamp;
> + int ret;
> +
> + buf->data_size = 0;
> + buf->timestamp = 0;
> + buf->flags = 0;
> + buf->attr &= ~BUF_ATTR_DEQUEUED;
> + buf->attr |= BUF_ATTR_DEFERRED;
> +
> + /* Leave stopped buffers for streamoff cleanup or the next streamon. */
> + if (inst_hfi_gen2->output_stopping ||
> + (inst->state != IRIS_INST_STREAMING &&
> + inst->state != IRIS_INST_OUTPUT_STREAMING))
> + return 0;
> +
> + ret = iris_queue_buffer(inst, buf);
> + if (ret) {
> + buf->attr &= ~BUF_ATTR_DEFERRED;
> + buf->attr |= BUF_ATTR_DEQUEUED;
> + buf->flags = V4L2_BUF_FLAG_ERROR;
> + buf->timestamp = timestamp;
> + }
> +
> + return ret;
> +}
> +
> static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst,
> struct iris_hfi_buffer *hfi_buffer)
> {
> + struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
> struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
> struct v4l2_m2m_buffer *m2m_buffer, *n;
> struct iris_buffer *buf;
> @@ -390,8 +419,18 @@ static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst,
>
> buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->flags);
>
> + if (inst->domain == DECODER &&
> + inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_NOSHOW) {
> + /* A hidden reference picture is neither a display frame nor an error. */
> + buf->data_size = 0;
> + if (inst->state == IRIS_INST_ERROR)
> + buf->flags |= V4L2_BUF_FLAG_ERROR;
> + if (!(buf->flags & (V4L2_BUF_FLAG_ERROR | V4L2_BUF_FLAG_LAST)))
> + return iris_hfi_gen2_requeue_output_buffer(inst, buf);
> + }
> +
> if (!buf->data_size && inst->state == IRIS_INST_STREAMING &&
> - !(hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST)) {
> + !(buf->flags & V4L2_BUF_FLAG_LAST)) {
> buf->flags |= V4L2_BUF_FLAG_ERROR;
> }
>
Attachment:
signature.asc
Description: This is a digitally signed message part