From 9746f27324527abb40fcdad9b731faf58b7681e6 Mon Sep 17 00:00:00 2001 From: ChengFangming Date: Fri, 28 Aug 2026 20:00:00 +0800 Subject: [PATCH 28/30] kernel-overlay: filter hidden VP9 superframes --- .../qcom/iris/iris_hfi_gen1_response.c | 19 +++++++++++++++---- .../media/platform/qcom/iris/iris_instance.h | 2 +- drivers/media/platform/qcom/iris/iris_vdec.c | 4 ++-- drivers/media/platform/qcom/iris/iris_vdec.h | 1 + 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c index 4fe6e19f6145..e48d606d5424 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c @@ -582,7 +582,16 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) if (inst->domain == DECODER && buf->type == BUF_OUTPUT && inst->core->iris_platform_data->legacy_vpu5) { - ret = iris_vdec_complete_pending_output(inst); + /* Legacy VPU5 emits both subframes from a VP9 superframe, including + * the leading show_frame=0 alt-ref frame. HFI gives both outputs the + * packet timestamp and does not set DROP_FRAME. Keep one output + * pending so a same-timestamp successor can replace the hidden frame. */ + if (inst->codec == V4L2_PIX_FMT_VP9 && filled_len && + inst->pending_output && + inst->pending_output->timestamp == timestamp_us) + ret = iris_vdec_recycle_pending_output(inst); + else + ret = iris_vdec_complete_pending_output(inst); if (ret) goto error; seek_was_pending = inst->seek_timestamp_pending; @@ -668,9 +677,11 @@ static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) if (inst->domain == DECODER && buf->type == BUF_OUTPUT && filled_len && inst->core->iris_platform_data->legacy_vpu5 && - !(hfi_flags & (HFI_BUFFERFLAG_DATACORRUPT | - HFI_BUFFERFLAG_DROP_FRAME)) && - !seek_was_pending && inst->seek_hold_frames) { + !seek_was_pending && + (inst->codec == V4L2_PIX_FMT_VP9 || + (!(hfi_flags & (HFI_BUFFERFLAG_DATACORRUPT | + HFI_BUFFERFLAG_DROP_FRAME)) && + inst->seek_hold_frames))) { ret = iris_vdec_hold_output(inst, buf); if (ret) goto error; diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h index 8aa0da43e10a..bdf2d12fecc1 100644 --- a/drivers/media/platform/qcom/iris/iris_instance.h +++ b/drivers/media/platform/qcom/iris/iris_instance.h @@ -79,7 +79,7 @@ struct iris_fmt { * @input_timestamp_valid: whether last_input_timestamp has been initialized * @seek_timestamp_pending: discard old-epoch output until seek_timestamp arrives * @corrupt_output_drops: consecutive corrupt legacy output frames recycled - * @pending_output: legacy output held for one frame to detect a timestamp jump + * @pending_output: legacy output held to filter stale or hidden VP9 frames * @seek_hold_frames: output frames held after a seek before resuming in-place delivery * @display_delay: requested firmware display delay * @display_delay_enable: whether the requested display delay is active diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index 2c3c59be82d8..4d19db04df22 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -24,7 +24,7 @@ #define IRIS1_SEEK_HOLD_FRAMES 30 #define IRIS1_MAX_4K_MBPF NUM_MBS_PER_FRAME(2176, 4096) -static int iris_vdec_recycle_pending_output(struct iris_inst *inst) +int iris_vdec_recycle_pending_output(struct iris_inst *inst) { struct iris_buffer *buf = inst->pending_output; @@ -33,7 +33,7 @@ static int iris_vdec_recycle_pending_output(struct iris_inst *inst) inst->pending_output = NULL; dev_info(inst->core->dev, - "Iris1 v138: recycling pending old-epoch output timestamp %llu ns\n", + "Iris1 v155: recycling pending output timestamp %llu ns\n", buf->timestamp); buf->data_size = 0; buf->flags = 0; diff --git a/drivers/media/platform/qcom/iris/iris_vdec.h b/drivers/media/platform/qcom/iris/iris_vdec.h index e947c05bd99f..befe51a9ad02 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.h +++ b/drivers/media/platform/qcom/iris/iris_vdec.h @@ -23,6 +23,7 @@ int iris_vdec_streamon_output(struct iris_inst *inst); u32 iris_vdec_get_admission_fps(struct iris_inst *inst); int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf); bool iris_vdec_discard_stale_frame(struct iris_inst *inst, u64 timestamp); +int iris_vdec_recycle_pending_output(struct iris_inst *inst); int iris_vdec_complete_pending_output(struct iris_inst *inst); int iris_vdec_hold_output(struct iris_inst *inst, struct iris_buffer *buf); void iris_vdec_clear_pending_output(struct iris_inst *inst); -- 2.55.0