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. Fixes: dc39473d0340 ("media: hantro: imx8m: Enable 10bit decoding") Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxxxxx> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@xxxxxxxxxxxxx> --- .../media/platform/verisilicon/hantro_drv.c | 11 ++++++++-- .../media/platform/verisilicon/hantro_v4l2.c | 22 ++++++++++--------- .../media/platform/verisilicon/imx8m_vpu_hw.c | 2 ++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c index 6d8bc55ea627..fa31b200b097 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -326,8 +326,15 @@ static int hantro_hevc_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_STATELESS_HEVC_SPS: - ctx->bit_depth = ctrl->p_new.p_hevc_sps->bit_depth_luma_minus8 + 8; - break; + { + const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps; + int bit_depth = sps->bit_depth_luma_minus8 + 8; + + if (ctx->bit_depth == bit_depth) + return 0; + + return hantro_reset_raw_fmt(ctx, bit_depth); + } default: return -EINVAL; } diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c index 6c5f4351b257..7c9a04171b45 100644 --- a/drivers/media/platform/verisilicon/hantro_v4l2.c +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -28,7 +28,7 @@ #include "hantro_hw.h" #include "hantro_v4l2.h" -#define HANTRO_DEFAULT_BIT_DEPTH 0 +#define HANTRO_DEFAULT_BIT_DEPTH 8 static int hantro_set_fmt_out(struct hantro_ctx *ctx, struct v4l2_pix_format_mplane *pix_mp); @@ -80,15 +80,11 @@ int hantro_get_format_depth(u32 fourcc) static bool hantro_check_depth_match(const struct hantro_fmt *fmt, int bit_depth) { - int fmt_depth, depth = 8; + int fmt_depth; if (!fmt->match_depth && !fmt->postprocessed) return true; - /* 0 means default depth, which is 8 */ - if (bit_depth) - depth = bit_depth; - fmt_depth = hantro_get_format_depth(fmt->fourcc); /* @@ -96,9 +92,9 @@ hantro_check_depth_match(const struct hantro_fmt *fmt, int bit_depth) * It may be possible to relax that on some HW. */ if (!fmt->match_depth) - return fmt_depth <= depth; + return fmt_depth <= bit_depth; - return fmt_depth == depth; + return fmt_depth == bit_depth; } static const struct hantro_fmt * @@ -398,6 +394,7 @@ 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, bit_depth); if (!raw_vpu_fmt) @@ -412,9 +409,14 @@ hantro_reset_raw_fmt(struct hantro_ctx *ctx, int bit_depth) raw_fmt.width = encoded_fmt->width; raw_fmt.height = encoded_fmt->height; if (ctx->is_encoder) - return hantro_set_fmt_out(ctx, &raw_fmt); + ret = hantro_set_fmt_out(ctx, &raw_fmt); else - return 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) 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