FILE
vdec.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/amphion/vdec.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2020-2021 NXP 4 */ 5 6#include <linux/init.h> 7#include <linux/interconnect.h> 8#include <linux/ioctl.h> 9#include <linux/list.h> 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/vmalloc.h> 13#include <linux/videodev2.h> 14#include <media/v4l2-device.h> 15#include <media/v4l2-event.h> 16#include <media/v4l2-mem2mem.h> 17#include <media/v4l2-ioctl.h> 18#include <media/videobuf2-v4l2.h> 19#include <media/videobuf2-dma-contig.h> 20#include <media/videobuf2-vmalloc.h> 21#include "vpu.h" 22#include "vpu_defs.h" 23#include "vpu_core.h" 24#include "vpu_helpers.h" 25#include "vpu_v4l2.h" 26#include "vpu_cmds.h" 27#include "vpu_rpc.h" 28 29#define VDEC_SLOT_CNT_DFT 32 30#define VDEC_MIN_BUFFER_CAP 8 31#define VDEC_MIN_BUFFER_OUT 8 32 33struct vdec_fs_info { 34 char name[8]; 35 u32 type; 36 u32 max_count; 37 u32 req_count; 38 u32 count; 39 u32 index; 40 u32 size; 41 struct vpu_buffer buffer[32]; 42 u32 tag; 43}; 44 45struct vdec_frame_store_t { 46 struct vpu_vb2_buffer *curr; 47 struct vpu_vb2_buffer *pend; 48 dma_addr_t addr; 49 unsigned int state; 50 u32 tag; 51}; 52 53struct vdec_t { 54 u32 seq_hdr_found; 55 struct vpu_buffer udata; 56 struct vpu_decode_params params; 57 struct vpu_dec_codec_info codec_info; 58 enum vpu_codec_state state; 59 60 struct vdec_frame_store_t *slots; 61 u32 slot_count; 62 u32 req_frame_count; 63 struct vdec_fs_info mbi; 64 struct vdec_fs_info dcp; 65 u32 seq_tag; 66 67 bool reset_codec; 68 bool fixed_fmt; 69 u32 decoded_frame_count; 70 u32 display_frame_count; 71 u32 sequence; 72 u32 eos_received; 73 bool is_source_changed; 74 u32 source_change; 75 u32 drain; 76 bool aborting; 77}; 78 79static const struct vpu_format vdec_formats[] = { 80 { 81 .pixfmt = V4L2_PIX_FMT_NV12M_8L128, 82 .mem_planes = 2, 83 .comp_planes = 2, 84 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 85 .sibling = V4L2_PIX_FMT_NV12_8L128, 86 }, 87 { 88 .pixfmt = V4L2_PIX_FMT_NV12_8L128, 89 .mem_planes = 1, 90 .comp_planes = 2, 91 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 92 .sibling = V4L2_PIX_FMT_NV12M_8L128, 93 }, 94 { 95 .pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128, 96 .mem_planes = 2, 97 .comp_planes = 2, 98 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 99 .sibling = V4L2_PIX_FMT_NV12_10BE_8L128, 100 }, 101 { 102 .pixfmt = V4L2_PIX_FMT_NV12_10BE_8L128, 103 .mem_planes = 1, 104 .comp_planes = 2, 105 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 106 .sibling = V4L2_PIX_FMT_NV12M_10BE_8L128 107 }, 108 { 109 .pixfmt = V4L2_PIX_FMT_H264, 110 .mem_planes = 1, 111 .comp_planes = 1, 112 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 113 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 114 }, 115 { 116 .pixfmt = V4L2_PIX_FMT_H264_MVC, 117 .mem_planes = 1, 118 .comp_planes = 1, 119 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 120 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 121 }, 122 { 123 .pixfmt = V4L2_PIX_FMT_HEVC, 124 .mem_planes = 1, 125 .comp_planes = 1, 126 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 127 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 128 }, 129 { 130 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G, 131 .mem_planes = 1, 132 .comp_planes = 1, 133 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 134 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 135 }, 136 { 137 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L, 138 .mem_planes = 1, 139 .comp_planes = 1, 140 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 141 .flags = V4L2_FMT_FLAG_COMPRESSED 142 }, 143 { 144 .pixfmt = V4L2_PIX_FMT_MPEG2, 145 .mem_planes = 1, 146 .comp_planes = 1, 147 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 148 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 149 }, 150 { 151 .pixfmt = V4L2_PIX_FMT_MPEG4, 152 .mem_planes = 1, 153 .comp_planes = 1, 154 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 155 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 156 }, 157 { 158 .pixfmt = V4L2_PIX_FMT_XVID, 159 .mem_planes = 1, 160 .comp_planes = 1, 161 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 162 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 163 }, 164 { 165 .pixfmt = V4L2_PIX_FMT_VP8, 166 .mem_planes = 1, 167 .comp_planes = 1, 168 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 169 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 170 }, 171 { 172 .pixfmt = V4L2_PIX_FMT_H263, 173 .mem_planes = 1, 174 .comp_planes = 1, 175 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 176 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 177 }, 178 { 179 .pixfmt = V4L2_PIX_FMT_SPK, 180 .mem_planes = 1, 181 .comp_planes = 1, 182 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 183 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 184 }, 185 { 186 .pixfmt = V4L2_PIX_FMT_RV30, 187 .mem_planes = 1, 188 .comp_planes = 1, 189 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 190 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 191 }, 192 { 193 .pixfmt = V4L2_PIX_FMT_RV40, 194 .mem_planes = 1, 195 .comp_planes = 1, 196 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 197 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION | V4L2_FMT_FLAG_COMPRESSED 198 }, 199 {0, 0, 0, 0}, 200}; 201 202static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) 203{ 204 struct vpu_inst *inst = ctrl_to_inst(ctrl); 205 struct vdec_t *vdec = inst->priv; 206 int ret = 0; 207 208 switch (ctrl->id) { 209 case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: 210 vdec->params.display_delay_enable = ctrl->val; 211 break; 212 case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: 213 vdec->params.display_delay = ctrl->val; 214 break; 215 default: 216 ret = -EINVAL; 217 break; 218 } 219 220 return ret; 221} 222 223static const struct v4l2_ctrl_ops vdec_ctrl_ops = { 224 .s_ctrl = vdec_op_s_ctrl, 225 .g_volatile_ctrl = vpu_helper_g_volatile_ctrl, 226}; 227 228static int vdec_ctrl_init(struct vpu_inst *inst) 229{ 230 struct v4l2_ctrl *ctrl; 231 int ret; 232 233 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20); 234 if (ret) 235 return ret; 236 237 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 238 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY, 239 0, 0, 1, 0); 240 241 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 242 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE, 243 0, 1, 1, 0); 244 245 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL, 246 V4L2_CID_MPEG_VIDEO_H264_PROFILE, 247 V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, 248 ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | 249 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | 250 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | 251 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED) | 252 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), 253 V4L2_MPEG_VIDEO_H264_PROFILE_MAIN); 254 255 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL, 256 V4L2_CID_MPEG_VIDEO_H264_LEVEL, 257 V4L2_MPEG_VIDEO_H264_LEVEL_6_2, 258 0, 259 V4L2_MPEG_VIDEO_H264_LEVEL_4_0); 260 261 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL, 262 V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, 263 V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, 264 ~((1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | 265 (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)), 266 V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN); 267 268 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, NULL, 269 V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, 270 V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, 271 0, 272 V4L2_MPEG_VIDEO_HEVC_LEVEL_4); 273 274 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 275 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2); 276 if (ctrl) 277 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 278 279 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 280 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2); 281 if (ctrl) 282 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 283 284 if (inst->ctrl_handler.error) { 285 ret = inst->ctrl_handler.error; 286 v4l2_ctrl_handler_free(&inst->ctrl_handler); 287 return ret; 288 } 289 290 ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler); 291 if (ret) { 292 dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret); 293 v4l2_ctrl_handler_free(&inst->ctrl_handler); 294 return ret; 295 } 296 297 return 0; 298} 299 300static void vdec_attach_frame_store(struct vpu_inst *inst, struct vb2_buffer *vb) 301{ 302 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 303 struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf); 304 struct vdec_t *vdec = inst->priv; 305 struct vdec_frame_store_t *new_slots = NULL; 306 dma_addr_t addr; 307 int i; 308 309 addr = vpu_get_vb_phy_addr(vb, 0); 310 for (i = 0; i < vdec->slot_count; i++) { 311 if (addr == vdec->slots[i].addr) { 312 if (vdec->slots[i].curr && vdec->slots[i].curr != vpu_buf) { 313 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED); 314 vdec->slots[i].pend = vpu_buf; 315 } else { 316 vpu_set_buffer_state(vbuf, vdec->slots[i].state); 317 } 318 vpu_buf->fs_id = i; 319 return; 320 } 321 } 322 323 for (i = 0; i < vdec->slot_count; i++) { 324 if (!vdec->slots[i].addr) { 325 vdec->slots[i].addr = addr; 326 vpu_buf->fs_id = i; 327 return; 328 } 329 } 330 331 new_slots = krealloc_array(vdec->slots, vdec->slot_count * 2, 332 sizeof(*vdec->slots), 333 GFP_KERNEL | __GFP_ZERO); 334 if (!new_slots) { 335 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_ERROR); 336 return; 337 } 338 339 vdec->slots = new_slots; 340 vdec->slot_count *= 2; 341 342 vdec->slots[i].addr = addr; 343 vpu_buf->fs_id = i; 344} 345 346static void vdec_reset_frame_store(struct vpu_inst *inst) 347{ 348 struct vdec_t *vdec = inst->priv; 349 350 if (!vdec->slots || !vdec->slot_count) 351 return; 352 353 vpu_trace(inst->dev, "inst[%d] reset slots\n", inst->id); 354 memset(vdec->slots, 0, sizeof(*vdec->slots) * vdec->slot_count); 355} 356 357static void vdec_handle_resolution_change(struct vpu_inst *inst) 358{ 359 struct vdec_t *vdec = inst->priv; 360 struct vb2_queue *q; 361 362 if (!inst->fh.m2m_ctx) 363 return; 364 365 if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) 366 return; 367 if (!vdec->source_change) 368 return; 369 370 q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx); 371 if (!list_empty(&q->done_list)) 372 return; 373 374 vdec->source_change--; 375 vpu_notify_source_change(inst); 376 vpu_set_last_buffer_dequeued(inst, false); 377} 378 379static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force) 380{ 381 struct vdec_t *vdec = inst->priv; 382 enum vpu_codec_state pre_state = inst->state; 383 384 if (state == VPU_CODEC_STATE_SEEK) { 385 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) 386 vdec->state = inst->state; 387 else 388 vdec->state = VPU_CODEC_STATE_ACTIVE; 389 } 390 if (inst->state != VPU_CODEC_STATE_SEEK || force) 391 inst->state = state; 392 else if (state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) 393 vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE; 394 395 if (inst->state != pre_state) 396 vpu_trace(inst->dev, "[%d] %s -> %s\n", inst->id, 397 vpu_codec_state_name(pre_state), vpu_codec_state_name(inst->state)); 398 399 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) 400 vdec_handle_resolution_change(inst); 401 402 return 0; 403} 404 405static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst) 406{ 407 struct vdec_t *vdec = inst->priv; 408 409 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) 410 return; 411 412 if (vdec->eos_received) { 413 if (!vpu_set_last_buffer_dequeued(inst, true)) { 414 vdec->eos_received--; 415 vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0); 416 } 417 } 418} 419 420static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 421{ 422 strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver)); 423 strscpy(cap->card, "amphion vpu decoder", sizeof(cap->card)); 424 strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info)); 425 426 return 0; 427} 428 429static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) 430{ 431 struct vpu_inst *inst = to_inst(file); 432 struct vdec_t *vdec = inst->priv; 433 const struct vpu_format *fmt; 434 int ret = -EINVAL; 435 436 vpu_inst_lock(inst); 437 if (V4L2_TYPE_IS_CAPTURE(f->type) && vdec->fixed_fmt) { 438 fmt = vpu_get_format(inst, f->type); 439 if (f->index == 1) 440 fmt = vpu_helper_find_sibling(inst, f->type, fmt->pixfmt); 441 if (f->index > 1) 442 fmt = NULL; 443 } else { 444 fmt = vpu_helper_enum_format(inst, f->type, f->index); 445 } 446 if (!fmt) 447 goto exit; 448 449 memset(f->reserved, 0, sizeof(f->reserved)); 450 f->pixelformat = fmt->pixfmt; 451 f->flags = fmt->flags; 452 ret = 0; 453exit: 454 vpu_inst_unlock(inst); 455 return ret; 456} 457 458static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f) 459{ 460 struct vpu_inst *inst = to_inst(file); 461 struct vdec_t *vdec = inst->priv; 462 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 463 struct vpu_format *cur_fmt; 464 int i; 465 466 vpu_inst_lock(inst); 467 cur_fmt = vpu_get_format(inst, f->type); 468 469 pixmp->pixelformat = cur_fmt->pixfmt; 470 pixmp->num_planes = cur_fmt->mem_planes; 471 pixmp->width = cur_fmt->width; 472 pixmp->height = cur_fmt->height; 473 pixmp->field = cur_fmt->field; 474 pixmp->flags = cur_fmt->flags; 475 for (i = 0; i < pixmp->num_planes; i++) { 476 pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i]; 477 pixmp->plane_fmt[i].sizeimage = vpu_get_fmt_plane_size(cur_fmt, i); 478 } 479 480 f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries; 481 f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars; 482 f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs; 483 f->fmt.pix_mp.quantization = vdec->codec_info.full_range; 484 vpu_inst_unlock(inst); 485 486 return 0; 487} 488 489static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f) 490{ 491 struct vpu_inst *inst = to_inst(file); 492 struct vdec_t *vdec = inst->priv; 493 struct vpu_format fmt; 494 495 vpu_inst_lock(inst); 496 if (V4L2_TYPE_IS_CAPTURE(f->type) && vdec->fixed_fmt) { 497 struct vpu_format *cap_fmt = vpu_get_format(inst, f->type); 498 499 if (!vpu_helper_match_format(inst, cap_fmt->type, cap_fmt->pixfmt, 500 f->fmt.pix_mp.pixelformat)) 501 f->fmt.pix_mp.pixelformat = cap_fmt->pixfmt; 502 } 503 504 vpu_try_fmt_common(inst, f, &fmt); 505 506 if (vdec->fixed_fmt) { 507 f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries; 508 f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars; 509 f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs; 510 f->fmt.pix_mp.quantization = vdec->codec_info.full_range; 511 } else { 512 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 513 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 514 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 515 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 516 } 517 vpu_inst_unlock(inst); 518 519 return 0; 520} 521 522static int vdec_s_fmt_common(struct vpu_inst *inst, struct v4l2_format *f) 523{ 524 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 525 struct vpu_format fmt; 526 struct vpu_format *cur_fmt; 527 struct vb2_queue *q; 528 struct vdec_t *vdec = inst->priv; 529 int i; 530 531 if (!inst->fh.m2m_ctx) 532 return -EINVAL; 533 534 q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type); 535 if (vb2_is_busy(q)) 536 return -EBUSY; 537 538 if (vpu_try_fmt_common(inst, f, &fmt)) 539 return -EINVAL; 540 541 cur_fmt = vpu_get_format(inst, f->type); 542 if (V4L2_TYPE_IS_OUTPUT(f->type) && inst->state != VPU_CODEC_STATE_DEINIT) { 543 if (cur_fmt->pixfmt != fmt.pixfmt) { 544 vdec->reset_codec = true; 545 vdec->fixed_fmt = false; 546 } 547 } 548 if (V4L2_TYPE_IS_OUTPUT(f->type) || !vdec->fixed_fmt) { 549 memcpy(cur_fmt, &fmt, sizeof(*cur_fmt)); 550 } else { 551 if (vpu_helper_match_format(inst, f->type, cur_fmt->pixfmt, pixmp->pixelformat)) { 552 cur_fmt->pixfmt = fmt.pixfmt; 553 cur_fmt->mem_planes = fmt.mem_planes; 554 } 555 pixmp->pixelformat = cur_fmt->pixfmt; 556 pixmp->num_planes = cur_fmt->mem_planes; 557 pixmp->width = cur_fmt->width; 558 pixmp->height = cur_fmt->height; 559 for (i = 0; i < pixmp->num_planes; i++) { 560 pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i]; 561 pixmp->plane_fmt[i].sizeimage = vpu_get_fmt_plane_size(cur_fmt, i); 562 } 563 pixmp->field = cur_fmt->field; 564 } 565 566 if (!vdec->fixed_fmt) { 567 if (V4L2_TYPE_IS_OUTPUT(f->type)) { 568 vdec->params.codec_format = cur_fmt->pixfmt; 569 vdec->codec_info.color_primaries = f->fmt.pix_mp.colorspace; 570 vdec->codec_info.transfer_chars = f->fmt.pix_mp.xfer_func; 571 vdec->codec_info.matrix_coeffs = f->fmt.pix_mp.ycbcr_enc; 572 vdec->codec_info.full_range = f->fmt.pix_mp.quantization; 573 } else { 574 vdec->params.output_format = cur_fmt->pixfmt; 575 inst->crop.left = 0; 576 inst->crop.top = 0; 577 inst->crop.width = cur_fmt->width; 578 inst->crop.height = cur_fmt->height; 579 } 580 } 581 582 vpu_trace(inst->dev, "[%d] %c%c%c%c %dx%d\n", inst->id, 583 f->fmt.pix_mp.pixelformat, 584 f->fmt.pix_mp.pixelformat >> 8, 585 f->fmt.pix_mp.pixelformat >> 16, 586 f->fmt.pix_mp.pixelformat >> 24, 587 f->fmt.pix_mp.width, 588 f->fmt.pix_mp.height); 589 590 return 0; 591} 592 593static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f) 594{ 595 struct vpu_inst *inst = to_inst(file); 596 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 597 struct vdec_t *vdec = inst->priv; 598 int ret = 0; 599 600 vpu_inst_lock(inst); 601 ret = vdec_s_fmt_common(inst, f); 602 if (ret) 603 goto exit; 604 605 if (V4L2_TYPE_IS_OUTPUT(f->type) && !vdec->fixed_fmt) { 606 struct v4l2_format fc; 607 608 memset(&fc, 0, sizeof(fc)); 609 fc.type = inst->cap_format.type; 610 fc.fmt.pix_mp.pixelformat = inst->cap_format.pixfmt; 611 fc.fmt.pix_mp.width = pixmp->width; 612 fc.fmt.pix_mp.height = pixmp->height; 613 vdec_s_fmt_common(inst, &fc); 614 } 615 616 f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries; 617 f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars; 618 f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs; 619 f->fmt.pix_mp.quantization = vdec->codec_info.full_range; 620 621exit: 622 vpu_inst_unlock(inst); 623 return ret; 624} 625 626static int vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 627{ 628 struct vpu_inst *inst = to_inst(file); 629 630 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 631 return -EINVAL; 632 633 switch (s->target) { 634 case V4L2_SEL_TGT_COMPOSE: 635 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 636 case V4L2_SEL_TGT_COMPOSE_PADDED: 637 s->r = inst->crop; 638 break; 639 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 640 s->r.left = 0; 641 s->r.top = 0; 642 s->r.width = inst->cap_format.width; 643 s->r.height = inst->cap_format.height; 644 break; 645 default: 646 return -EINVAL; 647 } 648 649 return 0; 650} 651 652static int vdec_drain(struct vpu_inst *inst) 653{ 654 struct vdec_t *vdec = inst->priv; 655 656 if (!inst->fh.m2m_ctx) 657 return 0; 658 659 if (!vdec->drain) 660 return 0; 661 662 if (!vpu_is_source_empty(inst)) 663 return 0; 664 665 if (!vdec->params.frame_count) { 666 vpu_set_last_buffer_dequeued(inst, true); 667 return 0; 668 } 669 670 vpu_iface_add_scode(inst, SCODE_PADDING_EOS); 671 vdec->params.end_flag = 1; 672 vpu_iface_set_decode_params(inst, &vdec->params, 1); 673 vdec->drain = 0; 674 vpu_trace(inst->dev, "[%d] frame_count = %d\n", inst->id, vdec->params.frame_count); 675 676 return 0; 677} 678 679static int vdec_cmd_start(struct vpu_inst *inst) 680{ 681 struct vdec_t *vdec = inst->priv; 682 683 switch (inst->state) { 684 case VPU_CODEC_STATE_STARTED: 685 case VPU_CODEC_STATE_DRAIN: 686 case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE: 687 vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0); 688 break; 689 default: 690 break; 691 } 692 vpu_process_capture_buffer(inst); 693 if (vdec->eos_received) 694 vdec_set_last_buffer_dequeued(inst); 695 return 0; 696} 697 698static int vdec_cmd_stop(struct vpu_inst *inst) 699{ 700 struct vdec_t *vdec = inst->priv; 701 702 vpu_trace(inst->dev, "[%d]\n", inst->id); 703 704 if (inst->state == VPU_CODEC_STATE_DEINIT) { 705 vpu_set_last_buffer_dequeued(inst, true); 706 } else { 707 vdec->drain = 1; 708 vdec_drain(inst); 709 } 710 711 return 0; 712} 713 714static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) 715{ 716 struct vpu_inst *inst = to_inst(file); 717 int ret; 718 719 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); 720 if (ret) 721 return ret; 722 723 vpu_inst_lock(inst); 724 switch (cmd->cmd) { 725 case V4L2_DEC_CMD_START: 726 vdec_cmd_start(inst); 727 vb2_clear_last_buffer_dequeued(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)); 728 break; 729 case V4L2_DEC_CMD_STOP: 730 vdec_cmd_stop(inst); 731 break; 732 default: 733 break; 734 } 735 vpu_inst_unlock(inst); 736 737 return 0; 738} 739 740static int vdec_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) 741{ 742 switch (sub->type) { 743 case V4L2_EVENT_EOS: 744 return v4l2_event_subscribe(fh, sub, 0, NULL); 745 case V4L2_EVENT_SOURCE_CHANGE: 746 return v4l2_src_change_event_subscribe(fh, sub); 747 case V4L2_EVENT_CTRL: 748 return v4l2_ctrl_subscribe_event(fh, sub); 749 default: 750 return -EINVAL; 751 } 752 753 return 0; 754} 755 756static const struct v4l2_ioctl_ops vdec_ioctl_ops = { 757 .vidioc_querycap = vdec_querycap, 758 .vidioc_enum_fmt_vid_cap = vdec_enum_fmt, 759 .vidioc_enum_fmt_vid_out = vdec_enum_fmt, 760 .vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt, 761 .vidioc_g_fmt_vid_out_mplane = vdec_g_fmt, 762 .vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt, 763 .vidioc_try_fmt_vid_out_mplane = vdec_try_fmt, 764 .vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt, 765 .vidioc_s_fmt_vid_out_mplane = vdec_s_fmt, 766 .vidioc_g_selection = vdec_g_selection, 767 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd, 768 .vidioc_decoder_cmd = vdec_decoder_cmd, 769 .vidioc_subscribe_event = vdec_subscribe_event, 770 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 771 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 772 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 773 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 774 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 775 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 776 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 777 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 778 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 779 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 780}; 781 782static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type) 783{ 784 struct vdec_t *vdec = inst->priv; 785 786 if (V4L2_TYPE_IS_OUTPUT(type)) 787 return true; 788 789 if (vdec->req_frame_count) 790 return true; 791 792 return false; 793} 794 795static struct vb2_v4l2_buffer *vdec_get_src_buffer(struct vpu_inst *inst, u32 count) 796{ 797 if (count > 1) 798 vpu_skip_frame(inst, count - 1); 799 800 return vpu_next_src_buf(inst); 801} 802 803static int vdec_frame_decoded(struct vpu_inst *inst, void *arg) 804{ 805 struct vdec_t *vdec = inst->priv; 806 struct vpu_dec_pic_info *info = arg; 807 struct vpu_vb2_buffer *vpu_buf; 808 struct vb2_v4l2_buffer *vbuf; 809 struct vb2_v4l2_buffer *src_buf; 810 int ret = 0; 811 812 if (!info || info->id >= vdec->slot_count) 813 return -EINVAL; 814 815 vpu_inst_lock(inst); 816 vpu_buf = vdec->slots[info->id].curr; 817 if (!vpu_buf) { 818 dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id); 819 ret = -EINVAL; 820 goto exit; 821 } 822 vbuf = &vpu_buf->m2m_buf.vb; 823 src_buf = vdec_get_src_buffer(inst, info->consumed_count); 824 if (src_buf) { 825 v4l2_m2m_buf_copy_metadata(src_buf, vbuf); 826 if (info->consumed_count) { 827 v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx); 828 vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE); 829 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); 830 } else { 831 vpu_set_buffer_state(src_buf, VPU_BUF_STATE_DECODED); 832 } 833 } 834 if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) 835 dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id); 836 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED); 837 vdec->slots[info->id].state = VPU_BUF_STATE_DECODED; 838 vdec->decoded_frame_count++; 839 if (vdec->params.display_delay_enable) { 840 struct vpu_format *cur_fmt; 841 842 cur_fmt = vpu_get_format(inst, inst->cap_format.type); 843 vdec->slots[info->id].state = VPU_BUF_STATE_READY; 844 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY); 845 for (int i = 0; i < vbuf->vb2_buf.num_planes; i++) 846 vb2_set_plane_payload(&vbuf->vb2_buf, 847 i, vpu_get_fmt_plane_size(cur_fmt, i)); 848 vbuf->field = cur_fmt->field; 849 vbuf->sequence = vdec->sequence++; 850 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp); 851 852 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 853 vdec->display_frame_count++; 854 } 855exit: 856 vpu_inst_unlock(inst); 857 858 return ret; 859} 860 861static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma) 862{ 863 struct vdec_t *vdec = inst->priv; 864 int i; 865 866 for (i = 0; i < vdec->slot_count; i++) { 867 if (!vdec->slots[i].curr) 868 continue; 869 if (luma == vdec->slots[i].addr) 870 return vdec->slots[i].curr; 871 } 872 873 return NULL; 874} 875 876static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame) 877{ 878 struct vdec_t *vdec = inst->priv; 879 struct vpu_format *cur_fmt; 880 struct vpu_vb2_buffer *vpu_buf; 881 struct vb2_v4l2_buffer *vbuf; 882 int i; 883 884 if (!frame) 885 return; 886 887 vpu_inst_lock(inst); 888 if (!vdec->params.display_delay_enable) 889 vdec->sequence++; 890 vpu_buf = vdec_find_buffer(inst, frame->luma); 891 vpu_inst_unlock(inst); 892 if (!vpu_buf) { 893 dev_err(inst->dev, "[%d] can't find buffer, id = %d, addr = 0x%x\n", 894 inst->id, frame->id, frame->luma); 895 return; 896 } 897 if (frame->skipped) { 898 dev_dbg(inst->dev, "[%d] frame skip\n", inst->id); 899 return; 900 } 901 902 cur_fmt = vpu_get_format(inst, inst->cap_format.type); 903 vbuf = &vpu_buf->m2m_buf.vb; 904 if (vpu_buf->fs_id != frame->id) 905 dev_err(inst->dev, "[%d] buffer id(%d(%d), %d) mismatch\n", 906 inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index, frame->id); 907 908 if (vdec->params.display_delay_enable) 909 return; 910 911 if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED) 912 dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id); 913 914 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY); 915 for (i = 0; i < vbuf->vb2_buf.num_planes; i++) 916 vb2_set_plane_payload(&vbuf->vb2_buf, i, vpu_get_fmt_plane_size(cur_fmt, i)); 917 vbuf->field = cur_fmt->field; 918 vbuf->sequence = vdec->sequence; 919 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp); 920 921 vpu_inst_lock(inst); 922 vdec->slots[vpu_buf->fs_id].state = VPU_BUF_STATE_READY; 923 vdec->display_frame_count++; 924 vpu_inst_unlock(inst); 925 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 926 dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n", 927 inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence); 928} 929 930static void vdec_stop_done(struct vpu_inst *inst) 931{ 932 struct vdec_t *vdec = inst->priv; 933 934 vpu_inst_lock(inst); 935 vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 0); 936 vdec->seq_hdr_found = 0; 937 vdec->req_frame_count = 0; 938 vdec->reset_codec = false; 939 vdec->fixed_fmt = false; 940 vdec->params.end_flag = 0; 941 vdec->drain = 0; 942 vdec->params.frame_count = 0; 943 vdec->decoded_frame_count = 0; 944 vdec->display_frame_count = 0; 945 vdec->sequence = 0; 946 vdec->eos_received = 0; 947 vdec->is_source_changed = false; 948 vdec->source_change = 0; 949 inst->total_input_count = 0; 950 vpu_inst_unlock(inst); 951} 952 953static bool vdec_check_source_change(struct vpu_inst *inst) 954{ 955 struct vdec_t *vdec = inst->priv; 956 const struct vpu_format *sibling; 957 958 if (!inst->fh.m2m_ctx) 959 return false; 960 961 if (vdec->reset_codec) 962 return false; 963 964 sibling = vpu_helper_find_sibling(inst, inst->cap_format.type, inst->cap_format.pixfmt); 965 if (sibling && vdec->codec_info.pixfmt == sibling->pixfmt) 966 vdec->codec_info.pixfmt = inst->cap_format.pixfmt; 967 968 if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx))) 969 return true; 970 if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt) 971 return true; 972 if (inst->cap_format.width != vdec->codec_info.decoded_width) 973 return true; 974 if (inst->cap_format.height != vdec->codec_info.decoded_height) 975 return true; 976 if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap) 977 return true; 978 if (inst->crop.left != vdec->codec_info.offset_x) 979 return true; 980 if (inst->crop.top != vdec->codec_info.offset_y) 981 return true; 982 if (inst->crop.width != vdec->codec_info.width) 983 return true; 984 if (inst->crop.height != vdec->codec_info.height) 985 return true; 986 987 return false; 988} 989 990static void vdec_init_fmt(struct vpu_inst *inst) 991{ 992 struct vdec_t *vdec = inst->priv; 993 struct v4l2_format f; 994 995 memset(&f, 0, sizeof(f)); 996 f.type = inst->cap_format.type; 997 f.fmt.pix_mp.pixelformat = vdec->codec_info.pixfmt; 998 f.fmt.pix_mp.width = vdec->codec_info.decoded_width; 999 f.fmt.pix_mp.height = vdec->codec_info.decoded_height; 1000 if (vdec->codec_info.progressive) 1001 f.fmt.pix_mp.field = V4L2_FIELD_NONE; 1002 else 1003 f.fmt.pix_mp.field = V4L2_FIELD_SEQ_TB; 1004 vpu_try_fmt_common(inst, &f, &inst->cap_format); 1005 1006 inst->out_format.width = vdec->codec_info.width; 1007 inst->out_format.height = vdec->codec_info.height; 1008} 1009 1010static void vdec_init_crop(struct vpu_inst *inst) 1011{ 1012 struct vdec_t *vdec = inst->priv; 1013 1014 inst->crop.left = vdec->codec_info.offset_x; 1015 inst->crop.top = vdec->codec_info.offset_y; 1016 inst->crop.width = vdec->codec_info.width; 1017 inst->crop.height = vdec->codec_info.height; 1018} 1019 1020static void vdec_init_mbi(struct vpu_inst *inst) 1021{ 1022 struct vdec_t *vdec = inst->priv; 1023 1024 vdec->mbi.size = vdec->codec_info.mbi_size; 1025 vdec->mbi.max_count = ARRAY_SIZE(vdec->mbi.buffer); 1026 scnprintf(vdec->mbi.name, sizeof(vdec->mbi.name), "mbi"); 1027 vdec->mbi.type = MEM_RES_MBI; 1028 vdec->mbi.tag = vdec->seq_tag; 1029} 1030 1031static void vdec_init_dcp(struct vpu_inst *inst) 1032{ 1033 struct vdec_t *vdec = inst->priv; 1034 1035 vdec->dcp.size = vdec->codec_info.dcp_size; 1036 vdec->dcp.max_count = ARRAY_SIZE(vdec->dcp.buffer); 1037 scnprintf(vdec->dcp.name, sizeof(vdec->dcp.name), "dcp"); 1038 vdec->dcp.type = MEM_RES_DCP; 1039 vdec->dcp.tag = vdec->seq_tag; 1040} 1041 1042static void vdec_request_one_fs(struct vdec_fs_info *fs) 1043{ 1044 fs->req_count++; 1045 if (fs->req_count > fs->max_count) 1046 fs->req_count = fs->max_count; 1047} 1048 1049static int vdec_alloc_fs_buffer(struct vpu_inst *inst, struct vdec_fs_info *fs) 1050{ 1051 struct vpu_buffer *buffer; 1052 1053 if (!fs->size) 1054 return -EINVAL; 1055 1056 if (fs->count >= fs->req_count) 1057 return -EINVAL; 1058 1059 buffer = &fs->buffer[fs->count]; 1060 if (buffer->virt && buffer->length >= fs->size) 1061 return 0; 1062 1063 vpu_free_dma(buffer); 1064 buffer->length = fs->size; 1065 return vpu_alloc_dma(inst->core, buffer); 1066} 1067 1068static void vdec_alloc_fs(struct vpu_inst *inst, struct vdec_fs_info *fs) 1069{ 1070 int ret; 1071 1072 while (fs->count < fs->req_count) { 1073 ret = vdec_alloc_fs_buffer(inst, fs); 1074 if (ret) 1075 break; 1076 fs->count++; 1077 } 1078} 1079 1080static void vdec_clear_fs(struct vdec_fs_info *fs) 1081{ 1082 u32 i; 1083 1084 if (!fs) 1085 return; 1086 1087 for (i = 0; i < ARRAY_SIZE(fs->buffer); i++) 1088 vpu_free_dma(&fs->buffer[i]); 1089 memset(fs, 0, sizeof(*fs)); 1090} 1091 1092static int vdec_response_fs(struct vpu_inst *inst, struct vdec_fs_info *fs) 1093{ 1094 struct vpu_fs_info info; 1095 int ret; 1096 1097 if (fs->index >= fs->count) 1098 return 0; 1099 1100 memset(&info, 0, sizeof(info)); 1101 info.id = fs->index; 1102 info.type = fs->type; 1103 info.tag = fs->tag; 1104 info.luma_addr = fs->buffer[fs->index].phys; 1105 info.luma_size = fs->buffer[fs->index].length; 1106 ret = vpu_session_alloc_fs(inst, &info); 1107 if (ret) 1108 return ret; 1109 1110 fs->index++; 1111 return 0; 1112} 1113 1114static int vdec_response_frame_abnormal(struct vpu_inst *inst) 1115{ 1116 struct vdec_t *vdec = inst->priv; 1117 struct vpu_fs_info info; 1118 int ret; 1119 1120 if (!vdec->req_frame_count) 1121 return 0; 1122 1123 memset(&info, 0, sizeof(info)); 1124 info.type = MEM_RES_FRAME; 1125 info.tag = vdec->seq_tag + 0xf0; 1126 ret = vpu_session_alloc_fs(inst, &info); 1127 if (ret) 1128 return ret; 1129 vdec->req_frame_count--; 1130 1131 return 0; 1132} 1133 1134static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf) 1135{ 1136 struct vdec_t *vdec = inst->priv; 1137 struct vpu_vb2_buffer *vpu_buf; 1138 struct vpu_fs_info info; 1139 int ret; 1140 1141 if (inst->state != VPU_CODEC_STATE_ACTIVE) 1142 return -EINVAL; 1143 1144 if (vdec->aborting) 1145 return -EINVAL; 1146 1147 if (!vdec->req_frame_count) 1148 return -EINVAL; 1149 1150 if (!vbuf) 1151 return -EINVAL; 1152 1153 vpu_buf = to_vpu_vb2_buffer(vbuf); 1154 if (vpu_buf->fs_id < 0 || vpu_buf->fs_id >= vdec->slot_count) { 1155 dev_err(inst->dev, "invalid fs %d for v4l2 buffer %d\n", 1156 vpu_buf->fs_id, vbuf->vb2_buf.index); 1157 return -EINVAL; 1158 } 1159 1160 if (vdec->slots[vpu_buf->fs_id].curr) { 1161 if (vdec->slots[vpu_buf->fs_id].curr != vpu_buf) { 1162 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_CHANGED); 1163 vdec->slots[vpu_buf->fs_id].pend = vpu_buf; 1164 } else { 1165 vpu_set_buffer_state(vbuf, vdec->slots[vpu_buf->fs_id].state); 1166 } 1167 dev_err(inst->dev, "[%d] repeat alloc fs %d (v4l2 index %d)\n", 1168 inst->id, vpu_buf->fs_id, vbuf->vb2_buf.index); 1169 return -EAGAIN; 1170 } 1171 1172 dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n", 1173 inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag); 1174 1175 memset(&info, 0, sizeof(info)); 1176 info.id = vpu_buf->fs_id; 1177 info.type = MEM_RES_FRAME; 1178 info.tag = vdec->seq_tag; 1179 info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0); 1180 info.luma_size = inst->cap_format.sizeimage[0]; 1181 if (vbuf->vb2_buf.num_planes > 1) 1182 info.chroma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 1); 1183 else 1184 info.chroma_addr = info.luma_addr + info.luma_size; 1185 info.chromau_size = inst->cap_format.sizeimage[1]; 1186 info.bytesperline = inst->cap_format.bytesperline[0]; 1187 ret = vpu_session_alloc_fs(inst, &info); 1188 if (ret) 1189 return ret; 1190 1191 vpu_buf->luma = info.luma_addr; 1192 vpu_buf->chroma_u = info.chroma_addr; 1193 vpu_buf->chroma_v = 0; 1194 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE); 1195 vdec->slots[info.id].tag = info.tag; 1196 vdec->slots[info.id].curr = vpu_buf; 1197 vdec->slots[info.id].state = VPU_BUF_STATE_INUSE; 1198 vdec->req_frame_count--; 1199 1200 return 0; 1201} 1202 1203static void vdec_response_fs_request(struct vpu_inst *inst, bool force) 1204{ 1205 struct vdec_t *vdec = inst->priv; 1206 int i; 1207 int ret; 1208 1209 if (force) { 1210 for (i = vdec->req_frame_count; i > 0; i--) 1211 vdec_response_frame_abnormal(inst); 1212 return; 1213 } 1214 1215 for (i = vdec->req_frame_count; i > 0; i--) { 1216 ret = vpu_process_capture_buffer(inst); 1217 if (ret) 1218 break; 1219 if (vdec->eos_received) 1220 break; 1221 } 1222 1223 for (i = vdec->mbi.index; i < vdec->mbi.count; i++) { 1224 if (vdec_response_fs(inst, &vdec->mbi)) 1225 break; 1226 if (vdec->eos_received) 1227 break; 1228 } 1229 for (i = vdec->dcp.index; i < vdec->dcp.count; i++) { 1230 if (vdec_response_fs(inst, &vdec->dcp)) 1231 break; 1232 if (vdec->eos_received) 1233 break; 1234 } 1235} 1236 1237static void vdec_response_fs_release(struct vpu_inst *inst, u32 id, u32 tag) 1238{ 1239 struct vpu_fs_info info; 1240 1241 memset(&info, 0, sizeof(info)); 1242 info.id = id; 1243 info.tag = tag; 1244 vpu_session_release_fs(inst, &info); 1245} 1246 1247static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf) 1248{ 1249 if (!inst->fh.m2m_ctx) 1250 return; 1251 if (vbuf->vb2_buf.state != VB2_BUF_STATE_ACTIVE) 1252 return; 1253 if (vpu_find_buf_by_idx(inst, vbuf->vb2_buf.type, vbuf->vb2_buf.index)) 1254 return; 1255 v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf); 1256} 1257 1258static void vdec_release_curr_frame_store(struct vpu_inst *inst, u32 id) 1259{ 1260 struct vdec_t *vdec = inst->priv; 1261 struct vpu_vb2_buffer *vpu_buf; 1262 struct vb2_v4l2_buffer *vbuf; 1263 1264 if (id >= vdec->slot_count) 1265 return; 1266 if (!vdec->slots[id].curr) 1267 return; 1268 1269 vpu_buf = vdec->slots[id].curr; 1270 vbuf = &vpu_buf->m2m_buf.vb; 1271 1272 vdec_response_fs_release(inst, id, vdec->slots[id].tag); 1273 if (vpu_buf->fs_id == id) { 1274 if (vpu_buf->state != VPU_BUF_STATE_READY) 1275 vdec_recycle_buffer(inst, vbuf); 1276 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE); 1277 } 1278 1279 vdec->slots[id].curr = NULL; 1280 vdec->slots[id].state = VPU_BUF_STATE_IDLE; 1281 1282 if (vdec->slots[id].pend) { 1283 vpu_set_buffer_state(&vdec->slots[id].pend->m2m_buf.vb, VPU_BUF_STATE_IDLE); 1284 vdec->slots[id].pend = NULL; 1285 } 1286} 1287 1288static void vdec_clear_slots(struct vpu_inst *inst) 1289{ 1290 struct vdec_t *vdec = inst->priv; 1291 int i; 1292 1293 for (i = 0; i < vdec->slot_count; i++) { 1294 if (!vdec->slots[i].curr) 1295 continue; 1296 1297 vpu_trace(inst->dev, "clear slot %d\n", i); 1298 vdec_release_curr_frame_store(inst, i); 1299 } 1300} 1301 1302static void vdec_update_v4l2_ctrl(struct vpu_inst *inst, u32 id, u32 val) 1303{ 1304 struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id); 1305 1306 if (ctrl) 1307 v4l2_ctrl_s_ctrl(ctrl, val); 1308} 1309 1310static void vdec_update_v4l2_profile_level(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr) 1311{ 1312 switch (inst->out_format.pixfmt) { 1313 case V4L2_PIX_FMT_H264: 1314 case V4L2_PIX_FMT_H264_MVC: 1315 vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE, 1316 vpu_get_h264_v4l2_profile(hdr)); 1317 vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LEVEL, 1318 vpu_get_h264_v4l2_level(hdr)); 1319 break; 1320 case V4L2_PIX_FMT_HEVC: 1321 vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, 1322 vpu_get_hevc_v4l2_profile(hdr)); 1323 vdec_update_v4l2_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, 1324 vpu_get_hevc_v4l2_level(hdr)); 1325 break; 1326 default: 1327 return; 1328 } 1329} 1330 1331static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr) 1332{ 1333 struct vdec_t *vdec = inst->priv; 1334 1335 vpu_inst_lock(inst); 1336 memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info)); 1337 1338 vpu_trace(inst->dev, "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d\n", 1339 inst->id, 1340 vdec->codec_info.decoded_width, 1341 vdec->codec_info.decoded_height, 1342 vdec->codec_info.offset_x, 1343 vdec->codec_info.offset_y, 1344 vdec->codec_info.width, 1345 vdec->codec_info.height, 1346 hdr->num_ref_frms, 1347 hdr->num_dpb_frms); 1348 inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms; 1349 vdec->is_source_changed = vdec_check_source_change(inst); 1350 vdec_init_fmt(inst); 1351 vdec_init_crop(inst); 1352 vdec_init_mbi(inst); 1353 vdec_init_dcp(inst); 1354 vdec_update_v4l2_profile_level(inst, hdr); 1355 if (!vdec->seq_hdr_found) { 1356 vdec->seq_tag = vdec->codec_info.tag; 1357 if (vdec->is_source_changed) { 1358 vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0); 1359 vdec->source_change++; 1360 vdec_handle_resolution_change(inst); 1361 vdec->is_source_changed = false; 1362 } 1363 } 1364 if (vdec->seq_tag != vdec->codec_info.tag) { 1365 vdec_response_fs_request(inst, true); 1366 vpu_trace(inst->dev, "[%d] seq tag change: %d -> %d\n", 1367 inst->id, vdec->seq_tag, vdec->codec_info.tag); 1368 } 1369 vdec->seq_hdr_found++; 1370 vdec->fixed_fmt = true; 1371 vpu_inst_unlock(inst); 1372} 1373 1374static void vdec_event_resolution_change(struct vpu_inst *inst) 1375{ 1376 struct vdec_t *vdec = inst->priv; 1377 1378 vpu_trace(inst->dev, "[%d]\n", inst->id); 1379 vpu_inst_lock(inst); 1380 vdec->seq_tag = vdec->codec_info.tag; 1381 vdec_clear_fs(&vdec->mbi); 1382 vdec_clear_fs(&vdec->dcp); 1383 vdec_clear_slots(inst); 1384 vdec_init_mbi(inst); 1385 vdec_init_dcp(inst); 1386 if (vdec->is_source_changed) { 1387 vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0); 1388 vdec->source_change++; 1389 vdec_handle_resolution_change(inst); 1390 vdec->is_source_changed = false; 1391 } 1392 vpu_inst_unlock(inst); 1393} 1394 1395static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs) 1396{ 1397 struct vdec_t *vdec = inst->priv; 1398 1399 if (!fs) 1400 return; 1401 1402 vpu_inst_lock(inst); 1403 1404 switch (fs->type) { 1405 case MEM_RES_FRAME: 1406 vdec->req_frame_count++; 1407 break; 1408 case MEM_RES_MBI: 1409 vdec_request_one_fs(&vdec->mbi); 1410 break; 1411 case MEM_RES_DCP: 1412 vdec_request_one_fs(&vdec->dcp); 1413 break; 1414 default: 1415 break; 1416 } 1417 1418 vdec_alloc_fs(inst, &vdec->mbi); 1419 vdec_alloc_fs(inst, &vdec->dcp); 1420 1421 vdec_response_fs_request(inst, false); 1422 1423 vpu_inst_unlock(inst); 1424} 1425 1426static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs) 1427{ 1428 struct vdec_t *vdec = inst->priv; 1429 1430 if (!fs || fs->id >= vdec->slot_count) 1431 return; 1432 if (fs->type != MEM_RES_FRAME) 1433 return; 1434 1435 if (fs->id >= vdec->slot_count) { 1436 dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id); 1437 return; 1438 } 1439 1440 vpu_inst_lock(inst); 1441 if (!vdec->slots[fs->id].curr) { 1442 dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id); 1443 goto exit; 1444 } 1445 1446 if (vdec->slots[fs->id].state == VPU_BUF_STATE_DECODED) { 1447 dev_dbg(inst->dev, "[%d] frame skip\n", inst->id); 1448 vdec->sequence++; 1449 } 1450 1451 vdec_release_curr_frame_store(inst, fs->id); 1452 vpu_process_capture_buffer(inst); 1453 1454exit: 1455 vpu_inst_unlock(inst); 1456} 1457 1458static void vdec_event_eos(struct vpu_inst *inst) 1459{ 1460 struct vdec_t *vdec = inst->priv; 1461 1462 vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n", 1463 inst->id, 1464 vdec->params.frame_count, 1465 vdec->decoded_frame_count, 1466 vdec->display_frame_count, 1467 vdec->sequence); 1468 vpu_inst_lock(inst); 1469 vdec->eos_received++; 1470 vdec->fixed_fmt = false; 1471 inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP; 1472 vdec_set_last_buffer_dequeued(inst); 1473 vpu_inst_unlock(inst); 1474} 1475 1476static void vdec_event_notify(struct vpu_inst *inst, u32 event, void *data) 1477{ 1478 switch (event) { 1479 case VPU_MSG_ID_SEQ_HDR_FOUND: 1480 vdec_event_seq_hdr(inst, data); 1481 break; 1482 case VPU_MSG_ID_RES_CHANGE: 1483 vdec_event_resolution_change(inst); 1484 break; 1485 case VPU_MSG_ID_FRAME_REQ: 1486 vdec_event_req_fs(inst, data); 1487 break; 1488 case VPU_MSG_ID_FRAME_RELEASE: 1489 vdec_evnet_rel_fs(inst, data); 1490 break; 1491 case VPU_MSG_ID_PIC_EOS: 1492 vdec_event_eos(inst); 1493 break; 1494 default: 1495 break; 1496 } 1497} 1498 1499static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb) 1500{ 1501 struct vdec_t *vdec = inst->priv; 1502 struct vb2_v4l2_buffer *vbuf; 1503 struct vpu_rpc_buffer_desc desc; 1504 u32 free_space; 1505 int ret; 1506 1507 vbuf = to_vb2_v4l2_buffer(vb); 1508 dev_dbg(inst->dev, "[%d] dec output [%d] %d : %ld\n", 1509 inst->id, vbuf->sequence, vb->index, vb2_get_plane_payload(vb, 0)); 1510 1511 if (inst->state == VPU_CODEC_STATE_DEINIT) 1512 return -EINVAL; 1513 if (vdec->reset_codec) 1514 return -EINVAL; 1515 1516 if (inst->state == VPU_CODEC_STATE_STARTED) 1517 vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0); 1518 1519 ret = vpu_iface_get_stream_buffer_desc(inst, &desc); 1520 if (ret) 1521 return ret; 1522 1523 free_space = vpu_helper_get_free_space(inst); 1524 if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000) 1525 return -ENOMEM; 1526 1527 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE); 1528 ret = vpu_iface_input_frame(inst, vb); 1529 if (ret < 0) 1530 return -ENOMEM; 1531 1532 dev_dbg(inst->dev, "[%d][INPUT TS]%32lld\n", inst->id, vb->timestamp); 1533 vdec->params.frame_count++; 1534 1535 if (vdec->drain) 1536 vdec_drain(inst); 1537 1538 return 0; 1539} 1540 1541static int vdec_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb) 1542{ 1543 struct vdec_t *vdec = inst->priv; 1544 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1545 int ret; 1546 1547 if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) 1548 return -EINVAL; 1549 if (vdec->reset_codec) 1550 return -EINVAL; 1551 1552 ret = vdec_response_frame(inst, vbuf); 1553 if (ret) 1554 return ret; 1555 v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf); 1556 return 0; 1557} 1558 1559static void vdec_on_queue_empty(struct vpu_inst *inst, u32 type) 1560{ 1561 struct vdec_t *vdec = inst->priv; 1562 1563 if (V4L2_TYPE_IS_OUTPUT(type)) 1564 return; 1565 1566 vdec_handle_resolution_change(inst); 1567 if (vdec->eos_received) 1568 vdec_set_last_buffer_dequeued(inst); 1569} 1570 1571static void vdec_abort(struct vpu_inst *inst) 1572{ 1573 struct vdec_t *vdec = inst->priv; 1574 struct vpu_rpc_buffer_desc desc; 1575 int ret; 1576 1577 vpu_trace(inst->dev, "[%d] state = %s\n", inst->id, vpu_codec_state_name(inst->state)); 1578 1579 vdec->aborting = true; 1580 vpu_iface_add_scode(inst, SCODE_PADDING_ABORT); 1581 vdec->params.end_flag = 1; 1582 vpu_iface_set_decode_params(inst, &vdec->params, 1); 1583 1584 vpu_session_abort(inst); 1585 1586 ret = vpu_iface_get_stream_buffer_desc(inst, &desc); 1587 if (!ret) 1588 vpu_iface_update_stream_buffer(inst, desc.rptr, 1); 1589 1590 vpu_session_rst_buf(inst); 1591 vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n", 1592 inst->id, 1593 vdec->params.frame_count, 1594 vdec->decoded_frame_count, 1595 vdec->display_frame_count, 1596 vdec->sequence); 1597 if (!vdec->seq_hdr_found) 1598 vdec->reset_codec = true; 1599 vdec->params.end_flag = 0; 1600 vdec->drain = 0; 1601 vdec->params.frame_count = 0; 1602 vdec->decoded_frame_count = 0; 1603 vdec->display_frame_count = 0; 1604 vdec->sequence = 0; 1605 vdec->aborting = false; 1606 inst->extra_size = 0; 1607} 1608 1609static void vdec_stop(struct vpu_inst *inst, bool free) 1610{ 1611 struct vdec_t *vdec = inst->priv; 1612 1613 vdec_clear_slots(inst); 1614 if (inst->state != VPU_CODEC_STATE_DEINIT) 1615 vpu_session_stop(inst); 1616 vdec_clear_fs(&vdec->mbi); 1617 vdec_clear_fs(&vdec->dcp); 1618 if (free) { 1619 vpu_free_dma(&vdec->udata); 1620 vpu_free_dma(&inst->stream_buffer); 1621 } 1622 vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 1); 1623 vdec->reset_codec = false; 1624} 1625 1626static void vdec_release(struct vpu_inst *inst) 1627{ 1628 if (inst->id != VPU_INST_NULL_ID) 1629 vpu_trace(inst->dev, "[%d]\n", inst->id); 1630 vdec_stop(inst, true); 1631} 1632 1633static void vdec_cleanup(struct vpu_inst *inst) 1634{ 1635 struct vdec_t *vdec; 1636 1637 if (!inst) 1638 return; 1639 1640 vdec = inst->priv; 1641 if (vdec) { 1642 kfree(vdec->slots); 1643 vdec->slots = NULL; 1644 vdec->slot_count = 0; 1645 } 1646 vfree(vdec); 1647 inst->priv = NULL; 1648 vfree(inst); 1649} 1650 1651static void vdec_init_params(struct vdec_t *vdec) 1652{ 1653 vdec->params.frame_count = 0; 1654 vdec->params.end_flag = 0; 1655} 1656 1657static int vdec_start(struct vpu_inst *inst) 1658{ 1659 struct vdec_t *vdec = inst->priv; 1660 int stream_buffer_size; 1661 int ret; 1662 1663 if (inst->state != VPU_CODEC_STATE_DEINIT) 1664 return 0; 1665 1666 vpu_trace(inst->dev, "[%d]\n", inst->id); 1667 if (!vdec->udata.virt) { 1668 vdec->udata.length = 0x1000; 1669 ret = vpu_alloc_dma(inst->core, &vdec->udata); 1670 if (ret) { 1671 dev_err(inst->dev, "[%d] alloc udata fail\n", inst->id); 1672 goto error; 1673 } 1674 } 1675 1676 if (!inst->stream_buffer.virt) { 1677 stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core); 1678 if (stream_buffer_size > 0) { 1679 inst->stream_buffer.length = stream_buffer_size; 1680 ret = vpu_alloc_dma(inst->core, &inst->stream_buffer); 1681 if (ret) { 1682 dev_err(inst->dev, "[%d] alloc stream buffer fail\n", inst->id); 1683 goto error; 1684 } 1685 inst->use_stream_buffer = true; 1686 } 1687 } 1688 1689 if (inst->use_stream_buffer) 1690 vpu_iface_config_stream_buffer(inst, &inst->stream_buffer); 1691 vpu_iface_init_instance(inst); 1692 vdec->params.udata.base = vdec->udata.phys; 1693 vdec->params.udata.size = vdec->udata.length; 1694 ret = vpu_iface_set_decode_params(inst, &vdec->params, 0); 1695 if (ret) { 1696 dev_err(inst->dev, "[%d] set decode params fail\n", inst->id); 1697 goto error; 1698 } 1699 1700 vdec_init_params(vdec); 1701 ret = vpu_session_start(inst); 1702 if (ret) { 1703 dev_err(inst->dev, "[%d] start fail\n", inst->id); 1704 goto error; 1705 } 1706 1707 vdec_update_state(inst, VPU_CODEC_STATE_STARTED, 0); 1708 1709 return 0; 1710error: 1711 vpu_free_dma(&vdec->udata); 1712 vpu_free_dma(&inst->stream_buffer); 1713 return ret; 1714} 1715 1716static int vdec_start_session(struct vpu_inst *inst, u32 type) 1717{ 1718 struct vdec_t *vdec = inst->priv; 1719 int ret = 0; 1720 1721 if (V4L2_TYPE_IS_OUTPUT(type)) { 1722 if (vdec->reset_codec) 1723 vdec_stop(inst, false); 1724 if (inst->state == VPU_CODEC_STATE_DEINIT) { 1725 ret = vdec_start(inst); 1726 if (ret) 1727 return ret; 1728 } 1729 } 1730 1731 if (V4L2_TYPE_IS_OUTPUT(type)) { 1732 vdec_update_state(inst, vdec->state, 1); 1733 vdec->eos_received = 0; 1734 vpu_process_output_buffer(inst); 1735 } else { 1736 vdec_cmd_start(inst); 1737 } 1738 if (inst->state == VPU_CODEC_STATE_ACTIVE) 1739 vdec_response_fs_request(inst, false); 1740 1741 return ret; 1742} 1743 1744static int vdec_stop_session(struct vpu_inst *inst, u32 type) 1745{ 1746 struct vdec_t *vdec = inst->priv; 1747 1748 if (inst->state == VPU_CODEC_STATE_DEINIT) 1749 return 0; 1750 1751 if (V4L2_TYPE_IS_OUTPUT(type)) { 1752 vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0); 1753 vdec->drain = 0; 1754 vdec_abort(inst); 1755 } else { 1756 if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) { 1757 if (vb2_is_streaming(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx))) 1758 vdec_abort(inst); 1759 vdec->eos_received = 0; 1760 } 1761 vdec_clear_slots(inst); 1762 } 1763 1764 return 0; 1765} 1766 1767static int vdec_get_slot_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i) 1768{ 1769 struct vdec_t *vdec = inst->priv; 1770 struct vpu_vb2_buffer *vpu_buf; 1771 int num = -1; 1772 1773 vpu_inst_lock(inst); 1774 if (i >= vdec->slot_count || !vdec->slots[i].addr) 1775 goto exit; 1776 1777 vpu_buf = vdec->slots[i].curr; 1778 1779 num = scnprintf(str, size, "slot[%2d] :", i); 1780 if (vpu_buf) { 1781 num += scnprintf(str + num, size - num, " %2d", 1782 vpu_buf->m2m_buf.vb.vb2_buf.index); 1783 num += scnprintf(str + num, size - num, "; state = %d", vdec->slots[i].state); 1784 } else { 1785 num += scnprintf(str + num, size - num, " -1"); 1786 } 1787 1788 if (vdec->slots[i].pend) 1789 num += scnprintf(str + num, size - num, "; %d", 1790 vdec->slots[i].pend->m2m_buf.vb.vb2_buf.index); 1791 1792 num += scnprintf(str + num, size - num, "\n"); 1793exit: 1794 vpu_inst_unlock(inst); 1795 1796 return num; 1797} 1798 1799static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i) 1800{ 1801 struct vdec_t *vdec = inst->priv; 1802 int num; 1803 1804 switch (i) { 1805 case 0: 1806 num = scnprintf(str, size, 1807 "req_frame_count = %d\ninterlaced = %d\n", 1808 vdec->req_frame_count, 1809 vdec->codec_info.progressive ? 0 : 1); 1810 break; 1811 case 1: 1812 num = scnprintf(str, size, 1813 "mbi: size = 0x%x request = %d, alloc = %d, response = %d\n", 1814 vdec->mbi.size, 1815 vdec->mbi.req_count, 1816 vdec->mbi.count, 1817 vdec->mbi.index); 1818 break; 1819 case 2: 1820 num = scnprintf(str, size, 1821 "dcp: size = 0x%x request = %d, alloc = %d, response = %d\n", 1822 vdec->dcp.size, 1823 vdec->dcp.req_count, 1824 vdec->dcp.count, 1825 vdec->dcp.index); 1826 break; 1827 case 3: 1828 num = scnprintf(str, size, "input_frame_count = %d\n", vdec->params.frame_count); 1829 break; 1830 case 4: 1831 num = scnprintf(str, size, "decoded_frame_count = %d\n", vdec->decoded_frame_count); 1832 break; 1833 case 5: 1834 num = scnprintf(str, size, "display_frame_count = %d\n", vdec->display_frame_count); 1835 break; 1836 case 6: 1837 num = scnprintf(str, size, "sequence = %d\n", vdec->sequence); 1838 break; 1839 case 7: 1840 num = scnprintf(str, size, "drain = %d, eos = %d, source_change = %d\n", 1841 vdec->drain, vdec->eos_received, vdec->source_change); 1842 break; 1843 case 8: 1844 num = scnprintf(str, size, "fps = %d/%d\n", 1845 vdec->codec_info.frame_rate.numerator, 1846 vdec->codec_info.frame_rate.denominator); 1847 break; 1848 case 9: 1849 num = scnprintf(str, size, "colorspace: %d, %d, %d, %d (%d)\n", 1850 vdec->codec_info.color_primaries, 1851 vdec->codec_info.transfer_chars, 1852 vdec->codec_info.matrix_coeffs, 1853 vdec->codec_info.full_range, 1854 vdec->codec_info.vui_present); 1855 break; 1856 default: 1857 num = vdec_get_slot_debug_info(inst, str, size, i - 10); 1858 break; 1859 } 1860 1861 return num; 1862} 1863 1864static struct vpu_inst_ops vdec_inst_ops = { 1865 .ctrl_init = vdec_ctrl_init, 1866 .check_ready = vdec_check_ready, 1867 .buf_done = vdec_buf_done, 1868 .get_one_frame = vdec_frame_decoded, 1869 .stop_done = vdec_stop_done, 1870 .event_notify = vdec_event_notify, 1871 .release = vdec_release, 1872 .cleanup = vdec_cleanup, 1873 .start = vdec_start_session, 1874 .stop = vdec_stop_session, 1875 .process_output = vdec_process_output, 1876 .process_capture = vdec_process_capture, 1877 .on_queue_empty = vdec_on_queue_empty, 1878 .get_debug_info = vdec_get_debug_info, 1879 .wait_prepare = vpu_inst_unlock, 1880 .wait_finish = vpu_inst_lock, 1881 .attach_frame_store = vdec_attach_frame_store, 1882 .reset_frame_store = vdec_reset_frame_store, 1883}; 1884 1885static void vdec_init(struct file *file) 1886{ 1887 struct vpu_inst *inst = to_inst(file); 1888 struct v4l2_format f; 1889 1890 memset(&f, 0, sizeof(f)); 1891 f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1892 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; 1893 f.fmt.pix_mp.width = 1280; 1894 f.fmt.pix_mp.height = 720; 1895 f.fmt.pix_mp.field = V4L2_FIELD_NONE; 1896 vdec_s_fmt(file, &inst->fh, &f); 1897 1898 memset(&f, 0, sizeof(f)); 1899 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1900 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M_8L128; 1901 f.fmt.pix_mp.width = 1280; 1902 f.fmt.pix_mp.height = 720; 1903 f.fmt.pix_mp.field = V4L2_FIELD_NONE; 1904 vdec_s_fmt(file, &inst->fh, &f); 1905} 1906 1907static int vdec_open(struct file *file) 1908{ 1909 struct vpu_inst *inst; 1910 struct vdec_t *vdec; 1911 int ret; 1912 1913 inst = vzalloc(sizeof(*inst)); 1914 if (!inst) 1915 return -ENOMEM; 1916 1917 vdec = vzalloc(sizeof(*vdec)); 1918 if (!vdec) { 1919 vfree(inst); 1920 return -ENOMEM; 1921 } 1922 1923 vdec->slots = kmalloc_array(VDEC_SLOT_CNT_DFT, 1924 sizeof(*vdec->slots), 1925 GFP_KERNEL | __GFP_ZERO); 1926 if (!vdec->slots) { 1927 vfree(vdec); 1928 vfree(inst); 1929 return -ENOMEM; 1930 } 1931 vdec->slot_count = VDEC_SLOT_CNT_DFT; 1932 1933 inst->ops = &vdec_inst_ops; 1934 inst->formats = vdec_formats; 1935 inst->type = VPU_CORE_TYPE_DEC; 1936 inst->priv = vdec; 1937 1938 ret = vpu_v4l2_open(file, inst); 1939 if (ret) 1940 return ret; 1941 1942 vdec->fixed_fmt = false; 1943 vdec->state = VPU_CODEC_STATE_ACTIVE; 1944 inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP; 1945 inst->min_buffer_out = VDEC_MIN_BUFFER_OUT; 1946 vdec_init(file); 1947 1948 return 0; 1949} 1950 1951static const struct v4l2_file_operations vdec_fops = { 1952 .owner = THIS_MODULE, 1953 .open = vdec_open, 1954 .release = vpu_v4l2_close, 1955 .unlocked_ioctl = video_ioctl2, 1956 .poll = v4l2_m2m_fop_poll, 1957 .mmap = v4l2_m2m_fop_mmap, 1958}; 1959 1960const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void) 1961{ 1962 return &vdec_ioctl_ops; 1963} 1964 1965const struct v4l2_file_operations *vdec_get_fops(void) 1966{ 1967 return &vdec_fops; 1968}
~/
Read-only file preview.