On Wed Dec 17 11:02:23 2025 +0800, Ming Qian wrote:
> After encountering a colorspace change in the stream, the decoder
> sends a V4L2_EVENT_SOURCE_CHANGE event with changes set to
> V4L2_EVENT_SRC_CH_RESOLUTION.
> 
> Then the client can detect and handle the colorspace change without any
> buffer reallocation
> 
> Signed-off-by: Ming Qian <[email protected]>
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/amphion/vdec.c     | 61 ++++++++++++++++++++-----------
 drivers/media/platform/amphion/vpu_v4l2.c |  1 -
 2 files changed, 40 insertions(+), 22 deletions(-)

---

diff --git a/drivers/media/platform/amphion/vdec.c 
b/drivers/media/platform/amphion/vdec.c
index f25dbcebdccf..beeaf75c76b4 100644
--- a/drivers/media/platform/amphion/vdec.c
+++ b/drivers/media/platform/amphion/vdec.c
@@ -950,7 +950,7 @@ static void vdec_stop_done(struct vpu_inst *inst)
        vpu_inst_unlock(inst);
 }
 
-static bool vdec_check_source_change(struct vpu_inst *inst)
+static bool vdec_check_source_change(struct vpu_inst *inst, struct 
vpu_dec_codec_info *hdr)
 {
        struct vdec_t *vdec = inst->priv;
        const struct vpu_format *sibling;
@@ -962,26 +962,35 @@ static bool vdec_check_source_change(struct vpu_inst 
*inst)
                return false;
 
        sibling = vpu_helper_find_sibling(inst, inst->cap_format.type, 
inst->cap_format.pixfmt);
-       if (sibling && vdec->codec_info.pixfmt == sibling->pixfmt)
-               vdec->codec_info.pixfmt = inst->cap_format.pixfmt;
+       if (sibling && hdr->pixfmt == sibling->pixfmt)
+               hdr->pixfmt = inst->cap_format.pixfmt;
 
        if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
                return true;
-       if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
+       if (inst->cap_format.pixfmt != hdr->pixfmt)
                return true;
-       if (inst->cap_format.width != vdec->codec_info.decoded_width)
+       if (inst->cap_format.width != hdr->decoded_width)
                return true;
-       if (inst->cap_format.height != vdec->codec_info.decoded_height)
+       if (inst->cap_format.height != hdr->decoded_height)
                return true;
        if (vpu_get_num_buffers(inst, inst->cap_format.type) < 
inst->min_buffer_cap)
                return true;
-       if (inst->crop.left != vdec->codec_info.offset_x)
+       if (inst->crop.left != hdr->offset_x)
                return true;
-       if (inst->crop.top != vdec->codec_info.offset_y)
+       if (inst->crop.top != hdr->offset_y)
                return true;
-       if (inst->crop.width != vdec->codec_info.width)
+       if (inst->crop.width != hdr->width)
                return true;
-       if (inst->crop.height != vdec->codec_info.height)
+       if (inst->crop.height != hdr->height)
+               return true;
+       if (!hdr->progressive)
+               return true;
+
+       if (vdec->seq_hdr_found &&
+           (hdr->color_primaries != vdec->codec_info.color_primaries ||
+            hdr->transfer_chars != vdec->codec_info.transfer_chars ||
+            hdr->matrix_coeffs != vdec->codec_info.matrix_coeffs ||
+            hdr->full_range != vdec->codec_info.full_range))
                return true;
 
        return false;
@@ -1333,20 +1342,25 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, 
struct vpu_dec_codec_info
        struct vdec_t *vdec = inst->priv;
 
        vpu_inst_lock(inst);
-       memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
 
-       vpu_trace(inst->dev, "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d\n",
+       vpu_trace(inst->dev,
+                 "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d, colorspace: 
%d, %d, %d, %d\n",
                  inst->id,
-                 vdec->codec_info.decoded_width,
-                 vdec->codec_info.decoded_height,
-                 vdec->codec_info.offset_x,
-                 vdec->codec_info.offset_y,
-                 vdec->codec_info.width,
-                 vdec->codec_info.height,
+                 hdr->decoded_width,
+                 hdr->decoded_height,
+                 hdr->offset_x,
+                 hdr->offset_y,
+                 hdr->width,
+                 hdr->height,
                  hdr->num_ref_frms,
-                 hdr->num_dpb_frms);
+                 hdr->num_dpb_frms,
+                 hdr->color_primaries,
+                 hdr->transfer_chars,
+                 hdr->matrix_coeffs,
+                 hdr->full_range);
        inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
-       vdec->is_source_changed = vdec_check_source_change(inst);
+       vdec->is_source_changed = vdec_check_source_change(inst, hdr);
+       memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
        vdec_init_fmt(inst);
        vdec_init_crop(inst);
        vdec_init_mbi(inst);
@@ -1375,7 +1389,12 @@ static void vdec_event_resolution_change(struct vpu_inst 
*inst)
 {
        struct vdec_t *vdec = inst->priv;
 
-       vpu_trace(inst->dev, "[%d]\n", inst->id);
+       vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, 
sequence : %d\n",
+                 inst->id,
+                 vdec->params.frame_count,
+                 vdec->decoded_frame_count,
+                 vdec->display_frame_count,
+                 vdec->sequence);
        vpu_inst_lock(inst);
        vdec->seq_tag = vdec->codec_info.tag;
        vdec_clear_fs(&vdec->mbi);
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c 
b/drivers/media/platform/amphion/vpu_v4l2.c
index 47dff9a35bb4..121165a7184f 100644
--- a/drivers/media/platform/amphion/vpu_v4l2.c
+++ b/drivers/media/platform/amphion/vpu_v4l2.c
@@ -102,7 +102,6 @@ static int vpu_notify_eos(struct vpu_inst *inst)
 int vpu_notify_source_change(struct vpu_inst *inst)
 {
        static const struct v4l2_event ev = {
-               .id = 0,
                .type = V4L2_EVENT_SOURCE_CHANGE,
                .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
        };
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to