mirror of
https://github.com/Fishwaldo/build.git
synced 2025-04-17 03:21:25 +00:00
89 lines
3.2 KiB
Diff
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
|