Skip to content

Commit 5bec609

Browse files
author
Dikshita Agarwal
committed
FROMLIST: media: iris: Add HEVC and VP9 formats for decoder
Extend the decoder driver's supported formats to include HEVC (H.265) and VP9. This change updates the format enumeration (VIDIOC_ENUM_FMT) and allows setting these formats via VIDIOC_S_FMT. Link: https://lore.kernel.org/linux-arm-msm/20250509-video-iris-hevc-vp9-v5-22-59b4ff7d331c@quicinc.com/ Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Acked-by: Vikash Garodia <quic_vgarodia@quicinc.com> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-QRD Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8550-HDK Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-HDK Tested-by: Vikash Garodia <quic_vgarodia@quicinc.com> # on sa8775p-ride Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
1 parent 8681664 commit 5bec609

File tree

8 files changed

+108
-11
lines changed

8 files changed

+108
-11
lines changed

drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,29 @@ static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core)
8888
static int iris_hfi_gen1_session_open(struct iris_inst *inst)
8989
{
9090
struct hfi_session_open_pkt packet;
91+
u32 codec = 0;
9192
int ret;
9293

9394
if (inst->state != IRIS_INST_DEINIT)
9495
return -EALREADY;
9596

97+
switch (inst->codec) {
98+
case V4L2_PIX_FMT_H264:
99+
codec = HFI_VIDEO_CODEC_H264;
100+
break;
101+
case V4L2_PIX_FMT_HEVC:
102+
codec = HFI_VIDEO_CODEC_HEVC;
103+
break;
104+
case V4L2_PIX_FMT_VP9:
105+
codec = HFI_VIDEO_CODEC_VP9;
106+
break;
107+
}
108+
96109
packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);
97110
packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT;
98111
packet.shdr.session_id = inst->session_id;
99112
packet.session_domain = HFI_SESSION_TYPE_DEC;
100-
packet.session_codec = HFI_VIDEO_CODEC_H264;
113+
packet.session_codec = codec;
101114

102115
reinit_completion(&inst->completion);
103116

drivers/media/platform/qcom/iris/iris_hfi_gen1_defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#define HFI_SESSION_TYPE_DEC 2
1414

1515
#define HFI_VIDEO_CODEC_H264 0x00000002
16+
#define HFI_VIDEO_CODEC_HEVC 0x00002000
17+
#define HFI_VIDEO_CODEC_VP9 0x00004000
1618

1719
#define HFI_ERR_NONE 0x0
1820

drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,19 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p
416416
static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
417417
{
418418
struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
419-
u32 codec = HFI_CODEC_DECODE_AVC;
419+
u32 codec = 0;
420+
421+
switch (inst->codec) {
422+
case V4L2_PIX_FMT_H264:
423+
codec = HFI_CODEC_DECODE_AVC;
424+
break;
425+
case V4L2_PIX_FMT_HEVC:
426+
codec = HFI_CODEC_DECODE_HEVC;
427+
break;
428+
case V4L2_PIX_FMT_VP9:
429+
codec = HFI_CODEC_DECODE_VP9;
430+
break;
431+
}
420432

421433
iris_hfi_gen2_packet_session_property(inst,
422434
HFI_PROP_CODEC,

drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ enum hfi_color_format {
104104
enum hfi_codec_type {
105105
HFI_CODEC_DECODE_AVC = 1,
106106
HFI_CODEC_ENCODE_AVC = 2,
107+
HFI_CODEC_DECODE_HEVC = 3,
108+
HFI_CODEC_ENCODE_HEVC = 4,
109+
HFI_CODEC_DECODE_VP9 = 5,
107110
};
108111

109112
enum hfi_picture_type {

drivers/media/platform/qcom/iris/iris_instance.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* @sequence_out: a sequence counter for output queue
4444
* @tss: timestamp metadata
4545
* @metadata_idx: index for metadata buffer
46+
* @codec: codec type
4647
* @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver
4748
*/
4849

@@ -75,6 +76,7 @@ struct iris_inst {
7576
u32 sequence_out;
7677
struct iris_ts_metadata tss[VIDEO_MAX_FRAME];
7778
u32 metadata_idx;
79+
u32 codec;
7880
bool last_buffer_dequeued;
7981
};
8082

drivers/media/platform/qcom/iris/iris_vdec.c

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ int iris_vdec_inst_init(struct iris_inst *inst)
3232
f->fmt.pix_mp.width = DEFAULT_WIDTH;
3333
f->fmt.pix_mp.height = DEFAULT_HEIGHT;
3434
f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
35+
inst->codec = f->fmt.pix_mp.pixelformat;
3536
f->fmt.pix_mp.num_planes = 1;
3637
f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
3738
f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
@@ -67,14 +68,67 @@ void iris_vdec_inst_deinit(struct iris_inst *inst)
6768
kfree(inst->fmt_src);
6869
}
6970

71+
static const struct iris_fmt iris_vdec_formats[] = {
72+
[IRIS_FMT_H264] = {
73+
.pixfmt = V4L2_PIX_FMT_H264,
74+
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
75+
},
76+
[IRIS_FMT_HEVC] = {
77+
.pixfmt = V4L2_PIX_FMT_HEVC,
78+
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
79+
},
80+
[IRIS_FMT_VP9] = {
81+
.pixfmt = V4L2_PIX_FMT_VP9,
82+
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
83+
},
84+
};
85+
86+
static const struct iris_fmt *
87+
find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
88+
{
89+
unsigned int size = ARRAY_SIZE(iris_vdec_formats);
90+
const struct iris_fmt *fmt = iris_vdec_formats;
91+
unsigned int i;
92+
93+
for (i = 0; i < size; i++) {
94+
if (fmt[i].pixfmt == pixfmt)
95+
break;
96+
}
97+
98+
if (i == size || fmt[i].type != type)
99+
return NULL;
100+
101+
return &fmt[i];
102+
}
103+
104+
static const struct iris_fmt *
105+
find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
106+
{
107+
const struct iris_fmt *fmt = iris_vdec_formats;
108+
unsigned int size = ARRAY_SIZE(iris_vdec_formats);
109+
110+
if (index >= size || fmt[index].type != type)
111+
return NULL;
112+
113+
return &fmt[index];
114+
}
115+
70116
int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
71117
{
118+
const struct iris_fmt *fmt;
119+
72120
switch (f->type) {
73121
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
74-
f->pixelformat = V4L2_PIX_FMT_H264;
122+
fmt = find_format_by_index(inst, f->index, f->type);
123+
if (!fmt)
124+
return -EINVAL;
125+
126+
f->pixelformat = fmt->pixfmt;
75127
f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
76128
break;
77129
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
130+
if (f->index)
131+
return -EINVAL;
78132
f->pixelformat = V4L2_PIX_FMT_NV12;
79133
break;
80134
default:
@@ -88,21 +142,23 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
88142
{
89143
struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
90144
struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
145+
const struct iris_fmt *fmt;
91146
struct v4l2_format *f_inst;
92147
struct vb2_queue *src_q;
93148

94149
memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
150+
fmt = find_format(inst, pixmp->pixelformat, f->type);
95151
switch (f->type) {
96152
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
97-
if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264) {
153+
if (!fmt) {
98154
f_inst = inst->fmt_src;
99155
f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
100156
f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
101157
f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
102158
}
103159
break;
104160
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
105-
if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
161+
if (!fmt) {
106162
f_inst = inst->fmt_dst;
107163
f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
108164
f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
@@ -145,13 +201,14 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
145201

146202
switch (f->type) {
147203
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
148-
if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_H264)
204+
if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
149205
return -EINVAL;
150206

151207
fmt = inst->fmt_src;
152208
fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
153-
154-
codec_align = DEFAULT_CODEC_ALIGNMENT;
209+
fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
210+
inst->codec = fmt->fmt.pix_mp.pixelformat;
211+
codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
155212
fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
156213
fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
157214
fmt->fmt.pix_mp.num_planes = 1;

drivers/media/platform/qcom/iris/iris_vdec.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88

99
struct iris_inst;
1010

11+
enum iris_fmt_type {
12+
IRIS_FMT_H264,
13+
IRIS_FMT_HEVC,
14+
IRIS_FMT_VP9,
15+
};
16+
17+
struct iris_fmt {
18+
u32 pixfmt;
19+
u32 type;
20+
};
21+
1122
int iris_vdec_inst_init(struct iris_inst *inst);
1223
void iris_vdec_inst_deinit(struct iris_inst *inst);
1324
int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);

drivers/media/platform/qcom/iris/iris_vidc.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,6 @@ static int iris_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f)
278278
{
279279
struct iris_inst *inst = iris_get_inst(filp, NULL);
280280

281-
if (f->index)
282-
return -EINVAL;
283-
284281
return iris_vdec_enum_fmt(inst, f);
285282
}
286283

0 commit comments

Comments
 (0)