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