[PATCH 2/2] media: iris: Add support for QC08C format for encoder

Dikshita Agarwal
2025-09-19T15:47:30Z

Introduce handling for the QC08C format in the encoder. Update format
checks and configuration to enable encoding to QC08C streams.

Signed-off-by: Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
---
drivers/media/platform/qcom/iris/iris_buffer.c | 12 ++++-
.../platform/qcom/iris/iris_hfi_gen1_command.c | 3 +-
.../platform/qcom/iris/iris_hfi_gen2_command.c | 3 +-
drivers/media/platform/qcom/iris/iris_venc.c | 59 ++++++++++++++++++----
4 files changed, 63 insertions(+), 14 deletions(-)

diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c
index 83dcf49e57ec1473bc4edd26c48ab0b247d23818..b89b1ee06cce151e7c04a80956380d154643c116 100644
--- a/drivers/media/platform/qcom/iris/iris_buffer.c
+++ b/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -171,9 +171,14 @@ static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst)
static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst)
{
u32 y_plane, uv_plane, y_stride, uv_stride;
- struct v4l2_format *f = inst->fmt_dst;
u32 uv_meta_stride, uv_meta_plane;
u32 y_meta_stride, y_meta_plane;
+ struct v4l2_format *f = NULL;
+
+ if (inst->domain == DECODER)
+ f = inst->fmt_dst;
+ else
+ f = inst->fmt_src;

y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, META_STRIDE_ALIGNED >> 1),
META_STRIDE_ALIGNED);
@@ -273,7 +278,10 @@ int iris_get_buffer_size(struct iris_inst *inst,
} else {
switch (buffer_type) {
case BUF_INPUT:
- return iris_yuv_buffer_size_nv12(inst);
+ if (inst->fmt_src->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C)
+ return iris_yuv_buffer_size_qc08c(inst);
+ else
+ return iris_yuv_buffer_size_nv12(inst);
case BUF_OUTPUT:
return iris_enc_bitstream_buffer_size(inst);
default:
diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
index e458d3349ce09aadb75d056ae84e3aab95f03078..52da7ef7bab08fb1cb2ac804ccc6e3c7f9677890 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
@@ -795,7 +795,8 @@ static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst, u32 plane)
} else {
pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
fmt.buffer_type = HFI_BUFFER_INPUT;
- fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
+ fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ?
+ HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC;
ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
}

diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
index 5ad202d3fcdc57a2b7b43de15763a686ce0f7bd7..6a772db2ec33fb002d8884753a41dc98b3a8439d 100644
--- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
+++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
@@ -447,7 +447,8 @@ static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane)
HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
} else {
pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
- hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
+ hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
+ HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
}

return iris_hfi_gen2_session_set_property(inst,
diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c
index 099bd5ed4ae0294725860305254c4cad1ec88d7e..51fa4a06a70e15310ad8e32d7e16b60b2ab11d5a 100644
--- a/drivers/media/platform/qcom/iris/iris_venc.c
+++ b/drivers/media/platform/qcom/iris/iris_venc.c
@@ -80,7 +80,7 @@ void iris_venc_inst_deinit(struct iris_inst *inst)
kfree(inst->fmt_src);
}

-static const struct iris_fmt iris_venc_formats[] = {
+static const struct iris_fmt iris_venc_formats_cap[] = {
[IRIS_FMT_H264] = {
.pixfmt = V4L2_PIX_FMT_H264,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
@@ -91,12 +91,35 @@ static const struct iris_fmt iris_venc_formats[] = {
},
};

+static const struct iris_fmt iris_venc_formats_out[] = {
+ [IRIS_FMT_NV12] = {
+ .pixfmt = V4L2_PIX_FMT_NV12,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ },
+ [IRIS_FMT_UBWC] = {
+ .pixfmt = V4L2_PIX_FMT_QC08C,
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ },
+};
+
static const struct iris_fmt *
find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
{
- const struct iris_fmt *fmt = iris_venc_formats;
- unsigned int size = ARRAY_SIZE(iris_venc_formats);
+ const struct iris_fmt *fmt = NULL;
+ unsigned int size = 0;
unsigned int i;
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ fmt = iris_venc_formats_out;
+ size = ARRAY_SIZE(iris_venc_formats_out);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ fmt = iris_venc_formats_cap;
+ size = ARRAY_SIZE(iris_venc_formats_cap);
+ break;
+ default:
+ return NULL;
+ }

for (i = 0; i < size; i++) {
if (fmt[i].pixfmt == pixfmt)
@@ -112,8 +135,21 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
static const struct iris_fmt *
find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
{
- const struct iris_fmt *fmt = iris_venc_formats;
- unsigned int size = ARRAY_SIZE(iris_venc_formats);
+ const struct iris_fmt *fmt = NULL;
+ unsigned int size = 0;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ fmt = iris_venc_formats_out;
+ size = ARRAY_SIZE(iris_venc_formats_out);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ fmt = iris_venc_formats_cap;
+ size = ARRAY_SIZE(iris_venc_formats_cap);
+ break;
+ default:
+ return NULL;
+ }

if (index >= size || fmt[index].type != type)
return NULL;
@@ -127,9 +163,11 @@ int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)

switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (f->index)
+ fmt = find_format_by_index(inst, f->index, f->type);
+ if (!fmt)
return -EINVAL;
- f->pixelformat = V4L2_PIX_FMT_NV12;
+
+ f->pixelformat = fmt->pixfmt;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
fmt = find_format_by_index(inst, f->index, f->type);
@@ -156,7 +194,7 @@ int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
fmt = find_format(inst, pixmp->pixelformat, f->type);
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) {
+ if (!fmt) {
f_inst = inst->fmt_src;
f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
@@ -221,7 +259,7 @@ static int iris_venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f)

iris_venc_try_fmt(inst, f);

- if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12)
+ if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
return -EINVAL;

fmt = inst->fmt_src;
@@ -289,7 +327,8 @@ int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat)
{
const struct iris_fmt *fmt = NULL;

- if (pixelformat != V4L2_PIX_FMT_NV12) {
+ fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ if (!fmt) {
fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (!fmt)
return -EINVAL;

--
2.34.1