]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: rkvdec: Add image format concept
authorJonas Karlman <jonas@kwiboo.se>
Tue, 25 Feb 2025 09:40:29 +0000 (10:40 +0100)
committerHans Verkuil <hverkuil@xs4all.nl>
Tue, 8 Apr 2025 07:21:21 +0000 (07:21 +0000)
Add an enum rkvdec_image_fmt used to signal an image format, e.g.
4:2:0 8-bit, 4:2:0 10-bit or any.

Tag each supported CAPUTRE format with an image format and use this tag
to filter out unsupported CAPTURE formats.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Tested-by: Christopher Obbard <chris.obbard@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 52e64b399dcc4a0c028cac908c0b1ceb49956c5f..70154948b4e32e2c439f259b0f1e1bbc8b52b063 100644 (file)
 #include "rkvdec.h"
 #include "rkvdec-regs.h"
 
-static u32 rkvdec_enum_decoded_fmt(struct rkvdec_ctx *ctx, int index)
+static bool rkvdec_image_fmt_match(enum rkvdec_image_fmt fmt1,
+                                  enum rkvdec_image_fmt fmt2)
+{
+       return fmt1 == fmt2 || fmt2 == RKVDEC_IMG_FMT_ANY ||
+              fmt1 == RKVDEC_IMG_FMT_ANY;
+}
+
+static u32 rkvdec_enum_decoded_fmt(struct rkvdec_ctx *ctx, int index,
+                                  enum rkvdec_image_fmt image_fmt)
 {
        const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
+       int fmt_idx = -1;
+       unsigned int i;
 
        if (WARN_ON(!desc))
                return 0;
 
-       if (index >= desc->num_decoded_fmts)
-               return 0;
+       for (i = 0; i < desc->num_decoded_fmts; i++) {
+               if (!rkvdec_image_fmt_match(desc->decoded_fmts[i].image_fmt,
+                                           image_fmt))
+                       continue;
+               fmt_idx++;
+               if (index == fmt_idx)
+                       return desc->decoded_fmts[i].fourcc;
+       }
 
-       return desc->decoded_fmts[index];
+       return 0;
 }
 
-static bool rkvdec_is_valid_fmt(struct rkvdec_ctx *ctx, u32 fourcc)
+static bool rkvdec_is_valid_fmt(struct rkvdec_ctx *ctx, u32 fourcc,
+                               enum rkvdec_image_fmt image_fmt)
 {
        const struct rkvdec_coded_fmt_desc *desc = ctx->coded_fmt_desc;
        unsigned int i;
 
        for (i = 0; i < desc->num_decoded_fmts; i++) {
-               if (desc->decoded_fmts[i] == fourcc)
+               if (rkvdec_image_fmt_match(desc->decoded_fmts[i].image_fmt,
+                                          image_fmt) &&
+                   desc->decoded_fmts[i].fourcc == fourcc)
                        return true;
        }
 
@@ -80,7 +99,7 @@ static void rkvdec_reset_decoded_fmt(struct rkvdec_ctx *ctx)
        struct v4l2_format *f = &ctx->decoded_fmt;
        u32 fourcc;
 
-       fourcc = rkvdec_enum_decoded_fmt(ctx, 0);
+       fourcc = rkvdec_enum_decoded_fmt(ctx, 0, ctx->image_fmt);
        rkvdec_reset_fmt(ctx, f, fourcc);
        f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
        f->fmt.pix_mp.width = ctx->coded_fmt.fmt.pix_mp.width;
@@ -149,8 +168,11 @@ static const struct rkvdec_ctrls rkvdec_h264_ctrls = {
        .num_ctrls = ARRAY_SIZE(rkvdec_h264_ctrl_descs),
 };
 
-static const u32 rkvdec_h264_vp9_decoded_fmts[] = {
-       V4L2_PIX_FMT_NV12,
+static const struct rkvdec_decoded_fmt_desc rkvdec_h264_vp9_decoded_fmts[] = {
+       {
+               .fourcc = V4L2_PIX_FMT_NV12,
+               .image_fmt = RKVDEC_IMG_FMT_420_8BIT,
+       },
 };
 
 static const struct rkvdec_ctrl_desc rkvdec_vp9_ctrl_descs[] = {
@@ -282,8 +304,9 @@ static int rkvdec_try_capture_fmt(struct file *file, void *priv,
        if (WARN_ON(!coded_desc))
                return -EINVAL;
 
-       if (!rkvdec_is_valid_fmt(ctx, pix_mp->pixelformat))
-               pix_mp->pixelformat = rkvdec_enum_decoded_fmt(ctx, 0);
+       if (!rkvdec_is_valid_fmt(ctx, pix_mp->pixelformat, ctx->image_fmt))
+               pix_mp->pixelformat = rkvdec_enum_decoded_fmt(ctx, 0,
+                                                             ctx->image_fmt);
 
        /* Always apply the frmsize constraint of the coded end. */
        pix_mp->width = max(pix_mp->width, ctx->coded_fmt.fmt.pix_mp.width);
@@ -400,6 +423,7 @@ static int rkvdec_s_output_fmt(struct file *file, void *priv,
         *
         * Note that this will propagates any size changes to the decoded format.
         */
+       ctx->image_fmt = RKVDEC_IMG_FMT_ANY;
        rkvdec_reset_decoded_fmt(ctx);
 
        /* Propagate colorspace information to capture. */
@@ -449,7 +473,7 @@ static int rkvdec_enum_capture_fmt(struct file *file, void *priv,
        struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv);
        u32 fourcc;
 
-       fourcc = rkvdec_enum_decoded_fmt(ctx, f->index);
+       fourcc = rkvdec_enum_decoded_fmt(ctx, f->index, ctx->image_fmt);
        if (!fourcc)
                return -EINVAL;
 
index 633335ebb9c498bb69ae4072b772f30858a89e48..6f8cf50c5d99aad2f52e321f54f3ca17166ddf98 100644 (file)
@@ -75,13 +75,23 @@ struct rkvdec_coded_fmt_ops {
        int (*try_ctrl)(struct rkvdec_ctx *ctx, struct v4l2_ctrl *ctrl);
 };
 
+enum rkvdec_image_fmt {
+       RKVDEC_IMG_FMT_ANY = 0,
+       RKVDEC_IMG_FMT_420_8BIT,
+};
+
+struct rkvdec_decoded_fmt_desc {
+       u32 fourcc;
+       enum rkvdec_image_fmt image_fmt;
+};
+
 struct rkvdec_coded_fmt_desc {
        u32 fourcc;
        struct v4l2_frmsize_stepwise frmsize;
        const struct rkvdec_ctrls *ctrls;
        const struct rkvdec_coded_fmt_ops *ops;
        unsigned int num_decoded_fmts;
-       const u32 *decoded_fmts;
+       const struct rkvdec_decoded_fmt_desc *decoded_fmts;
        u32 subsystem_flags;
 };
 
@@ -104,6 +114,7 @@ struct rkvdec_ctx {
        const struct rkvdec_coded_fmt_desc *coded_fmt_desc;
        struct v4l2_ctrl_handler ctrl_hdl;
        struct rkvdec_dev *dev;
+       enum rkvdec_image_fmt image_fmt;
        void *priv;
 };