venc.c (36302B)
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/delay.h> 13#include <linux/videodev2.h> 14#include <linux/ktime.h> 15#include <linux/rational.h> 16#include <linux/vmalloc.h> 17#include <media/v4l2-device.h> 18#include <media/v4l2-event.h> 19#include <media/v4l2-mem2mem.h> 20#include <media/v4l2-ioctl.h> 21#include <media/videobuf2-v4l2.h> 22#include <media/videobuf2-dma-contig.h> 23#include <media/videobuf2-vmalloc.h> 24#include "vpu.h" 25#include "vpu_defs.h" 26#include "vpu_core.h" 27#include "vpu_helpers.h" 28#include "vpu_v4l2.h" 29#include "vpu_cmds.h" 30#include "vpu_rpc.h" 31 32#define VENC_OUTPUT_ENABLE BIT(0) 33#define VENC_CAPTURE_ENABLE BIT(1) 34#define VENC_ENABLE_MASK (VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE) 35#define VENC_MAX_BUF_CNT 8 36#define VENC_MIN_BUFFER_OUT 6 37#define VENC_MIN_BUFFER_CAP 6 38 39struct venc_t { 40 struct vpu_encode_params params; 41 u32 request_key_frame; 42 u32 input_ready; 43 u32 cpb_size; 44 bool bitrate_change; 45 46 struct vpu_buffer enc[VENC_MAX_BUF_CNT]; 47 struct vpu_buffer ref[VENC_MAX_BUF_CNT]; 48 struct vpu_buffer act[VENC_MAX_BUF_CNT]; 49 struct list_head frames; 50 u32 frame_count; 51 u32 encode_count; 52 u32 ready_count; 53 u32 enable; 54 u32 stopped; 55 56 u32 skipped_count; 57 u32 skipped_bytes; 58 59 wait_queue_head_t wq; 60}; 61 62struct venc_frame_t { 63 struct list_head list; 64 struct vpu_enc_pic_info info; 65 u32 bytesused; 66 s64 timestamp; 67}; 68 69static const struct vpu_format venc_formats[] = { 70 { 71 .pixfmt = V4L2_PIX_FMT_NV12M, 72 .num_planes = 2, 73 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 74 }, 75 { 76 .pixfmt = V4L2_PIX_FMT_H264, 77 .num_planes = 1, 78 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 79 }, 80 {0, 0, 0, 0}, 81}; 82 83static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 84{ 85 strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver)); 86 strscpy(cap->card, "amphion vpu encoder", sizeof(cap->card)); 87 strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info)); 88 89 return 0; 90} 91 92static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) 93{ 94 struct vpu_inst *inst = to_inst(file); 95 const struct vpu_format *fmt; 96 97 memset(f->reserved, 0, sizeof(f->reserved)); 98 fmt = vpu_helper_enum_format(inst, f->type, f->index); 99 if (!fmt) 100 return -EINVAL; 101 102 f->pixelformat = fmt->pixfmt; 103 f->flags = fmt->flags; 104 105 return 0; 106} 107 108static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) 109{ 110 struct vpu_inst *inst = to_inst(file); 111 const struct vpu_core_resources *res; 112 113 if (!fsize || fsize->index) 114 return -EINVAL; 115 116 if (!vpu_helper_find_format(inst, 0, fsize->pixel_format)) 117 return -EINVAL; 118 119 res = vpu_get_resource(inst); 120 if (!res) 121 return -EINVAL; 122 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 123 fsize->stepwise.max_width = res->max_width; 124 fsize->stepwise.max_height = res->max_height; 125 fsize->stepwise.min_width = res->min_width; 126 fsize->stepwise.min_height = res->min_height; 127 fsize->stepwise.step_width = res->step_width; 128 fsize->stepwise.step_height = res->step_height; 129 130 return 0; 131} 132 133static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival) 134{ 135 struct vpu_inst *inst = to_inst(file); 136 const struct vpu_core_resources *res; 137 138 if (!fival || fival->index) 139 return -EINVAL; 140 141 if (!vpu_helper_find_format(inst, 0, fival->pixel_format)) 142 return -EINVAL; 143 144 if (!fival->width || !fival->height) 145 return -EINVAL; 146 147 res = vpu_get_resource(inst); 148 if (!res) 149 return -EINVAL; 150 if (fival->width < res->min_width || fival->width > res->max_width || 151 fival->height < res->min_height || fival->height > res->max_height) 152 return -EINVAL; 153 154 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; 155 fival->stepwise.min.numerator = 1; 156 fival->stepwise.min.denominator = USHRT_MAX; 157 fival->stepwise.max.numerator = USHRT_MAX; 158 fival->stepwise.max.denominator = 1; 159 fival->stepwise.step.numerator = 1; 160 fival->stepwise.step.denominator = 1; 161 162 return 0; 163} 164 165static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f) 166{ 167 struct vpu_inst *inst = to_inst(file); 168 struct venc_t *venc = inst->priv; 169 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 170 struct vpu_format *cur_fmt; 171 int i; 172 173 cur_fmt = vpu_get_format(inst, f->type); 174 175 pixmp->pixelformat = cur_fmt->pixfmt; 176 pixmp->num_planes = cur_fmt->num_planes; 177 pixmp->width = cur_fmt->width; 178 pixmp->height = cur_fmt->height; 179 pixmp->field = cur_fmt->field; 180 pixmp->flags = cur_fmt->flags; 181 for (i = 0; i < pixmp->num_planes; i++) { 182 pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i]; 183 pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i]; 184 } 185 186 f->fmt.pix_mp.colorspace = venc->params.color.primaries; 187 f->fmt.pix_mp.xfer_func = venc->params.color.transfer; 188 f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix; 189 f->fmt.pix_mp.quantization = venc->params.color.full_range; 190 191 return 0; 192} 193 194static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f) 195{ 196 struct vpu_inst *inst = to_inst(file); 197 198 vpu_try_fmt_common(inst, f); 199 200 return 0; 201} 202 203static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) 204{ 205 struct vpu_inst *inst = to_inst(file); 206 const struct vpu_format *fmt; 207 struct vpu_format *cur_fmt; 208 struct vb2_queue *q; 209 struct venc_t *venc = inst->priv; 210 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; 211 int i; 212 213 q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type); 214 if (!q) 215 return -EINVAL; 216 if (vb2_is_busy(q)) 217 return -EBUSY; 218 219 fmt = vpu_try_fmt_common(inst, f); 220 if (!fmt) 221 return -EINVAL; 222 223 cur_fmt = vpu_get_format(inst, f->type); 224 225 cur_fmt->pixfmt = fmt->pixfmt; 226 cur_fmt->num_planes = fmt->num_planes; 227 cur_fmt->flags = fmt->flags; 228 cur_fmt->width = pix_mp->width; 229 cur_fmt->height = pix_mp->height; 230 for (i = 0; i < fmt->num_planes; i++) { 231 cur_fmt->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage; 232 cur_fmt->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline; 233 } 234 235 if (pix_mp->field != V4L2_FIELD_ANY) 236 cur_fmt->field = pix_mp->field; 237 238 if (V4L2_TYPE_IS_OUTPUT(f->type)) { 239 venc->params.input_format = cur_fmt->pixfmt; 240 venc->params.src_stride = cur_fmt->bytesperline[0]; 241 venc->params.src_width = cur_fmt->width; 242 venc->params.src_height = cur_fmt->height; 243 venc->params.crop.left = 0; 244 venc->params.crop.top = 0; 245 venc->params.crop.width = cur_fmt->width; 246 venc->params.crop.height = cur_fmt->height; 247 } else { 248 venc->params.codec_format = cur_fmt->pixfmt; 249 venc->params.out_width = cur_fmt->width; 250 venc->params.out_height = cur_fmt->height; 251 } 252 253 if (V4L2_TYPE_IS_OUTPUT(f->type)) { 254 if (!vpu_color_check_primaries(pix_mp->colorspace)) { 255 venc->params.color.primaries = pix_mp->colorspace; 256 vpu_color_get_default(venc->params.color.primaries, 257 &venc->params.color.transfer, 258 &venc->params.color.matrix, 259 &venc->params.color.full_range); 260 } 261 if (!vpu_color_check_transfers(pix_mp->xfer_func)) 262 venc->params.color.transfer = pix_mp->xfer_func; 263 if (!vpu_color_check_matrix(pix_mp->ycbcr_enc)) 264 venc->params.color.matrix = pix_mp->ycbcr_enc; 265 if (!vpu_color_check_full_range(pix_mp->quantization)) 266 venc->params.color.full_range = pix_mp->quantization; 267 } 268 269 pix_mp->colorspace = venc->params.color.primaries; 270 pix_mp->xfer_func = venc->params.color.transfer; 271 pix_mp->ycbcr_enc = venc->params.color.matrix; 272 pix_mp->quantization = venc->params.color.full_range; 273 274 return 0; 275} 276 277static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm) 278{ 279 struct vpu_inst *inst = to_inst(file); 280 struct venc_t *venc = inst->priv; 281 struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; 282 283 if (!parm) 284 return -EINVAL; 285 286 if (!V4L2_TYPE_IS_OUTPUT(parm->type)) 287 return -EINVAL; 288 289 if (!vpu_helper_check_type(inst, parm->type)) 290 return -EINVAL; 291 292 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 293 parm->parm.capture.readbuffers = 0; 294 timeperframe->numerator = venc->params.frame_rate.numerator; 295 timeperframe->denominator = venc->params.frame_rate.denominator; 296 297 return 0; 298} 299 300static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm) 301{ 302 struct vpu_inst *inst = to_inst(file); 303 struct venc_t *venc = inst->priv; 304 struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; 305 unsigned long n, d; 306 307 if (!parm) 308 return -EINVAL; 309 310 if (!V4L2_TYPE_IS_OUTPUT(parm->type)) 311 return -EINVAL; 312 313 if (!vpu_helper_check_type(inst, parm->type)) 314 return -EINVAL; 315 316 if (!timeperframe->numerator) 317 timeperframe->numerator = venc->params.frame_rate.numerator; 318 if (!timeperframe->denominator) 319 timeperframe->denominator = venc->params.frame_rate.denominator; 320 321 venc->params.frame_rate.numerator = timeperframe->numerator; 322 venc->params.frame_rate.denominator = timeperframe->denominator; 323 324 rational_best_approximation(venc->params.frame_rate.numerator, 325 venc->params.frame_rate.denominator, 326 venc->params.frame_rate.numerator, 327 venc->params.frame_rate.denominator, 328 &n, &d); 329 venc->params.frame_rate.numerator = n; 330 venc->params.frame_rate.denominator = d; 331 332 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 333 memset(parm->parm.capture.reserved, 0, sizeof(parm->parm.capture.reserved)); 334 335 return 0; 336} 337 338static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 339{ 340 struct vpu_inst *inst = to_inst(file); 341 struct venc_t *venc = inst->priv; 342 343 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 344 return -EINVAL; 345 346 switch (s->target) { 347 case V4L2_SEL_TGT_CROP_DEFAULT: 348 case V4L2_SEL_TGT_CROP_BOUNDS: 349 s->r.left = 0; 350 s->r.top = 0; 351 s->r.width = inst->out_format.width; 352 s->r.height = inst->out_format.height; 353 break; 354 case V4L2_SEL_TGT_CROP: 355 s->r = venc->params.crop; 356 break; 357 default: 358 return -EINVAL; 359 } 360 361 return 0; 362} 363 364static int venc_valid_crop(struct venc_t *venc, const struct vpu_core_resources *res) 365{ 366 struct v4l2_rect *rect = NULL; 367 u32 min_width; 368 u32 min_height; 369 u32 src_width; 370 u32 src_height; 371 372 rect = &venc->params.crop; 373 min_width = res->min_width; 374 min_height = res->min_height; 375 src_width = venc->params.src_width; 376 src_height = venc->params.src_height; 377 378 if (rect->width == 0 || rect->height == 0) 379 return -EINVAL; 380 if (rect->left > src_width - min_width || rect->top > src_height - min_height) 381 return -EINVAL; 382 383 rect->width = min(rect->width, src_width - rect->left); 384 rect->width = max_t(u32, rect->width, min_width); 385 386 rect->height = min(rect->height, src_height - rect->top); 387 rect->height = max_t(u32, rect->height, min_height); 388 389 return 0; 390} 391 392static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 393{ 394 struct vpu_inst *inst = to_inst(file); 395 const struct vpu_core_resources *res; 396 struct venc_t *venc = inst->priv; 397 398 res = vpu_get_resource(inst); 399 if (!res) 400 return -EINVAL; 401 402 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 403 return -EINVAL; 404 if (s->target != V4L2_SEL_TGT_CROP) 405 return -EINVAL; 406 407 venc->params.crop.left = ALIGN(s->r.left, res->step_width); 408 venc->params.crop.top = ALIGN(s->r.top, res->step_height); 409 venc->params.crop.width = ALIGN(s->r.width, res->step_width); 410 venc->params.crop.height = ALIGN(s->r.height, res->step_height); 411 if (venc_valid_crop(venc, res)) { 412 venc->params.crop.left = 0; 413 venc->params.crop.top = 0; 414 venc->params.crop.width = venc->params.src_width; 415 venc->params.crop.height = venc->params.src_height; 416 } 417 418 inst->crop = venc->params.crop; 419 420 return 0; 421} 422 423static int venc_drain(struct vpu_inst *inst) 424{ 425 struct venc_t *venc = inst->priv; 426 int ret; 427 428 if (!inst->fh.m2m_ctx) 429 return 0; 430 431 if (inst->state != VPU_CODEC_STATE_DRAIN) 432 return 0; 433 434 if (!vpu_is_source_empty(inst)) 435 return 0; 436 437 if (!venc->input_ready) 438 return 0; 439 440 venc->input_ready = false; 441 vpu_trace(inst->dev, "[%d]\n", inst->id); 442 ret = vpu_session_stop(inst); 443 if (ret) 444 return ret; 445 inst->state = VPU_CODEC_STATE_STOP; 446 wake_up_all(&venc->wq); 447 448 return 0; 449} 450 451static int venc_request_eos(struct vpu_inst *inst) 452{ 453 inst->state = VPU_CODEC_STATE_DRAIN; 454 venc_drain(inst); 455 456 return 0; 457} 458 459static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd) 460{ 461 struct vpu_inst *inst = to_inst(file); 462 int ret; 463 464 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd); 465 if (ret) 466 return ret; 467 468 vpu_inst_lock(inst); 469 if (cmd->cmd == V4L2_ENC_CMD_STOP) { 470 if (inst->state == VPU_CODEC_STATE_DEINIT) 471 vpu_set_last_buffer_dequeued(inst); 472 else 473 venc_request_eos(inst); 474 } 475 vpu_inst_unlock(inst); 476 477 return 0; 478} 479 480static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) 481{ 482 switch (sub->type) { 483 case V4L2_EVENT_EOS: 484 return v4l2_event_subscribe(fh, sub, 0, NULL); 485 case V4L2_EVENT_CTRL: 486 return v4l2_ctrl_subscribe_event(fh, sub); 487 default: 488 return -EINVAL; 489 } 490} 491 492static const struct v4l2_ioctl_ops venc_ioctl_ops = { 493 .vidioc_querycap = venc_querycap, 494 .vidioc_enum_fmt_vid_cap = venc_enum_fmt, 495 .vidioc_enum_fmt_vid_out = venc_enum_fmt, 496 .vidioc_enum_framesizes = venc_enum_framesizes, 497 .vidioc_enum_frameintervals = venc_enum_frameintervals, 498 .vidioc_g_fmt_vid_cap_mplane = venc_g_fmt, 499 .vidioc_g_fmt_vid_out_mplane = venc_g_fmt, 500 .vidioc_try_fmt_vid_cap_mplane = venc_try_fmt, 501 .vidioc_try_fmt_vid_out_mplane = venc_try_fmt, 502 .vidioc_s_fmt_vid_cap_mplane = venc_s_fmt, 503 .vidioc_s_fmt_vid_out_mplane = venc_s_fmt, 504 .vidioc_g_parm = venc_g_parm, 505 .vidioc_s_parm = venc_s_parm, 506 .vidioc_g_selection = venc_g_selection, 507 .vidioc_s_selection = venc_s_selection, 508 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, 509 .vidioc_encoder_cmd = venc_encoder_cmd, 510 .vidioc_subscribe_event = venc_subscribe_event, 511 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 512 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 513 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 514 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 515 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 516 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 517 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 518 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 519 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 520 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 521}; 522 523static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) 524{ 525 struct vpu_inst *inst = ctrl_to_inst(ctrl); 526 struct venc_t *venc = inst->priv; 527 int ret = 0; 528 529 vpu_inst_lock(inst); 530 switch (ctrl->id) { 531 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 532 venc->params.profile = ctrl->val; 533 break; 534 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 535 venc->params.level = ctrl->val; 536 break; 537 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: 538 venc->params.rc_enable = ctrl->val; 539 break; 540 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: 541 venc->params.rc_mode = ctrl->val; 542 break; 543 case V4L2_CID_MPEG_VIDEO_BITRATE: 544 if (ctrl->val != venc->params.bitrate) 545 venc->bitrate_change = true; 546 venc->params.bitrate = ctrl->val; 547 break; 548 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: 549 venc->params.bitrate_max = ctrl->val; 550 break; 551 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 552 venc->params.gop_length = ctrl->val; 553 break; 554 case V4L2_CID_MPEG_VIDEO_B_FRAMES: 555 venc->params.bframes = ctrl->val; 556 break; 557 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: 558 venc->params.i_frame_qp = ctrl->val; 559 break; 560 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: 561 venc->params.p_frame_qp = ctrl->val; 562 break; 563 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: 564 venc->params.b_frame_qp = ctrl->val; 565 break; 566 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: 567 venc->request_key_frame = 1; 568 break; 569 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: 570 venc->cpb_size = ctrl->val * 1024; 571 break; 572 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: 573 venc->params.sar.enable = ctrl->val; 574 break; 575 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: 576 venc->params.sar.idc = ctrl->val; 577 break; 578 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH: 579 venc->params.sar.width = ctrl->val; 580 break; 581 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT: 582 venc->params.sar.height = ctrl->val; 583 break; 584 case V4L2_CID_MPEG_VIDEO_HEADER_MODE: 585 break; 586 default: 587 ret = -EINVAL; 588 break; 589 } 590 vpu_inst_unlock(inst); 591 592 return ret; 593} 594 595static const struct v4l2_ctrl_ops venc_ctrl_ops = { 596 .s_ctrl = venc_op_s_ctrl, 597 .g_volatile_ctrl = vpu_helper_g_volatile_ctrl, 598}; 599 600static int venc_ctrl_init(struct vpu_inst *inst) 601{ 602 struct v4l2_ctrl *ctrl; 603 int ret; 604 605 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20); 606 if (ret) 607 return ret; 608 609 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, 610 V4L2_CID_MPEG_VIDEO_H264_PROFILE, 611 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 612 ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | 613 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | 614 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), 615 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); 616 617 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, 618 V4L2_CID_MPEG_VIDEO_H264_LEVEL, 619 V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 620 0x0, 621 V4L2_MPEG_VIDEO_H264_LEVEL_4_0); 622 623 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 624 V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1); 625 626 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, 627 V4L2_CID_MPEG_VIDEO_BITRATE_MODE, 628 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 629 ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) | 630 (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)), 631 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR); 632 633 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 634 V4L2_CID_MPEG_VIDEO_BITRATE, 635 BITRATE_MIN, 636 BITRATE_MAX, 637 BITRATE_STEP, 638 BITRATE_DEFAULT); 639 640 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 641 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, 642 BITRATE_MIN, BITRATE_MAX, 643 BITRATE_STEP, 644 BITRATE_DEFAULT_PEAK); 645 646 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 647 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30); 648 649 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 650 V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0); 651 652 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 653 V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26); 654 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 655 V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28); 656 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 657 V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30); 658 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 659 V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0); 660 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 661 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2); 662 if (ctrl) 663 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 664 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 665 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2); 666 if (ctrl) 667 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 668 669 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 670 V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024); 671 672 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 673 V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1); 674 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, 675 V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC, 676 V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED, 677 0x0, 678 V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1); 679 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 680 V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH, 681 0, USHRT_MAX, 1, 1); 682 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 683 V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT, 684 0, USHRT_MAX, 1, 1); 685 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, 686 V4L2_CID_MPEG_VIDEO_HEADER_MODE, 687 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, 688 ~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME), 689 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME); 690 691 if (inst->ctrl_handler.error) { 692 ret = inst->ctrl_handler.error; 693 v4l2_ctrl_handler_free(&inst->ctrl_handler); 694 return ret; 695 } 696 697 ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler); 698 if (ret) { 699 dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret); 700 v4l2_ctrl_handler_free(&inst->ctrl_handler); 701 return ret; 702 } 703 704 return 0; 705} 706 707static bool venc_check_ready(struct vpu_inst *inst, unsigned int type) 708{ 709 struct venc_t *venc = inst->priv; 710 711 if (V4L2_TYPE_IS_OUTPUT(type)) { 712 if (vpu_helper_get_free_space(inst) < venc->cpb_size) 713 return false; 714 return venc->input_ready; 715 } 716 717 if (list_empty(&venc->frames)) 718 return false; 719 return true; 720} 721 722static u32 venc_get_enable_mask(u32 type) 723{ 724 if (V4L2_TYPE_IS_OUTPUT(type)) 725 return VENC_OUTPUT_ENABLE; 726 else 727 return VENC_CAPTURE_ENABLE; 728} 729 730static void venc_set_enable(struct venc_t *venc, u32 type, int enable) 731{ 732 u32 mask = venc_get_enable_mask(type); 733 734 if (enable) 735 venc->enable |= mask; 736 else 737 venc->enable &= ~mask; 738} 739 740static u32 venc_get_enable(struct venc_t *venc, u32 type) 741{ 742 return venc->enable & venc_get_enable_mask(type); 743} 744 745static void venc_input_done(struct vpu_inst *inst) 746{ 747 struct venc_t *venc = inst->priv; 748 749 vpu_inst_lock(inst); 750 venc->input_ready = true; 751 vpu_process_output_buffer(inst); 752 if (inst->state == VPU_CODEC_STATE_DRAIN) 753 venc_drain(inst); 754 vpu_inst_unlock(inst); 755} 756 757/* 758 * It's hardware limitation, that there may be several bytes 759 * redundant data at the beginning of frame. 760 * For android platform, the redundant data may cause cts test fail 761 * So driver will strip them 762 */ 763static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame) 764{ 765 struct venc_t *venc; 766 int skipped; 767 768 if (!frame || !frame->bytesused) 769 return -EINVAL; 770 771 venc = inst->priv; 772 skipped = vpu_helper_find_startcode(&inst->stream_buffer, 773 inst->cap_format.pixfmt, 774 frame->info.wptr - inst->stream_buffer.phys, 775 frame->bytesused); 776 if (skipped > 0) { 777 frame->bytesused -= skipped; 778 frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer, 779 frame->info.wptr, skipped); 780 venc->skipped_bytes += skipped; 781 venc->skipped_count++; 782 } 783 784 return 0; 785} 786 787static int venc_get_one_encoded_frame(struct vpu_inst *inst, 788 struct venc_frame_t *frame, 789 struct vb2_v4l2_buffer *vbuf) 790{ 791 struct venc_t *venc = inst->priv; 792 struct vb2_v4l2_buffer *src_buf; 793 794 if (!vbuf) 795 return -EAGAIN; 796 797 src_buf = vpu_find_buf_by_sequence(inst, inst->out_format.type, frame->info.frame_id); 798 if (src_buf) { 799 v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true); 800 vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE); 801 v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, src_buf); 802 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); 803 } else { 804 vbuf->vb2_buf.timestamp = frame->info.timestamp; 805 } 806 if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) { 807 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); 808 return 0; 809 } 810 if (frame->bytesused > vbuf->vb2_buf.planes[0].length) { 811 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); 812 return -ENOMEM; 813 } 814 815 venc_precheck_encoded_frame(inst, frame); 816 817 if (frame->bytesused) { 818 u32 rptr = frame->info.wptr; 819 void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0); 820 821 vpu_helper_copy_from_stream_buffer(&inst->stream_buffer, 822 &rptr, frame->bytesused, dst); 823 vpu_iface_update_stream_buffer(inst, rptr, 0); 824 } 825 vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused); 826 vbuf->sequence = frame->info.frame_id; 827 vbuf->field = inst->cap_format.field; 828 vbuf->flags |= frame->info.pic_type; 829 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE); 830 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp); 831 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 832 venc->ready_count++; 833 834 if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME) 835 dev_dbg(inst->dev, "[%d][%d]key frame\n", inst->id, frame->info.frame_id); 836 837 return 0; 838} 839 840static int venc_get_encoded_frames(struct vpu_inst *inst) 841{ 842 struct venc_t *venc; 843 struct venc_frame_t *frame; 844 struct venc_frame_t *tmp; 845 846 if (!inst->fh.m2m_ctx) 847 return 0; 848 venc = inst->priv; 849 list_for_each_entry_safe(frame, tmp, &venc->frames, list) { 850 if (venc_get_one_encoded_frame(inst, frame, 851 v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx))) 852 break; 853 list_del_init(&frame->list); 854 vfree(frame); 855 } 856 857 return 0; 858} 859 860static int venc_frame_encoded(struct vpu_inst *inst, void *arg) 861{ 862 struct vpu_enc_pic_info *info = arg; 863 struct venc_frame_t *frame; 864 struct venc_t *venc; 865 int ret = 0; 866 867 if (!info) 868 return -EINVAL; 869 venc = inst->priv; 870 frame = vzalloc(sizeof(*frame)); 871 if (!frame) 872 return -ENOMEM; 873 874 memcpy(&frame->info, info, sizeof(frame->info)); 875 frame->bytesused = info->frame_size; 876 877 vpu_inst_lock(inst); 878 list_add_tail(&frame->list, &venc->frames); 879 venc->encode_count++; 880 venc_get_encoded_frames(inst); 881 vpu_inst_unlock(inst); 882 883 return ret; 884} 885 886static void venc_set_last_buffer_dequeued(struct vpu_inst *inst) 887{ 888 struct venc_t *venc = inst->priv; 889 890 if (venc->stopped && list_empty(&venc->frames)) 891 vpu_set_last_buffer_dequeued(inst); 892} 893 894static void venc_stop_done(struct vpu_inst *inst) 895{ 896 struct venc_t *venc = inst->priv; 897 898 vpu_inst_lock(inst); 899 venc->stopped = true; 900 venc_set_last_buffer_dequeued(inst); 901 vpu_inst_unlock(inst); 902 903 wake_up_all(&venc->wq); 904} 905 906static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data) 907{ 908} 909 910static void venc_release(struct vpu_inst *inst) 911{ 912} 913 914static void venc_cleanup(struct vpu_inst *inst) 915{ 916 struct venc_t *venc; 917 918 if (!inst) 919 return; 920 921 venc = inst->priv; 922 if (venc) 923 vfree(venc); 924 inst->priv = NULL; 925 vfree(inst); 926} 927 928static int venc_start_session(struct vpu_inst *inst, u32 type) 929{ 930 struct venc_t *venc = inst->priv; 931 int stream_buffer_size; 932 int ret; 933 934 venc_set_enable(venc, type, 1); 935 if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK) 936 return 0; 937 938 vpu_iface_init_instance(inst); 939 stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core); 940 if (stream_buffer_size > 0) { 941 inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3); 942 ret = vpu_alloc_dma(inst->core, &inst->stream_buffer); 943 if (ret) 944 goto error; 945 946 inst->use_stream_buffer = true; 947 vpu_iface_config_stream_buffer(inst, &inst->stream_buffer); 948 } 949 950 ret = vpu_iface_set_encode_params(inst, &venc->params, 0); 951 if (ret) 952 goto error; 953 ret = vpu_session_configure_codec(inst); 954 if (ret) 955 goto error; 956 957 inst->state = VPU_CODEC_STATE_CONFIGURED; 958 /*vpu_iface_config_memory_resource*/ 959 960 /*config enc expert mode parameter*/ 961 ret = vpu_iface_set_encode_params(inst, &venc->params, 1); 962 if (ret) 963 goto error; 964 965 ret = vpu_session_start(inst); 966 if (ret) 967 goto error; 968 inst->state = VPU_CODEC_STATE_STARTED; 969 970 venc->bitrate_change = false; 971 venc->input_ready = true; 972 venc->frame_count = 0; 973 venc->encode_count = 0; 974 venc->ready_count = 0; 975 venc->stopped = false; 976 vpu_process_output_buffer(inst); 977 if (venc->frame_count == 0) 978 dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id); 979 980 return 0; 981error: 982 venc_set_enable(venc, type, 0); 983 inst->state = VPU_CODEC_STATE_DEINIT; 984 985 vpu_free_dma(&inst->stream_buffer); 986 return ret; 987} 988 989static void venc_cleanup_mem_resource(struct vpu_inst *inst) 990{ 991 struct venc_t *venc; 992 u32 i; 993 994 venc = inst->priv; 995 996 for (i = 0; i < ARRAY_SIZE(venc->enc); i++) 997 vpu_free_dma(&venc->enc[i]); 998 for (i = 0; i < ARRAY_SIZE(venc->ref); i++) 999 vpu_free_dma(&venc->ref[i]); 1000} 1001 1002static void venc_request_mem_resource(struct vpu_inst *inst, 1003 u32 enc_frame_size, 1004 u32 enc_frame_num, 1005 u32 ref_frame_size, 1006 u32 ref_frame_num, 1007 u32 act_frame_size, 1008 u32 act_frame_num) 1009{ 1010 struct venc_t *venc; 1011 u32 i; 1012 int ret; 1013 1014 venc = inst->priv; 1015 if (enc_frame_num > ARRAY_SIZE(venc->enc)) { 1016 dev_err(inst->dev, "[%d] enc num(%d) is out of range\n", inst->id, enc_frame_num); 1017 return; 1018 } 1019 if (ref_frame_num > ARRAY_SIZE(venc->ref)) { 1020 dev_err(inst->dev, "[%d] ref num(%d) is out of range\n", inst->id, ref_frame_num); 1021 return; 1022 } 1023 if (act_frame_num > ARRAY_SIZE(venc->act)) { 1024 dev_err(inst->dev, "[%d] act num(%d) is out of range\n", inst->id, act_frame_num); 1025 return; 1026 } 1027 1028 for (i = 0; i < enc_frame_num; i++) { 1029 venc->enc[i].length = enc_frame_size; 1030 ret = vpu_alloc_dma(inst->core, &venc->enc[i]); 1031 if (ret) { 1032 venc_cleanup_mem_resource(inst); 1033 return; 1034 } 1035 } 1036 for (i = 0; i < ref_frame_num; i++) { 1037 venc->ref[i].length = ref_frame_size; 1038 ret = vpu_alloc_dma(inst->core, &venc->ref[i]); 1039 if (ret) { 1040 venc_cleanup_mem_resource(inst); 1041 return; 1042 } 1043 } 1044 if (act_frame_num != 1 || act_frame_size > inst->act.length) { 1045 venc_cleanup_mem_resource(inst); 1046 return; 1047 } 1048 venc->act[0].length = act_frame_size; 1049 venc->act[0].phys = inst->act.phys; 1050 venc->act[0].virt = inst->act.virt; 1051 1052 for (i = 0; i < enc_frame_num; i++) 1053 vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]); 1054 for (i = 0; i < ref_frame_num; i++) 1055 vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]); 1056 for (i = 0; i < act_frame_num; i++) 1057 vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]); 1058} 1059 1060static void venc_cleanup_frames(struct venc_t *venc) 1061{ 1062 struct venc_frame_t *frame; 1063 struct venc_frame_t *tmp; 1064 1065 list_for_each_entry_safe(frame, tmp, &venc->frames, list) { 1066 list_del_init(&frame->list); 1067 vfree(frame); 1068 } 1069} 1070 1071static int venc_stop_session(struct vpu_inst *inst, u32 type) 1072{ 1073 struct venc_t *venc = inst->priv; 1074 1075 venc_set_enable(venc, type, 0); 1076 if (venc->enable & VENC_ENABLE_MASK) 1077 return 0; 1078 1079 if (inst->state == VPU_CODEC_STATE_DEINIT) 1080 return 0; 1081 1082 if (inst->state != VPU_CODEC_STATE_STOP) 1083 venc_request_eos(inst); 1084 1085 call_void_vop(inst, wait_prepare); 1086 if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) { 1087 set_bit(inst->id, &inst->core->hang_mask); 1088 vpu_session_debug(inst); 1089 } 1090 call_void_vop(inst, wait_finish); 1091 1092 inst->state = VPU_CODEC_STATE_DEINIT; 1093 venc_cleanup_frames(inst->priv); 1094 vpu_free_dma(&inst->stream_buffer); 1095 venc_cleanup_mem_resource(inst); 1096 1097 return 0; 1098} 1099 1100static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb) 1101{ 1102 struct venc_t *venc = inst->priv; 1103 struct vb2_v4l2_buffer *vbuf; 1104 u32 flags; 1105 1106 if (inst->state == VPU_CODEC_STATE_DEINIT) 1107 return -EINVAL; 1108 1109 vbuf = to_vb2_v4l2_buffer(vb); 1110 if (inst->state == VPU_CODEC_STATE_STARTED) 1111 inst->state = VPU_CODEC_STATE_ACTIVE; 1112 1113 flags = vbuf->flags; 1114 if (venc->request_key_frame) { 1115 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME; 1116 venc->request_key_frame = 0; 1117 } 1118 if (venc->bitrate_change) { 1119 vpu_session_update_parameters(inst, &venc->params); 1120 venc->bitrate_change = false; 1121 } 1122 dev_dbg(inst->dev, "[%d][INPUT TS]%32lld\n", inst->id, vb->timestamp); 1123 vpu_iface_input_frame(inst, vb); 1124 vbuf->flags = flags; 1125 venc->input_ready = false; 1126 venc->frame_count++; 1127 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE); 1128 1129 return 0; 1130} 1131 1132static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb) 1133{ 1134 struct venc_t *venc; 1135 struct venc_frame_t *frame = NULL; 1136 struct vb2_v4l2_buffer *vbuf; 1137 int ret; 1138 1139 venc = inst->priv; 1140 if (list_empty(&venc->frames)) 1141 return -EINVAL; 1142 1143 frame = list_first_entry(&venc->frames, struct venc_frame_t, list); 1144 vbuf = to_vb2_v4l2_buffer(vb); 1145 v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf); 1146 ret = venc_get_one_encoded_frame(inst, frame, vbuf); 1147 if (ret) 1148 return ret; 1149 1150 list_del_init(&frame->list); 1151 vfree(frame); 1152 return 0; 1153} 1154 1155static void venc_on_queue_empty(struct vpu_inst *inst, u32 type) 1156{ 1157 struct venc_t *venc = inst->priv; 1158 1159 if (V4L2_TYPE_IS_OUTPUT(type)) 1160 return; 1161 1162 if (venc->stopped) 1163 venc_set_last_buffer_dequeued(inst); 1164} 1165 1166static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i) 1167{ 1168 struct venc_t *venc = inst->priv; 1169 int num = -1; 1170 1171 switch (i) { 1172 case 0: 1173 num = scnprintf(str, size, "profile = %d\n", venc->params.profile); 1174 break; 1175 case 1: 1176 num = scnprintf(str, size, "level = %d\n", venc->params.level); 1177 break; 1178 case 2: 1179 num = scnprintf(str, size, "fps = %d/%d\n", 1180 venc->params.frame_rate.numerator, 1181 venc->params.frame_rate.denominator); 1182 break; 1183 case 3: 1184 num = scnprintf(str, size, "%d x %d -> %d x %d\n", 1185 venc->params.src_width, 1186 venc->params.src_height, 1187 venc->params.out_width, 1188 venc->params.out_height); 1189 break; 1190 case 4: 1191 num = scnprintf(str, size, "(%d, %d) %d x %d\n", 1192 venc->params.crop.left, 1193 venc->params.crop.top, 1194 venc->params.crop.width, 1195 venc->params.crop.height); 1196 break; 1197 case 5: 1198 num = scnprintf(str, size, 1199 "enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n", 1200 venc->enable, 1201 venc->frame_count, venc->encode_count, 1202 venc->ready_count, 1203 venc->stopped); 1204 break; 1205 case 6: 1206 num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length); 1207 break; 1208 case 7: 1209 num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes); 1210 break; 1211 case 8: 1212 num = scnprintf(str, size, "rc: %s, mode = %d, bitrate = %d(%d), qp = %d\n", 1213 venc->params.rc_enable ? "enable" : "disable", 1214 venc->params.rc_mode, 1215 venc->params.bitrate, 1216 venc->params.bitrate_max, 1217 venc->params.i_frame_qp); 1218 break; 1219 case 9: 1220 num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n", 1221 venc->params.sar.enable, 1222 venc->params.sar.idc, 1223 venc->params.sar.width, 1224 venc->params.sar.height); 1225 1226 break; 1227 case 10: 1228 num = scnprintf(str, size, 1229 "colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n", 1230 venc->params.color.primaries, 1231 venc->params.color.transfer, 1232 venc->params.color.matrix, 1233 venc->params.color.full_range); 1234 break; 1235 case 11: 1236 num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n", 1237 venc->skipped_count, venc->skipped_bytes); 1238 break; 1239 default: 1240 break; 1241 } 1242 1243 return num; 1244} 1245 1246static struct vpu_inst_ops venc_inst_ops = { 1247 .ctrl_init = venc_ctrl_init, 1248 .check_ready = venc_check_ready, 1249 .input_done = venc_input_done, 1250 .get_one_frame = venc_frame_encoded, 1251 .stop_done = venc_stop_done, 1252 .event_notify = venc_event_notify, 1253 .release = venc_release, 1254 .cleanup = venc_cleanup, 1255 .start = venc_start_session, 1256 .mem_request = venc_request_mem_resource, 1257 .stop = venc_stop_session, 1258 .process_output = venc_process_output, 1259 .process_capture = venc_process_capture, 1260 .on_queue_empty = venc_on_queue_empty, 1261 .get_debug_info = venc_get_debug_info, 1262 .wait_prepare = vpu_inst_unlock, 1263 .wait_finish = vpu_inst_lock, 1264}; 1265 1266static void venc_init(struct file *file) 1267{ 1268 struct vpu_inst *inst = to_inst(file); 1269 struct venc_t *venc; 1270 struct v4l2_format f; 1271 struct v4l2_streamparm parm; 1272 1273 venc = inst->priv; 1274 venc->params.qp_min = 1; 1275 venc->params.qp_max = 51; 1276 venc->params.qp_min_i = 1; 1277 venc->params.qp_max_i = 51; 1278 venc->params.bitrate_min = BITRATE_MIN; 1279 1280 memset(&f, 0, sizeof(f)); 1281 f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1282 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M; 1283 f.fmt.pix_mp.width = 1280; 1284 f.fmt.pix_mp.height = 720; 1285 f.fmt.pix_mp.field = V4L2_FIELD_NONE; 1286 f.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; 1287 venc_s_fmt(file, &inst->fh, &f); 1288 1289 memset(&f, 0, sizeof(f)); 1290 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1291 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; 1292 f.fmt.pix_mp.width = 1280; 1293 f.fmt.pix_mp.height = 720; 1294 f.fmt.pix_mp.field = V4L2_FIELD_NONE; 1295 venc_s_fmt(file, &inst->fh, &f); 1296 1297 memset(&parm, 0, sizeof(parm)); 1298 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1299 parm.parm.capture.timeperframe.numerator = 1; 1300 parm.parm.capture.timeperframe.denominator = 30; 1301 venc_s_parm(file, &inst->fh, &parm); 1302} 1303 1304static int venc_open(struct file *file) 1305{ 1306 struct vpu_inst *inst; 1307 struct venc_t *venc; 1308 int ret; 1309 1310 inst = vzalloc(sizeof(*inst)); 1311 if (!inst) 1312 return -ENOMEM; 1313 1314 venc = vzalloc(sizeof(*venc)); 1315 if (!venc) { 1316 vfree(inst); 1317 return -ENOMEM; 1318 } 1319 1320 inst->ops = &venc_inst_ops; 1321 inst->formats = venc_formats; 1322 inst->type = VPU_CORE_TYPE_ENC; 1323 inst->priv = venc; 1324 INIT_LIST_HEAD(&venc->frames); 1325 init_waitqueue_head(&venc->wq); 1326 1327 ret = vpu_v4l2_open(file, inst); 1328 if (ret) 1329 return ret; 1330 1331 inst->min_buffer_out = VENC_MIN_BUFFER_OUT; 1332 inst->min_buffer_cap = VENC_MIN_BUFFER_CAP; 1333 venc_init(file); 1334 1335 return 0; 1336} 1337 1338static const struct v4l2_file_operations venc_fops = { 1339 .owner = THIS_MODULE, 1340 .open = venc_open, 1341 .release = vpu_v4l2_close, 1342 .unlocked_ioctl = video_ioctl2, 1343 .poll = v4l2_m2m_fop_poll, 1344 .mmap = v4l2_m2m_fop_mmap, 1345}; 1346 1347const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void) 1348{ 1349 return &venc_ioctl_ops; 1350} 1351 1352const struct v4l2_file_operations *venc_get_fops(void) 1353{ 1354 return &venc_fops; 1355}