diff options
author | yjun | 2022-05-17 12:16:32 +0800 |
---|---|---|
committer | yjun | 2022-05-17 12:16:32 +0800 |
commit | d66c7d0fc0b35270f9fe591a311563cc0d851555 (patch) | |
tree | 78708ccbe7b46d0494838100815004e5f5fff152 /drv-media-cedrus-hevc-tiles-hack.patch | |
parent | df61abd38d06cbb1f4eca16f1e070d986a8b6dbd (diff) | |
download | aur-d66c7d0fc0b35270f9fe591a311563cc0d851555.tar.gz |
updpkg: linux-tqc-a01 5.17.7
Diffstat (limited to 'drv-media-cedrus-hevc-tiles-hack.patch')
-rw-r--r-- | drv-media-cedrus-hevc-tiles-hack.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/drv-media-cedrus-hevc-tiles-hack.patch b/drv-media-cedrus-hevc-tiles-hack.patch new file mode 100644 index 000000000000..7d1238b08c63 --- /dev/null +++ b/drv-media-cedrus-hevc-tiles-hack.patch @@ -0,0 +1,180 @@ +From 08ec2c0d449a9e91f9174b347bd3f560f50ca872 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec <jernej.skrabec@siol.net> +Date: Sat, 26 Oct 2019 21:23:55 +0200 +Subject: [PATCH 046/101] drv:media: cedrus: hevc: tiles hack + +Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> +--- + drivers/staging/media/sunxi/cedrus/cedrus.h | 2 + + .../staging/media/sunxi/cedrus/cedrus_h265.c | 93 +++++++++++++++++-- + 2 files changed, 89 insertions(+), 6 deletions(-) + +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h +index 9c7bfd2b6..c790963ef 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus.h ++++ b/drivers/staging/media/sunxi/cedrus/cedrus.h +@@ -144,6 +144,8 @@ struct cedrus_ctx { + ssize_t mv_col_buf_unit_size; + void *neighbor_info_buf; + dma_addr_t neighbor_info_buf_addr; ++ void *entry_points_buf; ++ dma_addr_t entry_points_buf_addr; + } h265; + struct { + unsigned int last_frame_p_type; +diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +index bb7eb5610..4fa5016a2 100644 +--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c ++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c +@@ -301,6 +301,61 @@ static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx, + } + } + ++static void write_entry_point_list(struct cedrus_ctx *ctx, ++ struct cedrus_run *run, ++ unsigned int ctb_addr_x, ++ unsigned int ctb_addr_y) ++{ ++ const struct v4l2_ctrl_hevc_slice_params *slice_params; ++ const struct v4l2_ctrl_hevc_pps *pps; ++ struct cedrus_dev *dev = ctx->dev; ++ int i, x, tx, y, ty; ++ u32 *entry_points; ++ ++ pps = run->h265.pps; ++ slice_params = run->h265.slice_params; ++ ++ for (x = 0, tx = 0; tx < pps->num_tile_columns_minus1 + 1; tx++) { ++ if (x + pps->column_width_minus1[tx] + 1 > ctb_addr_x) ++ break; ++ ++ x += pps->column_width_minus1[tx] + 1; ++ } ++ ++ for (y = 0, ty = 0; ty < pps->num_tile_rows_minus1 + 1; ty++) { ++ if (y + pps->row_height_minus1[ty] + 1 > ctb_addr_y) ++ break; ++ ++ y += pps->row_height_minus1[ty] + 1; ++ } ++ ++ cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, (y << 16) | (x << 0)); ++ cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, ++ ((y + pps->row_height_minus1[ty]) << 16) | ++ ((x + pps->column_width_minus1[tx]) << 0)); ++ ++ entry_points = ctx->codec.h265.entry_points_buf; ++ if (pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED) { ++ for (i = 0; i < slice_params->num_entry_point_offsets; i++) ++ entry_points[i] = slice_params->entry_point_offset_minus1[i] + 1; ++ } else { ++ for (i = 0; i < slice_params->num_entry_point_offsets; i++) { ++ if (tx + 1 >= pps->num_tile_columns_minus1 + 1) { ++ x = 0; ++ tx = 0; ++ y += pps->row_height_minus1[ty++] + 1; ++ } else { ++ x += pps->column_width_minus1[tx++] + 1; ++ } ++ ++ entry_points[i * 4 + 0] = slice_params->entry_point_offset_minus1[i] + 1; ++ entry_points[i * 4 + 1] = 0x0; ++ entry_points[i * 4 + 2] = (y << 16) | (x << 0); ++ entry_points[i * 4 + 3] = ((y + pps->row_height_minus1[ty]) << 16) | ((x + pps->column_width_minus1[tx]) << 0); ++ } ++ } ++} ++ + static void cedrus_h265_setup(struct cedrus_ctx *ctx, + struct cedrus_run *run) + { +@@ -312,6 +367,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, + const struct v4l2_hevc_pred_weight_table *pred_weight_table; + unsigned int width_in_ctb_luma, ctb_size_luma; + unsigned int log2_max_luma_coding_block_size; ++ unsigned int ctb_addr_x, ctb_addr_y; + dma_addr_t src_buf_addr; + dma_addr_t src_buf_end_addr; + u32 chroma_log2_weight_denom; +@@ -390,12 +446,19 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, + cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg); + + /* Coding tree block address */ +- reg = VE_DEC_H265_DEC_CTB_ADDR_X(slice_params->slice_segment_addr % width_in_ctb_luma); +- reg |= VE_DEC_H265_DEC_CTB_ADDR_Y(slice_params->slice_segment_addr / width_in_ctb_luma); ++ ctb_addr_x = slice_params->slice_segment_addr % width_in_ctb_luma; ++ ctb_addr_y = slice_params->slice_segment_addr / width_in_ctb_luma; ++ reg = VE_DEC_H265_DEC_CTB_ADDR_X(ctb_addr_x); ++ reg |= VE_DEC_H265_DEC_CTB_ADDR_Y(ctb_addr_y); + cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg); + +- cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0); +- cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0); ++ if ((pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) || ++ (pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED)) { ++ write_entry_point_list(ctx, run, ctb_addr_x, ctb_addr_y); ++ } else { ++ cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0); ++ cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0); ++ } + + /* Clear the number of correctly-decoded coding tree blocks. */ + if (ctx->fh.m2m_ctx->new_frame) +@@ -499,7 +562,9 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, + V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED, + pps->flags); + +- /* TODO: VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED */ ++ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED, ++ V4L2_HEVC_PPS_FLAG_TILES_ENABLED, ++ pps->flags); + + reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TRANSQUANT_BYPASS_ENABLED, + V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED, +@@ -575,12 +640,14 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, + + chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom + + pred_weight_table->delta_chroma_log2_weight_denom; +- reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(0) | ++ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(slice_params->num_entry_point_offsets) | + VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(chroma_log2_weight_denom) | + VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(pred_weight_table->luma_log2_weight_denom); + + cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO2, reg); + ++ cedrus_write(dev, VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR, ctx->codec.h265.entry_points_buf_addr >> 8); ++ + /* Decoded picture size. */ + + reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(ctx->src_fmt.width) | +@@ -674,6 +741,17 @@ static int cedrus_h265_start(struct cedrus_ctx *ctx) + if (!ctx->codec.h265.neighbor_info_buf) + return -ENOMEM; + ++ ctx->codec.h265.entry_points_buf = ++ dma_alloc_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE, ++ &ctx->codec.h265.entry_points_buf_addr, ++ GFP_KERNEL); ++ if (!ctx->codec.h265.entry_points_buf) { ++ dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE, ++ ctx->codec.h265.neighbor_info_buf, ++ ctx->codec.h265.neighbor_info_buf_addr); ++ return -ENOMEM; ++ } ++ + return 0; + } + +@@ -694,6 +772,9 @@ static void cedrus_h265_stop(struct cedrus_ctx *ctx) + ctx->codec.h265.neighbor_info_buf, + ctx->codec.h265.neighbor_info_buf_addr, + DMA_ATTR_NO_KERNEL_MAPPING); ++ dma_free_coherent(dev->dev, CEDRUS_H265_ENTRY_POINTS_BUF_SIZE, ++ ctx->codec.h265.entry_points_buf, ++ ctx->codec.h265.entry_points_buf_addr); + } + + static void cedrus_h265_trigger(struct cedrus_ctx *ctx) +-- +2.31.1 + |