Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: iris: Add support for QC08C format for decoder

Introduce handling for the QC08C format in the decoder. QC08C format is
NV12 with UBWC compression. Update format checks and configuration to
enable decoding of 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>

authored by

Dikshita Agarwal and committed by
Hans Verkuil
cfd71b14 7c1f3bd5

+72 -19
+4 -1
drivers/media/platform/qcom/iris/iris_buffer.c
··· 261 261 case BUF_INPUT: 262 262 return iris_dec_bitstream_buffer_size(inst); 263 263 case BUF_OUTPUT: 264 - return iris_yuv_buffer_size_nv12(inst); 264 + if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) 265 + return iris_yuv_buffer_size_qc08c(inst); 266 + else 267 + return iris_yuv_buffer_size_nv12(inst); 265 268 case BUF_DPB: 266 269 return iris_yuv_buffer_size_qc08c(inst); 267 270 default:
+8 -4
drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c
··· 774 774 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 775 775 if (iris_split_mode_enabled(inst)) { 776 776 fmt.buffer_type = HFI_BUFFER_OUTPUT; 777 - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 778 - HFI_COLOR_FORMAT_NV12_UBWC : 0; 777 + fmt.format = HFI_COLOR_FORMAT_NV12_UBWC; 779 778 780 779 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 781 780 if (ret) 782 781 return ret; 783 782 784 783 fmt.buffer_type = HFI_BUFFER_OUTPUT2; 785 - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 784 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 785 + HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; 786 786 787 787 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 788 788 } else { 789 789 fmt.buffer_type = HFI_BUFFER_OUTPUT; 790 - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 790 + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 791 + HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; 791 792 792 793 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 793 794 } ··· 806 805 { 807 806 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; 808 807 struct hfi_uncompressed_plane_actual_constraints_info pconstraint; 808 + 809 + if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) 810 + return 0; 809 811 810 812 pconstraint.buffer_type = HFI_BUFFER_OUTPUT2; 811 813 pconstraint.num_planes = 2;
+2 -1
drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c
··· 443 443 444 444 if (inst->domain == DECODER) { 445 445 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 446 - hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; 446 + hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? 447 + HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC; 447 448 } else { 448 449 pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; 449 450 hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
+6 -1
drivers/media/platform/qcom/iris/iris_instance.h
··· 15 15 #define DEFAULT_WIDTH 320 16 16 #define DEFAULT_HEIGHT 240 17 17 18 - enum iris_fmt_type { 18 + enum iris_fmt_type_out { 19 19 IRIS_FMT_H264, 20 20 IRIS_FMT_HEVC, 21 21 IRIS_FMT_VP9, 22 + }; 23 + 24 + enum iris_fmt_type_cap { 25 + IRIS_FMT_NV12, 26 + IRIS_FMT_QC08C, 22 27 }; 23 28 24 29 struct iris_fmt {
+2 -1
drivers/media/platform/qcom/iris/iris_utils.c
··· 34 34 35 35 bool iris_split_mode_enabled(struct iris_inst *inst) 36 36 { 37 - return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12; 37 + return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12 || 38 + inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C; 38 39 } 39 40 40 41 void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type,
+50 -11
drivers/media/platform/qcom/iris/iris_vdec.c
··· 67 67 kfree(inst->fmt_src); 68 68 } 69 69 70 - static const struct iris_fmt iris_vdec_formats[] = { 70 + static const struct iris_fmt iris_vdec_formats_out[] = { 71 71 [IRIS_FMT_H264] = { 72 72 .pixfmt = V4L2_PIX_FMT_H264, 73 73 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, ··· 82 82 }, 83 83 }; 84 84 85 + static const struct iris_fmt iris_vdec_formats_cap[] = { 86 + [IRIS_FMT_NV12] = { 87 + .pixfmt = V4L2_PIX_FMT_NV12, 88 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 89 + }, 90 + [IRIS_FMT_QC08C] = { 91 + .pixfmt = V4L2_PIX_FMT_QC08C, 92 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 93 + }, 94 + }; 95 + 85 96 static const struct iris_fmt * 86 97 find_format(struct iris_inst *inst, u32 pixfmt, u32 type) 87 98 { 88 - unsigned int size = ARRAY_SIZE(iris_vdec_formats); 89 - const struct iris_fmt *fmt = iris_vdec_formats; 99 + const struct iris_fmt *fmt = NULL; 100 + unsigned int size = 0; 90 101 unsigned int i; 102 + switch (type) { 103 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 104 + fmt = iris_vdec_formats_out; 105 + size = ARRAY_SIZE(iris_vdec_formats_out); 106 + break; 107 + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 108 + fmt = iris_vdec_formats_cap; 109 + size = ARRAY_SIZE(iris_vdec_formats_cap); 110 + break; 111 + default: 112 + return NULL; 113 + } 91 114 92 115 for (i = 0; i < size; i++) { 93 116 if (fmt[i].pixfmt == pixfmt) ··· 126 103 static const struct iris_fmt * 127 104 find_format_by_index(struct iris_inst *inst, u32 index, u32 type) 128 105 { 129 - const struct iris_fmt *fmt = iris_vdec_formats; 130 - unsigned int size = ARRAY_SIZE(iris_vdec_formats); 106 + const struct iris_fmt *fmt = NULL; 107 + unsigned int size = 0; 108 + 109 + switch (type) { 110 + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 111 + fmt = iris_vdec_formats_out; 112 + size = ARRAY_SIZE(iris_vdec_formats_out); 113 + break; 114 + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 115 + fmt = iris_vdec_formats_cap; 116 + size = ARRAY_SIZE(iris_vdec_formats_cap); 117 + break; 118 + default: 119 + return NULL; 120 + } 131 121 132 122 if (index >= size || fmt[index].type != type) 133 123 return NULL; ··· 162 126 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; 163 127 break; 164 128 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 165 - if (f->index) 129 + fmt = find_format_by_index(inst, f->index, f->type); 130 + if (!fmt) 166 131 return -EINVAL; 167 - f->pixelformat = V4L2_PIX_FMT_NV12; 132 + f->pixelformat = fmt->pixfmt; 168 133 break; 169 134 default: 170 135 return -EINVAL; ··· 194 157 } 195 158 break; 196 159 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 197 - if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) { 160 + if (!fmt) { 198 161 f_inst = inst->fmt_dst; 199 162 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 200 163 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; ··· 273 236 inst->crop.height = f->fmt.pix_mp.height; 274 237 break; 275 238 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 239 + if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 240 + return -EINVAL; 241 + 276 242 fmt = inst->fmt_dst; 277 243 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 278 - if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) 279 - return -EINVAL; 280 244 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 281 245 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 282 246 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); ··· 304 266 { 305 267 const struct iris_fmt *fmt = NULL; 306 268 307 - if (pixelformat != V4L2_PIX_FMT_NV12) { 269 + fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 270 + if (!fmt) { 308 271 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 309 272 if (!fmt) 310 273 return -EINVAL;