2023-01-25 17:28:12

by Benjamin Gaignard

[permalink] [raw]
Subject: [PATCH v4 0/2] media: verisilicon: HEVC: fix 10bits handling

When decoding a 10bits bitstreams HEVC driver should only expose 10bits pixel formats.
To fulfill this requirement it is needed to call hantro_reset_raw_fmt()
and to only change driver internal state in case of success.

Fluster score (140/147) doesn't change after this series.

version 4:
- Split the change in 2 patches.
- Change hantro_check_depth_match() prototype to avoid using
ctx->bit_depth
- Return the result of hantro_reset_raw_fmt() to the caller.
- Only set ctx->bit_depth when hantro_reset_raw_fmt() returns is ok.

Benjamin Gaignard (2):
media: verisilicon: Do not change context bit depth before validating
the format
media: verisilicon: HEVC: Only propose 10 bits compatible pixels
formats

.../media/platform/verisilicon/hantro_drv.c | 46 +++++++++++++---
.../platform/verisilicon/hantro_postproc.c | 2 +-
.../media/platform/verisilicon/hantro_v4l2.c | 53 +++++++++----------
.../media/platform/verisilicon/hantro_v4l2.h | 3 +-
.../media/platform/verisilicon/imx8m_vpu_hw.c | 2 +
5 files changed, 68 insertions(+), 38 deletions(-)

--
2.34.1



2023-01-25 17:28:14

by Benjamin Gaignard

[permalink] [raw]
Subject: [PATCH v4 1/2] media: verisilicon: Do not change context bit depth before validating the format

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 <[email protected]>
---
version 4:
- Change hantro_check_depth_match() prototype to avoid using
ctx->bit_depth
- Return the result of hantro_reset_raw_fmt() to the caller.

.../platform/verisilicon/hantro_postproc.c | 2 +-
.../media/platform/verisilicon/hantro_v4l2.c | 53 +++++++++----------
.../media/platform/verisilicon/hantro_v4l2.h | 3 +-
3 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c
index 09d8cf942689..6437423ccf3a 100644
--- a/drivers/media/platform/verisilicon/hantro_postproc.c
+++ b/drivers/media/platform/verisilicon/hantro_postproc.c
@@ -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,
diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
index 2c7a805289e7..2475bc05dee9 100644
--- a/drivers/media/platform/verisilicon/hantro_v4l2.c
+++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
@@ -76,17 +76,16 @@ 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, depth = 8;

if (!fmt->match_depth && !fmt->postprocessed)
return true;

/* 0 means default depth, which is 8 */
- if (ctx->bit_depth)
- ctx_depth = ctx->bit_depth;
+ if (bit_depth)
+ depth = bit_depth;

fmt_depth = hantro_get_format_depth(fmt->fourcc);

@@ -95,9 +94,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 <= depth;

- return fmt_depth == ctx_depth;
+ return fmt_depth == depth;
}

static const struct hantro_fmt *
@@ -119,7 +118,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 +127,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;
@@ -203,7 +202,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;
@@ -223,7 +222,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;
@@ -291,7 +290,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, 0);
pix_mp->pixelformat = fmt->fourcc;
}

@@ -379,15 +378,12 @@ 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, 0);

- if (ctx->is_encoder) {
- ctx->vpu_dst_fmt = vpu_fmt;
+ if (ctx->is_encoder)
fmt = &ctx->dst_fmt;
- } else {
- ctx->vpu_src_fmt = vpu_fmt;
+ else
fmt = &ctx->src_fmt;
- }

hantro_reset_fmt(fmt, vpu_fmt);
fmt->width = vpu_fmt->frmsize.min_width;
@@ -398,20 +394,21 @@ 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;

- 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 -EINVAL;

if (ctx->is_encoder) {
- ctx->vpu_src_fmt = raw_vpu_fmt;
raw_fmt = &ctx->src_fmt;
encoded_fmt = &ctx->dst_fmt;
} else {
- ctx->vpu_dst_fmt = raw_vpu_fmt;
raw_fmt = &ctx->dst_fmt;
encoded_fmt = &ctx->src_fmt;
}
@@ -420,15 +417,15 @@ 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);
+ return hantro_set_fmt_out(ctx, raw_fmt);
else
- hantro_set_fmt_cap(ctx, raw_fmt);
+ return hantro_set_fmt_cap(ctx, raw_fmt);
}

void hantro_reset_fmts(struct hantro_ctx *ctx)
{
hantro_reset_encoded_fmt(ctx);
- hantro_reset_raw_fmt(ctx);
+ hantro_reset_raw_fmt(ctx, 0);
}

