]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: rkvdec: Add get_image_fmt ops
authorJonas Karlman <jonas@kwiboo.se>
Thu, 1 May 2025 19:55:49 +0000 (15:55 -0400)
committerHans Verkuil <hverkuil@xs4all.nl>
Thu, 15 May 2025 06:13:31 +0000 (08:13 +0200)
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 <jonas@kwiboo.se>
Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Co-developed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
drivers/staging/media/rkvdec/rkvdec.c
drivers/staging/media/rkvdec/rkvdec.h

index 7b780392bb6a63cc954655ef940e87146d2b852f..f7eb67520ab0edd9ac1da3d0daf2af1bc6d37a09 100644 (file)
@@ -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[] = {
index 6f8cf50c5d99aad2f52e321f54f3ca17166ddf98..e466a2753ccfc13738e0a672bc578e521af2c3f2 100644 (file)
@@ -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 {