On Thu May 1 15:55:49 2025 -0400, Jonas Karlman wrote:
> Add support for a get_image_fmt() ops that returns the required image
> format.
> 
> The CAPTURE format is reset when the required image format changes and
> the buffer queue is not busy.
> 
> Signed-off-by: Jonas Karlman <jo...@kwiboo.se>
> Tested-by: Nicolas Dufresne <nicolas.dufre...@collabora.com>
> Reviewed-by: Jonas Karlman <jo...@kwiboo.se>
> Co-developed-by: Nicolas Dufresne <nicolas.dufre...@collabora.com>
> Signed-off-by: Nicolas Dufresne <nicolas.dufre...@collabora.com>
> Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>

Patch committed.

Thanks,
Hans Verkuil

 drivers/staging/media/rkvdec/rkvdec.c | 35 +++++++++++++++++++++++++++++++++++
 drivers/staging/media/rkvdec/rkvdec.h |  2 ++
 2 files changed, 37 insertions(+)

---

diff --git a/drivers/staging/media/rkvdec/rkvdec.c 
b/drivers/staging/media/rkvdec/rkvdec.c
index 7b780392bb6a..f7eb67520ab0 100644
--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -34,6 +34,15 @@ static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt 
fmt1,
               fmt1 == RKVDEC_IMG_FMT_ANY;
 }
 
+static bool rkvdec_image_fmt_changed(struct rkvdec_ctx *ctx,
+                                    enum rkvdec_image_fmt image_fmt)
+{
+       if (image_fmt == RKVDEC_IMG_FMT_ANY)
+               return false;
+
+       return ctx->image_fmt != image_fmt;
+}
+
 static u32 rkvdec_enum_decoded_fmt(struct rkvdec_ctx *ctx, int index,
                                   enum rkvdec_image_fmt image_fmt)
 {
@@ -118,8 +127,34 @@ static int rkvdec_try_ctrl(struct v4l2_ctrl *ctrl)
        return 0;
 }
 
+static int rkvdec_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct rkvdec_ctx *ctx = container_of(ctrl->handler, struct rkvdec_ctx, 
ctrl_hdl);
+       const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
+       enum rkvdec_image_fmt image_fmt;
+       struct vb2_queue *vq;
+
+       /* Check if this change requires a capture format reset */
+       if (!desc->ops->get_image_fmt)
+               return 0;
+
+       image_fmt = desc->ops->get_image_fmt(ctx, ctrl);
+       if (rkvdec_image_fmt_changed(ctx, image_fmt)) {
+               vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+                                    V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+               if (vb2_is_busy(vq))
+                       return -EBUSY;
+
+               ctx->image_fmt = image_fmt;
+               rkvdec_reset_decoded_fmt(ctx);
+       }
+
+       return 0;
+}
+
 static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = {
        .try_ctrl = rkvdec_try_ctrl,
+       .s_ctrl = rkvdec_s_ctrl,
 };
 
 static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = {
diff --git a/drivers/staging/media/rkvdec/rkvdec.h 
b/drivers/staging/media/rkvdec/rkvdec.h
index 6f8cf50c5d99..e466a2753ccf 100644
--- a/drivers/staging/media/rkvdec/rkvdec.h
+++ b/drivers/staging/media/rkvdec/rkvdec.h
@@ -73,6 +73,8 @@ struct rkvdec_coded_fmt_ops {
                     struct vb2_v4l2_buffer *dst_buf,
                     enum vb2_buffer_state result);
        int (*try_ctrl)(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl);
+       enum rkvdec_image_fmt (*get_image_fmt)(struct rkvdec_ctx *ctx,
+                                              struct v4l2_ctrl *ctrl);
 };
 
 enum rkvdec_image_fmt {

Reply via email to