1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <media/v4l2-event.h> 7 #include <media/v4l2-mem2mem.h> 8 9 #include "iris_buffer.h" 10 #include "iris_ctrls.h" 11 #include "iris_instance.h" 12 #include "iris_venc.h" 13 #include "iris_vpu_buffer.h" 14 15 int iris_venc_inst_init(struct iris_inst *inst) 16 { 17 struct iris_core *core = inst->core; 18 struct v4l2_format *f; 19 20 inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); 21 inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); 22 if (!inst->fmt_src || !inst->fmt_dst) { 23 kfree(inst->fmt_src); 24 kfree(inst->fmt_dst); 25 return -ENOMEM; 26 } 27 28 f = inst->fmt_dst; 29 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 30 f->fmt.pix_mp.width = DEFAULT_WIDTH; 31 f->fmt.pix_mp.height = DEFAULT_HEIGHT; 32 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; 33 inst->codec = f->fmt.pix_mp.pixelformat; 34 f->fmt.pix_mp.num_planes = 1; 35 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 36 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 37 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 38 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 39 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 40 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 41 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 42 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 43 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 44 45 f = inst->fmt_src; 46 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 47 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 48 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128); 49 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32); 50 f->fmt.pix_mp.num_planes = 1; 51 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128); 52 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 53 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 54 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 55 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 56 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 57 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 58 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 59 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 60 61 inst->crop.left = 0; 62 inst->crop.top = 0; 63 inst->crop.width = f->fmt.pix_mp.width; 64 inst->crop.height = f->fmt.pix_mp.height; 65 66 inst->operating_rate = DEFAULT_FPS; 67 inst->frame_rate = DEFAULT_FPS; 68 69 memcpy(&inst->fw_caps[0], &core->inst_fw_caps_enc[0], 70 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); 71 72 return iris_ctrls_init(inst); 73 } 74 75 void iris_venc_inst_deinit(struct iris_inst *inst) 76 { 77 kfree(inst->fmt_dst); 78 kfree(inst->fmt_src); 79 } 80 81 static const struct iris_fmt iris_venc_formats[] = { 82 [IRIS_FMT_H264] = { 83 .pixfmt = V4L2_PIX_FMT_H264, 84 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 85 }, 86 [IRIS_FMT_HEVC] = { 87 .pixfmt = V4L2_PIX_FMT_HEVC, 88 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 89 }, 90 }; 91 92 static const struct iris_fmt * 93 find_format(struct iris_inst *inst, u32 pixfmt, u32 type) 94 { 95 const struct iris_fmt *fmt = iris_venc_formats; 96 unsigned int size = ARRAY_SIZE(iris_venc_formats); 97 unsigned int i; 98 99 for (i = 0; i < size; i++) { 100 if (fmt[i].pixfmt == pixfmt) 101 break; 102 } 103 104 if (i == size || fmt[i].type != type) 105 return NULL; 106 107 return &fmt[i]; 108 } 109 110 static const struct iris_fmt * 111 find_format_by_index(struct iris_inst *inst, u32 index, u32 type) 112 { 113 const struct iris_fmt *fmt = iris_venc_formats; 114 unsigned int size = ARRAY_SIZE(iris_venc_formats); 115 116 if (index >= size || fmt[index].type != type) 117 return NULL; 118 119 return &fmt[index]; 120 } 121 122 int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) 123 { 124 const struct iris_fmt *fmt; 125 126 switch (f->type) { 127 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 128 if (f->index) 129 return -EINVAL; 130 f->pixelformat = V4L2_PIX_FMT_NV12; 131 break; 132 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 133 fmt = find_format_by_index(inst, f->index, f->type); 134 if (!fmt) 135 return -EINVAL; 136 137 f->pixelformat = fmt->pixfmt; 138 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL; 139 break; 140 default: 141 return -EINVAL; 142 } 143 144 return 0; 145 } 146 147 int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f) 148 { 149 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 150 const struct iris_fmt *fmt; 151 struct v4l2_format *f_inst; 152 153 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 154 fmt = find_format(inst, pixmp->pixelformat, f->type); 155 switch (f->type) { 156 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 157 if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) { 158 f_inst = inst->fmt_src; 159 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 160 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 161 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 162 } 163 break; 164 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 165 if (!fmt) { 166 f_inst = inst->fmt_dst; 167 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 168 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 169 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 170 } 171 break; 172 default: 173 return -EINVAL; 174 } 175 176 if (pixmp->field == V4L2_FIELD_ANY) 177 pixmp->field = V4L2_FIELD_NONE; 178 179 pixmp->num_planes = 1; 180 181 return 0; 182 } 183 184 static int iris_venc_s_fmt_output(struct iris_inst *inst, struct v4l2_format *f) 185 { 186 struct v4l2_format *fmt; 187 188 iris_venc_try_fmt(inst, f); 189 190 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 191 return -EINVAL; 192 193 fmt = inst->fmt_dst; 194 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 195 fmt->fmt.pix_mp.num_planes = 1; 196 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 197 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 198 199 if (f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT && 200 f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_REC709) 201 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 202 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 203 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 204 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 205 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 206 207 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 208 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 209 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 210 inst->codec = f->fmt.pix_mp.pixelformat; 211 memcpy(f, fmt, sizeof(struct v4l2_format)); 212 213 return 0; 214 } 215 216 static int iris_venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f) 217 { 218 struct v4l2_format *fmt, *output_fmt; 219 220 iris_venc_try_fmt(inst, f); 221 222 if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) 223 return -EINVAL; 224 225 fmt = inst->fmt_src; 226 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 227 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 228 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 229 fmt->fmt.pix_mp.num_planes = 1; 230 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 231 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); 232 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 233 234 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 235 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 236 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 237 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 238 239 output_fmt = inst->fmt_dst; 240 output_fmt->fmt.pix_mp.width = fmt->fmt.pix_mp.width; 241 output_fmt->fmt.pix_mp.height = fmt->fmt.pix_mp.height; 242 output_fmt->fmt.pix_mp.colorspace = fmt->fmt.pix_mp.colorspace; 243 output_fmt->fmt.pix_mp.xfer_func = fmt->fmt.pix_mp.xfer_func; 244 output_fmt->fmt.pix_mp.ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc; 245 output_fmt->fmt.pix_mp.quantization = fmt->fmt.pix_mp.quantization; 246 247 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 248 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 249 250 if (f->fmt.pix_mp.width != inst->crop.width || 251 f->fmt.pix_mp.height != inst->crop.height) { 252 inst->crop.top = 0; 253 inst->crop.left = 0; 254 inst->crop.width = fmt->fmt.pix_mp.width; 255 inst->crop.height = fmt->fmt.pix_mp.height; 256 257 iris_venc_s_fmt_output(inst, output_fmt); 258 } 259 260 memcpy(f, fmt, sizeof(struct v4l2_format)); 261 262 return 0; 263 } 264 265 int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f) 266 { 267 struct vb2_queue *q; 268 269 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 270 if (!q) 271 return -EINVAL; 272 273 if (vb2_is_busy(q)) 274 return -EBUSY; 275 276 switch (f->type) { 277 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 278 return iris_venc_s_fmt_input(inst, f); 279 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 280 return iris_venc_s_fmt_output(inst, f); 281 default: 282 return -EINVAL; 283 } 284 } 285 286 int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat) 287 { 288 const struct iris_fmt *fmt = NULL; 289 290 if (pixelformat != V4L2_PIX_FMT_NV12) { 291 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 292 if (!fmt) 293 return -EINVAL; 294 } 295 296 return 0; 297 } 298 299 int iris_venc_subscribe_event(struct iris_inst *inst, 300 const struct v4l2_event_subscription *sub) 301 { 302 switch (sub->type) { 303 case V4L2_EVENT_EOS: 304 return v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 305 case V4L2_EVENT_CTRL: 306 return v4l2_ctrl_subscribe_event(&inst->fh, sub); 307 default: 308 return -EINVAL; 309 } 310 } 311 312 int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s) 313 { 314 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 315 return -EINVAL; 316 317 switch (s->target) { 318 case V4L2_SEL_TGT_CROP: 319 s->r.left = 0; 320 s->r.top = 0; 321 322 if (s->r.width > inst->fmt_src->fmt.pix_mp.width || 323 s->r.height > inst->fmt_src->fmt.pix_mp.height) 324 return -EINVAL; 325 326 inst->crop.left = s->r.left; 327 inst->crop.top = s->r.top; 328 inst->crop.width = s->r.width; 329 inst->crop.height = s->r.height; 330 inst->fmt_dst->fmt.pix_mp.width = inst->crop.width; 331 inst->fmt_dst->fmt.pix_mp.height = inst->crop.height; 332 return iris_venc_s_fmt_output(inst, inst->fmt_dst); 333 default: 334 return -EINVAL; 335 } 336 } 337 338 int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm) 339 { 340 struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; 341 struct vb2_queue *src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx); 342 struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 343 struct v4l2_fract *timeperframe = NULL; 344 u32 default_rate = DEFAULT_FPS; 345 bool is_frame_rate = false; 346 u64 us_per_frame, fps; 347 u32 max_rate; 348 349 int ret = 0; 350 351 if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 352 timeperframe = &s_parm->parm.output.timeperframe; 353 max_rate = caps->max_operating_rate; 354 s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 355 } else { 356 timeperframe = &s_parm->parm.capture.timeperframe; 357 is_frame_rate = true; 358 max_rate = caps->max_frame_rate; 359 s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 360 } 361 362 if (!timeperframe->denominator || !timeperframe->numerator) { 363 if (!timeperframe->numerator) 364 timeperframe->numerator = 1; 365 if (!timeperframe->denominator) 366 timeperframe->denominator = default_rate; 367 } 368 369 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; 370 do_div(us_per_frame, timeperframe->denominator); 371 372 if (!us_per_frame) 373 return -EINVAL; 374 375 fps = (u64)USEC_PER_SEC; 376 do_div(fps, us_per_frame); 377 if (fps > max_rate) { 378 ret = -ENOMEM; 379 goto reset_rate; 380 } 381 382 if (is_frame_rate) 383 inst->frame_rate = (u32)fps; 384 else 385 inst->operating_rate = (u32)fps; 386 387 if ((s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && vb2_is_streaming(src_q)) || 388 (s_parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && vb2_is_streaming(dst_q))) { 389 ret = iris_check_core_mbpf(inst); 390 if (ret) 391 goto reset_rate; 392 ret = iris_check_core_mbps(inst); 393 if (ret) 394 goto reset_rate; 395 } 396 397 return 0; 398 399 reset_rate: 400 if (ret) { 401 if (is_frame_rate) 402 inst->frame_rate = default_rate; 403 else 404 inst->operating_rate = default_rate; 405 } 406 407 return ret; 408 } 409 410 int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm) 411 { 412 struct v4l2_fract *timeperframe = NULL; 413 414 if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 415 timeperframe = &s_parm->parm.output.timeperframe; 416 timeperframe->numerator = 1; 417 timeperframe->denominator = inst->operating_rate; 418 s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 419 } else { 420 timeperframe = &s_parm->parm.capture.timeperframe; 421 timeperframe->numerator = 1; 422 timeperframe->denominator = inst->frame_rate; 423 s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 424 } 425 426 return 0; 427 } 428