mirror of
https://github.com/armbian/build.git
synced 2025-08-12 06:06:58 +02:00
* Recycling of megous v5.16.4 patches The patches were sorted as far as possible. Some patches are renamed according to their place of application. The length of the patch name has been changed to improve readability using the `git format-patch --filename-max-length=75` method. The folder containing the patches will have the name `patches.name` and the corresponding file `series.name` for the convenience of processing and moving them upstream. But the control file remains `series.conf`. Signed-off-by: The-going <48602507+The-going@users.noreply.github.com> * Add a series of armbian patches for 5.16 Signed-off-by: The-going <48602507+The-going@users.noreply.github.com> * Remove patches whose fixes are already in the kernel Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>
246 lines
8.5 KiB
Diff
246 lines
8.5 KiB
Diff
From e5464070b7b15a21dc9bc133734f95a45d0c58e4 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 049/101] drv: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, 70 insertions(+), 58 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
index 35faf42f2..6ddcff8f5 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 4fa5016a2..3d7f87a80 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
@@ -91,26 +91,66 @@ 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 ctb_size_luma, width_in_ctb_luma;
|
|
+ unsigned int log2_max_luma_coding_block_size;
|
|
+
|
|
+ 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;
|
|
+ width_in_ctb_luma = DIV_ROUND_UP(sps->pic_width_in_luma_samples,
|
|
+ ctb_size_luma);
|
|
+
|
|
+ cedrus_buf->codec.h265.mv_col_buf_size = ALIGN(width_in_ctb_luma *
|
|
+ DIV_ROUND_UP(sps->pic_height_in_luma_samples, ctb_size_luma) *
|
|
+ CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE, 1024);
|
|
+
|
|
+ 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[],
|
|
- int buffer_index)
|
|
+ int buffer_index,
|
|
+ const struct v4l2_ctrl_hevc_sps *sps)
|
|
{
|
|
struct cedrus_dev *dev = ctx->dev;
|
|
dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 0);
|
|
dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 1);
|
|
dma_addr_t mv_col_buf_addr[2] = {
|
|
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, 0),
|
|
- cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index,
|
|
- field_pic ? 1 : 0)
|
|
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, sps),
|
|
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, sps)
|
|
};
|
|
u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
|
|
VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
|
|
@@ -134,7 +174,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 +190,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,
|
|
- buffer_index);
|
|
+ buffer_index, sps);
|
|
}
|
|
}
|
|
|
|
@@ -388,37 +388,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;
|
|
- // TODO: Abort the process here.
|
|
- return;
|
|
- }
|
|
- }
|
|
-
|
|
/* Activate H265 engine. */
|
|
cedrus_engine_enable(ctx, CEDRUS_CODEC_H265);
|
|
|
|
@@ -671,7 +682,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. */
|
|
|
|
@@ -682,7 +693,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.index);
|
|
+ run->dst->vb2_buf.index, sps);
|
|
|
|
cedrus_write(dev, VE_DEC_H265_OUTPUT_FRAME_IDX, output_pic_list_index);
|
|
|
|
@@ -732,9 +701,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,
|
|
@@ -759,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,
|
|
@@ -784,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,
|
|
@@ -792,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,
|
|
};
|
|
--
|
|
2.31.1
|
|
|