media: verisilicon: Do not change context bit depth before validating the format
authorBenjamin Gaignard <benjamin.gaignard@collabora.com>
Mon, 20 Feb 2023 10:48:47 +0000 (10:48 +0000)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 10 Apr 2023 13:18:13 +0000 (14:18 +0100)
It is needed to check if the proposed pixels format is valid before
updating context bit depth and other internal states.
Stop using ctx->bit_depth to check format depth match and return
result to the caller.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/verisilicon/hantro_postproc.c
drivers/media/platform/verisilicon/hantro_v4l2.c
drivers/media/platform/verisilicon/hantro_v4l2.h

index 09d8cf9..6437423 100644 (file)
@@ -197,7 +197,7 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx)
        unsigned int i, buf_size;
 
        /* this should always pick native format */
-       fmt = hantro_get_default_fmt(ctx, false);
+       fmt = hantro_get_default_fmt(ctx, false, ctx->bit_depth);
        if (!fmt)
                return -EINVAL;
        v4l2_fill_pixfmt_mp(&pix_mp, fmt->fourcc, ctx->src_fmt.width,
index d94c99f..d238d40 100644 (file)
@@ -28,6 +28,8 @@
 #include "hantro_hw.h"
 #include "hantro_v4l2.h"
 
+#define  HANTRO_DEFAULT_BIT_DEPTH 8
+
 static int hantro_set_fmt_out(struct hantro_ctx *ctx,
                              struct v4l2_pix_format_mplane *pix_mp);
 static int hantro_set_fmt_cap(struct hantro_ctx *ctx,
@@ -76,18 +78,13 @@ int hantro_get_format_depth(u32 fourcc)
 }
 
 static bool
-hantro_check_depth_match(const struct hantro_ctx *ctx,
-                        const struct hantro_fmt *fmt)
+hantro_check_depth_match(const struct hantro_fmt *fmt, int bit_depth)
 {
-       int fmt_depth, ctx_depth = 8;
+       int fmt_depth;
 
        if (!fmt->match_depth && !fmt->postprocessed)
                return true;
 
-       /* 0 means default depth, which is 8 */
-       if (ctx->bit_depth)
-               ctx_depth = ctx->bit_depth;
-
        fmt_depth = hantro_get_format_depth(fmt->fourcc);
 
        /*
@@ -95,9 +92,9 @@ hantro_check_depth_match(const struct hantro_ctx *ctx,
         * It may be possible to relax that on some HW.
         */
        if (!fmt->match_depth)
-               return fmt_depth <= ctx_depth;
+               return fmt_depth <= bit_depth;
 
-       return fmt_depth == ctx_depth;
+       return fmt_depth == bit_depth;
 }
 
 static const struct hantro_fmt *
@@ -119,7 +116,7 @@ hantro_find_format(const struct hantro_ctx *ctx, u32 fourcc)
 }
 
 const struct hantro_fmt *
-hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream)
+hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream, int bit_depth)
 {
        const struct hantro_fmt *formats;
        unsigned int i, num_fmts;
@@ -128,7 +125,7 @@ hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream)
        for (i = 0; i < num_fmts; i++) {
                if (bitstream == (formats[i].codec_mode !=
                                  HANTRO_MODE_NONE) &&
-                   hantro_check_depth_match(ctx, &formats[i]))
+                   hantro_check_depth_match(&formats[i], bit_depth))
                        return &formats[i];
        }
        return NULL;
