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