static void
@@ -528,7 +525,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;
@@ -591,7 +588,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, 0);

/* Colorimetry information are always propagated. */
ctx->src_fmt.colorspace = pix_mp->colorspace;
diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.h b/drivers/media/platform/verisilicon/hantro_v4l2.h
index 64f6f57e9d7a..9ea2fef57dcd 100644
--- a/drivers/media/platform/verisilicon/hantro_v4l2.h
+++ b/drivers/media/platform/verisilicon/hantro_v4l2.h
@@ -21,9 +21,10 @@
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_ */
--
2.34.1


2023-01-25 17:28:17

by Benjamin Gaignard

[permalink] [raw]
Subject: [PATCH v4 2/2] media: verisilicon: HEVC: Only propose 10 bits compatible pixels formats

When decoding a 10bits bitstreams HEVC driver should only expose
10bits pixel formats.
To fulfill this requirement it is needed to call hantro_reset_raw_fmt()
when bit depth change and to correctly set match_depth in pixel formats
enumeration.

Signed-off-by: Benjamin Gaignard <[email protected]>
---
version 4:
- Only set ctx->bit_depth when hantro_reset_raw_fmt() returns is ok.

.../media/platform/verisilicon/hantro_drv.c | 46 +++++++++++++++----
.../media/platform/verisilicon/imx8m_vpu_hw.c | 2 +
2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
index 8cb4a68c9119..30abab7ac9bf 100644
--- a/drivers/media/platform/verisilicon/hantro_drv.c
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
@@ -251,11 +251,6 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)

static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
{
- struct hantro_ctx *ctx;
-
- ctx = container_of(ctrl->handler,
- struct hantro_ctx, ctrl_handler);
-
if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;

@@ -274,8 +269,6 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
/* Only 8-bit and 10-bit are supported */
return -EINVAL;
-
- ctx->bit_depth = sps->bit_depth_luma_minus8 + 8;
} else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;

@@ -286,6 +279,38 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}