@@ -204,7 +201,7 @@ static int vidioc_enum_fmt(struct file *file, void *priv,
 
                if (skip_mode_none == mode_none)
                        continue;
-               if (!hantro_check_depth_match(ctx, fmt))
+               if (!hantro_check_depth_match(fmt, ctx->bit_depth))
                        continue;
                if (j == f->index) {
                        f->pixelformat = fmt->fourcc;
@@ -224,7 +221,7 @@ static int vidioc_enum_fmt(struct file *file, void *priv,
        for (i = 0; i < num_fmts; i++) {
                fmt = &formats[i];
 
-               if (!hantro_check_depth_match(ctx, fmt))
+               if (!hantro_check_depth_match(fmt, ctx->bit_depth))
                        continue;
                if (j == f->index) {
                        f->pixelformat = fmt->fourcc;
@@ -292,7 +289,7 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
 
        fmt = hantro_find_format(ctx, pix_mp->pixelformat);
        if (!fmt) {
-               fmt = hantro_get_default_fmt(ctx, coded);
+               fmt = hantro_get_default_fmt(ctx, coded, HANTRO_DEFAULT_BIT_DEPTH);
                pix_mp->pixelformat = fmt->fourcc;
        }
 
@@ -380,7 +377,7 @@ hantro_reset_encoded_fmt(struct hantro_ctx *ctx)
        const struct hantro_fmt *vpu_fmt;
        struct v4l2_pix_format_mplane fmt;
 
-       vpu_fmt = hantro_get_default_fmt(ctx, true);
+       vpu_fmt = hantro_get_default_fmt(ctx, true, HANTRO_DEFAULT_BIT_DEPTH);
        if (!vpu_fmt)
                return;
 
@@ -393,15 +390,16 @@ hantro_reset_encoded_fmt(struct hantro_ctx *ctx)
                hantro_set_fmt_out(ctx, &fmt);
 }
 
-static void
-hantro_reset_raw_fmt(struct hantro_ctx *ctx)
+int
+hantro_reset_raw_fmt(struct hantro_ctx *ctx, int bit_depth)
 {
        const struct hantro_fmt *raw_vpu_fmt;
        struct v4l2_pix_format_mplane raw_fmt, *encoded_fmt;
+       int ret;
 
-       raw_vpu_fmt = hantro_get_default_fmt(ctx, false);
+       raw_vpu_fmt = hantro_get_default_fmt(ctx, false, bit_depth);
        if (!raw_vpu_fmt)
-               return;
+               return -EINVAL;
 
        if (ctx->is_encoder)
                encoded_fmt = &ctx->dst_fmt;
@@ -412,15 +410,20 @@ hantro_reset_raw_fmt(struct hantro_ctx *ctx)
        raw_fmt.width = encoded_fmt->width;
        raw_fmt.height = encoded_fmt->height;
        if (ctx->is_encoder)
-               hantro_set_fmt_out(ctx, &raw_fmt);
+               ret = hantro_set_fmt_out(ctx, &raw_fmt);
        else
-               hantro_set_fmt_cap(ctx, &raw_fmt);
+               ret = hantro_set_fmt_cap(ctx, &raw_fmt);
+
+       if (!ret)
+               ctx->bit_depth = bit_depth;
+
+       return ret;
 }
 
 void hantro_reset_fmts(struct hantro_ctx *ctx)
 {
        hantro_reset_encoded_fmt(ctx);
-       hantro_reset_raw_fmt(ctx);
+       hantro_reset_raw_fmt(ctx, HANTRO_DEFAULT_BIT_DEPTH);
 }
 
 static void
@@ -520,7 +523,7 @@ static int hantro_set_fmt_out(struct hantro_ctx *ctx,
         * changes to the raw format.
         */
        if (!ctx->is_encoder)
-               hantro_reset_raw_fmt(ctx);
+               hantro_reset_raw_fmt(ctx, hantro_get_format_depth(pix_mp->pixelformat));
 
        /* Colorimetry information are always propagated. */
        ctx->dst_fmt.colorspace = pix_mp->colorspace;
@@ -583,7 +586,7 @@ static int hantro_set_fmt_cap(struct hantro_ctx *ctx,
         * changes to the raw format.
         */
        if (ctx->is_encoder)
-               hantro_reset_raw_fmt(ctx);
+               hantro_reset_raw_fmt(ctx, HANTRO_DEFAULT_BIT_DEPTH);
 
        /* Colorimetry information are always propagated. */
        ctx->src_fmt.colorspace = pix_mp->colorspace;
index 64f6f57..9ea2fef 100644 (file)
 extern const struct v4l2_ioctl_ops hantro_ioctl_ops;
 extern const struct vb2_ops hantro_queue_ops;
 
+int hantro_reset_raw_fmt(struct hantro_ctx *ctx, int bit_depth);
 void hantro_reset_fmts(struct hantro_ctx *ctx);
 int hantro_get_format_depth(u32 fourcc);
 const struct hantro_fmt *
-hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream);
+hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream, int bit_depth);
 
 #endif /* HANTRO_V4L2_H_ */