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 v4.8-rc7 1292 lines 36 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 strlcpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver)); 226 strlcpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); 227 strlcpy(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 return 0; 247} 248 249static int vidioc_venc_g_parm(struct file *file, void *priv, 250 struct v4l2_streamparm *a) 251{ 252 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 253 254 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 255 return -EINVAL; 256 257 a->parm.output.timeperframe.denominator = 258 ctx->enc_params.framerate_num; 259 a->parm.output.timeperframe.numerator = 260 ctx->enc_params.framerate_denom; 261 262 return 0; 263} 264 265static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx, 266 enum v4l2_buf_type type) 267{ 268 if (V4L2_TYPE_IS_OUTPUT(type)) 269 return &ctx->q_data[MTK_Q_DATA_SRC]; 270 271 return &ctx->q_data[MTK_Q_DATA_DST]; 272} 273 274static struct mtk_video_fmt *mtk_venc_find_format(struct v4l2_format *f) 275{ 276 struct mtk_video_fmt *fmt; 277 unsigned int k; 278 279 for (k = 0; k < NUM_FORMATS; k++) { 280 fmt = &mtk_video_formats[k]; 281 if (fmt->fourcc == f->fmt.pix.pixelformat) 282 return fmt; 283 } 284 285 return NULL; 286} 287 288/* V4L2 specification suggests the driver corrects the format struct if any of 289 * the dimensions is unsupported 290 */ 291static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_video_fmt *fmt) 292{ 293 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; 294 int i; 295 296 pix_fmt_mp->field = V4L2_FIELD_NONE; 297 298 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 299 pix_fmt_mp->num_planes = 1; 300 pix_fmt_mp->plane_fmt[0].bytesperline = 0; 301 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 302 int tmp_w, tmp_h; 303 304 pix_fmt_mp->height = clamp(pix_fmt_mp->height, 305 MTK_VENC_MIN_H, 306 MTK_VENC_MAX_H); 307 pix_fmt_mp->width = clamp(pix_fmt_mp->width, 308 MTK_VENC_MIN_W, 309 MTK_VENC_MAX_W); 310 311 /* find next closer width align 16, heign align 32, size align 312 * 64 rectangle 313 */ 314 tmp_w = pix_fmt_mp->width; 315 tmp_h = pix_fmt_mp->height; 316 v4l_bound_align_image(&pix_fmt_mp->width, 317 MTK_VENC_MIN_W, 318 MTK_VENC_MAX_W, 4, 319 &pix_fmt_mp->height, 320 MTK_VENC_MIN_H, 321 MTK_VENC_MAX_H, 5, 6); 322 323 if (pix_fmt_mp->width < tmp_w && 324 (pix_fmt_mp->width + 16) <= MTK_VENC_MAX_W) 325 pix_fmt_mp->width += 16; 326 if (pix_fmt_mp->height < tmp_h && 327 (pix_fmt_mp->height + 32) <= MTK_VENC_MAX_H) 328 pix_fmt_mp->height += 32; 329 330 mtk_v4l2_debug(0, 331 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d %d", 332 tmp_w, tmp_h, pix_fmt_mp->width, 333 pix_fmt_mp->height, 334 pix_fmt_mp->plane_fmt[0].sizeimage, 335 pix_fmt_mp->plane_fmt[1].sizeimage); 336 337 pix_fmt_mp->num_planes = fmt->num_planes; 338 pix_fmt_mp->plane_fmt[0].sizeimage = 339 pix_fmt_mp->width * pix_fmt_mp->height + 340 ((ALIGN(pix_fmt_mp->width, 16) * 2) * 16); 341 pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width; 342 343 if (pix_fmt_mp->num_planes == 2) { 344 pix_fmt_mp->plane_fmt[1].sizeimage = 345 (pix_fmt_mp->width * pix_fmt_mp->height) / 2 + 346 (ALIGN(pix_fmt_mp->width, 16) * 16); 347 pix_fmt_mp->plane_fmt[2].sizeimage = 0; 348 pix_fmt_mp->plane_fmt[1].bytesperline = 349 pix_fmt_mp->width; 350 pix_fmt_mp->plane_fmt[2].bytesperline = 0; 351 } else if (pix_fmt_mp->num_planes == 3) { 352 pix_fmt_mp->plane_fmt[1].sizeimage = 353 pix_fmt_mp->plane_fmt[2].sizeimage = 354 (pix_fmt_mp->width * pix_fmt_mp->height) / 4 + 355 ((ALIGN(pix_fmt_mp->width, 16) / 2) * 16); 356 pix_fmt_mp->plane_fmt[1].bytesperline = 357 pix_fmt_mp->plane_fmt[2].bytesperline = 358 pix_fmt_mp->width / 2; 359 } 360 } 361 362 for (i = 0; i < pix_fmt_mp->num_planes; i++) 363 memset(&(pix_fmt_mp->plane_fmt[i].reserved[0]), 0x0, 364 sizeof(pix_fmt_mp->plane_fmt[0].reserved)); 365 366 pix_fmt_mp->flags = 0; 367 memset(&pix_fmt_mp->reserved, 0x0, 368 sizeof(pix_fmt_mp->reserved)); 369 370 return 0; 371} 372 373static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx, 374 struct venc_enc_param *param) 375{ 376 struct mtk_q_data *q_data_src = &ctx->q_data[MTK_Q_DATA_SRC]; 377 struct mtk_enc_params *enc_params = &ctx->enc_params; 378 379 switch (q_data_src->fmt->fourcc) { 380 case V4L2_PIX_FMT_YUV420M: 381 param->input_yuv_fmt = VENC_YUV_FORMAT_I420; 382 break; 383 case V4L2_PIX_FMT_YVU420M: 384 param->input_yuv_fmt = VENC_YUV_FORMAT_YV12; 385 break; 386 case V4L2_PIX_FMT_NV12M: 387 param->input_yuv_fmt = VENC_YUV_FORMAT_NV12; 388 break; 389 case V4L2_PIX_FMT_NV21M: 390 param->input_yuv_fmt = VENC_YUV_FORMAT_NV21; 391 break; 392 default: 393 mtk_v4l2_err("Unsupport fourcc =%d", q_data_src->fmt->fourcc); 394 break; 395 } 396 param->h264_profile = enc_params->h264_profile; 397 param->h264_level = enc_params->h264_level; 398 399 /* Config visible resolution */ 400 param->width = q_data_src->visible_width; 401 param->height = q_data_src->visible_height; 402 /* Config coded resolution */ 403 param->buf_width = q_data_src->coded_width; 404 param->buf_height = q_data_src->coded_height; 405 param->frm_rate = enc_params->framerate_num / 406 enc_params->framerate_denom; 407 param->intra_period = enc_params->intra_period; 408 param->gop_size = enc_params->gop_size; 409 param->bitrate = enc_params->bitrate; 410 411 mtk_v4l2_debug(0, 412 "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d", 413 param->input_yuv_fmt, param->h264_profile, 414 param->h264_level, param->width, param->height, 415 param->buf_width, param->buf_height, 416 param->frm_rate, param->bitrate, 417 param->gop_size, param->intra_period); 418} 419 420static int vidioc_venc_s_fmt_cap(struct file *file, void *priv, 421 struct v4l2_format *f) 422{ 423 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 424 struct vb2_queue *vq; 425 struct mtk_q_data *q_data; 426 int i, ret; 427 struct mtk_video_fmt *fmt; 428 429 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 430 if (!vq) { 431 mtk_v4l2_err("fail to get vq"); 432 return -EINVAL; 433 } 434 435 if (vb2_is_busy(vq)) { 436 mtk_v4l2_err("queue busy"); 437 return -EBUSY; 438 } 439 440 q_data = mtk_venc_get_q_data(ctx, f->type); 441 if (!q_data) { 442 mtk_v4l2_err("fail to get q data"); 443 return -EINVAL; 444 } 445 446 fmt = mtk_venc_find_format(f); 447 if (!fmt) { 448 f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; 449 fmt = mtk_venc_find_format(f); 450 } 451 452 q_data->fmt = fmt; 453 ret = vidioc_try_fmt(f, q_data->fmt); 454 if (ret) 455 return ret; 456 457 q_data->coded_width = f->fmt.pix_mp.width; 458 q_data->coded_height = f->fmt.pix_mp.height; 459 q_data->field = f->fmt.pix_mp.field; 460 461 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { 462 struct v4l2_plane_pix_format *plane_fmt; 463 464 plane_fmt = &f->fmt.pix_mp.plane_fmt[i]; 465 q_data->bytesperline[i] = plane_fmt->bytesperline; 466 q_data->sizeimage[i] = plane_fmt->sizeimage; 467 } 468 469 if (ctx->state == MTK_STATE_FREE) { 470 ret = venc_if_init(ctx, q_data->fmt->fourcc); 471 if (ret) { 472 mtk_v4l2_err("venc_if_init failed=%d, codec type=%x", 473 ret, q_data->fmt->fourcc); 474 return -EBUSY; 475 } 476 ctx->state = MTK_STATE_INIT; 477 } 478 479 return 0; 480} 481 482static int vidioc_venc_s_fmt_out(struct file *file, void *priv, 483 struct v4l2_format *f) 484{ 485 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 486 struct vb2_queue *vq; 487 struct mtk_q_data *q_data; 488 int ret, i; 489 struct mtk_video_fmt *fmt; 490 unsigned int pitch_w_div16; 491 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; 492 493 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 494 if (!vq) { 495 mtk_v4l2_err("fail to get vq"); 496 return -EINVAL; 497 } 498 499 if (vb2_is_busy(vq)) { 500 mtk_v4l2_err("queue busy"); 501 return -EBUSY; 502 } 503 504 q_data = mtk_venc_get_q_data(ctx, f->type); 505 if (!q_data) { 506 mtk_v4l2_err("fail to get q data"); 507 return -EINVAL; 508 } 509 510 fmt = mtk_venc_find_format(f); 511 if (!fmt) { 512 f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; 513 fmt = mtk_venc_find_format(f); 514 } 515 516 pix_fmt_mp->height = clamp(pix_fmt_mp->height, 517 MTK_VENC_MIN_H, 518 MTK_VENC_MAX_H); 519 pix_fmt_mp->width = clamp(pix_fmt_mp->width, 520 MTK_VENC_MIN_W, 521 MTK_VENC_MAX_W); 522 523 q_data->visible_width = f->fmt.pix_mp.width; 524 q_data->visible_height = f->fmt.pix_mp.height; 525 q_data->fmt = fmt; 526 ret = vidioc_try_fmt(f, q_data->fmt); 527 if (ret) 528 return ret; 529 530 q_data->coded_width = f->fmt.pix_mp.width; 531 q_data->coded_height = f->fmt.pix_mp.height; 532 533 pitch_w_div16 = DIV_ROUND_UP(q_data->visible_width, 16); 534 if (pitch_w_div16 % 8 != 0) { 535 /* Adjust returned width/height, so application could correctly 536 * allocate hw required memory 537 */ 538 q_data->visible_height += 32; 539 vidioc_try_fmt(f, q_data->fmt); 540 } 541 542 q_data->field = f->fmt.pix_mp.field; 543 ctx->colorspace = f->fmt.pix_mp.colorspace; 544 ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 545 ctx->quantization = f->fmt.pix_mp.quantization; 546 ctx->xfer_func = f->fmt.pix_mp.xfer_func; 547 548 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) { 549 struct v4l2_plane_pix_format *plane_fmt; 550 551 plane_fmt = &f->fmt.pix_mp.plane_fmt[i]; 552 q_data->bytesperline[i] = plane_fmt->bytesperline; 553 q_data->sizeimage[i] = plane_fmt->sizeimage; 554 } 555 556 return 0; 557} 558 559static int vidioc_venc_g_fmt(struct file *file, void *priv, 560 struct v4l2_format *f) 561{ 562 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; 563 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 564 struct vb2_queue *vq; 565 struct mtk_q_data *q_data; 566 int i; 567 568 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 569 if (!vq) 570 return -EINVAL; 571 572 q_data = mtk_venc_get_q_data(ctx, f->type); 573 574 pix->width = q_data->coded_width; 575 pix->height = q_data->coded_height; 576 pix->pixelformat = q_data->fmt->fourcc; 577 pix->field = q_data->field; 578 pix->num_planes = q_data->fmt->num_planes; 579 for (i = 0; i < pix->num_planes; i++) { 580 pix->plane_fmt[i].bytesperline = q_data->bytesperline[i]; 581 pix->plane_fmt[i].sizeimage = q_data->sizeimage[i]; 582 memset(&(pix->plane_fmt[i].reserved[0]), 0x0, 583 sizeof(pix->plane_fmt[i].reserved)); 584 } 585 586 pix->flags = 0; 587 pix->colorspace = ctx->colorspace; 588 pix->ycbcr_enc = ctx->ycbcr_enc; 589 pix->quantization = ctx->quantization; 590 pix->xfer_func = ctx->xfer_func; 591 592 return 0; 593} 594 595static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, 596 struct v4l2_format *f) 597{ 598 struct mtk_video_fmt *fmt; 599 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 600 601 fmt = mtk_venc_find_format(f); 602 if (!fmt) { 603 f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; 604 fmt = mtk_venc_find_format(f); 605 } 606 f->fmt.pix_mp.colorspace = ctx->colorspace; 607 f->fmt.pix_mp.ycbcr_enc = ctx->ycbcr_enc; 608 f->fmt.pix_mp.quantization = ctx->quantization; 609 f->fmt.pix_mp.xfer_func = ctx->xfer_func; 610 611 return vidioc_try_fmt(f, fmt); 612} 613 614static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, 615 struct v4l2_format *f) 616{ 617 struct mtk_video_fmt *fmt; 618 619 fmt = mtk_venc_find_format(f); 620 if (!fmt) { 621 f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; 622 fmt = mtk_venc_find_format(f); 623 } 624 if (!f->fmt.pix_mp.colorspace) { 625 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; 626 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 627 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 628 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 629 } 630 631 return vidioc_try_fmt(f, fmt); 632} 633 634static int vidioc_venc_qbuf(struct file *file, void *priv, 635 struct v4l2_buffer *buf) 636{ 637 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 638 639 if (ctx->state == MTK_STATE_ABORT) { 640 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", 641 ctx->id); 642 return -EIO; 643 } 644 645 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 646} 647 648static int vidioc_venc_dqbuf(struct file *file, void *priv, 649 struct v4l2_buffer *buf) 650{ 651 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); 652 653 if (ctx->state == MTK_STATE_ABORT) { 654 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error", 655 ctx->id); 656 return -EIO; 657 } 658 659 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); 660} 661 662const struct v4l2_ioctl_ops mtk_venc_ioctl_ops = { 663 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 664 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 665 666 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 667 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 668 .vidioc_qbuf = vidioc_venc_qbuf, 669 .vidioc_dqbuf = vidioc_venc_dqbuf, 670 671 .vidioc_querycap = vidioc_venc_querycap, 672 .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane, 673 .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane, 674 .vidioc_enum_framesizes = vidioc_enum_framesizes, 675 676 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane, 677 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane, 678 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 679 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 680 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 681 682 .vidioc_s_parm = vidioc_venc_s_parm, 683 .vidioc_g_parm = vidioc_venc_g_parm, 684 .vidioc_s_fmt_vid_cap_mplane = vidioc_venc_s_fmt_cap, 685 .vidioc_s_fmt_vid_out_mplane = vidioc_venc_s_fmt_out, 686 687 .vidioc_g_fmt_vid_cap_mplane = vidioc_venc_g_fmt, 688 .vidioc_g_fmt_vid_out_mplane = vidioc_venc_g_fmt, 689 690 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 691 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 692}; 693 694static int vb2ops_venc_queue_setup(struct vb2_queue *vq, 695 unsigned int *nbuffers, 696 unsigned int *nplanes, 697 unsigned int sizes[], 698 struct device *alloc_devs[]) 699{ 700 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq); 701 struct mtk_q_data *q_data; 702 unsigned int i; 703 704 q_data = mtk_venc_get_q_data(ctx, vq->type); 705 706 if (q_data == NULL) 707 return -EINVAL; 708 709 if (*nplanes) { 710 for (i = 0; i < *nplanes; i++) 711 if (sizes[i] < q_data->sizeimage[i]) 712 return -EINVAL; 713 } else { 714 *nplanes = q_data->fmt->num_planes; 715 for (i = 0; i < *nplanes; i++) 716 sizes[i] = q_data->sizeimage[i]; 717 } 718 719 return 0; 720} 721 722static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb) 723{ 724 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 725 struct mtk_q_data *q_data; 726 int i; 727 728 q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type); 729 730 for (i = 0; i < q_data->fmt->num_planes; i++) { 731 if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) { 732 mtk_v4l2_err("data will not fit into plane %d (%lu < %d)", 733 i, vb2_plane_size(vb, i), 734 q_data->sizeimage[i]); 735 return -EINVAL; 736 } 737 } 738 739 return 0; 740} 741 742static void vb2ops_venc_buf_queue(struct vb2_buffer *vb) 743{ 744 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 745 struct vb2_v4l2_buffer *vb2_v4l2 = 746 container_of(vb, struct vb2_v4l2_buffer, vb2_buf); 747 748 struct mtk_video_enc_buf *mtk_buf = 749 container_of(vb2_v4l2, struct mtk_video_enc_buf, vb); 750 751 if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && 752 (ctx->param_change != MTK_ENCODE_PARAM_NONE)) { 753 mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x", 754 ctx->id, 755 mtk_buf->vb.vb2_buf.index, 756 ctx->param_change); 757 mtk_buf->param_change = ctx->param_change; 758 mtk_buf->enc_params = ctx->enc_params; 759 ctx->param_change = MTK_ENCODE_PARAM_NONE; 760 } 761 762 v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb)); 763} 764 765static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) 766{ 767 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); 768 struct venc_enc_param param; 769 int ret; 770 int i; 771 772 /* Once state turn into MTK_STATE_ABORT, we need stop_streaming 773 * to clear it 774 */ 775 if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) { 776 ret = -EIO; 777 goto err_set_param; 778 } 779 780 /* Do the initialization when both start_streaming have been called */ 781 if (V4L2_TYPE_IS_OUTPUT(q->type)) { 782 if (!vb2_start_streaming_called(&ctx->m2m_ctx->cap_q_ctx.q)) 783 return 0; 784 } else { 785 if (!vb2_start_streaming_called(&ctx->m2m_ctx->out_q_ctx.q)) 786 return 0; 787 } 788 789 mtk_venc_set_param(ctx, &param); 790 ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, &param); 791 if (ret) { 792 mtk_v4l2_err("venc_if_set_param failed=%d", ret); 793 ctx->state = MTK_STATE_ABORT; 794 goto err_set_param; 795 } 796 ctx->param_change = MTK_ENCODE_PARAM_NONE; 797 798 if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) && 799 (ctx->enc_params.seq_hdr_mode != 800 V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE)) { 801 ret = venc_if_set_param(ctx, 802 VENC_SET_PARAM_PREPEND_HEADER, 803 NULL); 804 if (ret) { 805 mtk_v4l2_err("venc_if_set_param failed=%d", ret); 806 ctx->state = MTK_STATE_ABORT; 807 goto err_set_param; 808 } 809 ctx->state = MTK_STATE_HEADER; 810 } 811 812 return 0; 813 814err_set_param: 815 for (i = 0; i < q->num_buffers; ++i) { 816 if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) { 817 mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED", 818 ctx->id, i, q->type, 819 (int)q->bufs[i]->state); 820 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q->bufs[i]), 821 VB2_BUF_STATE_QUEUED); 822 } 823 } 824 825 return ret; 826} 827 828static void vb2ops_venc_stop_streaming(struct vb2_queue *q) 829{ 830 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); 831 struct vb2_buffer *src_buf, *dst_buf; 832 int ret; 833 834 mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type); 835 836 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 837 while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) { 838 dst_buf->planes[0].bytesused = 0; 839 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 840 VB2_BUF_STATE_ERROR); 841 } 842 } else { 843 while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) 844 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), 845 VB2_BUF_STATE_ERROR); 846 } 847 848 if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 849 vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q)) || 850 (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 851 vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q))) { 852 mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d", 853 ctx->id, q->type, 854 vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q), 855 vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q)); 856 return; 857 } 858 859 /* Release the encoder if both streams are stopped. */ 860 ret = venc_if_deinit(ctx); 861 if (ret) 862 mtk_v4l2_err("venc_if_deinit failed=%d", ret); 863 864 ctx->state = MTK_STATE_FREE; 865} 866 867static struct vb2_ops mtk_venc_vb2_ops = { 868 .queue_setup = vb2ops_venc_queue_setup, 869 .buf_prepare = vb2ops_venc_buf_prepare, 870 .buf_queue = vb2ops_venc_buf_queue, 871 .wait_prepare = vb2_ops_wait_prepare, 872 .wait_finish = vb2_ops_wait_finish, 873 .start_streaming = vb2ops_venc_start_streaming, 874 .stop_streaming = vb2ops_venc_stop_streaming, 875}; 876 877static int mtk_venc_encode_header(void *priv) 878{ 879 struct mtk_vcodec_ctx *ctx = priv; 880 int ret; 881 struct vb2_buffer *dst_buf; 882 struct mtk_vcodec_mem bs_buf; 883 struct venc_done_result enc_result; 884 885 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 886 if (!dst_buf) { 887 mtk_v4l2_debug(1, "No dst buffer"); 888 return -EINVAL; 889 } 890 891 bs_buf.va = vb2_plane_vaddr(dst_buf, 0); 892 bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); 893 bs_buf.size = (size_t)dst_buf->planes[0].length; 894 895 mtk_v4l2_debug(1, 896 "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", 897 ctx->id, 898 dst_buf->index, bs_buf.va, 899 (u64)bs_buf.dma_addr, 900 bs_buf.size); 901 902 ret = venc_if_encode(ctx, 903 VENC_START_OPT_ENCODE_SEQUENCE_HEADER, 904 NULL, &bs_buf, &enc_result); 905 906 if (ret) { 907 dst_buf->planes[0].bytesused = 0; 908 ctx->state = MTK_STATE_ABORT; 909 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 910 VB2_BUF_STATE_ERROR); 911 mtk_v4l2_err("venc_if_encode failed=%d", ret); 912 return -EINVAL; 913 } 914 915 ctx->state = MTK_STATE_HEADER; 916 dst_buf->planes[0].bytesused = enc_result.bs_size; 917 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), VB2_BUF_STATE_DONE); 918 919 return 0; 920} 921 922static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) 923{ 924 struct venc_enc_param enc_prm; 925 struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 926 struct vb2_v4l2_buffer *vb2_v4l2 = 927 container_of(vb, struct vb2_v4l2_buffer, vb2_buf); 928 struct mtk_video_enc_buf *mtk_buf = 929 container_of(vb2_v4l2, struct mtk_video_enc_buf, vb); 930 931 int ret = 0; 932 933 memset(&enc_prm, 0, sizeof(enc_prm)); 934 if (mtk_buf->param_change == MTK_ENCODE_PARAM_NONE) 935 return 0; 936 937 if (mtk_buf->param_change & MTK_ENCODE_PARAM_BITRATE) { 938 enc_prm.bitrate = mtk_buf->enc_params.bitrate; 939 mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d", 940 ctx->id, 941 mtk_buf->vb.vb2_buf.index, 942 enc_prm.bitrate); 943 ret |= venc_if_set_param(ctx, 944 VENC_SET_PARAM_ADJUST_BITRATE, 945 &enc_prm); 946 } 947 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FRAMERATE) { 948 enc_prm.frm_rate = mtk_buf->enc_params.framerate_num / 949 mtk_buf->enc_params.framerate_denom; 950 mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d", 951 ctx->id, 952 mtk_buf->vb.vb2_buf.index, 953 enc_prm.frm_rate); 954 ret |= venc_if_set_param(ctx, 955 VENC_SET_PARAM_ADJUST_FRAMERATE, 956 &enc_prm); 957 } 958 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_GOP_SIZE) { 959 enc_prm.gop_size = mtk_buf->enc_params.gop_size; 960 mtk_v4l2_debug(1, "change param intra period=%d", 961 enc_prm.gop_size); 962 ret |= venc_if_set_param(ctx, 963 VENC_SET_PARAM_GOP_SIZE, 964 &enc_prm); 965 } 966 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) { 967 mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d", 968 ctx->id, 969 mtk_buf->vb.vb2_buf.index, 970 mtk_buf->enc_params.force_intra); 971 if (mtk_buf->enc_params.force_intra) 972 ret |= venc_if_set_param(ctx, 973 VENC_SET_PARAM_FORCE_INTRA, 974 NULL); 975 } 976 977 mtk_buf->param_change = MTK_ENCODE_PARAM_NONE; 978 979 if (ret) { 980 ctx->state = MTK_STATE_ABORT; 981 mtk_v4l2_err("venc_if_set_param %d failed=%d", 982 mtk_buf->param_change, ret); 983 return -1; 984 } 985 986 return 0; 987} 988 989/* 990 * v4l2_m2m_streamoff() holds dev_mutex and waits mtk_venc_worker() 991 * to call v4l2_m2m_job_finish(). 992 * If mtk_venc_worker() tries to acquire dev_mutex, it will deadlock. 993 * So this function must not try to acquire dev->dev_mutex. 994 * This means v4l2 ioctls and mtk_venc_worker() can run at the same time. 995 * mtk_venc_worker() should be carefully implemented to avoid bugs. 996 */ 997static void mtk_venc_worker(struct work_struct *work) 998{ 999 struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx, 1000 encode_work); 1001 struct vb2_buffer *src_buf, *dst_buf; 1002 struct venc_frm_buf frm_buf; 1003 struct mtk_vcodec_mem bs_buf; 1004 struct venc_done_result enc_result; 1005 int ret, i; 1006 struct vb2_v4l2_buffer *vb2_v4l2; 1007 1008 /* check dst_buf, dst_buf may be removed in device_run 1009 * to stored encdoe header so we need check dst_buf and 1010 * call job_finish here to prevent recursion 1011 */ 1012 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 1013 if (!dst_buf) { 1014 v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx); 1015 return; 1016 } 1017 1018 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 1019 memset(&frm_buf, 0, sizeof(frm_buf)); 1020 for (i = 0; i < src_buf->num_planes ; i++) { 1021 frm_buf.fb_addr[i].va = vb2_plane_vaddr(src_buf, i); 1022 frm_buf.fb_addr[i].dma_addr = 1023 vb2_dma_contig_plane_dma_addr(src_buf, i); 1024 frm_buf.fb_addr[i].size = 1025 (size_t)src_buf->planes[i].length; 1026 } 1027 bs_buf.va = vb2_plane_vaddr(dst_buf, 0); 1028 bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); 1029 bs_buf.size = (size_t)dst_buf->planes[0].length; 1030 1031 mtk_v4l2_debug(2, 1032 "Framebuf VA=%p PA=%llx Size=0x%zx;VA=%p PA=0x%llx Size=0x%zx;VA=%p PA=0x%llx Size=%zu", 1033 frm_buf.fb_addr[0].va, 1034 (u64)frm_buf.fb_addr[0].dma_addr, 1035 frm_buf.fb_addr[0].size, 1036 frm_buf.fb_addr[1].va, 1037 (u64)frm_buf.fb_addr[1].dma_addr, 1038 frm_buf.fb_addr[1].size, 1039 frm_buf.fb_addr[2].va, 1040 (u64)frm_buf.fb_addr[2].dma_addr, 1041 frm_buf.fb_addr[2].size); 1042 1043 ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME, 1044 &frm_buf, &bs_buf, &enc_result); 1045 1046 vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf); 1047 if (enc_result.is_key_frm) 1048 vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME; 1049 1050 if (ret) { 1051 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), 1052 VB2_BUF_STATE_ERROR); 1053 dst_buf->planes[0].bytesused = 0; 1054 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 1055 VB2_BUF_STATE_ERROR); 1056 mtk_v4l2_err("venc_if_encode failed=%d", ret); 1057 } else { 1058 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf), 1059 VB2_BUF_STATE_DONE); 1060 dst_buf->planes[0].bytesused = enc_result.bs_size; 1061 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), 1062 VB2_BUF_STATE_DONE); 1063 mtk_v4l2_debug(2, "venc_if_encode bs size=%d", 1064 enc_result.bs_size); 1065 } 1066 1067 v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx); 1068 1069 mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>", 1070 src_buf->index, dst_buf->index, ret, 1071 enc_result.bs_size); 1072} 1073 1074static void m2mops_venc_device_run(void *priv) 1075{ 1076 struct mtk_vcodec_ctx *ctx = priv; 1077 1078 if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) && 1079 (ctx->state != MTK_STATE_HEADER)) { 1080 /* encode h264 sps/pps header */ 1081 mtk_venc_encode_header(ctx); 1082 queue_work(ctx->dev->encode_workqueue, &ctx->encode_work); 1083 return; 1084 } 1085 1086 mtk_venc_param_change(ctx); 1087 queue_work(ctx->dev->encode_workqueue, &ctx->encode_work); 1088} 1089 1090static int m2mops_venc_job_ready(void *m2m_priv) 1091{ 1092 struct mtk_vcodec_ctx *ctx = m2m_priv; 1093 1094 if (ctx->state == MTK_STATE_ABORT || ctx->state == MTK_STATE_FREE) { 1095 mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.", 1096 ctx->id, ctx->state); 1097 return 0; 1098 } 1099 1100 return 1; 1101} 1102 1103static void m2mops_venc_job_abort(void *priv) 1104{ 1105 struct mtk_vcodec_ctx *ctx = priv; 1106 1107 ctx->state = MTK_STATE_ABORT; 1108} 1109 1110static void m2mops_venc_lock(void *m2m_priv) 1111{ 1112 struct mtk_vcodec_ctx *ctx = m2m_priv; 1113 1114 mutex_lock(&ctx->dev->dev_mutex); 1115} 1116 1117static void m2mops_venc_unlock(void *m2m_priv) 1118{ 1119 struct mtk_vcodec_ctx *ctx = m2m_priv; 1120 1121 mutex_unlock(&ctx->dev->dev_mutex); 1122} 1123 1124const struct v4l2_m2m_ops mtk_venc_m2m_ops = { 1125 .device_run = m2mops_venc_device_run, 1126 .job_ready = m2mops_venc_job_ready, 1127 .job_abort = m2mops_venc_job_abort, 1128 .lock = m2mops_venc_lock, 1129 .unlock = m2mops_venc_unlock, 1130}; 1131 1132void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx) 1133{ 1134 struct mtk_q_data *q_data; 1135 1136 ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex; 1137 ctx->fh.m2m_ctx = ctx->m2m_ctx; 1138 ctx->fh.ctrl_handler = &ctx->ctrl_hdl; 1139 INIT_WORK(&ctx->encode_work, mtk_venc_worker); 1140 1141 ctx->colorspace = V4L2_COLORSPACE_REC709; 1142 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 1143 ctx->quantization = V4L2_QUANTIZATION_DEFAULT; 1144 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; 1145 1146 q_data = &ctx->q_data[MTK_Q_DATA_SRC]; 1147 memset(q_data, 0, sizeof(struct mtk_q_data)); 1148 q_data->visible_width = DFT_CFG_WIDTH; 1149 q_data->visible_height = DFT_CFG_HEIGHT; 1150 q_data->coded_width = DFT_CFG_WIDTH; 1151 q_data->coded_height = DFT_CFG_HEIGHT; 1152 q_data->field = V4L2_FIELD_NONE; 1153 1154 q_data->fmt = &mtk_video_formats[OUT_FMT_IDX]; 1155 1156 v4l_bound_align_image(&q_data->coded_width, 1157 MTK_VENC_MIN_W, 1158 MTK_VENC_MAX_W, 4, 1159 &q_data->coded_height, 1160 MTK_VENC_MIN_H, 1161 MTK_VENC_MAX_H, 5, 6); 1162 1163 if (q_data->coded_width < DFT_CFG_WIDTH && 1164 (q_data->coded_width + 16) <= MTK_VENC_MAX_W) 1165 q_data->coded_width += 16; 1166 if (q_data->coded_height < DFT_CFG_HEIGHT && 1167 (q_data->coded_height + 32) <= MTK_VENC_MAX_H) 1168 q_data->coded_height += 32; 1169 1170 q_data->sizeimage[0] = 1171 q_data->coded_width * q_data->coded_height+ 1172 ((ALIGN(q_data->coded_width, 16) * 2) * 16); 1173 q_data->bytesperline[0] = q_data->coded_width; 1174 q_data->sizeimage[1] = 1175 (q_data->coded_width * q_data->coded_height) / 2 + 1176 (ALIGN(q_data->coded_width, 16) * 16); 1177 q_data->bytesperline[1] = q_data->coded_width; 1178 1179 q_data = &ctx->q_data[MTK_Q_DATA_DST]; 1180 memset(q_data, 0, sizeof(struct mtk_q_data)); 1181 q_data->coded_width = DFT_CFG_WIDTH; 1182 q_data->coded_height = DFT_CFG_HEIGHT; 1183 q_data->fmt = &mtk_video_formats[CAP_FMT_IDX]; 1184 q_data->field = V4L2_FIELD_NONE; 1185 ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] = 1186 DFT_CFG_WIDTH * DFT_CFG_HEIGHT; 1187 ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = 0; 1188 1189} 1190 1191int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) 1192{ 1193 const struct v4l2_ctrl_ops *ops = &mtk_vcodec_enc_ctrl_ops; 1194 struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl; 1195 1196 v4l2_ctrl_handler_init(handler, MTK_MAX_CTRLS_HINT); 1197 1198 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE, 1199 1, 4000000, 1, 4000000); 1200 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_B_FRAMES, 1201 0, 2, 1, 0); 1202 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 1203 0, 1, 1, 1); 1204 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 1205 0, 51, 1, 51); 1206 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, 1207 0, 65535, 1, 0); 1208 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1209 0, 65535, 1, 0); 1210 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, 1211 0, 1, 1, 0); 1212 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 1213 0, 0, 0, 0); 1214 v4l2_ctrl_new_std_menu(handler, ops, 1215 V4L2_CID_MPEG_VIDEO_HEADER_MODE, 1216 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, 1217 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); 1218 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, 1219 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, 1220 0, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN); 1221 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, 1222 V4L2_MPEG_VIDEO_H264_LEVEL_4_2, 1223 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0); 1224 if (handler->error) { 1225 mtk_v4l2_err("Init control handler fail %d", 1226 handler->error); 1227 return handler->error; 1228 } 1229 1230 v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); 1231 1232 return 0; 1233} 1234 1235int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq, 1236 struct vb2_queue *dst_vq) 1237{ 1238 struct mtk_vcodec_ctx *ctx = priv; 1239 int ret; 1240 1241 /* Note: VB2_USERPTR works with dma-contig because mt8173 1242 * support iommu 1243 * https://patchwork.kernel.org/patch/8335461/ 1244 * https://patchwork.kernel.org/patch/7596181/ 1245 */ 1246 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1247 src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; 1248 src_vq->drv_priv = ctx; 1249 src_vq->buf_struct_size = sizeof(struct mtk_video_enc_buf); 1250 src_vq->ops = &mtk_venc_vb2_ops; 1251 src_vq->mem_ops = &vb2_dma_contig_memops; 1252 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1253 src_vq->lock = &ctx->dev->dev_mutex; 1254 src_vq->dev = &ctx->dev->plat_dev->dev; 1255 1256 ret = vb2_queue_init(src_vq); 1257 if (ret) 1258 return ret; 1259 1260 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1261 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR; 1262 dst_vq->drv_priv = ctx; 1263 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 1264 dst_vq->ops = &mtk_venc_vb2_ops; 1265 dst_vq->mem_ops = &vb2_dma_contig_memops; 1266 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1267 dst_vq->lock = &ctx->dev->dev_mutex; 1268 dst_vq->dev = &ctx->dev->plat_dev->dev; 1269 1270 return vb2_queue_init(dst_vq); 1271} 1272 1273int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx) 1274{ 1275 struct mtk_vcodec_dev *dev = ctx->dev; 1276 1277 mutex_unlock(&dev->enc_mutex); 1278 return 0; 1279} 1280 1281int mtk_venc_lock(struct mtk_vcodec_ctx *ctx) 1282{ 1283 struct mtk_vcodec_dev *dev = ctx->dev; 1284 1285 mutex_lock(&dev->enc_mutex); 1286 return 0; 1287} 1288 1289void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx) 1290{ 1291 venc_if_deinit(ctx); 1292}