Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.0-rc5 1351 lines 38 kB view raw
1/* 2* Copyright (c) 2016 MediaTek Inc. 3* Author: PC Chen <pc.chen@mediatek.com> 4* Tiffany Lin <tiffany.lin@mediatek.com> 5* 6* This program is free software; you can redistribute it and/or modify 7* it under the terms of the GNU General Public License version 2 as 8* published by the Free Software Foundation. 9* 10* This program is distributed in the hope that it will be useful, 11* but WITHOUT ANY WARRANTY; without even the implied warranty of 12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13* GNU General Public License for more details. 14*/ 15 16#include <media/v4l2-event.h> 17#include <media/v4l2-mem2mem.h> 18#include <media/videobuf2-dma-contig.h> 19#include <soc/mediatek/smi.h> 20 21#include "mtk_vcodec_drv.h" 22#include "mtk_vcodec_enc.h" 23#include "mtk_vcodec_intr.h" 24#include "mtk_vcodec_util.h" 25#include "venc_drv_if.h" 26 27#define MTK_VENC_MIN_W 160U 28#define MTK_VENC_MIN_H 128U 29#define MTK_VENC_MAX_W 1920U 30#define MTK_VENC_MAX_H 1088U 31#define DFT_CFG_WIDTH MTK_VENC_MIN_W 32#define DFT_CFG_HEIGHT MTK_VENC_MIN_H 33#define MTK_MAX_CTRLS_HINT 20 34#define OUT_FMT_IDX 0 35#define CAP_FMT_IDX 4 36 37 38static void mtk_venc_worker(struct work_struct *work); 39 40static struct mtk_video_fmt mtk_video_formats[] = { 41 { 42 .fourcc = V4L2_PIX_FMT_NV12M, 43 .type = MTK_FMT_FRAME, 44 .num_planes = 2, 45 }, 46 { 47 .fourcc = V4L2_PIX_FMT_NV21M, 48 .type = MTK_FMT_FRAME, 49 .num_planes = 2, 50 }, 51 { 52 .fourcc = V4L2_PIX_FMT_YUV420M, 53 .type = MTK_FMT_FRAME, 54 .num_planes = 3, 55 }, 56 { 57 .fourcc = V4L2_PIX_FMT_YVU420M, 58 .type = MTK_FMT_FRAME, 59 .num_planes = 3, 60 }, 61 { 62 .fourcc = V4L2_PIX_FMT_H264, 63 .type = MTK_FMT_ENC, 64 .num_planes = 1, 65 }, 66 { 67 .fourcc = V4L2_PIX_FMT_VP8, 68 .type = MTK_FMT_ENC, 69 .num_planes = 1, 70 }, 71}; 72 73#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats) 74 75static const struct mtk_codec_framesizes mtk_venc_framesizes[] = { 76 { 77 .fourcc = V4L2_PIX_FMT_H264, 78 .stepwise = { MTK_VENC_MIN_W, MTK_VENC_MAX_W, 16, 79 MTK_VENC_MIN_H, MTK_VENC_MAX_H, 16 }, 80 }, 81 { 82 .fourcc = V4L2_PIX_FMT_VP8, 83 .stepwise = { MTK_VENC_MIN_W, MTK_VENC_MAX_W, 16, 84 MTK_VENC_MIN_H, MTK_VENC_MAX_H, 16 }, 85 }, 86}; 87 88#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_venc_framesizes) 89 90static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl) 91{ 92 struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl); 93 struct mtk_enc_params *p = &ctx->enc_params; 94 int ret = 0; 95 96 switch (ctrl->id) { 97 case V4L2_CID_MPEG_VIDEO_BITRATE: 98 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d", 99 ctrl->val); 100 p->bitrate = ctrl->val; 101 ctx->param_change |= MTK_ENCODE_PARAM_BITRATE; 102 break; 103 case V4L2_CID_MPEG_VIDEO_B_FRAMES: 104 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d", 105 ctrl->val); 106 p->num_b_frame = ctrl->val; 107 break; 108 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: 109 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d", 110 ctrl->val); 111 p->rc_frame = ctrl->val; 112 break; 113 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: 114 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d", 115 ctrl->val); 116 p->h264_max_qp = ctrl->val; 117 break; 118 case V4L2_CID_MPEG_VIDEO_HEADER_MODE: 119 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d", 120 ctrl->val); 121 p->seq_hdr_mode = ctrl->val; 122 break; 123 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: 124 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d", 125 ctrl->val); 126 p->rc_mb = ctrl->val; 127 break; 128 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 129 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d", 130 ctrl->val); 131 p->h264_profile = ctrl->val; 132 break; 133 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 134 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d", 135 ctrl->val); 136 p->h264_level = ctrl->val; 137 break; 138 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: 139 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d", 140 ctrl->val); 141 p->intra_period = ctrl->val; 142 ctx->param_change |= MTK_ENCODE_PARAM_INTRA_PERIOD; 143 break; 144 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 145 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d", 146 ctrl->val); 147 p->gop_size = ctrl->val; 148 ctx->param_change |= MTK_ENCODE_PARAM_GOP_SIZE; 149 break; 150 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: 151 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME"); 152 p->force_intra = 1; 153 ctx->param_change |= MTK_ENCODE_PARAM_FORCE_INTRA; 154 break; 155 default: 156 ret = -EINVAL; 157 break; 158 } 159 160 return ret; 161} 162 163static const struct v4l2_ctrl_ops mtk_vcodec_enc_ctrl_ops = { 164 .s_ctrl = vidioc_venc_s_ctrl, 165}; 166 167static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) 168{ 169 struct mtk_video_fmt *fmt; 170 int i, j = 0; 171 172 for (i = 0; i < NUM_FORMATS; ++i) { 173 if (output_queue && mtk_video_formats[i].type != MTK_FMT_FRAME) 174 continue; 175 if (!output_queue && mtk_video_formats[i].type != MTK_FMT_ENC) 176 continue; 177 178 if (j == f->index) { 179 fmt = &mtk_video_formats[i]; 180 f->pixelformat = fmt->fourcc; 181 memset(f->reserved, 0, sizeof(f->reserved)); 182 return 0; 183 } 184 ++j; 185 } 186 187 return -EINVAL; 188} 189 190static int vidioc_enum_framesizes(struct file *file, void *fh, 191 struct v4l2_frmsizeenum *fsize) 192{ 193 int i = 0; 194 195 if (fsize->index != 0) 196 return -EINVAL; 197 198 for (i = 0; i < NUM_SUPPORTED_FRAMESIZE; ++i) { 199 if (fsize->pixel_format != mtk_venc_framesizes[i].fourcc) 200 continue; 201 202 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 203 fsize->stepwise = mtk_venc_framesizes[i].stepwise; 204 return 0; 205 } 206 207 return -EINVAL; 208} 209 210static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, 211 struct v4l2_fmtdesc *f) 212{ 213 return vidioc_enum_fmt(f, false); 214} 215 216static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, 217 struct v4l2_fmtdesc *f) 218{ 219 return vidioc_enum_fmt(f, true); 220} 221 222static int vidioc_venc_querycap(struct file *file, void *priv, 223 struct v4l2_capability *cap) 224{ 225 strscpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver)); 226 strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); 227 strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); 228 229 return 0; 230} 231 232static int vidioc_venc_s_parm(struct file *file, void *priv, 233 struct v4l2_streamparm *a) 234{ 235 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 236 237 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 238 return -EINVAL; 239 240 ctx->enc_params.framerate_num = 241 a->parm.output.timeperframe.denominator; 242 ctx->enc_params.framerate_denom = 243 a->parm.output.timeperframe.numerator; 244 ctx->param_change |= MTK_ENCODE_PARAM_FRAMERATE; 245 246 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 247 248 return 0; 249} 250 251static int vidioc_venc_g_parm(struct file *file, void *priv, 252 struct v4l2_streamparm *a) 253{ 254 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 255 256 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 257 return -EINVAL; 258 259 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 260 a->parm.output.timeperframe.denominator = 261 ctx->enc_params.framerate_num; 262 a->parm.output.timeperframe.numerator = 263 ctx->enc_params.framerate_denom; 264 265 return 0; 266} 267 268static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx, 269 enum v4l2_buf_type type) 270{ 271 if (V4L2_TYPE_IS_OUTPUT(type)) 272 return &ctx->q_data[MTK_Q_DATA_SRC]; 273 274 return &ctx->q_data[MTK_Q_DATA_DST]; 275} 276 277static struct mtk_video_fmt *mtk_venc_find_format(struct v4l2_format *f) 278{ 279 struct mtk_video_fmt *fmt; 280 unsigned int k; 281 282 for (k = 0; k < NUM_FORMATS; k++) { 283 fmt = &mtk_video_formats[k]; 284 if (fmt->fourcc == f->fmt.pix.pixelformat) 285 return fmt; 286 } 287 288 return NULL; 289} 290 291/* V4L2 specification suggests the driver corrects the format struct if any of 292 * the dimensions is unsupported 293 */ 294static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_video_fmt *fmt) 295{ 296 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; 297 int i; 298 299 pix_fmt_mp->field = V4L2_FIELD_NONE; 300 301 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 302 pix_fmt_mp->num_planes = 1; 303 pix_fmt_mp->plane_fmt[0].bytesperline = 0; 304 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 305 int tmp_w, tmp_h; 306 307 pix_fmt_mp->height = clamp(pix_fmt_mp->height, 308 MTK_VENC_MIN_H, 309 MTK_VENC_MAX_H); 310 pix_fmt_mp->width = clamp(pix_fmt_mp->width, 311 MTK_VENC_MIN_W, 312 MTK_VENC_MAX_W); 313 314 /* find next closer width align 16, heign align 32, size align 315 * 64 rectangle 316 */ 317 tmp_w = pix_fmt_mp->width; 318 tmp_h = pix_fmt_mp->height; 319 v4l_bound_align_image(&pix_fmt_mp->width, 320 MTK_VENC_MIN_W, 321 MTK_VENC_MAX_W, 4, 322 &pix_fmt_mp->height, 323 MTK_VENC_MIN_H, 324 MTK_VENC_MAX_H, 5, 6); 325 326 if (pix_fmt_mp->width < tmp_w && 327 (pix_fmt_mp->width + 16) <= MTK_VENC_MAX_W) 328 pix_fmt_mp->width += 16; 329 if (pix_fmt_mp->height < tmp_h && 330 (pix_fmt_mp->height + 32) <= MTK_VENC_MAX_H) 331 pix_fmt_mp->height += 32; 332 333 mtk_v4l2_debug(0, 334 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d %d", 335 tmp_w, tmp_h, pix_fmt_mp->width, 336 pix_fmt_mp->height, 337 pix_fmt_mp->plane_fmt[0].sizeimage, 338 pix_fmt_mp->plane_fmt[1].sizeimage); 339 340 pix_fmt_mp->num_planes = fmt->num_planes; 341 pix_fmt_mp->plane_fmt[0].sizeimage = 342 pix_fmt_mp->width * pix_fmt_mp->height + 343 ((ALIGN(pix_fmt_mp->width, 16) * 2) * 16); 344 pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width; 345 346 if (pix_fmt_mp->num_planes == 2) { 347 pix_fmt_mp->plane_fmt[1].sizeimage = 348 (pix_fmt_mp->width * pix_fmt_mp->height) / 2 + 349 (ALIGN(pix_fmt_mp->width, 16) * 16); 350 pix_fmt_mp->plane_fmt[2].sizeimage = 0; 351 pix_fmt_mp->plane_fmt[1].bytesperline = 352 pix_fmt_mp->width; 353 pix_fmt_mp->plane_fmt[2].bytesperline = 0; 354 } else if (pix_fmt_mp->num_planes == 3) { 355 pix_fmt_mp->plane_fmt[1].sizeimage = 356 pix_fmt_mp->plane_fmt[2].sizeimage = 357 (pix_fmt_mp->width * pix_fmt_mp->height) / 4 + 358 ((ALIGN(pix_fmt_mp->width, 16) / 2) * 16); 359 pix_fmt_mp->plane_fmt[1].bytesperline = 360 pix_fmt_mp->plane_fmt[2].bytesperline = 361 pix_fmt_mp->width / 2; 362 } 363 } 364 365 for (i = 0; i < pix_fmt_mp->num_planes; i++) 366 memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0, 367 sizeof(pix_fmt_mp->plane_fmt[0].reserved)); 368 369 pix_fmt_mp->flags = 0; 370 memset(&pix_fmt_mp->reserved, 0x0, 371 sizeof(pix_fmt_mp->reserved)); 372 373 return 0; 374} 375 376static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx, 377 struct venc_enc_param *param) 378{ 379 struct mtk_q_data *q_data_src = &ctx->q_data[MTK_Q_DATA_SRC]; 380 struct mtk_enc_params *enc_params = &ctx->enc_params; 381 382 switch (q_data_src->fmt->fourcc) { 383 case V4L2_PIX_FMT_YUV420M: 384 param->input_yuv_fmt = VENC_YUV_FORMAT_I420; 385 break; 386 case V4L2_PIX_FMT_YVU420M: 387 param->input_yuv_fmt = VENC_YUV_FORMAT_YV12; 388 break; 389 case V4L2_PIX_FMT_NV12M: 390 param->input_yuv_fmt = VENC_YUV_FORMAT_NV12; 391 break; 392 case V4L2_PIX_FMT_NV21M: 393 param->input_yuv_fmt = VENC_YUV_FORMAT_NV21; 394 break; 395 default: 396 mtk_v4l2_err("Unsupport fourcc =%d", q_data_src->fmt->fourcc); 397 break; 398 } 399 param->h264_profile = enc_params->h264_profile; 400 param->h264_level = enc_params->h264_level; 401 402 /* Config visible resolution */ 403 param->width = q_data_src->visible_width; 404 param->height = q_data_src->visible_height; 405 /* Config coded resolution */ 406 param->buf_width = q_data_src->coded_width; 407 param->buf_height = q_data_src->coded_height; 408 param->frm_rate = enc_params->framerate_num / 409 enc_params->framerate_denom; 410 param->intra_period = enc_params->intra_period; 411 param->gop_size = enc_params->gop_size; 412 param->bitrate = enc_params->bitrate; 413 414 mtk_v4l2_debug(0, 415 "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d", 416 param->input_yuv_fmt, param->h264_profile, 417 param->h264_level, param->width, param->height, 418 param->buf_width, param->buf_height, 419 param->frm_rate, param->bitrate, 420 param->gop_size, param->intra_period); 421} 422 423static int vidioc_venc_s_fmt_cap(struct file *file, void *priv, 424 struct v4l2_format *f) 425{ 426 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 427 struct vb2_queue *vq; 428 struct mtk_q_data *q_data; 429 int i, ret; 430 struct mtk_video_fmt *fmt; 431 432 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 433 if (!vq) { 434 mtk_v4l2_err("fail to get vq"); 435 return -EINVAL; 436 } 437 438 if (vb2_is_busy(vq)) { 439 mtk_v4l2_err("queue busy"); 440 return -EBUSY; 441 } 442 443 q_data = mtk_venc_get_q_data(ctx, f->type); 444 if (!q_data) { 445 mtk_v4l2_err("fail to get q data"); 446 return -EINVAL; 447 } 448 449 fmt = mtk_venc_find_format(f); 450 if (!fmt) { 451 f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; 452 fmt = mtk_venc_find_format(f); 453 } 454 455 q_data->fmt = fmt; 456 ret = vidioc_try_fmt(f, q_data->fmt); 457 if (ret) 458 return ret; 459 460 q_data->coded_width = f->fmt.pix_mp.width; 461 q_data->coded_height = f->fmt.pix_mp.height; 462 q_data->field = f->fmt.pix_mp.field; 463 464 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { 465 struct v4l2_plane_pix_format *plane_fmt; 466 467 plane_fmt = &f->fmt.pix_mp.plane_fmt[i]; 468 q_data->bytesperline[i] = plane_fmt->bytesperline; 469 q_data->sizeimage[i] = plane_fmt->sizeimage; 470 } 471 472 if (ctx->state == MTK_STATE_FREE) { 473 ret = venc_if_init(ctx, q_data->fmt->fourcc); 474 if (ret) { 475 mtk_v4l2_err("venc_if_init failed=%d, codec type=%x", 476 ret, q_data->fmt->fourcc); 477 return -EBUSY; 478 } 479 ctx->state = MTK_STATE_INIT; 480 } 481 482 return 0; 483} 484 485static int vidioc_venc_s_fmt_out(struct file *file, void *priv, 486 struct v4l2_format *f) 487{ 488 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 489 struct vb2_queue *vq; 490 struct mtk_q_data *q_data; 491 int ret, i; 492 struct mtk_video_fmt *fmt; 493 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; 494 495 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 496 if (!vq) { 497 mtk_v4l2_err("fail to get vq"); 498 return -EINVAL; 499 } 500 501 if (vb2_is_busy(vq)) { 502 mtk_v4l2_err("queue busy"); 503 return -EBUSY; 504 } 505 506 q_data = mtk_venc_get_q_data(ctx, f->type); 507 if (!q_data) { 508 mtk_v4l2_err("fail to get q data"); 509 return -EINVAL; 510 } 511 512 fmt = mtk_venc_find_format(f); 513 if (!fmt) { 514 f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; 515 fmt = mtk_venc_find_format(f); 516 } 517 518 pix_fmt_mp->height = clamp(pix_fmt_mp->height, 519 MTK_VENC_MIN_H, 520 MTK_VENC_MAX_H); 521 pix_fmt_mp->width = clamp(pix_fmt_mp->width, 522 MTK_VENC_MIN_W, 523 MTK_VENC_MAX_W); 524 525 q_data->visible_width = f->fmt.pix_mp.width; 526 q_data->visible_height = f->fmt.pix_mp.height; 527 q_data->fmt = fmt; 528 ret = vidioc_try_fmt(f, q_data->fmt); 529 if (ret) 530 return ret; 531 532 q_data->coded_width = f->fmt.pix_mp.width; 533 q_data->coded_height = f->fmt.pix_mp.height; 534 535 q_data->field = f->fmt.pix_mp.field; 536 ctx->colorspace = f->fmt.pix_mp.colorspace; 537 ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 538 ctx->quantization = f->fmt.pix_mp.quantization; 539 ctx->xfer_func = f->fmt.pix_mp.xfer_func; 540 541 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { 542 struct v4l2_plane_pix_format *plane_fmt; 543 544 plane_fmt = &f->fmt.pix_mp.plane_fmt[i]; 545 q_data->bytesperline[i] = plane_fmt->bytesperline; 546 q_data->sizeimage[i] = plane_fmt->sizeimage; 547 } 548 549 return 0; 550} 551 552static int vidioc_venc_g_fmt(struct file *file, void *priv, 553 struct v4l2_format *f) 554{ 555 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; 556 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 557 struct vb2_queue *vq; 558 struct mtk_q_data *q_data; 559 int i; 560 561 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 562 if (!vq) 563 return -EINVAL; 564 565 q_data = mtk_venc_get_q_data(ctx, f->type); 566 567 pix->width = q_data->coded_width; 568 pix->height = q_data->coded_height; 569 pix->pixelformat = q_data->fmt->fourcc; 570 pix->field = q_data->field; 571 pix->num_planes = q_data->fmt->num_planes; 572 for (i = 0; i < pix->num_planes; i++) { 573 pix->plane_fmt[i].bytesperline = q_data->bytesperline[i]; 574 pix->plane_fmt[i].sizeimage = q_data->sizeimage[i]; 575 memset(&(pix->plane_fmt[i].reserved[0]), 0x0, 576 sizeof(pix->plane_fmt[i].reserved)); 577 } 578 579 pix->flags = 0; 580 pix->colorspace = ctx->colorspace; 581 pix->ycbcr_enc = ctx->ycbcr_enc; 582 pix->quantization = ctx->quantization; 583 pix->xfer_func = ctx->xfer_func; 584 585 return 0; 586} 587 588static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, 589 struct v4l2_format *f) 590{ 591 struct mtk_video_fmt *fmt; 592 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 593 594 fmt = mtk_venc_find_format(f); 595 if (!fmt) { 596 f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; 597 fmt = mtk_venc_find_format(f); 598 } 599 f->fmt.pix_mp.colorspace = ctx->colorspace; 600 f->fmt.pix_mp.ycbcr_enc = ctx->ycbcr_enc; 601 f->fmt.pix_mp.quantization = ctx->quantization; 602 f->fmt.pix_mp.xfer_func = ctx->xfer_func; 603 604 return vidioc_try_fmt(f, fmt); 605} 606 607static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, 608 struct v4l2_format *f) 609{ 610 struct mtk_video_fmt *fmt; 611 612 fmt = mtk_venc_find_format(f); 613 if (!fmt) { 614 f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; 615 fmt = mtk_venc_find_format(f); 616 } 617 if (!f->fmt.pix_mp.colorspace) { 618 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; 619 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 620 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 621 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 622 } 623 624 return vidioc_try_fmt(f, fmt); 625} 626 627static int vidioc_venc_g_selection(struct file *file, void *priv, 628 struct v4l2_selection *s) 629{ 630 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 631 struct mtk_q_data *q_data; 632 633 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 634 return -EINVAL; 635 636 q_data = mtk_venc_get_q_data(ctx, s->type); 637 if (!q_data) 638 return -EINVAL; 639 640 switch (s->target) { 641 case V4L2_SEL_TGT_CROP_DEFAULT: 642 case V4L2_SEL_TGT_CROP_BOUNDS: 643 s->r.top = 0; 644 s->r.left = 0; 645 s->r.width = q_data->coded_width; 646 s->r.height = q_data->coded_height; 647 break; 648 case V4L2_SEL_TGT_CROP: 649 s->r.top = 0; 650 s->r.left = 0; 651 s->r.width = q_data->visible_width; 652 s->r.height = q_data->visible_height; 653 break; 654 default: 655 return -EINVAL; 656 } 657 658 return 0; 659} 660 661static int vidioc_venc_s_selection(struct file *file, void *priv, 662 struct v4l2_selection *s) 663{ 664 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 665 struct mtk_q_data *q_data; 666 667 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 668 return -EINVAL; 669 670 q_data = mtk_venc_get_q_data(ctx, s->type); 671 if (!q_data) 672 return -EINVAL; 673 674 switch (s->target) { 675 case V4L2_SEL_TGT_CROP: 676 /* Only support crop from (0,0) */ 677 s->r.top = 0; 678 s->r.left = 0; 679 s->r.width = min(s->r.width, q_data->coded_width); 680 s->r.height = min(s->r.height, q_data->coded_height); 681 q_data->visible_width = s->r.width; 682 q_data->visible_height = s->r.height; 683 break; 684 default: 685 return -EINVAL; 686 } 687 return 0; 688} 689 690static int vidioc_venc_qbuf(struct file *file, void *priv, 691 struct v4l2_buffer *buf) 692{ 693 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 694 695 if (ctx->state == MTK_STATE_ABORT) { 696 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", 697 ctx->id); 698 return -EIO; 699 } 700 701 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 702} 703 704static int vidioc_venc_dqbuf(struct file *file, void *priv, 705 struct v4l2_buffer *buf) 706{ 707 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 708 709 if (ctx->state == MTK_STATE_ABORT) { 710 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", 711 ctx->id); 712 return -EIO; 713 } 714 715 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); 716} 717 718const struct v4l2_ioctl_ops mtk_venc_ioctl_ops = { 719 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 720 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 721 722 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 723 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 724 .vidioc_qbuf = vidioc_venc_qbuf, 725 .vidioc_dqbuf = vidioc_venc_dqbuf, 726 727 .vidioc_querycap = vidioc_venc_querycap, 728 .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane, 729 .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane, 730 .vidioc_enum_framesizes = vidioc_enum_framesizes, 731 732 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane, 733 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane, 734 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 735 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 736 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 737 738 .vidioc_s_parm = vidioc_venc_s_parm, 739 .vidioc_g_parm = vidioc_venc_g_parm, 740 .vidioc_s_fmt_vid_cap_mplane = vidioc_venc_s_fmt_cap, 741 .vidioc_s_fmt_vid_out_mplane = vidioc_venc_s_fmt_out, 742 743 .vidioc_g_fmt_vid_cap_mplane = vidioc_venc_g_fmt, 744 .vidioc_g_fmt_vid_out_mplane = vidioc_venc_g_fmt, 745 746 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 747 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 748 749 .vidioc_g_selection = vidioc_venc_g_selection, 750 .vidioc_s_selection = vidioc_venc_s_selection, 751}; 752 753static int vb2ops_venc_queue_setup(struct vb2_queue *vq, 754 unsigned int *nbuffers, 755 unsigned int *nplanes, 756 unsigned int sizes[], 757 struct device *alloc_devs[]) 758{ 759 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq); 760 struct mtk_q_data *q_data; 761 unsigned int i; 762 763 q_data = mtk_venc_get_q_data(ctx, vq->type); 764 765 if (q_data == NULL) 766 return -EINVAL; 767 768 if (*nplanes) { 769 for (i = 0; i < *nplanes; i++) 770 if (sizes[i] < q_data->sizeimage[i]) 771 return -EINVAL; 772 } else { 773 *nplanes = q_data->fmt->num_planes; 774 for (i = 0; i < *nplanes; i++) 775 sizes[i] = q_data->sizeimage[i]; 776 } 777 778 return 0; 779} 780 781static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb) 782{ 783 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 784 struct mtk_q_data *q_data; 785 int i; 786 787 q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type); 788 789 for (i = 0; i < q_data->fmt->num_planes; i++) { 790 if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { 791 mtk_v4l2_err("data will not fit into plane %d (%lu < %d)", 792 i, vb2_plane_size(vb, i), 793 q_data->sizeimage[i]); 794 return -EINVAL; 795 } 796 } 797 798 return 0; 799} 800 801static void vb2ops_venc_buf_queue(struct vb2_buffer *vb) 802{ 803 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 804 struct vb2_v4l2_buffer *vb2_v4l2 = 805 container_of(vb, struct vb2_v4l2_buffer, vb2_buf); 806 807 struct mtk_video_enc_buf *mtk_buf = 808 container_of(vb2_v4l2, struct mtk_video_enc_buf, vb); 809 810 if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && 811 (ctx->param_change != MTK_ENCODE_PARAM_NONE)) { 812 mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x", 813 ctx->id, 814 mtk_buf->vb.vb2_buf.index, 815 ctx->param_change); 816 mtk_buf->param_change = ctx->param_change; 817 mtk_buf->enc_params = ctx->enc_params; 818 ctx->param_change = MTK_ENCODE_PARAM_NONE; 819 } 820 821 v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb)); 822} 823 824static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) 825{ 826 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); 827 struct venc_enc_param param; 828 int ret; 829 int i; 830 831 /* Once state turn into MTK_STATE_ABORT, we need stop_streaming 832 * to clear it 833 */ 834 if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) { 835 ret = -EIO; 836 goto err_set_param; 837 } 838 839 /* Do the initialization when both start_streaming have been called */ 840 if (V4L2_TYPE_IS_OUTPUT(q->type)) { 841 if (!vb2_start_streaming_called(&ctx->m2m_ctx->cap_q_ctx.q)) 842 return 0; 843 } else { 844 if (!vb2_start_streaming_called(&ctx->m2m_ctx->out_q_ctx.q)) 845 return 0; 846 } 847 848 mtk_venc_set_param(ctx, &param); 849 ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, &param); 850 if (ret) { 851 mtk_v4l2_err("venc_if_set_param failed=%d", ret); 852 ctx->state = MTK_STATE_ABORT; 853 goto err_set_param; 854 } 855 ctx->param_change = MTK_ENCODE_PARAM_NONE; 856 857 if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) && 858 (ctx->enc_params.seq_hdr_mode != 859 V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE)) { 860 ret = venc_if_set_param(ctx, 861 VENC_SET_PARAM_PREPEND_HEADER, 862 NULL); 863 if (ret) { 864 mtk_v4l2_err("venc_if_set_param failed=%d", ret); 865 ctx->state = MTK_STATE_ABORT; 866 goto err_set_param; 867 } 868 ctx->state = MTK_STATE_HEADER; 869 } 870 871 return 0; 872 873err_set_param: 874 for (i = 0; i < q->num_buffers; ++i) { 875 if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) { 876 mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED", 877 ctx->id, i, q->type, 878 (int)q->bufs[i]->state); 879 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q->bufs[i]), 880 VB2_BUF_STATE_QUEUED); 881 } 882 } 883 884 return ret; 885} 886 887static void vb2ops_venc_stop_streaming(struct vb2_queue *q) 888{ 889 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); 890 struct vb2_buffer *src_buf, *dst_buf; 891 int ret; 892 893 mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type); 894 895 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 896 while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { 897 dst_buf->planes[0].bytesused = 0; 898 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 899 VB2_BUF_STATE_ERROR); 900 } 901 } else { 902 while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) 903 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), 904 VB2_BUF_STATE_ERROR); 905 } 906 907 if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 908 vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q)) || 909 (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 910 vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q))) { 911 mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d", 912 ctx->id, q->type, 913 vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q), 914 vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q)); 915 return; 916 } 917 918 /* Release the encoder if both streams are stopped. */ 919 ret = venc_if_deinit(ctx); 920 if (ret) 921 mtk_v4l2_err("venc_if_deinit failed=%d", ret); 922 923 ctx->state = MTK_STATE_FREE; 924} 925 926static const struct vb2_ops mtk_venc_vb2_ops = { 927 .queue_setup = vb2ops_venc_queue_setup, 928 .buf_prepare = vb2ops_venc_buf_prepare, 929 .buf_queue = vb2ops_venc_buf_queue, 930 .wait_prepare = vb2_ops_wait_prepare, 931 .wait_finish = vb2_ops_wait_finish, 932 .start_streaming = vb2ops_venc_start_streaming, 933 .stop_streaming = vb2ops_venc_stop_streaming, 934}; 935 936static int mtk_venc_encode_header(void *priv) 937{ 938 struct mtk_vcodec_ctx *ctx = priv; 939 int ret; 940 struct vb2_buffer *src_buf, *dst_buf; 941 struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; 942 struct mtk_vcodec_mem bs_buf; 943 struct venc_done_result enc_result; 944 945 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 946 if (!dst_buf) { 947 mtk_v4l2_debug(1, "No dst buffer"); 948 return -EINVAL; 949 } 950 951 bs_buf.va = vb2_plane_vaddr(dst_buf, 0); 952 bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); 953 bs_buf.size = (size_t)dst_buf->planes[0].length; 954 955 mtk_v4l2_debug(1, 956 "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", 957 ctx->id, 958 dst_buf->index, bs_buf.va, 959 (u64)bs_buf.dma_addr, 960 bs_buf.size); 961 962 ret = venc_if_encode(ctx, 963 VENC_START_OPT_ENCODE_SEQUENCE_HEADER, 964 NULL, &bs_buf, &enc_result); 965 966 if (ret) { 967 dst_buf->planes[0].bytesused = 0; 968 ctx->state = MTK_STATE_ABORT; 969 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 970 VB2_BUF_STATE_ERROR); 971 mtk_v4l2_err("venc_if_encode failed=%d", ret); 972 return -EINVAL; 973 } 974 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 975 if (src_buf) { 976 src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); 977 dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf); 978 dst_buf->timestamp = src_buf->timestamp; 979 dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode; 980 } else { 981 mtk_v4l2_err("No timestamp for the header buffer."); 982 } 983 984 ctx->state = MTK_STATE_HEADER; 985 dst_buf->planes[0].bytesused = enc_result.bs_size; 986 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), VB2_BUF_STATE_DONE); 987 988 return 0; 989} 990 991static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) 992{ 993 struct venc_enc_param enc_prm; 994 struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 995 struct vb2_v4l2_buffer *vb2_v4l2 = 996 container_of(vb, struct vb2_v4l2_buffer, vb2_buf); 997 struct mtk_video_enc_buf *mtk_buf = 998 container_of(vb2_v4l2, struct mtk_video_enc_buf, vb); 999 1000 int ret = 0; 1001 1002 memset(&enc_prm, 0, sizeof(enc_prm)); 1003 if (mtk_buf->param_change == MTK_ENCODE_PARAM_NONE) 1004 return 0; 1005 1006 if (mtk_buf->param_change & MTK_ENCODE_PARAM_BITRATE) { 1007 enc_prm.bitrate = mtk_buf->enc_params.bitrate; 1008 mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d", 1009 ctx->id, 1010 mtk_buf->vb.vb2_buf.index, 1011 enc_prm.bitrate); 1012 ret |= venc_if_set_param(ctx, 1013 VENC_SET_PARAM_ADJUST_BITRATE, 1014 &enc_prm); 1015 } 1016 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FRAMERATE) { 1017 enc_prm.frm_rate = mtk_buf->enc_params.framerate_num / 1018 mtk_buf->enc_params.framerate_denom; 1019 mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d", 1020 ctx->id, 1021 mtk_buf->vb.vb2_buf.index, 1022 enc_prm.frm_rate); 1023 ret |= venc_if_set_param(ctx, 1024 VENC_SET_PARAM_ADJUST_FRAMERATE, 1025 &enc_prm); 1026 } 1027 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_GOP_SIZE) { 1028 enc_prm.gop_size = mtk_buf->enc_params.gop_size; 1029 mtk_v4l2_debug(1, "change param intra period=%d", 1030 enc_prm.gop_size); 1031 ret |= venc_if_set_param(ctx, 1032 VENC_SET_PARAM_GOP_SIZE, 1033 &enc_prm); 1034 } 1035 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) { 1036 mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d", 1037 ctx->id, 1038 mtk_buf->vb.vb2_buf.index, 1039 mtk_buf->enc_params.force_intra); 1040 if (mtk_buf->enc_params.force_intra) 1041 ret |= venc_if_set_param(ctx, 1042 VENC_SET_PARAM_FORCE_INTRA, 1043 NULL); 1044 } 1045 1046 mtk_buf->param_change = MTK_ENCODE_PARAM_NONE; 1047 1048 if (ret) { 1049 ctx->state = MTK_STATE_ABORT; 1050 mtk_v4l2_err("venc_if_set_param %d failed=%d", 1051 mtk_buf->param_change, ret); 1052 return -1; 1053 } 1054 1055 return 0; 1056} 1057 1058/* 1059 * v4l2_m2m_streamoff() holds dev_mutex and waits mtk_venc_worker() 1060 * to call v4l2_m2m_job_finish(). 1061 * If mtk_venc_worker() tries to acquire dev_mutex, it will deadlock. 1062 * So this function must not try to acquire dev->dev_mutex. 1063 * This means v4l2 ioctls and mtk_venc_worker() can run at the same time. 1064 * mtk_venc_worker() should be carefully implemented to avoid bugs. 1065 */ 1066static void mtk_venc_worker(struct work_struct *work) 1067{ 1068 struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx, 1069 encode_work); 1070 struct vb2_buffer *src_buf, *dst_buf; 1071 struct venc_frm_buf frm_buf; 1072 struct mtk_vcodec_mem bs_buf; 1073 struct venc_done_result enc_result; 1074 int ret, i; 1075 struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; 1076 1077 /* check dst_buf, dst_buf may be removed in device_run 1078 * to stored encdoe header so we need check dst_buf and 1079 * call job_finish here to prevent recursion 1080 */ 1081 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 1082 if (!dst_buf) { 1083 v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx); 1084 return; 1085 } 1086 1087 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 1088 memset(&frm_buf, 0, sizeof(frm_buf)); 1089 for (i = 0; i < src_buf->num_planes ; i++) { 1090 frm_buf.fb_addr[i].dma_addr = 1091 vb2_dma_contig_plane_dma_addr(src_buf, i); 1092 frm_buf.fb_addr[i].size = 1093 (size_t)src_buf->planes[i].length; 1094 } 1095 bs_buf.va = vb2_plane_vaddr(dst_buf, 0); 1096 bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); 1097 bs_buf.size = (size_t)dst_buf->planes[0].length; 1098 1099 mtk_v4l2_debug(2, 1100 "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu", 1101 (u64)frm_buf.fb_addr[0].dma_addr, 1102 frm_buf.fb_addr[0].size, 1103 (u64)frm_buf.fb_addr[1].dma_addr, 1104 frm_buf.fb_addr[1].size, 1105 (u64)frm_buf.fb_addr[2].dma_addr, 1106 frm_buf.fb_addr[2].size); 1107 1108 ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME, 1109 &frm_buf, &bs_buf, &enc_result); 1110 1111 src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); 1112 dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf); 1113 1114 dst_buf->timestamp = src_buf->timestamp; 1115 dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode; 1116 1117 if (enc_result.is_key_frm) 1118 dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME; 1119 1120 if (ret) { 1121 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), 1122 VB2_BUF_STATE_ERROR); 1123 dst_buf->planes[0].bytesused = 0; 1124 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 1125 VB2_BUF_STATE_ERROR); 1126 mtk_v4l2_err("venc_if_encode failed=%d", ret); 1127 } else { 1128 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), 1129 VB2_BUF_STATE_DONE); 1130 dst_buf->planes[0].bytesused = enc_result.bs_size; 1131 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 1132 VB2_BUF_STATE_DONE); 1133 mtk_v4l2_debug(2, "venc_if_encode bs size=%d", 1134 enc_result.bs_size); 1135 } 1136 1137 v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx); 1138 1139 mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>", 1140 src_buf->index, dst_buf->index, ret, 1141 enc_result.bs_size); 1142} 1143 1144static void m2mops_venc_device_run(void *priv) 1145{ 1146 struct mtk_vcodec_ctx *ctx = priv; 1147 1148 if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) && 1149 (ctx->state != MTK_STATE_HEADER)) { 1150 /* encode h264 sps/pps header */ 1151 mtk_venc_encode_header(ctx); 1152 queue_work(ctx->dev->encode_workqueue, &ctx->encode_work); 1153 return; 1154 } 1155 1156 mtk_venc_param_change(ctx); 1157 queue_work(ctx->dev->encode_workqueue, &ctx->encode_work); 1158} 1159 1160static int m2mops_venc_job_ready(void *m2m_priv) 1161{ 1162 struct mtk_vcodec_ctx *ctx = m2m_priv; 1163 1164 if (ctx->state == MTK_STATE_ABORT || ctx->state == MTK_STATE_FREE) { 1165 mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.", 1166 ctx->id, ctx->state); 1167 return 0; 1168 } 1169 1170 return 1; 1171} 1172 1173static void m2mops_venc_job_abort(void *priv) 1174{ 1175 struct mtk_vcodec_ctx *ctx = priv; 1176 1177 ctx->state = MTK_STATE_ABORT; 1178} 1179 1180const struct v4l2_m2m_ops mtk_venc_m2m_ops = { 1181 .device_run = m2mops_venc_device_run, 1182 .job_ready = m2mops_venc_job_ready, 1183 .job_abort = m2mops_venc_job_abort, 1184}; 1185 1186void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx) 1187{ 1188 struct mtk_q_data *q_data; 1189 1190 ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex; 1191 ctx->fh.m2m_ctx = ctx->m2m_ctx; 1192 ctx->fh.ctrl_handler = &ctx->ctrl_hdl; 1193 INIT_WORK(&ctx->encode_work, mtk_venc_worker); 1194 1195 ctx->colorspace = V4L2_COLORSPACE_REC709; 1196 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 1197 ctx->quantization = V4L2_QUANTIZATION_DEFAULT; 1198 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; 1199 1200 q_data = &ctx->q_data[MTK_Q_DATA_SRC]; 1201 memset(q_data, 0, sizeof(struct mtk_q_data)); 1202 q_data->visible_width = DFT_CFG_WIDTH; 1203 q_data->visible_height = DFT_CFG_HEIGHT; 1204 q_data->coded_width = DFT_CFG_WIDTH; 1205 q_data->coded_height = DFT_CFG_HEIGHT; 1206 q_data->field = V4L2_FIELD_NONE; 1207 1208 q_data->fmt = &mtk_video_formats[OUT_FMT_IDX]; 1209 1210 v4l_bound_align_image(&q_data->coded_width, 1211 MTK_VENC_MIN_W, 1212 MTK_VENC_MAX_W, 4, 1213 &q_data->coded_height, 1214 MTK_VENC_MIN_H, 1215 MTK_VENC_MAX_H, 5, 6); 1216 1217 if (q_data->coded_width < DFT_CFG_WIDTH && 1218 (q_data->coded_width + 16) <= MTK_VENC_MAX_W) 1219 q_data->coded_width += 16; 1220 if (q_data->coded_height < DFT_CFG_HEIGHT && 1221 (q_data->coded_height + 32) <= MTK_VENC_MAX_H) 1222 q_data->coded_height += 32; 1223 1224 q_data->sizeimage[0] = 1225 q_data->coded_width * q_data->coded_height+ 1226 ((ALIGN(q_data->coded_width, 16) * 2) * 16); 1227 q_data->bytesperline[0] = q_data->coded_width; 1228 q_data->sizeimage[1] = 1229 (q_data->coded_width * q_data->coded_height) / 2 + 1230 (ALIGN(q_data->coded_width, 16) * 16); 1231 q_data->bytesperline[1] = q_data->coded_width; 1232 1233 q_data = &ctx->q_data[MTK_Q_DATA_DST]; 1234 memset(q_data, 0, sizeof(struct mtk_q_data)); 1235 q_data->coded_width = DFT_CFG_WIDTH; 1236 q_data->coded_height = DFT_CFG_HEIGHT; 1237 q_data->fmt = &mtk_video_formats[CAP_FMT_IDX]; 1238 q_data->field = V4L2_FIELD_NONE; 1239 ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] = 1240 DFT_CFG_WIDTH * DFT_CFG_HEIGHT; 1241 ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = 0; 1242 1243} 1244 1245int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) 1246{ 1247 const struct v4l2_ctrl_ops *ops = &mtk_vcodec_enc_ctrl_ops; 1248 struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; 1249 1250 v4l2_ctrl_handler_init(handler, MTK_MAX_CTRLS_HINT); 1251 1252 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE, 1253 1, 4000000, 1, 4000000); 1254 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_B_FRAMES, 1255 0, 2, 1, 0); 1256 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 1257 0, 1, 1, 1); 1258 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 1259 0, 51, 1, 51); 1260 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, 1261 0, 65535, 1, 0); 1262 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1263 0, 65535, 1, 0); 1264 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, 1265 0, 1, 1, 0); 1266 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 1267 0, 0, 0, 0); 1268 v4l2_ctrl_new_std_menu(handler, ops, 1269 V4L2_CID_MPEG_VIDEO_HEADER_MODE, 1270 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, 1271 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); 1272 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, 1273 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1274 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); 1275 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, 1276 V4L2_MPEG_VIDEO_H264_LEVEL_4_2, 1277 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); 1278 if (handler->error) { 1279 mtk_v4l2_err("Init control handler fail %d", 1280 handler->error); 1281 return handler->error; 1282 } 1283 1284 v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); 1285 1286 return 0; 1287} 1288 1289int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq, 1290 struct vb2_queue *dst_vq) 1291{ 1292 struct mtk_vcodec_ctx *ctx = priv; 1293 int ret; 1294 1295 /* Note: VB2_USERPTR works with dma-contig because mt8173 1296 * support iommu 1297 * https://patchwork.kernel.org/patch/8335461/ 1298 * https://patchwork.kernel.org/patch/7596181/ 1299 */ 1300 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1301 src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; 1302 src_vq->drv_priv = ctx; 1303 src_vq->buf_struct_size = sizeof(struct mtk_video_enc_buf); 1304 src_vq->ops = &mtk_venc_vb2_ops; 1305 src_vq->mem_ops = &vb2_dma_contig_memops; 1306 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1307 src_vq->lock = &ctx->dev->dev_mutex; 1308 src_vq->dev = &ctx->dev->plat_dev->dev; 1309 1310 ret = vb2_queue_init(src_vq); 1311 if (ret) 1312 return ret; 1313 1314 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1315 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; 1316 dst_vq->drv_priv = ctx; 1317 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 1318 dst_vq->ops = &mtk_venc_vb2_ops; 1319 dst_vq->mem_ops = &vb2_dma_contig_memops; 1320 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1321 dst_vq->lock = &ctx->dev->dev_mutex; 1322 dst_vq->dev = &ctx->dev->plat_dev->dev; 1323 1324 return vb2_queue_init(dst_vq); 1325} 1326 1327int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx) 1328{ 1329 struct mtk_vcodec_dev *dev = ctx->dev; 1330 1331 mutex_unlock(&dev->enc_mutex); 1332 return 0; 1333} 1334 1335int mtk_venc_lock(struct mtk_vcodec_ctx *ctx) 1336{ 1337 struct mtk_vcodec_dev *dev = ctx->dev; 1338 1339 mutex_lock(&dev->enc_mutex); 1340 return 0; 1341} 1342 1343void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx) 1344{ 1345 int ret = venc_if_deinit(ctx); 1346 1347 if (ret) 1348 mtk_v4l2_err("venc_if_deinit failed=%d", ret); 1349 1350 ctx->state = MTK_STATE_FREE; 1351}