build/patch/kernel/sunxi-legacy/0623-media-cedrus-10bit-HEVC-hack.patch
Igor Pečovnik caa47bad65
Move sunxi/64 current to 5.7, legacy to 5.4 (#2098)
* Move sunxi/64 current to 5.7, legacy to 5.4
* Update sunxidev config
2020-07-18 23:08:52 +02:00

89 lines
3.2 KiB
Diff

From 60808cc1810d47f91c368de8ffb7db59cabceaf9 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Tue, 28 May 2019 21:05:34 +0200
Subject: [PATCH] 10-bit HEVC hack
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
.../staging/media/sunxi/cedrus/cedrus_h265.c | 12 +++++++++++
.../staging/media/sunxi/cedrus/cedrus_regs.h | 4 ++++
.../staging/media/sunxi/cedrus/cedrus_video.c | 20 ++++++++++++++-----
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index 97dce6ffbbc5..d866662cd5a5 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -520,6 +520,18 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
cedrus_write(dev, VE_DEC_H265_DEC_PCM_CTRL, reg);
+ if (sps->bit_depth_luma_minus8) {
+ unsigned int size;
+
+ size = ALIGN(ctx->src_fmt.width, 16) * ALIGN(ctx->src_fmt.height, 16);
+
+ reg = (size * 3) / 2;
+ cedrus_write(dev, VE_DEC_H265_OFFSET_ADDR_FIRST_OUT, reg);
+
+ reg = DIV_ROUND_UP(ctx->src_fmt.width, 4);
+ cedrus_write(dev, VE_DEC_H265_10BIT_CONFIGURE, ALIGN(reg, 32));
+ }
+
/* PPS. */
reg = VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(pps->pps_cr_qp_offset) |
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
index df1cceef8d93..150eae2d92d2 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
@@ -498,6 +498,10 @@
#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
+#define VE_DEC_H265_OFFSET_ADDR_FIRST_OUT (VE_ENGINE_DEC_H265 + 0x84)
+#define VE_DEC_H265_OFFSET_ADDR_SECOND_OUT (VE_ENGINE_DEC_H265 + 0x88)
+#define VE_DEC_H265_10BIT_CONFIGURE (VE_ENGINE_DEC_H265 + 0x8c)
+
#define VE_DEC_H265_LOW_ADDR_PRIMARY_CHROMA(a) \
SHIFT_AND_MASK_BITS(a, 31, 24)
#define VE_DEC_H265_LOW_ADDR_SECONDARY_CHROMA(a) \
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
index 497b1199d3fe..178ad45b79d8 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -367,17 +367,27 @@ static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
{
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
struct v4l2_pix_format *pix_fmt;
+ unsigned int extra_size = 0;
- if (V4L2_TYPE_IS_OUTPUT(vq->type))
+ if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
pix_fmt = &ctx->src_fmt;
- else
+ } else {
pix_fmt = &ctx->dst_fmt;
+ /* The HEVC decoder needs extra size on the output buffer. */
+ if (ctx->src_fmt.pixelformat == V4L2_PIX_FMT_HEVC_SLICE) {
+ extra_size = DIV_ROUND_UP(pix_fmt->width, 4);
+ extra_size = ALIGN(extra_size, 32);
+ extra_size *= ALIGN(pix_fmt->height, 16) * 3;
+ extra_size /= 2;
+ }
+ }
+
if (*nplanes) {
- if (sizes[0] < pix_fmt->sizeimage)
- return -EINVAL;
+ if (sizes[0] < (pix_fmt->sizeimage + extra_size))
+ sizes[0] = pix_fmt->sizeimage + extra_size;
} else {
- sizes[0] = pix_fmt->sizeimage;
+ sizes[0] = pix_fmt->sizeimage + extra_size;
*nplanes = 1;
}
--
2.23.0