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