1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 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_power.h" 13 #include "iris_vdec.h" 14 #include "iris_vpu_buffer.h" 15 16 #define DEFAULT_WIDTH 320 17 #define DEFAULT_HEIGHT 240 18 #define DEFAULT_CODEC_ALIGNMENT 16 19 20 int iris_vdec_inst_init(struct iris_inst *inst) 21 { 22 struct iris_core *core = inst->core; 23 struct v4l2_format *f; 24 25 inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); 26 inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); 27 28 inst->fw_min_count = MIN_BUFFERS; 29 30 f = inst->fmt_src; 31 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_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_INPUT); 39 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 40 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 41 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 42 43 f = inst->fmt_dst; 44 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_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_OUTPUT); 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_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 57 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 58 59 memcpy(&inst->fw_caps[0], &core->inst_fw_caps[0], 60 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); 61 62 return iris_ctrls_init(inst); 63 } 64 65 void iris_vdec_inst_deinit(struct iris_inst *inst) 66 { 67 kfree(inst->fmt_dst); 68 kfree(inst->fmt_src); 69 } 70 71 static const struct iris_fmt iris_vdec_formats[] = { 72 [IRIS_FMT_H264] = { 73 .pixfmt = V4L2_PIX_FMT_H264, 74 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 75 }, 76 [IRIS_FMT_HEVC] = { 77 .pixfmt = V4L2_PIX_FMT_HEVC, 78 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 79 }, 80 [IRIS_FMT_VP9] = { 81 .pixfmt = V4L2_PIX_FMT_VP9, 82 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 83 }, 84 }; 85 86 static const struct iris_fmt * 87 find_format(struct iris_inst *inst, u32 pixfmt, u32 type) 88 { 89 unsigned int size = ARRAY_SIZE(iris_vdec_formats); 90 const struct iris_fmt *fmt = iris_vdec_formats; 91 unsigned int i; 92 93 for (i = 0; i < size; i++) { 94 if (fmt[i].pixfmt == pixfmt) 95 break; 96 } 97 98 if (i == size || fmt[i].type != type) 99 return NULL; 100 101 return &fmt[i]; 102 } 103 104 static const struct iris_fmt * 105 find_format_by_index(struct iris_inst *inst, u32 index, u32 type) 106 { 107 const struct iris_fmt *fmt = iris_vdec_formats; 108 unsigned int size = ARRAY_SIZE(iris_vdec_formats); 109 110 if (index >= size || fmt[index].type != type) 111 return NULL; 112 113 return &fmt[index]; 114 } 115 116 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) 117 { 118 const struct iris_fmt *fmt; 119 120 switch (f->type) { 121 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 122 fmt = find_format_by_index(inst, f->index, f->type); 123 if (!fmt) 124 return -EINVAL; 125 126 f->pixelformat = fmt->pixfmt; 127 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; 128 break; 129 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 130 if (f->index) 131 return -EINVAL; 132 f->pixelformat = V4L2_PIX_FMT_NV12; 133 break; 134 default: 135 return -EINVAL; 136 } 137 138 return 0; 139 } 140 141 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) 142 { 143 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 144 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 145 const struct iris_fmt *fmt; 146 struct v4l2_format *f_inst; 147 struct vb2_queue *src_q; 148 149 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 150 fmt = find_format(inst, pixmp->pixelformat, f->type); 151 switch (f->type) { 152 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 153 if (!fmt) { 154 f_inst = inst->fmt_src; 155 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 156 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 157 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 158 } 159 break; 160 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 161 if (!fmt) { 162 f_inst = inst->fmt_dst; 163 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 164 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 165 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 166 } 167 168 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 169 if (vb2_is_streaming(src_q)) { 170 f_inst = inst->fmt_src; 171 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 172 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 173 } 174 break; 175 default: 176 return -EINVAL; 177 } 178 179 if (pixmp->field == V4L2_FIELD_ANY) 180 pixmp->field = V4L2_FIELD_NONE; 181 182 pixmp->num_planes = 1; 183 184 return 0; 185 } 186 187 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) 188 { 189 struct v4l2_format *fmt, *output_fmt; 190 struct vb2_queue *q; 191 u32 codec_align; 192 193 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 194 if (!q) 195 return -EINVAL; 196 197 if (vb2_is_busy(q)) 198 return -EBUSY; 199 200 iris_vdec_try_fmt(inst, f); 201 202 switch (f->type) { 203 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 204 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 205 return -EINVAL; 206 207 fmt = inst->fmt_src; 208 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 209 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 210 inst->codec = fmt->fmt.pix_mp.pixelformat; 211 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 212 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); 213 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); 214 fmt->fmt.pix_mp.num_planes = 1; 215 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 216 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 217 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 218 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 219 220 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 221 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 222 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 223 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 224 225 output_fmt = inst->fmt_dst; 226 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 227 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 228 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 229 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 230 231 /* Update capture format based on new ip w/h */ 232 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 233 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 234 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT); 235 236 inst->crop.left = 0; 237 inst->crop.top = 0; 238 inst->crop.width = f->fmt.pix_mp.width; 239 inst->crop.height = f->fmt.pix_mp.height; 240 break; 241 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 242 fmt = inst->fmt_dst; 243 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 244 if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) 245 return -EINVAL; 246 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 247 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 248 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 249 fmt->fmt.pix_mp.num_planes = 1; 250 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); 251 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 252 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 253 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 254 255 inst->crop.top = 0; 256 inst->crop.left = 0; 257 inst->crop.width = f->fmt.pix_mp.width; 258 inst->crop.height = f->fmt.pix_mp.height; 259 break; 260 default: 261 return -EINVAL; 262 } 263 memcpy(f, fmt, sizeof(*fmt)); 264 265 return 0; 266 } 267 268 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub) 269 { 270 int ret = 0; 271 272 switch (sub->type) { 273 case V4L2_EVENT_EOS: 274 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 275 break; 276 case V4L2_EVENT_SOURCE_CHANGE: 277 ret = v4l2_src_change_event_subscribe(&inst->fh, sub); 278 break; 279 case V4L2_EVENT_CTRL: 280 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub); 281 break; 282 default: 283 return -EINVAL; 284 } 285 286 return ret; 287 } 288 289 void iris_vdec_src_change(struct iris_inst *inst) 290 { 291 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 292 struct v4l2_event event = {0}; 293 struct vb2_queue *src_q; 294 295 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 296 if (!vb2_is_streaming(src_q)) 297 return; 298 299 event.type = V4L2_EVENT_SOURCE_CHANGE; 300 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION; 301 v4l2_event_queue_fh(&inst->fh, &event); 302 } 303 304 305 static void iris_vdec_flush_deferred_buffers(struct iris_inst *inst, 306 enum iris_buffer_type type) 307 { 308 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 309 struct v4l2_m2m_buffer *buffer, *n; 310 struct iris_buffer *buf; 311 312 if (type == BUF_INPUT) { 313 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { 314 buf = to_iris_buffer(&buffer->vb); 315 if (buf->attr & BUF_ATTR_DEFERRED) { 316 if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 317 buf->attr |= BUF_ATTR_BUFFER_DONE; 318 buf->data_size = 0; 319 iris_vb2_buffer_done(inst, buf); 320 } 321 } 322 } 323 } else { 324 v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { 325 buf = to_iris_buffer(&buffer->vb); 326 if (buf->attr & BUF_ATTR_DEFERRED) { 327 if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 328 buf->attr |= BUF_ATTR_BUFFER_DONE; 329 buf->data_size = 0; 330 iris_vb2_buffer_done(inst, buf); 331 } 332 } 333 } 334 } 335 } 336 337 static void iris_vdec_kill_session(struct iris_inst *inst) 338 { 339 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 340 341 if (!inst->session_id) 342 return; 343 344 hfi_ops->session_close(inst); 345 iris_inst_change_state(inst, IRIS_INST_ERROR); 346 } 347 348 int iris_vdec_session_streamoff(struct iris_inst *inst, u32 plane) 349 { 350 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 351 enum iris_buffer_type buffer_type; 352 int ret; 353 354 switch (plane) { 355 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 356 buffer_type = BUF_INPUT; 357 break; 358 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 359 buffer_type = BUF_OUTPUT; 360 break; 361 default: 362 return -EINVAL; 363 } 364 365 ret = hfi_ops->session_stop(inst, plane); 366 if (ret) 367 goto error; 368 369 ret = iris_inst_state_change_streamoff(inst, plane); 370 if (ret) 371 goto error; 372 373 iris_vdec_flush_deferred_buffers(inst, buffer_type); 374 375 return 0; 376 377 error: 378 iris_vdec_kill_session(inst); 379 iris_vdec_flush_deferred_buffers(inst, buffer_type); 380 381 return ret; 382 } 383 384 static int iris_vdec_process_streamon_input(struct iris_inst *inst) 385 { 386 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 387 enum iris_inst_sub_state set_sub_state = 0; 388 int ret; 389 390 iris_scale_power(inst); 391 392 ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 393 if (ret) 394 return ret; 395 396 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 397 ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0); 398 if (ret) 399 return ret; 400 } 401 402 if (inst->sub_state & IRIS_INST_SUB_DRC || 403 inst->sub_state & IRIS_INST_SUB_DRAIN || 404 inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) { 405 if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) { 406 if (hfi_ops->session_pause) { 407 ret = hfi_ops->session_pause(inst, 408 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 409 if (ret) 410 return ret; 411 } 412 set_sub_state = IRIS_INST_SUB_INPUT_PAUSE; 413 } 414 } 415 416 ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 417 if (ret) 418 return ret; 419 420 return iris_inst_change_sub_state(inst, 0, set_sub_state); 421 } 422 423 int iris_vdec_streamon_input(struct iris_inst *inst) 424 { 425 int ret; 426 427 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 428 if (ret) 429 return ret; 430 431 ret = iris_alloc_and_queue_persist_bufs(inst); 432 if (ret) 433 return ret; 434 435 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 436 437 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 438 if (ret) 439 return ret; 440 441 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 442 if (ret) 443 return ret; 444 445 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 446 if (ret) 447 return ret; 448 449 return iris_vdec_process_streamon_input(inst); 450 } 451 452 static int iris_vdec_process_streamon_output(struct iris_inst *inst) 453 { 454 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 455 bool drain_active = false, drc_active = false; 456 enum iris_inst_sub_state clear_sub_state = 0; 457 int ret = 0; 458 459 iris_scale_power(inst); 460 461 drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN && 462 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST; 463 464 drc_active = inst->sub_state & IRIS_INST_SUB_DRC && 465 inst->sub_state & IRIS_INST_SUB_DRC_LAST; 466 467 if (drc_active) 468 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 469 else if (drain_active) 470 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 471 472 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 473 ret = iris_alloc_and_queue_input_int_bufs(inst); 474 if (ret) 475 return ret; 476 ret = iris_set_stage(inst, STAGE); 477 if (ret) 478 return ret; 479 ret = iris_set_pipe(inst, PIPE); 480 if (ret) 481 return ret; 482 } 483 484 if (inst->state == IRIS_INST_INPUT_STREAMING && 485 inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 486 if (!drain_active) 487 ret = hfi_ops->session_resume_drc(inst, 488 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 489 else if (hfi_ops->session_resume_drain) 490 ret = hfi_ops->session_resume_drain(inst, 491 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 492 if (ret) 493 return ret; 494 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 495 } 496 497 if (inst->sub_state & IRIS_INST_SUB_FIRST_IPSC) 498 clear_sub_state |= IRIS_INST_SUB_FIRST_IPSC; 499 500 ret = hfi_ops->session_start(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 501 if (ret) 502 return ret; 503 504 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) 505 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 506 507 ret = iris_inst_state_change_streamon(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 508 if (ret) 509 return ret; 510 511 inst->last_buffer_dequeued = false; 512 513 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 514 } 515 516 int iris_vdec_streamon_output(struct iris_inst *inst) 517 { 518 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 519 int ret; 520 521 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 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 return ret; 530 531 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 532 if (ret) 533 return ret; 534 535 ret = iris_vdec_process_streamon_output(inst); 536 if (ret) 537 goto error; 538 539 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 540 if (ret) 541 goto error; 542 543 return ret; 544 545 error: 546 iris_vdec_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 547 548 return ret; 549 } 550 551 static int 552 iris_vdec_vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf) 553 { 554 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2); 555 556 buf->type = iris_v4l2_type_to_driver(vb2->type); 557 buf->index = vb2->index; 558 buf->fd = vb2->planes[0].m.fd; 559 buf->buffer_size = vb2->planes[0].length; 560 buf->data_offset = vb2->planes[0].data_offset; 561 buf->data_size = vb2->planes[0].bytesused - vb2->planes[0].data_offset; 562 buf->flags = vbuf->flags; 563 buf->timestamp = vb2->timestamp; 564 buf->attr = 0; 565 566 return 0; 567 } 568 569 static void 570 iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 571 { 572 u32 mask = V4L2_BUF_FLAG_TIMECODE | V4L2_BUF_FLAG_TSTAMP_SRC_MASK; 573 struct vb2_buffer *vb = &vbuf->vb2_buf; 574 u64 ts_us = vb->timestamp; 575 576 if (inst->metadata_idx >= ARRAY_SIZE(inst->tss)) 577 inst->metadata_idx = 0; 578 579 do_div(ts_us, NSEC_PER_USEC); 580 581 inst->tss[inst->metadata_idx].flags = vbuf->flags & mask; 582 inst->tss[inst->metadata_idx].tc = vbuf->timecode; 583 inst->tss[inst->metadata_idx].ts_us = ts_us; 584 inst->tss[inst->metadata_idx].ts_ns = vb->timestamp; 585 586 inst->metadata_idx++; 587 } 588 589 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 590 { 591 struct iris_buffer *buf = to_iris_buffer(vbuf); 592 struct vb2_buffer *vb2 = &vbuf->vb2_buf; 593 struct vb2_queue *q; 594 int ret; 595 596 ret = iris_vdec_vb2_buffer_to_driver(vb2, buf); 597 if (ret) 598 return ret; 599 600 if (buf->type == BUF_INPUT) 601 iris_set_ts_metadata(inst, vbuf); 602 603 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); 604 if (!vb2_is_streaming(q)) { 605 buf->attr |= BUF_ATTR_DEFERRED; 606 return 0; 607 } 608 609 iris_scale_power(inst); 610 611 return iris_queue_buffer(inst, buf); 612 } 613 614 int iris_vdec_start_cmd(struct iris_inst *inst) 615 { 616 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 617 enum iris_inst_sub_state clear_sub_state = 0; 618 struct vb2_queue *dst_vq; 619 int ret; 620 621 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 622 623 if (inst->sub_state & IRIS_INST_SUB_DRC && 624 inst->sub_state & IRIS_INST_SUB_DRC_LAST) { 625 vb2_clear_last_buffer_dequeued(dst_vq); 626 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 627 628 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 629 ret = hfi_ops->session_resume_drc(inst, 630 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 631 if (ret) 632 return ret; 633 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 634 } 635 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 636 ret = hfi_ops->session_resume_drc(inst, 637 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 638 if (ret) 639 return ret; 640 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 641 } 642 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN && 643 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { 644 vb2_clear_last_buffer_dequeued(dst_vq); 645 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 646 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 647 if (hfi_ops->session_resume_drain) { 648 ret = 649 hfi_ops->session_resume_drain(inst, 650 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 651 if (ret) 652 return ret; 653 } 654 655 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 656 } 657 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 658 if (hfi_ops->session_resume_drain) { 659 ret = 660 hfi_ops->session_resume_drain(inst, 661 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 662 if (ret) 663 return ret; 664 } 665 666 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 667 } 668 } else { 669 dev_err(inst->core->dev, "start called before receiving last_flag\n"); 670 iris_inst_change_state(inst, IRIS_INST_ERROR); 671 return -EBUSY; 672 } 673 674 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 675 } 676 677 int iris_vdec_stop_cmd(struct iris_inst *inst) 678 { 679 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 680 int ret; 681 682 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 683 if (ret) 684 return ret; 685 686 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); 687 } 688