]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
media: iris: Add support for QC08C format for encoder
authorDikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
Wed, 8 Oct 2025 09:52:27 +0000 (15:22 +0530)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Thu, 6 Nov 2025 10:18:09 +0000 (11:18 +0100)
Introduce handling for the QC08C format in the encoder. QC08C
format is NV12 with UBWC compression. Update format checks and
configuration to enable encoding to QC08C streams.

Signed-off-by: Dikshita Agarwal <dikshita.agarwal@oss.qualcomm.com>
Reviewed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/platform/qcom/iris/iris_buffer.c
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
drivers/media/platform/qcom/iris/iris_venc.c

index 83dcf49e57ec1473bc4edd26c48ab0b247d23818..b89b1ee06cce151e7c04a80956380d154643c116 100644 (file)
@@ -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:
index e458d3349ce09aadb75d056ae84e3aab95f03078..52da7ef7bab08fb1cb2ac804ccc6e3c7f9677890 100644 (file)
@@ -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));
        }
 
index 5ad202d3fcdc57a2b7b43de15763a686ce0f7bd7..6a772db2ec33fb002d8884753a41dc98b3a8439d 100644 (file)
@@ -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,
index 8a65c9cc601071b84a184bd7811f6f882f98fce8..5830eba93c68b27fa9db87bac63a691eaca338d2 100644 (file)
@@ -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_QC08C] = {
+               .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;
@@ -287,7 +325,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;