Skip to content

Commit 86caab2

Browse files
paulkocialkowskimchehab
authored andcommitted
media: cedrus: Add HEVC/H.265 decoding support
This introduces support for HEVC/H.265 to the Cedrus VPU driver, with both uni-directional and bi-directional prediction modes supported. Field-coded (interlaced) pictures, custom quantization matrices and 10-bit output are not supported at this point. Signed-off-by: Paul Kocialkowski <[email protected]> Signed-off-by: Hans Verkuil <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent de06f28 commit 86caab2

8 files changed

Lines changed: 977 additions & 5 deletions

File tree

drivers/staging/media/sunxi/cedrus/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
33

44
sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o \
5-
cedrus_mpeg2.o cedrus_h264.o
5+
cedrus_mpeg2.o cedrus_h264.o cedrus_h265.o

drivers/staging/media/sunxi/cedrus/cedrus.c

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,45 @@ static const struct cedrus_control cedrus_controls[] = {
9595
.codec = CEDRUS_CODEC_H264,
9696
.required = false,
9797
},
98+
{
99+
.cfg = {
100+
.id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
101+
},
102+
.codec = CEDRUS_CODEC_H265,
103+
.required = true,
104+
},
105+
{
106+
.cfg = {
107+
.id = V4L2_CID_MPEG_VIDEO_HEVC_PPS,
108+
},
109+
.codec = CEDRUS_CODEC_H265,
110+
.required = true,
111+
},
112+
{
113+
.cfg = {
114+
.id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS,
115+
},
116+
.codec = CEDRUS_CODEC_H265,
117+
.required = true,
118+
},
119+
{
120+
.cfg = {
121+
.id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE,
122+
.max = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
123+
.def = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
124+
},
125+
.codec = CEDRUS_CODEC_H265,
126+
.required = false,
127+
},
128+
{
129+
.cfg = {
130+
.id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE,
131+
.max = V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE,
132+
.def = V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE,
133+
},
134+
.codec = CEDRUS_CODEC_H265,
135+
.required = false,
136+
},
98137
};
99138

100139
#define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
@@ -340,6 +379,7 @@ static int cedrus_probe(struct platform_device *pdev)
340379

341380
dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
342381
dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264;
382+
dev->dec_ops[CEDRUS_CODEC_H265] = &cedrus_dec_ops_h265;
343383

344384
mutex_init(&dev->dev_mutex);
345385

@@ -450,22 +490,26 @@ static const struct cedrus_variant sun8i_a33_cedrus_variant = {
450490
};
451491

452492
static const struct cedrus_variant sun8i_h3_cedrus_variant = {
453-
.capabilities = CEDRUS_CAPABILITY_UNTILED,
493+
.capabilities = CEDRUS_CAPABILITY_UNTILED |
494+
CEDRUS_CAPABILITY_H265_DEC,
454495
.mod_rate = 402000000,
455496
};
456497

457498
static const struct cedrus_variant sun50i_a64_cedrus_variant = {
458-
.capabilities = CEDRUS_CAPABILITY_UNTILED,
499+
.capabilities = CEDRUS_CAPABILITY_UNTILED |
500+
CEDRUS_CAPABILITY_H265_DEC,
459501
.mod_rate = 402000000,
460502
};
461503

462504
static const struct cedrus_variant sun50i_h5_cedrus_variant = {
463-
.capabilities = CEDRUS_CAPABILITY_UNTILED,
505+
.capabilities = CEDRUS_CAPABILITY_UNTILED |
506+
CEDRUS_CAPABILITY_H265_DEC,
464507
.mod_rate = 402000000,
465508
};
466509

467510
static const struct cedrus_variant sun50i_h6_cedrus_variant = {
468-
.capabilities = CEDRUS_CAPABILITY_UNTILED,
511+
.capabilities = CEDRUS_CAPABILITY_UNTILED |
512+
CEDRUS_CAPABILITY_H265_DEC,
469513
.quirks = CEDRUS_QUIRK_NO_DMA_OFFSET,
470514
.mod_rate = 600000000,
471515
};

drivers/staging/media/sunxi/cedrus/cedrus.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
#define CEDRUS_NAME "cedrus"
2828

2929
#define CEDRUS_CAPABILITY_UNTILED BIT(0)
30+
#define CEDRUS_CAPABILITY_H265_DEC BIT(1)
3031

3132
#define CEDRUS_QUIRK_NO_DMA_OFFSET BIT(0)
3233

3334
enum cedrus_codec {
3435
CEDRUS_CODEC_MPEG2,
3536
CEDRUS_CODEC_H264,
37+
CEDRUS_CODEC_H265,
3638
CEDRUS_CODEC_LAST,
3739
};
3840

@@ -67,13 +69,20 @@ struct cedrus_mpeg2_run {
6769
const struct v4l2_ctrl_mpeg2_quantization *quantization;
6870
};
6971

72+
struct cedrus_h265_run {
73+
const struct v4l2_ctrl_hevc_sps *sps;
74+
const struct v4l2_ctrl_hevc_pps *pps;
75+
const struct v4l2_ctrl_hevc_slice_params *slice_params;
76+
};
77+
7078
struct cedrus_run {
7179
struct vb2_v4l2_buffer *src;
7280
struct vb2_v4l2_buffer *dst;
7381

7482
union {
7583
struct cedrus_h264_run h264;
7684
struct cedrus_mpeg2_run mpeg2;
85+
struct cedrus_h265_run h265;
7786
};
7887
};
7988

@@ -110,6 +119,14 @@ struct cedrus_ctx {
110119
void *neighbor_info_buf;
111120
dma_addr_t neighbor_info_buf_dma;
112121
} h264;
122+
struct {
123+
void *mv_col_buf;
124+
dma_addr_t mv_col_buf_addr;
125+
ssize_t mv_col_buf_size;
126+
ssize_t mv_col_buf_unit_size;
127+
void *neighbor_info_buf;
128+
dma_addr_t neighbor_info_buf_addr;
129+
} h265;
113130
} codec;
114131
};
115132

@@ -155,6 +172,7 @@ struct cedrus_dev {
155172

156173
extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
157174
extern struct cedrus_dec_ops cedrus_dec_ops_h264;
175+
extern struct cedrus_dec_ops cedrus_dec_ops_h265;
158176

159177
static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
160178
{

drivers/staging/media/sunxi/cedrus/cedrus_dec.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ void cedrus_device_run(void *priv)
5959
V4L2_CID_MPEG_VIDEO_H264_SPS);
6060
break;
6161

62+
case V4L2_PIX_FMT_HEVC_SLICE:
63+
run.h265.sps = cedrus_find_control_data(ctx,
64+
V4L2_CID_MPEG_VIDEO_HEVC_SPS);
65+
run.h265.pps = cedrus_find_control_data(ctx,
66+
V4L2_CID_MPEG_VIDEO_HEVC_PPS);
67+
run.h265.slice_params = cedrus_find_control_data(ctx,
68+
V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
69+
break;
70+
6271
default:
6372
break;
6473
}

0 commit comments

Comments
 (0)