+static int hantro_hevc_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct hantro_ctx *ctx;
+
+ ctx = container_of(ctrl->handler,
+ struct hantro_ctx, ctrl_handler);
+
+ vpu_debug(1, "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val);
+
+ switch (ctrl->id) {
+ case V4L2_CID_STATELESS_HEVC_SPS:
+ {
+ const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
+ int bit_depth = sps->bit_depth_luma_minus8 + 8;
+ int ret;
+
+ if (ctx->bit_depth == bit_depth)
+ return 0;
+
+ ret = hantro_reset_raw_fmt(ctx, bit_depth);
+ if (!ret)
+ ctx->bit_depth = bit_depth;
+
+ return ret;
+ }
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int hantro_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct hantro_ctx *ctx;
@@ -328,6 +353,11 @@ static const struct v4l2_ctrl_ops hantro_ctrl_ops = {
.try_ctrl = hantro_try_ctrl,
};

+static const struct v4l2_ctrl_ops hantro_hevc_ctrl_ops = {
+ .s_ctrl = hantro_hevc_s_ctrl,
+ .try_ctrl = hantro_try_ctrl,
+};
+
static const struct v4l2_ctrl_ops hantro_jpeg_ctrl_ops = {
.s_ctrl = hantro_jpeg_s_ctrl,
};
@@ -470,7 +500,7 @@ static const struct hantro_ctrl controls[] = {
.codec = HANTRO_HEVC_DECODER,
.cfg = {
.id = V4L2_CID_STATELESS_HEVC_SPS,
- .ops = &hantro_ctrl_ops,
+ .ops = &hantro_hevc_ctrl_ops,
},
}, {
.codec = HANTRO_HEVC_DECODER,
diff --git a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
index b390228fd3b4..f850d8bddef6 100644
--- a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
+++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
@@ -152,6 +152,7 @@ static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
{
.fourcc = V4L2_PIX_FMT_NV12,
.codec_mode = HANTRO_MODE_NONE,
+ .match_depth = true,
.postprocessed = true,
.frmsize = {
.min_width = FMT_MIN_WIDTH,
@@ -165,6 +166,7 @@ static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
{
.fourcc = V4L2_PIX_FMT_P010,
.codec_mode = HANTRO_MODE_NONE,
+ .match_depth = true,
.postprocessed = true,
.frmsize = {
.min_width = FMT_MIN_WIDTH,
--
2.34.1


2023-01-26 14:26:26

by Nicolas Dufresne

[permalink] [raw]
Subject: Re: [PATCH v4 1/2] media: verisilicon: Do not change context bit depth before validating the format

Le mercredi 25 janvier 2023 à 18:27 +0100, Benjamin Gaignard a écrit :
> 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 <[email protected]>

Reviewed-by: Nicolas Dufresne <[email protected]>

I'm not sure if the fixes tag will do a great job, but blame indicated that it
fixes. Ezequiel, can you provide your feedback on if we need a Fixes and which
hash should be point to ? My quick blame says this:

Fixes: 953aaa1492c5 ("media: rockchip/vpu: Prepare things to support decoders")

> ---
> version 4:
> - Change hantro_check_depth_match() prototype to avoid using
> ctx->bit_depth
> - Return the result of hantro_reset_raw_fmt() to the caller.
>
> .../platform/verisilicon/hantro_postproc.c | 2 +-
> .../media/platform/verisilicon/hantro_v4l2.c | 53 +++++++++----------
> .../media/platform/verisilicon/hantro_v4l2.h | 3 +-
> 3 files changed, 28 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c
> index 09d8cf942689..6437423ccf3a 100644
> --- a/drivers/media/platform/verisilicon/hantro_postproc.c
> +++ b/drivers/media/platform/verisilicon/hantro_postproc.c
> @@ -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,
> diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
> index 2c7a805289e7..2475bc05dee9 100644
> --- a/drivers/media/platform/verisilicon/hantro_v4l2.c
> +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
> @@ -76,17 +76,16 @@ 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, depth = 8;
>
> if (!fmt->match_depth && !fmt->postprocessed)
> return true;
>
> /* 0 means default depth, which is 8 */
> - if (ctx->bit_depth)
> - ctx_depth = ctx->bit_depth;
> + if (bit_depth)
> + depth = bit_depth;
>
> fmt_depth = hantro_get_format_depth(fmt->fourcc);
>
> @@ -95,9 +94,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 <= depth;
>
> - return fmt_depth == ctx_depth;
> + return fmt_depth == depth;
> }
>
> static const struct hantro_fmt *
> @@ -119,7 +118,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 +127,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;
> @@ -203,7 +202,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;
> @@ -223,7 +222,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;
> @@ -291,7 +290,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, 0);
> pix_mp->pixelformat = fmt->fourcc;
> }
>
> @@ -379,15 +378,12 @@ 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, 0);
>
> - if (ctx->is_encoder) {
> - ctx->vpu_dst_fmt = vpu_fmt;
> + if (ctx->is_encoder)
> fmt = &ctx->dst_fmt;
> - } else {
> - ctx->vpu_src_fmt = vpu_fmt;
> + else
> fmt = &ctx->src_fmt;
> - }
>
> hantro_reset_fmt(fmt, vpu_fmt);
> fmt->width = vpu_fmt->frmsize.min_width;
> @@ -398,20 +394,21 @@ 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;
>
> - 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 -EINVAL;
>
> if (ctx->is_encoder) {
> - ctx->vpu_src_fmt = raw_vpu_fmt;
> raw_fmt = &ctx->src_fmt;
> encoded_fmt = &ctx->dst_fmt;
> } else {
> - ctx->vpu_dst_fmt = raw_vpu_fmt;
> raw_fmt = &ctx->dst_fmt;
> encoded_fmt = &ctx->src_fmt;
> }
> @@ -420,15 +417,15 @@ 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);
> + return hantro_set_fmt_out(ctx, raw_fmt);
> else
> - hantro_set_fmt_cap(ctx, raw_fmt);
> + return hantro_set_fmt_cap(ctx, raw_fmt);
> }
>
> void hantro_reset_fmts(struct hantro_ctx *ctx)
> {
> hantro_reset_encoded_fmt(ctx);
> - hantro_reset_raw_fmt(ctx);
> + hantro_reset_raw_fmt(ctx, 0);
> }
>
> static void
> @@ -528,7 +525,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;
> @@ -591,7 +588,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, 0);
>
> /* Colorimetry information are always propagated. */
> ctx->src_fmt.colorspace = pix_mp->colorspace;
> diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.h b/drivers/media/platform/verisilicon/hantro_v4l2.h
> index 64f6f57e9d7a..9ea2fef57dcd 100644
> --- a/drivers/media/platform/verisilicon/hantro_v4l2.h
> +++ b/drivers/media/platform/verisilicon/hantro_v4l2.h
> @@ -21,9 +21,10 @@
> 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_ */


2023-01-26 14:33:40

by Nicolas Dufresne

[permalink] [raw]
Subject: Re: [PATCH v4 2/2] media: verisilicon: HEVC: Only propose 10 bits compatible pixels formats

Hi Benjamin,

Le mercredi 25 janvier 2023 à 18:27 +0100, Benjamin Gaignard a écrit :
> When decoding a 10bits bitstreams HEVC driver should only expose
> 10bits pixel formats.
> To fulfill this requirement it is needed to call hantro_reset_raw_fmt()
> when bit depth change and to correctly set match_depth in pixel formats
> enumeration.
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> version 4:
> - Only set ctx->bit_depth when hantro_reset_raw_fmt() returns is ok.
>
> .../media/platform/verisilicon/hantro_drv.c | 46 +++++++++++++++----
> .../media/platform/verisilicon/imx8m_vpu_hw.c | 2 +
> 2 files changed, 40 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
> index 8cb4a68c9119..30abab7ac9bf 100644
> --- a/drivers/media/platform/verisilicon/hantro_drv.c
> +++ b/drivers/media/platform/verisilicon/hantro_drv.c
> @@ -251,11 +251,6 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
>
> static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
> {
> - struct hantro_ctx *ctx;
> -
> - ctx = container_of(ctrl->handler,
> - struct hantro_ctx, ctrl_handler);
> -
> if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
> const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
>
> @@ -274,8 +269,6 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
> if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2)
> /* Only 8-bit and 10-bit are supported */
> return -EINVAL;
> -
> - ctx->bit_depth = sps->bit_depth_luma_minus8 + 8;
> } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
> const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
>
> @@ -286,6 +279,38 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
> return 0;
> }
>
> +static int hantro_hevc_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct hantro_ctx *ctx;
> +
> + ctx = container_of(ctrl->handler,
> + struct hantro_ctx, ctrl_handler);
> +
> + vpu_debug(1, "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val);

This trace feels redundant with the v4l2 core traces, mind dropping it ?

Other then that, the patch looks good to me, but should have included a Fixes
tag for backport purposes. Could it be ?

Fixes: dc39473d0340 ("media: hantro: imx8m: Enable 10bit decoding")

With that adjusted:

Reviewed-by: Nicolas Dufresne <[email protected]>

> +
> + switch (ctrl->id) {
> + case V4L2_CID_STATELESS_HEVC_SPS:
> + {
> + const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps;
> + int bit_depth = sps->bit_depth_luma_minus8 + 8;
> + int ret;
> +
> + if (ctx->bit_depth == bit_depth)
> + return 0;
> +
> + ret = hantro_reset_raw_fmt(ctx, bit_depth);
> + if (!ret)
> + ctx->bit_depth = bit_depth;
> +
> + return ret;
> + }
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> static int hantro_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
> {
> struct hantro_ctx *ctx;
> @@ -328,6 +353,11 @@ static const struct v4l2_ctrl_ops hantro_ctrl_ops = {
> .try_ctrl = hantro_try_ctrl,
> };
>
> +static const struct v4l2_ctrl_ops hantro_hevc_ctrl_ops = {
> + .s_ctrl = hantro_hevc_s_ctrl,
> + .try_ctrl = hantro_try_ctrl,
> +};
> +
> static const struct v4l2_ctrl_ops hantro_jpeg_ctrl_ops = {
> .s_ctrl = hantro_jpeg_s_ctrl,
> };
> @@ -470,7 +500,7 @@ static const struct hantro_ctrl controls[] = {
> .codec = HANTRO_HEVC_DECODER,
> .cfg = {
> .id = V4L2_CID_STATELESS_HEVC_SPS,
> - .ops = &hantro_ctrl_ops,
> + .ops = &hantro_hevc_ctrl_ops,
> },
> }, {
> .codec = HANTRO_HEVC_DECODER,
> diff --git a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
> index b390228fd3b4..f850d8bddef6 100644
> --- a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
> +++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c
> @@ -152,6 +152,7 @@ static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
> {
> .fourcc = V4L2_PIX_FMT_NV12,
> .codec_mode = HANTRO_MODE_NONE,
> + .match_depth = true,
> .postprocessed = true,
> .frmsize = {
> .min_width = FMT_MIN_WIDTH,
> @@ -165,6 +166,7 @@ static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {
> {
> .fourcc = V4L2_PIX_FMT_P010,
> .codec_mode = HANTRO_MODE_NONE,
> + .match_depth = true,
> .postprocessed = true,
> .frmsize = {
> .min_width = FMT_MIN_WIDTH,