mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-28 05:06:43 +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