AV1 film grain feature requires to use the postprocessor to produce
valid frames. In such case the driver shouldn't propose native pixels
format but only post-processed pixels format.
If a codec set need_postproc field in hantro_ctx structure to true
native pixel formats will be ignored.
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@xxxxxxxxxxxxx>
---
drivers/media/platform/verisilicon/hantro.h | 3 ++
.../media/platform/verisilicon/hantro_drv.c | 5 ++
.../platform/verisilicon/hantro_postproc.c | 4 ++
.../media/platform/verisilicon/hantro_v4l2.c | 46 +++++++++++++------
4 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h
index a98cb40a8d3b..7a5357e810fb 100644
--- a/drivers/media/platform/verisilicon/hantro.h
+++ b/drivers/media/platform/verisilicon/hantro.h
@@ -231,6 +231,8 @@ struct hantro_dev {
* @ctrl_handler: Control handler used to register controls.
* @jpeg_quality: User-specified JPEG compression quality.
* @bit_depth: Bit depth of current frame
+ * @need_postproc: Set to true if the bitstream features require to
+ * use the post-processor.
*
* @codec_ops: Set of operations related to codec mode.
* @postproc: Post-processing context.
@@ -258,6 +260,7 @@ struct hantro_ctx {
struct v4l2_ctrl_handler ctrl_handler;
int jpeg_quality;
int bit_depth;
+ bool need_postproc;
const struct hantro_codec_ops *codec_ops;
struct hantro_postproc_ctx postproc;
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
index 4fc6dea16ae6..8d7055c0bf3b 100644
--- a/drivers/media/platform/verisilicon/hantro_drv.c
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
@@ -346,6 +346,11 @@ static int hantro_av1_s_ctrl(struct v4l2_ctrl *ctrl)
return -EINVAL;
ctx->bit_depth = bit_depth;
+
+ if (ctrl->p_new.p_av1_sequence->flags
+ & V4L2_AV1_SEQUENCE_FLAG_FILM_GRAIN_PARAMS_PRESENT)
+ ctx->need_postproc = true;
+
break;
default:
return -EINVAL;
diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c
index 7dc39519a2ee..293e5612e2ce 100644
--- a/drivers/media/platform/verisilicon/hantro_postproc.c
+++ b/drivers/media/platform/verisilicon/hantro_postproc.c
@@ -57,6 +57,10 @@ bool hantro_needs_postproc(const struct hantro_ctx *ctx,
{
if (ctx->is_encoder)
return false;
+
+ if (ctx->need_postproc)
+ return true;
+
return fmt->postprocessed;
}
diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
index bbe79dbd2cd9..5c381766cca3 100644
--- a/drivers/media/platform/verisilicon/hantro_v4l2.c
+++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
@@ -38,6 +38,11 @@ hantro_get_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts)
{
const struct hantro_fmt *formats;
+ if (ctx->need_postproc) {
+ *num_fmts = 0;
+ return NULL;
+ }
+
if (ctx->is_encoder) {
formats = ctx->dev->variant->enc_fmts;
*num_fmts = ctx->dev->variant->num_enc_fmts;
@@ -132,6 +137,15 @@ hantro_get_default_fmt(const struct hantro_ctx *ctx, bool bitstream)
hantro_check_depth_match(ctx, &formats[i]))
return &formats[i];
}
+
+ formats = hantro_get_postproc_formats(ctx, &num_fmts);
+ for (i = 0; i < num_fmts; i++) {
+ if (bitstream == (formats[i].codec_mode !=
+ HANTRO_MODE_NONE) &&
+ hantro_check_depth_match(ctx, &formats[i]))
+ return &formats[i];
+ }
+
return NULL;
}
@@ -261,19 +275,6 @@ static int vidioc_g_fmt_out_mplane(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct hantro_ctx *ctx = fh_to_ctx(priv);
-
- vpu_debug(4, "f->type = %d\n", f->type);
-
- *pix_mp = ctx->dst_fmt;
-
- return 0;
-}
-
static int hantro_try_fmt(const struct hantro_ctx *ctx,
struct v4l2_pix_format_mplane *pix_mp,
enum v4l2_buf_type type)
@@ -353,6 +354,25 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
return 0;
}
+static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+ struct hantro_ctx *ctx = fh_to_ctx(priv);
+ int ret;
+
+ vpu_debug(4, "f->type = %d\n", f->type);
+
+ ret = hantro_try_fmt(ctx, pix_mp, f->type);
+ if (ret)
+ return ret;
+
+ ctx->vpu_dst_fmt = hantro_find_format(ctx, pix_mp->pixelformat);
+ ctx->dst_fmt = *pix_mp;
+