2 * Copyright (c) 2016 MediaTek Inc.
3 * Author: PC Chen <pc.chen@mediatek.com>
4 * Tiffany Lin <tiffany.lin@mediatek.com>
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.
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.
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>
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"
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
38 static void mtk_venc_worker(struct work_struct
*work
);
40 static struct mtk_video_fmt mtk_video_formats
[] = {
42 .fourcc
= V4L2_PIX_FMT_NV12M
,
43 .type
= MTK_FMT_FRAME
,
47 .fourcc
= V4L2_PIX_FMT_NV21M
,
48 .type
= MTK_FMT_FRAME
,
52 .fourcc
= V4L2_PIX_FMT_YUV420M
,
53 .type
= MTK_FMT_FRAME
,
57 .fourcc
= V4L2_PIX_FMT_YVU420M
,
58 .type
= MTK_FMT_FRAME
,
62 .fourcc
= V4L2_PIX_FMT_H264
,
67 .fourcc
= V4L2_PIX_FMT_VP8
,
73 #define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
75 static const struct mtk_codec_framesizes mtk_venc_framesizes
[] = {
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 },
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 },
88 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_venc_framesizes)
90 static int vidioc_venc_s_ctrl(struct v4l2_ctrl
*ctrl
)
92 struct mtk_vcodec_ctx
*ctx
= ctrl_to_ctx(ctrl
);
93 struct mtk_enc_params
*p
= &ctx
->enc_params
;
97 case V4L2_CID_MPEG_VIDEO_BITRATE
:
98 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d",
100 p
->bitrate
= ctrl
->val
;
101 ctx
->param_change
|= MTK_ENCODE_PARAM_BITRATE
;
103 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
104 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d",
106 p
->num_b_frame
= ctrl
->val
;
108 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
:
109 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d",
111 p
->rc_frame
= ctrl
->val
;
113 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP
:
114 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d",
116 p
->h264_max_qp
= ctrl
->val
;
118 case V4L2_CID_MPEG_VIDEO_HEADER_MODE
:
119 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d",
121 p
->seq_hdr_mode
= ctrl
->val
;
123 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
:
124 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d",
126 p
->rc_mb
= ctrl
->val
;
128 case V4L2_CID_MPEG_VIDEO_H264_PROFILE
:
129 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d",
131 p
->h264_profile
= ctrl
->val
;
133 case V4L2_CID_MPEG_VIDEO_H264_LEVEL
:
134 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d",
136 p
->h264_level
= ctrl
->val
;
138 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
:
139 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d",
141 p
->intra_period
= ctrl
->val
;
142 ctx
->param_change
|= MTK_ENCODE_PARAM_INTRA_PERIOD
;
144 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
145 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d",
147 p
->gop_size
= ctrl
->val
;
148 ctx
->param_change
|= MTK_ENCODE_PARAM_GOP_SIZE
;
150 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
:
151 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME");
153 ctx
->param_change
|= MTK_ENCODE_PARAM_FORCE_INTRA
;
163 static const struct v4l2_ctrl_ops mtk_vcodec_enc_ctrl_ops
= {
164 .s_ctrl
= vidioc_venc_s_ctrl
,
167 static int vidioc_enum_fmt(struct v4l2_fmtdesc
*f
, bool output_queue
)
169 struct mtk_video_fmt
*fmt
;
172 for (i
= 0; i
< NUM_FORMATS
; ++i
) {
173 if (output_queue
&& mtk_video_formats
[i
].type
!= MTK_FMT_FRAME
)
175 if (!output_queue
&& mtk_video_formats
[i
].type
!= MTK_FMT_ENC
)
179 fmt
= &mtk_video_formats
[i
];
180 f
->pixelformat
= fmt
->fourcc
;
181 memset(f
->reserved
, 0, sizeof(f
->reserved
));
190 static int vidioc_enum_framesizes(struct file
*file
, void *fh
,
191 struct v4l2_frmsizeenum
*fsize
)
195 if (fsize
->index
!= 0)
198 for (i
= 0; i
< NUM_SUPPORTED_FRAMESIZE
; ++i
) {
199 if (fsize
->pixel_format
!= mtk_venc_framesizes
[i
].fourcc
)
202 fsize
->type
= V4L2_FRMSIZE_TYPE_STEPWISE
;
203 fsize
->stepwise
= mtk_venc_framesizes
[i
].stepwise
;
210 static int vidioc_enum_fmt_vid_cap_mplane(struct file
*file
, void *pirv
,
211 struct v4l2_fmtdesc
*f
)
213 return vidioc_enum_fmt(f
, false);
216 static int vidioc_enum_fmt_vid_out_mplane(struct file
*file
, void *prov
,
217 struct v4l2_fmtdesc
*f
)
219 return vidioc_enum_fmt(f
, true);
222 static int vidioc_venc_querycap(struct file
*file
, void *priv
,
223 struct v4l2_capability
*cap
)
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
));
232 static int vidioc_venc_s_parm(struct file
*file
, void *priv
,
233 struct v4l2_streamparm
*a
)
235 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
237 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
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
;
249 static int vidioc_venc_g_parm(struct file
*file
, void *priv
,
250 struct v4l2_streamparm
*a
)
252 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
254 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
257 a
->parm
.output
.timeperframe
.denominator
=
258 ctx
->enc_params
.framerate_num
;
259 a
->parm
.output
.timeperframe
.numerator
=
260 ctx
->enc_params
.framerate_denom
;
265 static struct mtk_q_data
*mtk_venc_get_q_data(struct mtk_vcodec_ctx
*ctx
,
266 enum v4l2_buf_type type
)
268 if (V4L2_TYPE_IS_OUTPUT(type
))
269 return &ctx
->q_data
[MTK_Q_DATA_SRC
];
271 return &ctx
->q_data
[MTK_Q_DATA_DST
];
274 static struct mtk_video_fmt
*mtk_venc_find_format(struct v4l2_format
*f
)
276 struct mtk_video_fmt
*fmt
;
279 for (k
= 0; k
< NUM_FORMATS
; k
++) {
280 fmt
= &mtk_video_formats
[k
];
281 if (fmt
->fourcc
== f
->fmt
.pix
.pixelformat
)
288 /* V4L2 specification suggests the driver corrects the format struct if any of
289 * the dimensions is unsupported
291 static int vidioc_try_fmt(struct v4l2_format
*f
, struct mtk_video_fmt
*fmt
)
293 struct v4l2_pix_format_mplane
*pix_fmt_mp
= &f
->fmt
.pix_mp
;
296 pix_fmt_mp
->field
= V4L2_FIELD_NONE
;
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
) {
304 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
307 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
311 /* find next closer width align 16, heign align 32, size align
314 tmp_w
= pix_fmt_mp
->width
;
315 tmp_h
= pix_fmt_mp
->height
;
316 v4l_bound_align_image(&pix_fmt_mp
->width
,
321 MTK_VENC_MAX_H
, 5, 6);
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;
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
,
334 pix_fmt_mp
->plane_fmt
[0].sizeimage
,
335 pix_fmt_mp
->plane_fmt
[1].sizeimage
);
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
;
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
=
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;
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
));
366 pix_fmt_mp
->flags
= 0;
367 memset(&pix_fmt_mp
->reserved
, 0x0,
368 sizeof(pix_fmt_mp
->reserved
));
373 static void mtk_venc_set_param(struct mtk_vcodec_ctx
*ctx
,
374 struct venc_enc_param
*param
)
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
;
379 switch (q_data_src
->fmt
->fourcc
) {
380 case V4L2_PIX_FMT_YUV420M
:
381 param
->input_yuv_fmt
= VENC_YUV_FORMAT_I420
;
383 case V4L2_PIX_FMT_YVU420M
:
384 param
->input_yuv_fmt
= VENC_YUV_FORMAT_YV12
;
386 case V4L2_PIX_FMT_NV12M
:
387 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV12
;
389 case V4L2_PIX_FMT_NV21M
:
390 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV21
;
393 mtk_v4l2_err("Unsupport fourcc =%d", q_data_src
->fmt
->fourcc
);
396 param
->h264_profile
= enc_params
->h264_profile
;
397 param
->h264_level
= enc_params
->h264_level
;
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
;
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
);
420 static int vidioc_venc_s_fmt_cap(struct file
*file
, void *priv
,
421 struct v4l2_format
*f
)
423 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
424 struct vb2_queue
*vq
;
425 struct mtk_q_data
*q_data
;
427 struct mtk_video_fmt
*fmt
;
429 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
431 mtk_v4l2_err("fail to get vq");
435 if (vb2_is_busy(vq
)) {
436 mtk_v4l2_err("queue busy");
440 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
442 mtk_v4l2_err("fail to get q data");
446 fmt
= mtk_venc_find_format(f
);
448 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[CAP_FMT_IDX
].fourcc
;
449 fmt
= mtk_venc_find_format(f
);
453 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
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
;
461 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
462 struct v4l2_plane_pix_format
*plane_fmt
;
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
;
469 if (ctx
->state
== MTK_STATE_FREE
) {
470 ret
= venc_if_init(ctx
, q_data
->fmt
->fourcc
);
472 mtk_v4l2_err("venc_if_init failed=%d, codec type=%x",
473 ret
, q_data
->fmt
->fourcc
);
476 ctx
->state
= MTK_STATE_INIT
;
482 static int vidioc_venc_s_fmt_out(struct file
*file
, void *priv
,
483 struct v4l2_format
*f
)
485 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
486 struct vb2_queue
*vq
;
487 struct mtk_q_data
*q_data
;
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
;
493 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
495 mtk_v4l2_err("fail to get vq");
499 if (vb2_is_busy(vq
)) {
500 mtk_v4l2_err("queue busy");
504 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
506 mtk_v4l2_err("fail to get q data");
510 fmt
= mtk_venc_find_format(f
);
512 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[OUT_FMT_IDX
].fourcc
;
513 fmt
= mtk_venc_find_format(f
);
516 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
519 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
523 q_data
->visible_width
= f
->fmt
.pix_mp
.width
;
524 q_data
->visible_height
= f
->fmt
.pix_mp
.height
;
526 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
530 q_data
->coded_width
= f
->fmt
.pix_mp
.width
;
531 q_data
->coded_height
= f
->fmt
.pix_mp
.height
;
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
538 q_data
->visible_height
+= 32;
539 vidioc_try_fmt(f
, q_data
->fmt
);
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
;
548 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
549 struct v4l2_plane_pix_format
*plane_fmt
;
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
;
559 static int vidioc_venc_g_fmt(struct file
*file
, void *priv
,
560 struct v4l2_format
*f
)
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
;
568 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
572 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
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
));
587 pix
->colorspace
= ctx
->colorspace
;
588 pix
->ycbcr_enc
= ctx
->ycbcr_enc
;
589 pix
->quantization
= ctx
->quantization
;
590 pix
->xfer_func
= ctx
->xfer_func
;
595 static int vidioc_try_fmt_vid_cap_mplane(struct file
*file
, void *priv
,
596 struct v4l2_format
*f
)
598 struct mtk_video_fmt
*fmt
;
599 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
601 fmt
= mtk_venc_find_format(f
);
603 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[CAP_FMT_IDX
].fourcc
;
604 fmt
= mtk_venc_find_format(f
);
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
;
611 return vidioc_try_fmt(f
, fmt
);
614 static int vidioc_try_fmt_vid_out_mplane(struct file
*file
, void *priv
,
615 struct v4l2_format
*f
)
617 struct mtk_video_fmt
*fmt
;
619 fmt
= mtk_venc_find_format(f
);
621 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[OUT_FMT_IDX
].fourcc
;
622 fmt
= mtk_venc_find_format(f
);
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
;
631 return vidioc_try_fmt(f
, fmt
);
634 static int vidioc_venc_qbuf(struct file
*file
, void *priv
,
635 struct v4l2_buffer
*buf
)
637 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
639 if (ctx
->state
== MTK_STATE_ABORT
) {
640 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
645 return v4l2_m2m_qbuf(file
, ctx
->m2m_ctx
, buf
);
648 static int vidioc_venc_dqbuf(struct file
*file
, void *priv
,
649 struct v4l2_buffer
*buf
)
651 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
653 if (ctx
->state
== MTK_STATE_ABORT
) {
654 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
659 return v4l2_m2m_dqbuf(file
, ctx
->m2m_ctx
, buf
);
662 const struct v4l2_ioctl_ops mtk_venc_ioctl_ops
= {
663 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
664 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
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
,
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
,
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
,
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
,
687 .vidioc_g_fmt_vid_cap_mplane
= vidioc_venc_g_fmt
,
688 .vidioc_g_fmt_vid_out_mplane
= vidioc_venc_g_fmt
,
690 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
691 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
694 static 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
[])
700 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vq
);
701 struct mtk_q_data
*q_data
;
704 q_data
= mtk_venc_get_q_data(ctx
, vq
->type
);
710 for (i
= 0; i
< *nplanes
; i
++)
711 if (sizes
[i
] < q_data
->sizeimage
[i
])
714 *nplanes
= q_data
->fmt
->num_planes
;
715 for (i
= 0; i
< *nplanes
; i
++)
716 sizes
[i
] = q_data
->sizeimage
[i
];
722 static int vb2ops_venc_buf_prepare(struct vb2_buffer
*vb
)
724 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
725 struct mtk_q_data
*q_data
;
728 q_data
= mtk_venc_get_q_data(ctx
, vb
->vb2_queue
->type
);
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
]);
742 static void vb2ops_venc_buf_queue(struct vb2_buffer
*vb
)
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
);
748 struct mtk_video_enc_buf
*mtk_buf
=
749 container_of(vb2_v4l2
, struct mtk_video_enc_buf
, vb
);
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",
755 mtk_buf
->vb
.vb2_buf
.index
,
757 mtk_buf
->param_change
= ctx
->param_change
;
758 mtk_buf
->enc_params
= ctx
->enc_params
;
759 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
762 v4l2_m2m_buf_queue(ctx
->m2m_ctx
, to_vb2_v4l2_buffer(vb
));
765 static int vb2ops_venc_start_streaming(struct vb2_queue
*q
, unsigned int count
)
767 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
768 struct venc_enc_param param
;
772 /* Once state turn into MTK_STATE_ABORT, we need stop_streaming
775 if ((ctx
->state
== MTK_STATE_ABORT
) || (ctx
->state
== MTK_STATE_FREE
)) {
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
))
785 if (!vb2_start_streaming_called(&ctx
->m2m_ctx
->out_q_ctx
.q
))
789 mtk_venc_set_param(ctx
, ¶m
);
790 ret
= venc_if_set_param(ctx
, VENC_SET_PARAM_ENC
, ¶m
);
792 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
793 ctx
->state
= MTK_STATE_ABORT
;
796 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
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
,
805 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
806 ctx
->state
= MTK_STATE_ABORT
;
809 ctx
->state
= MTK_STATE_HEADER
;
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",
819 (int)q
->bufs
[i
]->state
);
820 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q
->bufs
[i
]),
821 VB2_BUF_STATE_QUEUED
);
828 static void vb2ops_venc_stop_streaming(struct vb2_queue
*q
)
830 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
831 struct vb2_buffer
*src_buf
, *dst_buf
;
834 mtk_v4l2_debug(2, "[%d]-> type=%d", ctx
->id
, q
->type
);
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
);
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
);
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",
854 vb2_is_streaming(&ctx
->m2m_ctx
->out_q_ctx
.q
),
855 vb2_is_streaming(&ctx
->m2m_ctx
->cap_q_ctx
.q
));
859 /* Release the encoder if both streams are stopped. */
860 ret
= venc_if_deinit(ctx
);
862 mtk_v4l2_err("venc_if_deinit failed=%d", ret
);
864 ctx
->state
= MTK_STATE_FREE
;
867 static 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
,
877 static int mtk_venc_encode_header(void *priv
)
879 struct mtk_vcodec_ctx
*ctx
= priv
;
881 struct vb2_buffer
*dst_buf
;
882 struct mtk_vcodec_mem bs_buf
;
883 struct venc_done_result enc_result
;
885 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
887 mtk_v4l2_debug(1, "No dst buffer");
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
;
896 "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu",
898 dst_buf
->index
, bs_buf
.va
,
899 (u64
)bs_buf
.dma_addr
,
902 ret
= venc_if_encode(ctx
,
903 VENC_START_OPT_ENCODE_SEQUENCE_HEADER
,
904 NULL
, &bs_buf
, &enc_result
);
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
);
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
);
922 static int mtk_venc_param_change(struct mtk_vcodec_ctx
*ctx
)
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
);
933 memset(&enc_prm
, 0, sizeof(enc_prm
));
934 if (mtk_buf
->param_change
== MTK_ENCODE_PARAM_NONE
)
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",
941 mtk_buf
->vb
.vb2_buf
.index
,
943 ret
|= venc_if_set_param(ctx
,
944 VENC_SET_PARAM_ADJUST_BITRATE
,
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",
952 mtk_buf
->vb
.vb2_buf
.index
,
954 ret
|= venc_if_set_param(ctx
,
955 VENC_SET_PARAM_ADJUST_FRAMERATE
,
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",
962 ret
|= venc_if_set_param(ctx
,
963 VENC_SET_PARAM_GOP_SIZE
,
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",
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
,
977 mtk_buf
->param_change
= MTK_ENCODE_PARAM_NONE
;
980 ctx
->state
= MTK_STATE_ABORT
;
981 mtk_v4l2_err("venc_if_set_param %d failed=%d",
982 mtk_buf
->param_change
, ret
);
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.
997 static void mtk_venc_worker(struct work_struct
*work
)
999 struct mtk_vcodec_ctx
*ctx
= container_of(work
, struct mtk_vcodec_ctx
,
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
;
1006 struct vb2_v4l2_buffer
*vb2_v4l2
;
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
1012 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
1014 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
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
;
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
;
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
);
1043 ret
= venc_if_encode(ctx
, VENC_START_OPT_ENCODE_FRAME
,
1044 &frm_buf
, &bs_buf
, &enc_result
);
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
;
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
);
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
);
1067 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
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
);
1074 static void m2mops_venc_device_run(void *priv
)
1076 struct mtk_vcodec_ctx
*ctx
= priv
;
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
);
1086 mtk_venc_param_change(ctx
);
1087 queue_work(ctx
->dev
->encode_workqueue
, &ctx
->encode_work
);
1090 static int m2mops_venc_job_ready(void *m2m_priv
)
1092 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
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
);
1103 static void m2mops_venc_job_abort(void *priv
)
1105 struct mtk_vcodec_ctx
*ctx
= priv
;
1107 ctx
->state
= MTK_STATE_ABORT
;
1110 static void m2mops_venc_lock(void *m2m_priv
)
1112 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
1114 mutex_lock(&ctx
->dev
->dev_mutex
);
1117 static void m2mops_venc_unlock(void *m2m_priv
)
1119 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
1121 mutex_unlock(&ctx
->dev
->dev_mutex
);
1124 const 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
,
1132 void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx
*ctx
)
1134 struct mtk_q_data
*q_data
;
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
);
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
;
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
;
1154 q_data
->fmt
= &mtk_video_formats
[OUT_FMT_IDX
];
1156 v4l_bound_align_image(&q_data
->coded_width
,
1159 &q_data
->coded_height
,
1161 MTK_VENC_MAX_H
, 5, 6);
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;
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
;
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;
1191 int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx
*ctx
)
1193 const struct v4l2_ctrl_ops
*ops
= &mtk_vcodec_enc_ctrl_ops
;
1194 struct v4l2_ctrl_handler
*handler
= &ctx
->ctrl_hdl
;
1196 v4l2_ctrl_handler_init(handler
, MTK_MAX_CTRLS_HINT
);
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
,
1202 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
,
1204 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_MAX_QP
,
1206 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
,
1208 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
1210 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
,
1212 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
,
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",
1227 return handler
->error
;
1230 v4l2_ctrl_handler_setup(&ctx
->ctrl_hdl
);
1235 int mtk_vcodec_enc_queue_init(void *priv
, struct vb2_queue
*src_vq
,
1236 struct vb2_queue
*dst_vq
)
1238 struct mtk_vcodec_ctx
*ctx
= priv
;
1241 /* Note: VB2_USERPTR works with dma-contig because mt8173
1243 * https://patchwork.kernel.org/patch/8335461/
1244 * https://patchwork.kernel.org/patch/7596181/
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
;
1256 ret
= vb2_queue_init(src_vq
);
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
;
1270 return vb2_queue_init(dst_vq
);
1273 int mtk_venc_unlock(struct mtk_vcodec_ctx
*ctx
)
1275 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1277 mutex_unlock(&dev
->enc_mutex
);
1281 int mtk_venc_lock(struct mtk_vcodec_ctx
*ctx
)
1283 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1285 mutex_lock(&dev
->enc_mutex
);
1289 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx
*ctx
)
1291 venc_if_deinit(ctx
);