Merge pull request #4267 from jernejsk/cedrus_update

Allwinner: Update Cedrus patches
This commit is contained in:
CvH
2020-03-16 06:52:30 +01:00
committed by GitHub
3 changed files with 378 additions and 152 deletions

View File

@@ -0,0 +1,121 @@
From 2756ad266f18d546551a3eab0650c95ddb62e0ff Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Sat, 14 Mar 2020 22:21:42 +0000
Subject: [PATCH] v4l2 request hevc: Set SPS control at initialization
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
libavcodec/v4l2_request_hevc.c | 61 ++++++++++++++++++++++------------
1 file changed, 40 insertions(+), 21 deletions(-)
diff --git a/libavcodec/v4l2_request_hevc.c b/libavcodec/v4l2_request_hevc.c
index 94977c5d0e..0ab1c201b0 100644
--- a/libavcodec/v4l2_request_hevc.c
+++ b/libavcodec/v4l2_request_hevc.c
@@ -231,21 +231,12 @@ static void v4l2_request_hevc_fill_slice_params(const HEVCContext *h,
slice_params->entry_point_offset_minus1[i] = sh->entry_point_offset[i] - 1;
}
-static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
- av_unused const uint8_t *buffer,
- av_unused uint32_t size)
+static void fill_sps(struct v4l2_ctrl_hevc_sps *ctrl, const HEVCContext *h)
{
- const HEVCContext *h = avctx->priv_data;
const HEVCSPS *sps = h->ps.sps;
- const HEVCPPS *pps = h->ps.pps;
- const ScalingList *sl = pps->scaling_list_data_present_flag ?
- &pps->scaling_list :
- sps->scaling_list_enable_flag ?
- &sps->scaling_list : NULL;
- V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
/* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
- controls->sps = (struct v4l2_ctrl_hevc_sps) {
+ *ctrl = (struct v4l2_ctrl_hevc_sps) {
.chroma_format_idc = sps->chroma_format_idc,
.pic_width_in_luma_samples = sps->width,
.pic_height_in_luma_samples = sps->height,
@@ -270,31 +261,47 @@ static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
};
if (sps->separate_colour_plane_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE;
if (sps->scaling_list_enable_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED;
if (sps->amp_enabled_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_AMP_ENABLED;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_AMP_ENABLED;
if (sps->sao_enabled)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET;
if (sps->pcm_enabled_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_ENABLED;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_PCM_ENABLED;
if (sps->pcm.loop_filter_disable_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED;
if (sps->long_term_ref_pics_present_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT;
if (sps->sps_temporal_mvp_enabled_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED;
if (sps->sps_strong_intra_smoothing_enable_flag)
- controls->sps.flags |= V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED;
+ ctrl->flags |= V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED;
+}
+
+static int v4l2_request_hevc_start_frame(AVCodecContext *avctx,
+ av_unused const uint8_t *buffer,
+ av_unused uint32_t size)
+{
+ const HEVCContext *h = avctx->priv_data;
+ const HEVCSPS *sps = h->ps.sps;
+ const HEVCPPS *pps = h->ps.pps;
+ const ScalingList *sl = pps->scaling_list_data_present_flag ?
+ &pps->scaling_list :
+ sps->scaling_list_enable_flag ?
+ &sps->scaling_list : NULL;
+ V4L2RequestControlsHEVC *controls = h->ref->hwaccel_picture_private;
+
+ fill_sps(&controls->sps, h);
if (sl) {
for (int i = 0; i < 6; i++) {
@@ -502,9 +509,21 @@ static int v4l2_request_hevc_set_controls(AVCodecContext *avctx)
static int v4l2_request_hevc_init(AVCodecContext *avctx)
{
+ const HEVCContext *h = avctx->priv_data;
+ struct v4l2_ctrl_hevc_sps sps;
int ret;
- ret = ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 3 * 1024 * 1024, NULL, 0);
+ struct v4l2_ext_control control[] = {
+ {
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
+ .ptr = &sps,
+ .size = sizeof(sps),
+ }
+ };
+
+ fill_sps(&sps, h);
+
+ ret = ff_v4l2_request_init(avctx, V4L2_PIX_FMT_HEVC_SLICE, 3 * 1024 * 1024, control, FF_ARRAY_ELEMS(control));
if (ret)
return ret;
--
2.25.1

View File

@@ -1,90 +0,0 @@
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