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_power.h" 14 #include "iris_venc.h" 15 #include "iris_vpu_buffer.h" 16 17 int iris_venc_inst_init(struct iris_inst *inst) 18 { 19 struct iris_core *core = inst->core; 20 struct v4l2_format *f; 21 22 inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); 23 inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); 24 if (!inst->fmt_src || !inst->fmt_dst) { 25 kfree(inst->fmt_src); 26 kfree(inst->fmt_dst); 27 return -ENOMEM; 28 } 29 30 f = inst->fmt_dst; 31 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 32 f->fmt.pix_mp.width = DEFAULT_WIDTH; 33 f->fmt.pix_mp.height = DEFAULT_HEIGHT; 34 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; 35 inst->codec = f->fmt.pix_mp.pixelformat; 36 f->fmt.pix_mp.num_planes = 1; 37 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 38 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 39 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 40 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 41 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 42 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 43 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 44 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 45 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 46 47 f = inst->fmt_src; 48 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 49 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 50 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128); 51 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32); 52 f->fmt.pix_mp.num_planes = 1; 53 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128); 54 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 55 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 56 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 57 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 58 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 59 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 60 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 61 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 62 63 inst->crop.left = 0; 64 inst->crop.top = 0; 65 inst->crop.width = DEFAULT_WIDTH; 66 inst->crop.height = DEFAULT_HEIGHT; 67 68 inst->operating_rate = DEFAULT_FPS; 69 inst->frame_rate = DEFAULT_FPS; 70 71 inst->enc_raw_width = DEFAULT_WIDTH; 72 inst->enc_raw_height = DEFAULT_HEIGHT; 73 inst->enc_scale_width = DEFAULT_WIDTH; 74 inst->enc_scale_height = DEFAULT_HEIGHT; 75 76 memcpy(&inst->fw_caps[0], &core->inst_fw_caps_enc[0], 77 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); 78 79 return iris_ctrls_init(inst); 80 } 81 82 void iris_venc_inst_deinit(struct iris_inst *inst) 83 { 84 kfree(inst->fmt_dst); 85 kfree(inst->fmt_src); 86 } 87 88 static const struct iris_fmt iris_venc_formats_cap[] = { 89 [IRIS_FMT_H264] = { 90 .pixfmt = V4L2_PIX_FMT_H264, 91 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 92 }, 93 [IRIS_FMT_HEVC] = { 94 .pixfmt = V4L2_PIX_FMT_HEVC, 95 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 96 }, 97 }; 98 99 static const struct iris_fmt iris_venc_formats_out[] = { 100 [IRIS_FMT_NV12] = { 101 .pixfmt = V4L2_PIX_FMT_NV12, 102 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 103 }, 104 [IRIS_FMT_QC08C] = { 105 .pixfmt = V4L2_PIX_FMT_QC08C, 106 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 107 }, 108 }; 109 110 static const struct iris_fmt * 111 find_format(struct iris_inst *inst, u32 pixfmt, u32 type) 112 { 113 const struct iris_fmt *fmt = NULL; 114 unsigned int size = 0; 115 unsigned int i; 116 switch (type) { 117 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 118 fmt = iris_venc_formats_out; 119 size = ARRAY_SIZE(iris_venc_formats_out); 120 break; 121 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 122 fmt = iris_venc_formats_cap; 123 size = ARRAY_SIZE(iris_venc_formats_cap); 124 break; 125 default: 126 return NULL; 127 } 128 129 for (i = 0; i < size; i++) { 130 if (fmt[i].pixfmt == pixfmt) 131 break; 132 } 133 134 if (i == size || fmt[i].type != type) 135 return NULL; 136 137 return &fmt[i]; 138 } 139 140 static const struct iris_fmt * 141 find_format_by_index(struct iris_inst *inst, u32 index, u32 type) 142 { 143 const struct iris_fmt *fmt = NULL; 144 unsigned int size = 0; 145 146 switch (type) { 147 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 148 fmt = iris_venc_formats_out; 149 size = ARRAY_SIZE(iris_venc_formats_out); 150 break; 151 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 152 fmt = iris_venc_formats_cap; 153 size = ARRAY_SIZE(iris_venc_formats_cap); 154 break; 155 default: 156 return NULL; 157 } 158 159 if (index >= size || fmt[index].type != type) 160 return NULL; 161 162 return &fmt[index]; 163 } 164 165 int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) 166 { 167 const struct iris_fmt *fmt; 168 169 switch (f->type) { 170 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 171 fmt = find_format_by_index(inst, f->index, f->type); 172 if (!fmt) 173 return -EINVAL; 174 175 f->pixelformat = fmt->pixfmt; 176 break; 177 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 178 fmt = find_format_by_index(inst, f->index, f->type); 179 if (!fmt) 180 return -EINVAL; 181 182 f->pixelformat = fmt->pixfmt; 183 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL; 184 break; 185 default: 186 return -EINVAL; 187 } 188 189 return 0; 190 } 191 192 int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f) 193 { 194 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 195 const struct iris_fmt *fmt; 196 struct v4l2_format *f_inst; 197 198 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 199 fmt = find_format(inst, pixmp->pixelformat, f->type); 200 switch (f->type) { 201 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 202 if (!fmt) { 203 f_inst = inst->fmt_src; 204 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 205 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 206 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 207 } 208 break; 209 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 210 if (!fmt) { 211 f_inst = inst->fmt_dst; 212 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 213 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 214 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 215 } 216 break; 217 default: 218 return -EINVAL; 219 } 220 221 if (pixmp->field == V4L2_FIELD_ANY) 222 pixmp->field = V4L2_FIELD_NONE; 223 224 pixmp->num_planes = 1; 225 226 return 0; 227 } 228 229 static int iris_venc_s_fmt_output(struct iris_inst *inst, struct v4l2_format *f) 230 { 231 const struct iris_fmt *venc_fmt; 232 struct v4l2_format *fmt; 233 u32 codec_align; 234 235 iris_venc_try_fmt(inst, f); 236 237 venc_fmt = find_format(inst, f->fmt.pix_mp.pixelformat, f->type); 238 if (!venc_fmt) 239 return -EINVAL; 240 241 codec_align = venc_fmt->pixfmt == V4L2_PIX_FMT_HEVC ? 32 : 16; 242 243 fmt = inst->fmt_dst; 244 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 245 /* 246 * If output format size != input format size, 247 * it is considered a scaling case, 248 * and the scaled size needs to be saved. 249 */ 250 if (f->fmt.pix_mp.width != inst->fmt_src->fmt.pix_mp.width || 251 f->fmt.pix_mp.height != inst->fmt_src->fmt.pix_mp.height) { 252 inst->enc_scale_width = f->fmt.pix_mp.width; 253 inst->enc_scale_height = f->fmt.pix_mp.height; 254 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); 255 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); 256 } 257 fmt->fmt.pix_mp.num_planes = 1; 258 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 259 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 260 261 if (f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT && 262 f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_REC709) 263 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 264 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 265 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 266 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 267 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 268 269 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 270 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 271 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 272 inst->codec = f->fmt.pix_mp.pixelformat; 273 memcpy(f, fmt, sizeof(struct v4l2_format)); 274 275 return 0; 276 } 277 278 static int iris_venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f) 279 { 280 struct v4l2_format *fmt, *output_fmt; 281 282 iris_venc_try_fmt(inst, f); 283 284 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 285 return -EINVAL; 286 287 fmt = inst->fmt_src; 288 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 289 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 290 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 291 fmt->fmt.pix_mp.num_planes = 1; 292 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 293 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); 294 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 295 296 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 297 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 298 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 299 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 300 301 output_fmt = inst->fmt_dst; 302 output_fmt->fmt.pix_mp.width = fmt->fmt.pix_mp.width; 303 output_fmt->fmt.pix_mp.height = fmt->fmt.pix_mp.height; 304 output_fmt->fmt.pix_mp.colorspace = fmt->fmt.pix_mp.colorspace; 305 output_fmt->fmt.pix_mp.xfer_func = fmt->fmt.pix_mp.xfer_func; 306 output_fmt->fmt.pix_mp.ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc; 307 output_fmt->fmt.pix_mp.quantization = fmt->fmt.pix_mp.quantization; 308 309 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 310 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 311 312 inst->enc_raw_width = f->fmt.pix_mp.width; 313 inst->enc_raw_height = f->fmt.pix_mp.height; 314 inst->enc_scale_width = f->fmt.pix_mp.width; 315 inst->enc_scale_height = f->fmt.pix_mp.height; 316 317 if (f->fmt.pix_mp.width != inst->crop.width || 318 f->fmt.pix_mp.height != inst->crop.height) { 319 inst->crop.top = 0; 320 inst->crop.left = 0; 321 inst->crop.width = fmt->fmt.pix_mp.width; 322 inst->crop.height = fmt->fmt.pix_mp.height; 323 324 iris_venc_s_fmt_output(inst, output_fmt); 325 } 326 327 memcpy(f, fmt, sizeof(struct v4l2_format)); 328 329 return 0; 330 } 331 332 int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f) 333 { 334 struct vb2_queue *q; 335 336 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 337 338 if (vb2_is_busy(q)) 339 return -EBUSY; 340 341 switch (f->type) { 342 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 343 return iris_venc_s_fmt_input(inst, f); 344 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 345 return iris_venc_s_fmt_output(inst, f); 346 default: 347 return -EINVAL; 348 } 349 } 350 351 int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat) 352 { 353 const struct iris_fmt *fmt = NULL; 354 355 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 356 if (!fmt) { 357 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 358 if (!fmt) 359 return -EINVAL; 360 } 361 362 return 0; 363 } 364 365 int iris_venc_subscribe_event(struct iris_inst *inst, 366 const struct v4l2_event_subscription *sub) 367 { 368 switch (sub->type) { 369 case V4L2_EVENT_EOS: 370 return v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 371 case V4L2_EVENT_CTRL: 372 return v4l2_ctrl_subscribe_event(&inst->fh, sub); 373 default: 374 return -EINVAL; 375 } 376 } 377 378 int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s) 379 { 380 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 381 return -EINVAL; 382 383 switch (s->target) { 384 case V4L2_SEL_TGT_CROP: 385 s->r.left = 0; 386 s->r.top = 0; 387 388 if (s->r.width > inst->fmt_src->fmt.pix_mp.width || 389 s->r.height > inst->fmt_src->fmt.pix_mp.height) 390 return -EINVAL; 391 392 inst->crop.left = s->r.left; 393 inst->crop.top = s->r.top; 394 inst->crop.width = s->r.width; 395 inst->crop.height = s->r.height; 396 inst->fmt_dst->fmt.pix_mp.width = inst->crop.width; 397 inst->fmt_dst->fmt.pix_mp.height = inst->crop.height; 398 return iris_venc_s_fmt_output(inst, inst->fmt_dst); 399 default: 400 return -EINVAL; 401 } 402 } 403 404 int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm) 405 { 406 struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; 407 struct vb2_queue *src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx); 408 struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 409 struct v4l2_fract *timeperframe = NULL; 410 u32 default_rate = DEFAULT_FPS; 411 bool is_frame_rate = false; 412 u32 fps, max_rate; 413 414 int ret = 0; 415 416 if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 417 timeperframe = &s_parm->parm.output.timeperframe; 418 max_rate = caps->max_operating_rate; 419 s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 420 } else { 421 timeperframe = &s_parm->parm.capture.timeperframe; 422 is_frame_rate = true; 423 max_rate = caps->max_frame_rate; 424 s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 425 } 426 427 if (!timeperframe->denominator || !timeperframe->numerator) { 428 if (!timeperframe->numerator) 429 timeperframe->numerator = 1; 430 if (!timeperframe->denominator) 431 timeperframe->denominator = default_rate; 432 } 433 434 fps = timeperframe->denominator / timeperframe->numerator; 435 if (!fps) 436 return -EINVAL; 437 438 if (fps > max_rate) { 439 ret = -ENOMEM; 440 goto reset_rate; 441 } 442 443 if (is_frame_rate) 444 inst->frame_rate = fps; 445 else 446 inst->operating_rate = fps; 447 448 if ((s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && vb2_is_streaming(src_q)) || 449 (s_parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && vb2_is_streaming(dst_q))) { 450 ret = iris_check_core_mbpf(inst); 451 if (ret) 452 goto reset_rate; 453 ret = iris_check_core_mbps(inst); 454 if (ret) 455 goto reset_rate; 456 } 457 458 return 0; 459 460 reset_rate: 461 if (ret) { 462 if (is_frame_rate) 463 inst->frame_rate = default_rate; 464 else 465 inst->operating_rate = default_rate; 466 } 467 468 return ret; 469 } 470 471 int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm) 472 { 473 struct v4l2_fract *timeperframe = NULL; 474 475 if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 476 timeperframe = &s_parm->parm.output.timeperframe; 477 timeperframe->numerator = 1; 478 timeperframe->denominator = inst->operating_rate; 479 s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 480 } else { 481 timeperframe = &s_parm->parm.capture.timeperframe; 482 timeperframe->numerator = 1; 483 timeperframe->denominator = inst->frame_rate; 484 s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 485 } 486 487 return 0; 488 } 489 490 int iris_venc_streamon_input(struct iris_inst *inst) 491 { 492 int ret; 493 494 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 495 if (ret) 496 return ret; 497 498 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP); 499 if (ret) 500 return ret; 501 502 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 503 504 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 505 if (ret) 506 return ret; 507 508 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 509 if (ret) 510 return ret; 511 512 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 513 if (ret) 514 return ret; 515 516 return iris_process_streamon_input(inst); 517 } 518 519 int iris_venc_streamon_output(struct iris_inst *inst) 520 { 521 int ret; 522 523 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 524 if (ret) 525 goto error; 526 527 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP); 528 if (ret) 529 return ret; 530 531 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 532 533 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 534 if (ret) 535 goto error; 536 537 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 538 if (ret) 539 goto error; 540 541 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 542 if (ret) 543 goto error; 544 545 ret = iris_process_streamon_output(inst); 546 if (ret) 547 goto error; 548 549 return ret; 550 551 error: 552 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 553 554 return ret; 555 } 556 557 int iris_venc_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 558 { 559 struct iris_buffer *buf = to_iris_buffer(vbuf); 560 struct vb2_buffer *vb2 = &vbuf->vb2_buf; 561 struct vb2_queue *q; 562 int ret; 563 564 ret = iris_vb2_buffer_to_driver(vb2, buf); 565 if (ret) 566 return ret; 567 568 if (buf->type == BUF_INPUT) 569 iris_set_ts_metadata(inst, vbuf); 570 571 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); 572 if (!vb2_is_streaming(q)) { 573 buf->attr |= BUF_ATTR_DEFERRED; 574 return 0; 575 } 576 577 iris_scale_power(inst); 578 579 return iris_queue_buffer(inst, buf); 580 } 581 582 int iris_venc_start_cmd(struct iris_inst *inst) 583 { 584 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 585 enum iris_inst_sub_state clear_sub_state = 0; 586 struct vb2_queue *dst_vq; 587 int ret; 588 589 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 590 591 if (inst->sub_state & IRIS_INST_SUB_DRAIN && 592 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { 593 vb2_clear_last_buffer_dequeued(dst_vq); 594 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 595 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 596 if (hfi_ops->session_resume_drain) { 597 ret = hfi_ops->session_resume_drain(inst, 598 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 599 if (ret) 600 return ret; 601 } 602 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 603 } 604 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 605 if (hfi_ops->session_resume_drain) { 606 ret = hfi_ops->session_resume_drain(inst, 607 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 608 if (ret) 609 return ret; 610 } 611 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 612 } 613 } else { 614 dev_err(inst->core->dev, "start called before receiving last_flag\n"); 615 iris_inst_change_state(inst, IRIS_INST_ERROR); 616 return -EBUSY; 617 } 618 619 inst->last_buffer_dequeued = false; 620 621 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 622 } 623 624 int iris_venc_stop_cmd(struct iris_inst *inst) 625 { 626 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 627 int ret; 628 629 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 630 if (ret) 631 return ret; 632 633 ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); 634 635 iris_scale_power(inst); 636 637 return ret; 638 } 639