mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
linux (Allwinner): rebase patches for 6.2-rc1
This commit is contained in:
parent
83ec8acf6b
commit
56c75e7140
@ -1,50 +0,0 @@
|
||||
From b6d288bb8823e11114297d1e406ccd977106aaf9 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 9 Nov 2019 13:06:15 +0100
|
||||
Subject: [PATCH 28/44] media: cedrus: Add callback for buffer cleanup
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 1 +
|
||||
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 13 +++++++++++++
|
||||
2 files changed, 14 insertions(+)
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -166,6 +166,7 @@ struct cedrus_dec_ops {
|
||||
int (*start)(struct cedrus_ctx *ctx);
|
||||
void (*stop)(struct cedrus_ctx *ctx);
|
||||
void (*trigger)(struct cedrus_ctx *ctx);
|
||||
+ void (*buf_cleanup)(struct cedrus_ctx *ctx, struct cedrus_buffer *buf);
|
||||
};
|
||||
|
||||
struct cedrus_variant {
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -469,6 +469,18 @@ static int cedrus_buf_prepare(struct vb2
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void cedrus_buf_cleanup(struct vb2_buffer *vb)
|
||||
+{
|
||||
+ struct vb2_queue *vq = vb->vb2_queue;
|
||||
+ struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
+ struct cedrus_dev *dev = ctx->dev;
|
||||
+ struct cedrus_dec_ops *ops = dev->dec_ops[ctx->current_codec];
|
||||
+
|
||||
+ if (!V4L2_TYPE_IS_OUTPUT(vq->type) && ops->buf_cleanup)
|
||||
+ ops->buf_cleanup(ctx,
|
||||
+ vb2_to_cedrus_buffer(vq->bufs[vb->index]));
|
||||
+}
|
||||
+
|
||||
static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
{
|
||||
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
|
||||
@@ -551,6 +563,7 @@ static void cedrus_buf_request_complete(
|
||||
static struct vb2_ops cedrus_qops = {
|
||||
.queue_setup = cedrus_queue_setup,
|
||||
.buf_prepare = cedrus_buf_prepare,
|
||||
+ .buf_cleanup = cedrus_buf_cleanup,
|
||||
.buf_queue = cedrus_buf_queue,
|
||||
.buf_out_validate = cedrus_buf_out_validate,
|
||||
.buf_request_complete = cedrus_buf_request_complete,
|
@ -1,240 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 9 Nov 2019 13:22:05 +0100
|
||||
Subject: [PATCH] media: cedrus: hevc: Improve buffer management
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 9 +-
|
||||
.../staging/media/sunxi/cedrus/cedrus_h265.c | 119 ++++++++++--------
|
||||
2 files changed, 69 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
index ab7653c8915e..54a860ec738d 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -106,6 +106,11 @@ struct cedrus_buffer {
|
||||
unsigned int position;
|
||||
enum cedrus_h264_pic_type pic_type;
|
||||
} h264;
|
||||
+ struct {
|
||||
+ void *mv_col_buf;
|
||||
+ dma_addr_t mv_col_buf_dma;
|
||||
+ ssize_t mv_col_buf_size;
|
||||
+ } h265;
|
||||
} codec;
|
||||
};
|
||||
|
||||
@@ -139,10 +144,6 @@ struct cedrus_ctx {
|
||||
ssize_t intra_pred_buf_size;
|
||||
} h264;
|
||||
struct {
|
||||
- void *mv_col_buf;
|
||||
- dma_addr_t mv_col_buf_addr;
|
||||
- ssize_t mv_col_buf_size;
|
||||
- ssize_t mv_col_buf_unit_size;
|
||||
void *neighbor_info_buf;
|
||||
dma_addr_t neighbor_info_buf_addr;
|
||||
void *entry_points_buf;
|
||||
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
index 4b01d3881214..4d425196d415 100644
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -91,26 +91,65 @@ static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
|
||||
|
||||
static inline dma_addr_t
|
||||
cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
|
||||
- unsigned int index, unsigned int field)
|
||||
+ unsigned int index,
|
||||
+ const struct v4l2_ctrl_hevc_sps *sps)
|
||||
{
|
||||
- return ctx->codec.h265.mv_col_buf_addr + index *
|
||||
- ctx->codec.h265.mv_col_buf_unit_size +
|
||||
- field * ctx->codec.h265.mv_col_buf_unit_size / 2;
|
||||
+ struct cedrus_buffer *cedrus_buf = NULL;
|
||||
+ struct vb2_buffer *buf = NULL;
|
||||
+ struct vb2_queue *vq;
|
||||
+
|
||||
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||||
+ if (vq)
|
||||
+ buf = vb2_get_buffer(vq, index);
|
||||
+
|
||||
+ if (buf)
|
||||
+ cedrus_buf = vb2_to_cedrus_buffer(buf);
|
||||
+
|
||||
+ if (!cedrus_buf)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!cedrus_buf->codec.h265.mv_col_buf_size) {
|
||||
+ unsigned int log2_max_luma_coding_block_size;
|
||||
+ unsigned int ctb_size_luma;
|
||||
+
|
||||
+ log2_max_luma_coding_block_size =
|
||||
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
||||
+ sps->log2_diff_max_min_luma_coding_block_size;
|
||||
+ ctb_size_luma = 1 << log2_max_luma_coding_block_size;
|
||||
+
|
||||
+ cedrus_buf->codec.h265.mv_col_buf_size =
|
||||
+ DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma) *
|
||||
+ DIV_ROUND_UP(sps->pic_height_in_luma_samples, ctb_size_luma) *
|
||||
+ CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
|
||||
+
|
||||
+ cedrus_buf->codec.h265.mv_col_buf =
|
||||
+ dma_alloc_attrs(ctx->dev->dev,
|
||||
+ cedrus_buf->codec.h265.mv_col_buf_size,
|
||||
+ &cedrus_buf->codec.h265.mv_col_buf_dma,
|
||||
+ GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
+
|
||||
+ if (!cedrus_buf->codec.h265.mv_col_buf) {
|
||||
+ cedrus_buf->codec.h265.mv_col_buf_size = 0;
|
||||
+ cedrus_buf->codec.h265.mv_col_buf_dma = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return cedrus_buf->codec.h265.mv_col_buf_dma;
|
||||
}
|
||||
|
||||
static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
|
||||
unsigned int index,
|
||||
bool field_pic,
|
||||
u32 pic_order_cnt[],
|
||||
- struct vb2_buffer *buf)
|
||||
+ struct vb2_buffer *buf,
|
||||
+ const struct v4l2_ctrl_hevc_sps *sps)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buf, 0);
|
||||
dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buf, 1);
|
||||
dma_addr_t mv_col_buf_addr[2] = {
|
||||
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, 0),
|
||||
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index,
|
||||
- field_pic ? 1 : 0)
|
||||
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, sps),
|
||||
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buf->index, sps)
|
||||
};
|
||||
u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
|
||||
VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
|
||||
@@ -134,7 +173,8 @@ static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
|
||||
|
||||
static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
|
||||
const struct v4l2_hevc_dpb_entry *dpb,
|
||||
- u8 num_active_dpb_entries)
|
||||
+ u8 num_active_dpb_entries,
|
||||
+ const struct v4l2_ctrl_hevc_sps *sps)
|
||||
{
|
||||
struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||||
@@ -149,7 +189,7 @@ static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
|
||||
|
||||
cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
|
||||
pic_order_cnt,
|
||||
- buf);
|
||||
+ buf, sps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,36 +428,6 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
width_in_ctb_luma =
|
||||
DIV_ROUND_UP(sps->pic_width_in_luma_samples, ctb_size_luma);
|
||||
|
||||
- /* MV column buffer size and allocation. */
|
||||
- if (!ctx->codec.h265.mv_col_buf_size) {
|
||||
- unsigned int num_buffers =
|
||||
- run->dst->vb2_buf.vb2_queue->num_buffers;
|
||||
-
|
||||
- /*
|
||||
- * Each CTB requires a MV col buffer with a specific unit size.
|
||||
- * Since the address is given with missing lsb bits, 1 KiB is
|
||||
- * added to each buffer to ensure proper alignment.
|
||||
- */
|
||||
- ctx->codec.h265.mv_col_buf_unit_size =
|
||||
- DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) *
|
||||
- DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) *
|
||||
- CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf_size = num_buffers *
|
||||
- ctx->codec.h265.mv_col_buf_unit_size;
|
||||
-
|
||||
- /* Buffer is never accessed by CPU, so we can skip kernel mapping. */
|
||||
- ctx->codec.h265.mv_col_buf =
|
||||
- dma_alloc_attrs(dev->dev,
|
||||
- ctx->codec.h265.mv_col_buf_size,
|
||||
- &ctx->codec.h265.mv_col_buf_addr,
|
||||
- GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
- if (!ctx->codec.h265.mv_col_buf) {
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
- return -ENOMEM;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Activate H265 engine. */
|
||||
cedrus_engine_enable(ctx, CEDRUS_CODEC_H265);
|
||||
|
||||
@@ -672,7 +681,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
|
||||
/* Write decoded picture buffer in pic list. */
|
||||
cedrus_h265_frame_info_write_dpb(ctx, decode_params->dpb,
|
||||
- decode_params->num_active_dpb_entries);
|
||||
+ decode_params->num_active_dpb_entries, sps);
|
||||
|
||||
/* Output frame. */
|
||||
|
||||
@@ -683,7 +692,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
||||
cedrus_h265_frame_info_write_single(ctx, output_pic_list_index,
|
||||
slice_params->pic_struct != 0,
|
||||
pic_order_cnt,
|
||||
- &run->dst->vb2_buf);
|
||||
+ &run->dst->vb2_buf, sps);
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_OUTPUT_FRAME_IDX, output_pic_list_index);
|
||||
|
||||
@@ -732,9 +741,6 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- /* The buffer size is calculated at setup time. */
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
-
|
||||
/* Buffer is never accessed by CPU, so we can skip kernel mapping. */
|
||||
ctx->codec.h265.neighbor_info_buf =
|
||||
dma_alloc_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
@@ -761,15 +767,6 @@ static void cedrus_h265_stop(struct cedrus_ctx *ctx)
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- if (ctx->codec.h265.mv_col_buf_size > 0) {
|
||||
- dma_free_attrs(dev->dev, ctx->codec.h265.mv_col_buf_size,
|
||||
- ctx->codec.h265.mv_col_buf,
|
||||
- ctx->codec.h265.mv_col_buf_addr,
|
||||
- DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
-
|
||||
- ctx->codec.h265.mv_col_buf_size = 0;
|
||||
- }
|
||||
-
|
||||
dma_free_attrs(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
||||
ctx->codec.h265.neighbor_info_buf,
|
||||
ctx->codec.h265.neighbor_info_buf_addr,
|
||||
@@ -786,6 +783,17 @@ static void cedrus_h265_trigger(struct cedrus_ctx *ctx)
|
||||
cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_DEC_SLICE);
|
||||
}
|
||||
|
||||
+static void cedrus_h265_buf_cleanup(struct cedrus_ctx *ctx,
|
||||
+ struct cedrus_buffer *buf)
|
||||
+{
|
||||
+ if (buf->codec.h265.mv_col_buf_size)
|
||||
+ dma_free_attrs(ctx->dev->dev,
|
||||
+ buf->codec.h265.mv_col_buf_size,
|
||||
+ buf->codec.h265.mv_col_buf,
|
||||
+ buf->codec.h265.mv_col_buf_dma,
|
||||
+ DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
+}
|
||||
+
|
||||
struct cedrus_dec_ops cedrus_dec_ops_h265 = {
|
||||
.irq_clear = cedrus_h265_irq_clear,
|
||||
.irq_disable = cedrus_h265_irq_disable,
|
||||
@@ -794,4 +802,5 @@ struct cedrus_dec_ops cedrus_dec_ops_h265 = {
|
||||
.start = cedrus_h265_start,
|
||||
.stop = cedrus_h265_stop,
|
||||
.trigger = cedrus_h265_trigger,
|
||||
+ .buf_cleanup = cedrus_h265_buf_cleanup,
|
||||
};
|
@ -1,201 +0,0 @@
|
||||
From a881ce25cba8e45c6a86b5a680981c3b14b5b1e1 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sat, 9 Nov 2019 14:12:42 +0100
|
||||
Subject: [PATCH 30/44] media: cedrus: h264: Improve buffer management
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.h | 3 +
|
||||
.../staging/media/sunxi/cedrus/cedrus_h264.c | 93 ++++++++-----------
|
||||
2 files changed, 44 insertions(+), 52 deletions(-)
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
||||
@@ -104,6 +104,9 @@ struct cedrus_buffer {
|
||||
struct {
|
||||
unsigned int position;
|
||||
enum cedrus_h264_pic_type pic_type;
|
||||
+ void *mv_col_buf;
|
||||
+ dma_addr_t mv_col_buf_dma;
|
||||
+ ssize_t mv_col_buf_size;
|
||||
} h264;
|
||||
struct {
|
||||
void *mv_col_buf;
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
||||
@@ -55,16 +55,14 @@ static void cedrus_h264_write_sram(struc
|
||||
}
|
||||
|
||||
static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx,
|
||||
- unsigned int position,
|
||||
+ struct cedrus_buffer *buf,
|
||||
unsigned int field)
|
||||
{
|
||||
- dma_addr_t addr = ctx->codec.h264.mv_col_buf_dma;
|
||||
+ dma_addr_t addr = buf->codec.h264.mv_col_buf_dma;
|
||||
|
||||
- /* Adjust for the position */
|
||||
- addr += position * ctx->codec.h264.mv_col_buf_field_size * 2;
|
||||
-
|
||||
- /* Adjust for the field */
|
||||
- addr += field * ctx->codec.h264.mv_col_buf_field_size;
|
||||
+ /* Adjust for the field */
|
||||
+ if (field)
|
||||
+ addr += buf->codec.h264.mv_col_buf_size / 2;
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -76,7 +74,6 @@ static void cedrus_fill_ref_pic(struct c
|
||||
struct cedrus_h264_sram_ref_pic *pic)
|
||||
{
|
||||
struct vb2_buffer *vbuf = &buf->m2m_buf.vb.vb2_buf;
|
||||
- unsigned int position = buf->codec.h264.position;
|
||||
|
||||
pic->top_field_order_cnt = cpu_to_le32(top_field_order_cnt);
|
||||
pic->bottom_field_order_cnt = cpu_to_le32(bottom_field_order_cnt);
|
||||
@@ -85,9 +82,9 @@ static void cedrus_fill_ref_pic(struct c
|
||||
pic->luma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0));
|
||||
pic->chroma_ptr = cpu_to_le32(cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1));
|
||||
pic->mv_col_top_ptr =
|
||||
- cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 0));
|
||||
+ cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, buf, 0));
|
||||
pic->mv_col_bot_ptr =
|
||||
- cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, position, 1));
|
||||
+ cpu_to_le32(cedrus_h264_mv_col_buf_addr(ctx, buf, 1));
|
||||
}
|
||||
|
||||
static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
||||
@@ -146,6 +143,28 @@ static void cedrus_write_frame_list(stru
|
||||
output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
|
||||
output_buf->codec.h264.position = position;
|
||||
|
||||
+ if (!output_buf->codec.h264.mv_col_buf_size) {
|
||||
+ const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
|
||||
+ unsigned int field_size;
|
||||
+
|
||||
+ field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
|
||||
+ DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
|
||||
+ if (!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE))
|
||||
+ field_size = field_size * 2;
|
||||
+ if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
|
||||
+ field_size = field_size * 2;
|
||||
+
|
||||
+ output_buf->codec.h264.mv_col_buf_size = field_size * 2;
|
||||
+ output_buf->codec.h264.mv_col_buf =
|
||||
+ dma_alloc_attrs(dev->dev,
|
||||
+ output_buf->codec.h264.mv_col_buf_size,
|
||||
+ &output_buf->codec.h264.mv_col_buf_dma,
|
||||
+ GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
+
|
||||
+ if (!output_buf->codec.h264.mv_col_buf)
|
||||
+ output_buf->codec.h264.mv_col_buf_size = 0;
|
||||
+ }
|
||||
+
|
||||
if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)
|
||||
output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD;
|
||||
else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
|
||||
@@ -516,8 +535,6 @@ static int cedrus_h264_start(struct cedr
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
unsigned int pic_info_size;
|
||||
- unsigned int field_size;
|
||||
- unsigned int mv_col_size;
|
||||
int ret;
|
||||
|
||||
/* Formula for picture buffer size is taken from CedarX source. */
|
||||
@@ -560,38 +577,6 @@ static int cedrus_h264_start(struct cedr
|
||||
goto err_pic_buf;
|
||||
}
|
||||
|
||||
- field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
|
||||
- DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
|
||||
-
|
||||
- /*
|
||||
- * FIXME: This is actually conditional to
|
||||
- * V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE not being set, we
|
||||
- * might have to rework this if memory efficiency ever is
|
||||
- * something we need to work on.
|
||||
- */
|
||||
- field_size = field_size * 2;
|
||||
-
|
||||
- /*
|
||||
- * FIXME: This is actually conditional to
|
||||
- * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY not being set, we might
|
||||
- * have to rework this if memory efficiency ever is something
|
||||
- * we need to work on.
|
||||
- */
|
||||
- field_size = field_size * 2;
|
||||
- ctx->codec.h264.mv_col_buf_field_size = field_size;
|
||||
-
|
||||
- mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM;
|
||||
- ctx->codec.h264.mv_col_buf_size = mv_col_size;
|
||||
- ctx->codec.h264.mv_col_buf =
|
||||
- dma_alloc_attrs(dev->dev,
|
||||
- ctx->codec.h264.mv_col_buf_size,
|
||||
- &ctx->codec.h264.mv_col_buf_dma,
|
||||
- GFP_KERNEL, DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
- if (!ctx->codec.h264.mv_col_buf) {
|
||||
- ret = -ENOMEM;
|
||||
- goto err_neighbor_buf;
|
||||
- }
|
||||
-
|
||||
if (ctx->src_fmt.width > 2048) {
|
||||
/*
|
||||
* Formulas for deblock and intra prediction buffer sizes
|
||||
@@ -606,7 +592,7 @@ static int cedrus_h264_start(struct cedr
|
||||
GFP_KERNEL);
|
||||
if (!ctx->codec.h264.deblk_buf) {
|
||||
ret = -ENOMEM;
|
||||
- goto err_mv_col_buf;
|
||||
+ goto err_neighbor_buf;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -633,12 +619,6 @@ err_deblk_buf:
|
||||
ctx->codec.h264.deblk_buf,
|
||||
ctx->codec.h264.deblk_buf_dma);
|
||||
|
||||
-err_mv_col_buf:
|
||||
- dma_free_attrs(dev->dev, ctx->codec.h264.mv_col_buf_size,
|
||||
- ctx->codec.h264.mv_col_buf,
|
||||
- ctx->codec.h264.mv_col_buf_dma,
|
||||
- DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
-
|
||||
err_neighbor_buf:
|
||||
dma_free_attrs(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
|
||||
ctx->codec.h264.neighbor_info_buf,
|
||||
@@ -654,10 +635,6 @@ static void cedrus_h264_stop(struct cedr
|
||||
{
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
|
||||
- dma_free_attrs(dev->dev, ctx->codec.h264.mv_col_buf_size,
|
||||
- ctx->codec.h264.mv_col_buf,
|
||||
- ctx->codec.h264.mv_col_buf_dma,
|
||||
- DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
dma_free_attrs(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
|
||||
ctx->codec.h264.neighbor_info_buf,
|
||||
ctx->codec.h264.neighbor_info_buf_dma,
|
||||
@@ -681,6 +659,17 @@ static void cedrus_h264_trigger(struct c
|
||||
VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE);
|
||||
}
|
||||
|
||||
+static void cedrus_h264_buf_cleanup(struct cedrus_ctx *ctx,
|
||||
+ struct cedrus_buffer *buf)
|
||||
+{
|
||||
+ if (buf->codec.h264.mv_col_buf_size)
|
||||
+ dma_free_attrs(ctx->dev->dev,
|
||||
+ buf->codec.h264.mv_col_buf_size,
|
||||
+ buf->codec.h264.mv_col_buf,
|
||||
+ buf->codec.h264.mv_col_buf_dma,
|
||||
+ DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
+}
|
||||
+
|
||||
struct cedrus_dec_ops cedrus_dec_ops_h264 = {
|
||||
.irq_clear = cedrus_h264_irq_clear,
|
||||
.irq_disable = cedrus_h264_irq_disable,
|
||||
@@ -689,4 +677,5 @@ struct cedrus_dec_ops cedrus_dec_ops_h26
|
||||
.start = cedrus_h264_start,
|
||||
.stop = cedrus_h264_stop,
|
||||
.trigger = cedrus_h264_trigger,
|
||||
+ .buf_cleanup = cedrus_h264_buf_cleanup,
|
||||
};
|
@ -1,155 +0,0 @@
|
||||
From 54389b5956af51023b073a08eeb7a746a4a37119 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sun, 15 Mar 2020 21:35:39 +0100
|
||||
Subject: [PATCH 31/44] WIp: 10-bit HEVC support
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/staging/media/sunxi/cedrus/cedrus.c | 4 +--
|
||||
.../staging/media/sunxi/cedrus/cedrus_h265.c | 12 ++++++++
|
||||
.../staging/media/sunxi/cedrus/cedrus_regs.h | 4 +++
|
||||
.../staging/media/sunxi/cedrus/cedrus_video.c | 30 +++++++++++++++----
|
||||
.../staging/media/sunxi/cedrus/cedrus_video.h | 2 +-
|
||||
5 files changed, 44 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
||||
@@ -289,7 +289,7 @@ static int cedrus_open(struct file *file
|
||||
goto err_ctrls;
|
||||
}
|
||||
ctx->dst_fmt.pixelformat = V4L2_PIX_FMT_NV12_32L32;
|
||||
- cedrus_prepare_format(&ctx->dst_fmt);
|
||||
+ cedrus_prepare_format(&ctx->dst_fmt, 0);
|
||||
ctx->src_fmt.pixelformat = V4L2_PIX_FMT_MPEG2_SLICE;
|
||||
/*
|
||||
* TILED_NV12 has more strict requirements, so copy the width and
|
||||
@@ -297,7 +297,7 @@ static int cedrus_open(struct file *file
|
||||
*/
|
||||
ctx->src_fmt.width = ctx->dst_fmt.width;
|
||||
ctx->src_fmt.height = ctx->dst_fmt.height;
|
||||
- cedrus_prepare_format(&ctx->src_fmt);
|
||||
+ cedrus_prepare_format(&ctx->src_fmt, 0);
|
||||
|
||||
v4l2_fh_add(&ctx->fh);
|
||||
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
||||
@@ -534,6 +534,18 @@ static void cedrus_h265_setup(struct ced
|
||||
|
||||
cedrus_write(dev, VE_DEC_H265_DEC_PCM_CTRL, reg);
|
||||
|
||||
+ if (sps->bit_depth_luma_minus8 == 2) {
|
||||
+ 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) |
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
||||
@@ -499,6 +499,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) \
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
||||
@@ -100,7 +100,7 @@ static struct cedrus_format *cedrus_find
|
||||
return &cedrus_formats[i];
|
||||
}
|
||||
|
||||
-void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
|
||||
+void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt, int extended)
|
||||
{
|
||||
unsigned int width = pix_fmt->width;
|
||||
unsigned int height = pix_fmt->height;
|
||||
@@ -155,6 +155,17 @@ void cedrus_prepare_format(struct v4l2_p
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (extended) {
|
||||
+ unsigned int extra_size;
|
||||
+
|
||||
+ 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;
|
||||
+
|
||||
+ sizeimage += extra_size;
|
||||
+ }
|
||||
+
|
||||
pix_fmt->width = width;
|
||||
pix_fmt->height = height;
|
||||
|
||||
@@ -247,17 +258,27 @@ static int cedrus_try_fmt_vid_cap(struct
|
||||
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
|
||||
struct cedrus_dev *dev = ctx->dev;
|
||||
struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
|
||||
+ const struct v4l2_ctrl_hevc_sps *sps;
|
||||
struct cedrus_format *fmt =
|
||||
cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
|
||||
dev->capabilities);
|
||||
+ int extended;
|
||||
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
|
||||
+ sps = cedrus_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SPS);
|
||||
+
|
||||
+ /* The 10-bitHEVC decoder needs extra size on the output buffer. */
|
||||
+ extended = ctx->src_fmt.pixelformat == V4L2_PIX_FMT_HEVC_SLICE &&
|
||||
+ sps->bit_depth_luma_minus8 == 2;
|
||||
+
|
||||
pix_fmt->pixelformat = fmt->pixelformat;
|
||||
pix_fmt->width = ctx->src_fmt.width;
|
||||
pix_fmt->height = ctx->src_fmt.height;
|
||||
- cedrus_prepare_format(pix_fmt);
|
||||
+
|
||||
+ pix_fmt->pixelformat = fmt->pixelformat;
|
||||
+ cedrus_prepare_format(pix_fmt, extended);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -275,8 +296,7 @@ static int cedrus_try_fmt_vid_out(struct
|
||||
if (!fmt)
|
||||
return -EINVAL;
|
||||
|
||||
- pix_fmt->pixelformat = fmt->pixelformat;
|
||||
- cedrus_prepare_format(pix_fmt);
|
||||
+ cedrus_prepare_format(pix_fmt, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -357,7 +377,7 @@ static int cedrus_s_fmt_vid_out(struct f
|
||||
ctx->dst_fmt.quantization = f->fmt.pix.quantization;
|
||||
ctx->dst_fmt.width = ctx->src_fmt.width;
|
||||
ctx->dst_fmt.height = ctx->src_fmt.height;
|
||||
- cedrus_prepare_format(&ctx->dst_fmt);
|
||||
+ cedrus_prepare_format(&ctx->dst_fmt, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.h
|
||||
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.h
|
||||
@@ -26,6 +26,6 @@ extern const struct v4l2_ioctl_ops cedru
|
||||
|
||||
int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
|
||||
struct vb2_queue *dst_vq);
|
||||
-void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt);
|
||||
+void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt, int extended);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user