On Fri Sep 5 16:19:21 2025 +0000, Jonas Karlman wrote:
> Add filtering of coded formats and controls depending on a variant
> capabilities.
> 
> Signed-off-by: Alex Bee <[email protected]>
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Jonas Karlman <[email protected]>
> Tested-by: Diederik de Haas <[email protected]>  # Rock64, RockPro64, 
> Quartz64-B, NanoPi R5S
> Tested-by: Detlev Casanova <[email protected]> # RK3399
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/rockchip/rkvdec/rkvdec.c | 67 ++++++++++++++++++-------
 1 file changed, 49 insertions(+), 18 deletions(-)

---

diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c 
b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 056c827c6b95..f5784f00c78e 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -365,13 +365,36 @@ static const struct rkvdec_coded_fmt_desc 
rkvdec_coded_fmts[] = {
        }
 };
 
+static bool rkvdec_is_capable(struct rkvdec_ctx *ctx, unsigned int capability)
+{
+       return (ctx->dev->variant->capabilities & capability) == capability;
+}
+
 static const struct rkvdec_coded_fmt_desc *
-rkvdec_find_coded_fmt_desc(u32 fourcc)
+rkvdec_enum_coded_fmt_desc(struct rkvdec_ctx *ctx, int index)
 {
+       int fmt_idx = -1;
        unsigned int i;
 
        for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
-               if (rkvdec_coded_fmts[i].fourcc == fourcc)
+               if (!rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability))
+                       continue;
+               fmt_idx++;
+               if (index == fmt_idx)
+                       return &rkvdec_coded_fmts[i];
+       }
+
+       return NULL;
+}
+
+static const struct rkvdec_coded_fmt_desc *
+rkvdec_find_coded_fmt_desc(struct rkvdec_ctx *ctx, u32 fourcc)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
+               if (rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability) &&
+                   rkvdec_coded_fmts[i].fourcc == fourcc)
                        return &rkvdec_coded_fmts[i];
        }
 
@@ -382,7 +405,7 @@ static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
 {
        struct v4l2_format *f = &ctx->coded_fmt;
 
-       ctx->coded_fmt_desc = &rkvdec_coded_fmts[0];
+       ctx->coded_fmt_desc = rkvdec_enum_coded_fmt_desc(ctx, 0);
        rkvdec_reset_fmt(ctx, f, ctx->coded_fmt_desc->fourcc);
 
        f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
@@ -396,21 +419,22 @@ static void rkvdec_reset_coded_fmt(struct rkvdec_ctx *ctx)
 static int rkvdec_enum_framesizes(struct file *file, void *priv,
                                  struct v4l2_frmsizeenum *fsize)
 {
-       const struct rkvdec_coded_fmt_desc *fmt;
+       struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
+       const struct rkvdec_coded_fmt_desc *desc;
 
        if (fsize->index != 0)
                return -EINVAL;
 
-       fmt = rkvdec_find_coded_fmt_desc(fsize->pixel_format);
-       if (!fmt)
+       desc = rkvdec_find_coded_fmt_desc(ctx, fsize->pixel_format);
+       if (!desc)
                return -EINVAL;
 
        fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
        fsize->stepwise.min_width = 1;
-       fsize->stepwise.max_width = fmt->frmsize.max_width;
+       fsize->stepwise.max_width = desc->frmsize.max_width;
        fsize->stepwise.step_width = 1;
        fsize->stepwise.min_height = 1;
-       fsize->stepwise.max_height = fmt->frmsize.max_height;
+       fsize->stepwise.max_height = desc->frmsize.max_height;
        fsize->stepwise.step_height = 1;
 
        return 0;
@@ -470,10 +494,10 @@ static int rkvdec_try_output_fmt(struct file *file, void 
*priv,
        struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
        const struct rkvdec_coded_fmt_desc *desc;
 
-       desc = rkvdec_find_coded_fmt_desc(pix_mp->pixelformat);
+       desc = rkvdec_find_coded_fmt_desc(ctx, pix_mp->pixelformat);
        if (!desc) {
-               pix_mp->pixelformat = rkvdec_coded_fmts[0].fourcc;
-               desc = &rkvdec_coded_fmts[0];
+               desc = rkvdec_enum_coded_fmt_desc(ctx, 0);
+               pix_mp->pixelformat = desc->fourcc;
        }
 
        v4l2_apply_frmsize_constraints(&pix_mp->width,
@@ -550,7 +574,7 @@ static int rkvdec_s_output_fmt(struct file *file, void 
*priv,
        if (ret)
                return ret;
 
-       desc = rkvdec_find_coded_fmt_desc(f->fmt.pix_mp.pixelformat);
+       desc = rkvdec_find_coded_fmt_desc(ctx, f->fmt.pix_mp.pixelformat);
        if (!desc)
                return -EINVAL;
        ctx->coded_fmt_desc = desc;
@@ -602,10 +626,14 @@ static int rkvdec_g_capture_fmt(struct file *file, void 
*priv,
 static int rkvdec_enum_output_fmt(struct file *file, void *priv,
                                  struct v4l2_fmtdesc *f)
 {
-       if (f->index >= ARRAY_SIZE(rkvdec_coded_fmts))
+       struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
+       const struct rkvdec_coded_fmt_desc *desc;
+
+       desc = rkvdec_enum_coded_fmt_desc(ctx, f->index);
+       if (!desc)
                return -EINVAL;
 
-       f->pixelformat = rkvdec_coded_fmts[f->index].fourcc;
+       f->pixelformat = desc->fourcc;
        return 0;
 }
 
@@ -969,14 +997,17 @@ static int rkvdec_init_ctrls(struct rkvdec_ctx *ctx)
        int ret;
 
        for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++)
-               nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
+               if (rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability))
+                       nctrls += rkvdec_coded_fmts[i].ctrls->num_ctrls;
 
        v4l2_ctrl_handler_init(&ctx->ctrl_hdl, nctrls);
 
        for (i = 0; i < ARRAY_SIZE(rkvdec_coded_fmts); i++) {
-               ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls);
-               if (ret)
-                       goto err_free_handler;
+               if (rkvdec_is_capable(ctx, rkvdec_coded_fmts[i].capability)) {
+                       ret = rkvdec_add_ctrls(ctx, rkvdec_coded_fmts[i].ctrls);
+                       if (ret)
+                               goto err_free_handler;
+               }
        }
 
        ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to