Commit 2845d9d6 authored by Jernej Skrabec's avatar Jernej Skrabec Committed by Mauro Carvalho Chehab

media: cedrus: hevc: Add support for scaling lists

HEVC frames may use scaling list feature. Add support for it.
Signed-off-by: default avatarJernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent 5523dc7b
...@@ -135,6 +135,12 @@ static const struct cedrus_control cedrus_controls[] = { ...@@ -135,6 +135,12 @@ static const struct cedrus_control cedrus_controls[] = {
}, },
.codec = CEDRUS_CODEC_H265, .codec = CEDRUS_CODEC_H265,
}, },
{
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX,
},
.codec = CEDRUS_CODEC_H265,
},
{ {
.cfg = { .cfg = {
.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE, .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE,
......
...@@ -78,6 +78,7 @@ struct cedrus_h265_run { ...@@ -78,6 +78,7 @@ struct cedrus_h265_run {
const struct v4l2_ctrl_hevc_pps *pps; const struct v4l2_ctrl_hevc_pps *pps;
const struct v4l2_ctrl_hevc_slice_params *slice_params; const struct v4l2_ctrl_hevc_slice_params *slice_params;
const struct v4l2_ctrl_hevc_decode_params *decode_params; const struct v4l2_ctrl_hevc_decode_params *decode_params;
const struct v4l2_ctrl_hevc_scaling_matrix *scaling_matrix;
}; };
struct cedrus_vp8_run { struct cedrus_vp8_run {
......
...@@ -72,6 +72,8 @@ void cedrus_device_run(void *priv) ...@@ -72,6 +72,8 @@ void cedrus_device_run(void *priv)
V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
run.h265.decode_params = cedrus_find_control_data(ctx, run.h265.decode_params = cedrus_find_control_data(ctx,
V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS); V4L2_CID_MPEG_VIDEO_HEVC_DECODE_PARAMS);
run.h265.scaling_matrix = cedrus_find_control_data(ctx,
V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX);
break; break;
case V4L2_PIX_FMT_VP8_FRAME: case V4L2_PIX_FMT_VP8_FRAME:
......
...@@ -238,6 +238,69 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num) ...@@ -238,6 +238,69 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
} }
} }
static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx,
struct cedrus_run *run)
{
const struct v4l2_ctrl_hevc_scaling_matrix *scaling;
struct cedrus_dev *dev = ctx->dev;
u32 i, j, k, val;
scaling = run->h265.scaling_matrix;
cedrus_write(dev, VE_DEC_H265_SCALING_LIST_DC_COEF0,
(scaling->scaling_list_dc_coef_32x32[1] << 24) |
(scaling->scaling_list_dc_coef_32x32[0] << 16) |
(scaling->scaling_list_dc_coef_16x16[1] << 8) |
(scaling->scaling_list_dc_coef_16x16[0] << 0));
cedrus_write(dev, VE_DEC_H265_SCALING_LIST_DC_COEF1,
(scaling->scaling_list_dc_coef_16x16[5] << 24) |
(scaling->scaling_list_dc_coef_16x16[4] << 16) |
(scaling->scaling_list_dc_coef_16x16[3] << 8) |
(scaling->scaling_list_dc_coef_16x16[2] << 0));
cedrus_h265_sram_write_offset(dev, VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS);
for (i = 0; i < 6; i++)
for (j = 0; j < 8; j++)
for (k = 0; k < 8; k += 4) {
val = ((u32)scaling->scaling_list_8x8[i][j + (k + 3) * 8] << 24) |
((u32)scaling->scaling_list_8x8[i][j + (k + 2) * 8] << 16) |
((u32)scaling->scaling_list_8x8[i][j + (k + 1) * 8] << 8) |
scaling->scaling_list_8x8[i][j + k * 8];
cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
}
for (i = 0; i < 2; i++)
for (j = 0; j < 8; j++)
for (k = 0; k < 8; k += 4) {
val = ((u32)scaling->scaling_list_32x32[i][j + (k + 3) * 8] << 24) |
((u32)scaling->scaling_list_32x32[i][j + (k + 2) * 8] << 16) |
((u32)scaling->scaling_list_32x32[i][j + (k + 1) * 8] << 8) |
scaling->scaling_list_32x32[i][j + k * 8];
cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
}
for (i = 0; i < 6; i++)
for (j = 0; j < 8; j++)
for (k = 0; k < 8; k += 4) {
val = ((u32)scaling->scaling_list_16x16[i][j + (k + 3) * 8] << 24) |
((u32)scaling->scaling_list_16x16[i][j + (k + 2) * 8] << 16) |
((u32)scaling->scaling_list_16x16[i][j + (k + 1) * 8] << 8) |
scaling->scaling_list_16x16[i][j + k * 8];
cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
}
for (i = 0; i < 6; i++)
for (j = 0; j < 4; j++) {
val = ((u32)scaling->scaling_list_4x4[i][j + 12] << 24) |
((u32)scaling->scaling_list_4x4[i][j + 8] << 16) |
((u32)scaling->scaling_list_4x4[i][j + 4] << 8) |
scaling->scaling_list_4x4[i][j];
cedrus_write(dev, VE_DEC_H265_SRAM_DATA, val);
}
}
static void cedrus_h265_setup(struct cedrus_ctx *ctx, static void cedrus_h265_setup(struct cedrus_ctx *ctx,
struct cedrus_run *run) struct cedrus_run *run)
{ {
...@@ -527,7 +590,12 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx, ...@@ -527,7 +590,12 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
/* Scaling list. */ /* Scaling list. */
reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT; if (sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED) {
cedrus_h265_write_scaling_list(ctx, run);
reg = VE_DEC_H265_SCALING_LIST_CTRL0_FLAG_ENABLED;
} else {
reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT;
}
cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg); cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg);
/* Neightbor information address. */ /* Neightbor information address. */
......
...@@ -494,6 +494,8 @@ ...@@ -494,6 +494,8 @@
#define VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR (VE_ENGINE_DEC_H265 + 0x64) #define VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR (VE_ENGINE_DEC_H265 + 0x64)
#define VE_DEC_H265_TILE_START_CTB (VE_ENGINE_DEC_H265 + 0x68) #define VE_DEC_H265_TILE_START_CTB (VE_ENGINE_DEC_H265 + 0x68)
#define VE_DEC_H265_TILE_END_CTB (VE_ENGINE_DEC_H265 + 0x6c) #define VE_DEC_H265_TILE_END_CTB (VE_ENGINE_DEC_H265 + 0x6c)
#define VE_DEC_H265_SCALING_LIST_DC_COEF0 (VE_ENGINE_DEC_H265 + 0x78)
#define VE_DEC_H265_SCALING_LIST_DC_COEF1 (VE_ENGINE_DEC_H265 + 0x7c)
#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80) #define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment