media: venus: Add a handling of QC10C compressed format
authorStanimir Varbanov <stanimir.varbanov@linaro.org>
Thu, 3 Mar 2022 15:06:35 +0000 (15:06 +0000)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Sun, 24 Apr 2022 07:34:18 +0000 (08:34 +0100)
This adds QC10C compressed pixel format in the Venus driver, and
make it possible to discover from v4l2 clients.

Note: The QC10C format will be enumerable via VIDIOC_ENUM_FMT when
the bitstream is 10-bits and the headers are parsed.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/qcom/venus/helpers.c
drivers/media/platform/qcom/venus/vdec.c

index 0589066c510b9513fedbd2a0b0c9cbe69165e121..5c1104379c4910046b89938632f5869a75740f51 100644 (file)
@@ -610,6 +610,8 @@ static u32 to_hfi_raw_fmt(u32 v4l2_fmt)
                return HFI_COLOR_FORMAT_NV21;
        case V4L2_PIX_FMT_QC08C:
                return HFI_COLOR_FORMAT_NV12_UBWC;
+       case V4L2_PIX_FMT_QC10C:
+               return HFI_COLOR_FORMAT_YUV420_TP10_UBWC;
        default:
                break;
        }
@@ -1192,7 +1194,8 @@ int venus_helper_set_format_constraints(struct venus_inst *inst)
        if (!IS_V6(inst->core))
                return 0;
 
-       if (inst->opb_fmt == HFI_COLOR_FORMAT_NV12_UBWC)
+       if (inst->opb_fmt == HFI_COLOR_FORMAT_NV12_UBWC ||
+           inst->opb_fmt == HFI_COLOR_FORMAT_YUV420_TP10_UBWC)
                return 0;
 
        pconstraint.buffer_type = HFI_BUFFER_OUTPUT2;
@@ -1763,27 +1766,6 @@ int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt,
        if (!caps)
                return -EINVAL;
 
-       if (inst->bit_depth == VIDC_BITDEPTH_10 &&
-           inst->session_type == VIDC_SESSION_TYPE_DEC) {
-               found_ubwc =
-                       find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
-                                          HFI_COLOR_FORMAT_YUV420_TP10_UBWC);
-               found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2,
-                                          HFI_COLOR_FORMAT_NV12);
-               if (found_ubwc && found) {
-                       /*
-                        * Hard-code DPB buffers to be 10bit UBWC and decoder
-                        * output buffers in 8bit NV12 until V4L2 is able to
-                        * expose compressed/tiled formats to applications.
-                        */
-                       *out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC;
-                       *out2_fmt = HFI_COLOR_FORMAT_NV12;
-                       return 0;
-               }
-
-               return -EINVAL;
-       }
-
        if (ubwc) {
                ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE;
                found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
index b7408e0845a6296881641a1ca3405f58166374cf..2232969e709aa38e8dd15824a10d4b770852f4e3 100644 (file)
@@ -35,6 +35,10 @@ static const struct venus_format vdec_formats[] = {
                .num_planes = 1,
                .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
        }, {
+               .pixfmt = V4L2_PIX_FMT_QC10C,
+               .num_planes = 1,
+               .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+       },{
                .pixfmt = V4L2_PIX_FMT_NV12,
                .num_planes = 1,
                .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
@@ -114,6 +118,10 @@ find_format(struct venus_inst *inst, u32 pixfmt, u32 type)
            !venus_helper_check_format(inst, fmt[i].pixfmt))
                return NULL;
 
+       if (V4L2_TYPE_IS_CAPTURE(type) && fmt[i].pixfmt == V4L2_PIX_FMT_QC10C &&
+           !(inst->bit_depth == VIDC_BITDEPTH_10))
+               return NULL;
+
        return &fmt[i];
 }
 
@@ -133,11 +141,16 @@ find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type)
                if (fmt[i].type != type)
                        continue;
 
-               if (V4L2_TYPE_IS_OUTPUT(type))
+               if (V4L2_TYPE_IS_OUTPUT(type)) {
                        valid = venus_helper_check_codec(inst, fmt[i].pixfmt);
-               else if (V4L2_TYPE_IS_CAPTURE(type))
+               } else if (V4L2_TYPE_IS_CAPTURE(type)) {
                        valid = venus_helper_check_format(inst, fmt[i].pixfmt);
 
+                       if (fmt[i].pixfmt == V4L2_PIX_FMT_QC10C &&
+                           !(inst->bit_depth == VIDC_BITDEPTH_10))
+                               valid = false;
+               }
+
                if (k == index && valid)
                        break;
                if (valid)
@@ -1539,7 +1552,7 @@ static const struct hfi_inst_ops vdec_hfi_ops = {
 static void vdec_inst_init(struct venus_inst *inst)
 {
        inst->hfi_codec = HFI_VIDEO_CODEC_H264;
-       inst->fmt_out = &vdec_formats[7];
+       inst->fmt_out = &vdec_formats[8];
        inst->fmt_cap = &vdec_formats[0];
        inst->width = frame_width_min(inst);
        inst->height = ALIGN(frame_height_min(inst), 32);