1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016 MediaTek Inc.
4 * Author: PC Chen <pc.chen@mediatek.com>
5 * Tiffany Lin <tiffany.lin@mediatek.com>
8 #include <media/v4l2-event.h>
9 #include <media/v4l2-mem2mem.h>
10 #include <media/videobuf2-dma-contig.h>
11 #include <soc/mediatek/smi.h>
13 #include "mtk_vcodec_drv.h"
14 #include "mtk_vcodec_enc.h"
15 #include "mtk_vcodec_intr.h"
16 #include "mtk_vcodec_util.h"
17 #include "venc_drv_if.h"
19 #define MTK_VENC_MIN_W 160U
20 #define MTK_VENC_MIN_H 128U
21 #define MTK_VENC_MAX_W 1920U
22 #define MTK_VENC_MAX_H 1088U
23 #define DFT_CFG_WIDTH MTK_VENC_MIN_W
24 #define DFT_CFG_HEIGHT MTK_VENC_MIN_H
25 #define MTK_MAX_CTRLS_HINT 20
30 static void mtk_venc_worker(struct work_struct
*work
);
32 static const struct mtk_video_fmt mtk_video_formats
[] = {
34 .fourcc
= V4L2_PIX_FMT_NV12M
,
35 .type
= MTK_FMT_FRAME
,
39 .fourcc
= V4L2_PIX_FMT_NV21M
,
40 .type
= MTK_FMT_FRAME
,
44 .fourcc
= V4L2_PIX_FMT_YUV420M
,
45 .type
= MTK_FMT_FRAME
,
49 .fourcc
= V4L2_PIX_FMT_YVU420M
,
50 .type
= MTK_FMT_FRAME
,
54 .fourcc
= V4L2_PIX_FMT_H264
,
59 .fourcc
= V4L2_PIX_FMT_VP8
,
65 #define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
67 static const struct mtk_codec_framesizes mtk_venc_framesizes
[] = {
69 .fourcc
= V4L2_PIX_FMT_H264
,
70 .stepwise
= { MTK_VENC_MIN_W
, MTK_VENC_MAX_W
, 16,
71 MTK_VENC_MIN_H
, MTK_VENC_MAX_H
, 16 },
74 .fourcc
= V4L2_PIX_FMT_VP8
,
75 .stepwise
= { MTK_VENC_MIN_W
, MTK_VENC_MAX_W
, 16,
76 MTK_VENC_MIN_H
, MTK_VENC_MAX_H
, 16 },
80 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_venc_framesizes)
82 static int vidioc_venc_s_ctrl(struct v4l2_ctrl
*ctrl
)
84 struct mtk_vcodec_ctx
*ctx
= ctrl_to_ctx(ctrl
);
85 struct mtk_enc_params
*p
= &ctx
->enc_params
;
89 case V4L2_CID_MPEG_VIDEO_BITRATE
:
90 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d",
92 p
->bitrate
= ctrl
->val
;
93 ctx
->param_change
|= MTK_ENCODE_PARAM_BITRATE
;
95 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
96 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d",
98 p
->num_b_frame
= ctrl
->val
;
100 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
:
101 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d",
103 p
->rc_frame
= ctrl
->val
;
105 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP
:
106 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d",
108 p
->h264_max_qp
= ctrl
->val
;
110 case V4L2_CID_MPEG_VIDEO_HEADER_MODE
:
111 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d",
113 p
->seq_hdr_mode
= ctrl
->val
;
115 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
:
116 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d",
118 p
->rc_mb
= ctrl
->val
;
120 case V4L2_CID_MPEG_VIDEO_H264_PROFILE
:
121 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d",
123 p
->h264_profile
= ctrl
->val
;
125 case V4L2_CID_MPEG_VIDEO_H264_LEVEL
:
126 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d",
128 p
->h264_level
= ctrl
->val
;
130 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
:
131 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d",
133 p
->intra_period
= ctrl
->val
;
134 ctx
->param_change
|= MTK_ENCODE_PARAM_INTRA_PERIOD
;
136 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
137 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d",
139 p
->gop_size
= ctrl
->val
;
140 ctx
->param_change
|= MTK_ENCODE_PARAM_GOP_SIZE
;
142 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
:
143 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME");
145 ctx
->param_change
|= MTK_ENCODE_PARAM_FORCE_INTRA
;
155 static const struct v4l2_ctrl_ops mtk_vcodec_enc_ctrl_ops
= {
156 .s_ctrl
= vidioc_venc_s_ctrl
,
159 static int vidioc_enum_fmt(struct v4l2_fmtdesc
*f
, bool output_queue
)
161 const struct mtk_video_fmt
*fmt
;
164 for (i
= 0; i
< NUM_FORMATS
; ++i
) {
165 if (output_queue
&& mtk_video_formats
[i
].type
!= MTK_FMT_FRAME
)
167 if (!output_queue
&& mtk_video_formats
[i
].type
!= MTK_FMT_ENC
)
171 fmt
= &mtk_video_formats
[i
];
172 f
->pixelformat
= fmt
->fourcc
;
173 memset(f
->reserved
, 0, sizeof(f
->reserved
));
182 static int vidioc_enum_framesizes(struct file
*file
, void *fh
,
183 struct v4l2_frmsizeenum
*fsize
)
187 if (fsize
->index
!= 0)
190 for (i
= 0; i
< NUM_SUPPORTED_FRAMESIZE
; ++i
) {
191 if (fsize
->pixel_format
!= mtk_venc_framesizes
[i
].fourcc
)
194 fsize
->type
= V4L2_FRMSIZE_TYPE_STEPWISE
;
195 fsize
->stepwise
= mtk_venc_framesizes
[i
].stepwise
;
202 static int vidioc_enum_fmt_vid_cap(struct file
*file
, void *priv
,
203 struct v4l2_fmtdesc
*f
)
205 return vidioc_enum_fmt(f
, false);
208 static int vidioc_enum_fmt_vid_out(struct file
*file
, void *priv
,
209 struct v4l2_fmtdesc
*f
)
211 return vidioc_enum_fmt(f
, true);
214 static int vidioc_venc_querycap(struct file
*file
, void *priv
,
215 struct v4l2_capability
*cap
)
217 strscpy(cap
->driver
, MTK_VCODEC_ENC_NAME
, sizeof(cap
->driver
));
218 strscpy(cap
->bus_info
, MTK_PLATFORM_STR
, sizeof(cap
->bus_info
));
219 strscpy(cap
->card
, MTK_PLATFORM_STR
, sizeof(cap
->card
));
224 static int vidioc_venc_s_parm(struct file
*file
, void *priv
,
225 struct v4l2_streamparm
*a
)
227 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
229 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
232 ctx
->enc_params
.framerate_num
=
233 a
->parm
.output
.timeperframe
.denominator
;
234 ctx
->enc_params
.framerate_denom
=
235 a
->parm
.output
.timeperframe
.numerator
;
236 ctx
->param_change
|= MTK_ENCODE_PARAM_FRAMERATE
;
238 a
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
243 static int vidioc_venc_g_parm(struct file
*file
, void *priv
,
244 struct v4l2_streamparm
*a
)
246 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
248 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
251 a
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
252 a
->parm
.output
.timeperframe
.denominator
=
253 ctx
->enc_params
.framerate_num
;
254 a
->parm
.output
.timeperframe
.numerator
=
255 ctx
->enc_params
.framerate_denom
;
260 static struct mtk_q_data
*mtk_venc_get_q_data(struct mtk_vcodec_ctx
*ctx
,
261 enum v4l2_buf_type type
)
263 if (V4L2_TYPE_IS_OUTPUT(type
))
264 return &ctx
->q_data
[MTK_Q_DATA_SRC
];
266 return &ctx
->q_data
[MTK_Q_DATA_DST
];
269 static const struct mtk_video_fmt
*mtk_venc_find_format(struct v4l2_format
*f
)
271 const struct mtk_video_fmt
*fmt
;
274 for (k
= 0; k
< NUM_FORMATS
; k
++) {
275 fmt
= &mtk_video_formats
[k
];
276 if (fmt
->fourcc
== f
->fmt
.pix
.pixelformat
)
283 /* V4L2 specification suggests the driver corrects the format struct if any of
284 * the dimensions is unsupported
286 static int vidioc_try_fmt(struct v4l2_format
*f
,
287 const struct mtk_video_fmt
*fmt
)
289 struct v4l2_pix_format_mplane
*pix_fmt_mp
= &f
->fmt
.pix_mp
;
292 pix_fmt_mp
->field
= V4L2_FIELD_NONE
;
294 if (f
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) {
295 pix_fmt_mp
->num_planes
= 1;
296 pix_fmt_mp
->plane_fmt
[0].bytesperline
= 0;
297 } else if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) {
300 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
303 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
307 /* find next closer width align 16, heign align 32, size align
310 tmp_w
= pix_fmt_mp
->width
;
311 tmp_h
= pix_fmt_mp
->height
;
312 v4l_bound_align_image(&pix_fmt_mp
->width
,
317 MTK_VENC_MAX_H
, 5, 6);
319 if (pix_fmt_mp
->width
< tmp_w
&&
320 (pix_fmt_mp
->width
+ 16) <= MTK_VENC_MAX_W
)
321 pix_fmt_mp
->width
+= 16;
322 if (pix_fmt_mp
->height
< tmp_h
&&
323 (pix_fmt_mp
->height
+ 32) <= MTK_VENC_MAX_H
)
324 pix_fmt_mp
->height
+= 32;
327 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d %d",
328 tmp_w
, tmp_h
, pix_fmt_mp
->width
,
330 pix_fmt_mp
->plane_fmt
[0].sizeimage
,
331 pix_fmt_mp
->plane_fmt
[1].sizeimage
);
333 pix_fmt_mp
->num_planes
= fmt
->num_planes
;
334 pix_fmt_mp
->plane_fmt
[0].sizeimage
=
335 pix_fmt_mp
->width
* pix_fmt_mp
->height
;
336 pix_fmt_mp
->plane_fmt
[0].bytesperline
= pix_fmt_mp
->width
;
338 if (pix_fmt_mp
->num_planes
== 2) {
339 pix_fmt_mp
->plane_fmt
[1].sizeimage
=
340 (pix_fmt_mp
->width
* pix_fmt_mp
->height
) / 2;
341 pix_fmt_mp
->plane_fmt
[2].sizeimage
= 0;
342 pix_fmt_mp
->plane_fmt
[1].bytesperline
=
344 pix_fmt_mp
->plane_fmt
[2].bytesperline
= 0;
345 } else if (pix_fmt_mp
->num_planes
== 3) {
346 pix_fmt_mp
->plane_fmt
[1].sizeimage
=
347 pix_fmt_mp
->plane_fmt
[2].sizeimage
=
348 (pix_fmt_mp
->width
* pix_fmt_mp
->height
) / 4;
349 pix_fmt_mp
->plane_fmt
[1].bytesperline
=
350 pix_fmt_mp
->plane_fmt
[2].bytesperline
=
351 pix_fmt_mp
->width
/ 2;
355 for (i
= 0; i
< pix_fmt_mp
->num_planes
; i
++)
356 memset(&(pix_fmt_mp
->plane_fmt
[i
].reserved
[0]), 0x0,
357 sizeof(pix_fmt_mp
->plane_fmt
[0].reserved
));
359 pix_fmt_mp
->flags
= 0;
360 memset(&pix_fmt_mp
->reserved
, 0x0,
361 sizeof(pix_fmt_mp
->reserved
));
366 static void mtk_venc_set_param(struct mtk_vcodec_ctx
*ctx
,
367 struct venc_enc_param
*param
)
369 struct mtk_q_data
*q_data_src
= &ctx
->q_data
[MTK_Q_DATA_SRC
];
370 struct mtk_enc_params
*enc_params
= &ctx
->enc_params
;
372 switch (q_data_src
->fmt
->fourcc
) {
373 case V4L2_PIX_FMT_YUV420M
:
374 param
->input_yuv_fmt
= VENC_YUV_FORMAT_I420
;
376 case V4L2_PIX_FMT_YVU420M
:
377 param
->input_yuv_fmt
= VENC_YUV_FORMAT_YV12
;
379 case V4L2_PIX_FMT_NV12M
:
380 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV12
;
382 case V4L2_PIX_FMT_NV21M
:
383 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV21
;
386 mtk_v4l2_err("Unsupported fourcc =%d", q_data_src
->fmt
->fourcc
);
389 param
->h264_profile
= enc_params
->h264_profile
;
390 param
->h264_level
= enc_params
->h264_level
;
392 /* Config visible resolution */
393 param
->width
= q_data_src
->visible_width
;
394 param
->height
= q_data_src
->visible_height
;
395 /* Config coded resolution */
396 param
->buf_width
= q_data_src
->coded_width
;
397 param
->buf_height
= q_data_src
->coded_height
;
398 param
->frm_rate
= enc_params
->framerate_num
/
399 enc_params
->framerate_denom
;
400 param
->intra_period
= enc_params
->intra_period
;
401 param
->gop_size
= enc_params
->gop_size
;
402 param
->bitrate
= enc_params
->bitrate
;
405 "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d",
406 param
->input_yuv_fmt
, param
->h264_profile
,
407 param
->h264_level
, param
->width
, param
->height
,
408 param
->buf_width
, param
->buf_height
,
409 param
->frm_rate
, param
->bitrate
,
410 param
->gop_size
, param
->intra_period
);
413 static int vidioc_venc_s_fmt_cap(struct file
*file
, void *priv
,
414 struct v4l2_format
*f
)
416 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
417 struct vb2_queue
*vq
;
418 struct mtk_q_data
*q_data
;
420 const struct mtk_video_fmt
*fmt
;
422 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
424 mtk_v4l2_err("fail to get vq");
428 if (vb2_is_busy(vq
)) {
429 mtk_v4l2_err("queue busy");
433 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
435 mtk_v4l2_err("fail to get q data");
439 fmt
= mtk_venc_find_format(f
);
441 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[CAP_FMT_IDX
].fourcc
;
442 fmt
= mtk_venc_find_format(f
);
446 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
450 q_data
->coded_width
= f
->fmt
.pix_mp
.width
;
451 q_data
->coded_height
= f
->fmt
.pix_mp
.height
;
452 q_data
->field
= f
->fmt
.pix_mp
.field
;
454 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
455 struct v4l2_plane_pix_format
*plane_fmt
;
457 plane_fmt
= &f
->fmt
.pix_mp
.plane_fmt
[i
];
458 q_data
->bytesperline
[i
] = plane_fmt
->bytesperline
;
459 q_data
->sizeimage
[i
] = plane_fmt
->sizeimage
;
462 if (ctx
->state
== MTK_STATE_FREE
) {
463 ret
= venc_if_init(ctx
, q_data
->fmt
->fourcc
);
465 mtk_v4l2_err("venc_if_init failed=%d, codec type=%x",
466 ret
, q_data
->fmt
->fourcc
);
469 ctx
->state
= MTK_STATE_INIT
;
475 static int vidioc_venc_s_fmt_out(struct file
*file
, void *priv
,
476 struct v4l2_format
*f
)
478 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
479 struct vb2_queue
*vq
;
480 struct mtk_q_data
*q_data
;
482 const struct mtk_video_fmt
*fmt
;
483 struct v4l2_pix_format_mplane
*pix_fmt_mp
= &f
->fmt
.pix_mp
;
485 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
487 mtk_v4l2_err("fail to get vq");
491 if (vb2_is_busy(vq
)) {
492 mtk_v4l2_err("queue busy");
496 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
498 mtk_v4l2_err("fail to get q data");
502 fmt
= mtk_venc_find_format(f
);
504 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[OUT_FMT_IDX
].fourcc
;
505 fmt
= mtk_venc_find_format(f
);
508 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
511 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
515 q_data
->visible_width
= f
->fmt
.pix_mp
.width
;
516 q_data
->visible_height
= f
->fmt
.pix_mp
.height
;
518 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
522 q_data
->coded_width
= f
->fmt
.pix_mp
.width
;
523 q_data
->coded_height
= f
->fmt
.pix_mp
.height
;
525 q_data
->field
= f
->fmt
.pix_mp
.field
;
526 ctx
->colorspace
= f
->fmt
.pix_mp
.colorspace
;
527 ctx
->ycbcr_enc
= f
->fmt
.pix_mp
.ycbcr_enc
;
528 ctx
->quantization
= f
->fmt
.pix_mp
.quantization
;
529 ctx
->xfer_func
= f
->fmt
.pix_mp
.xfer_func
;
531 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
532 struct v4l2_plane_pix_format
*plane_fmt
;
534 plane_fmt
= &f
->fmt
.pix_mp
.plane_fmt
[i
];
535 q_data
->bytesperline
[i
] = plane_fmt
->bytesperline
;
536 q_data
->sizeimage
[i
] = plane_fmt
->sizeimage
;
542 static int vidioc_venc_g_fmt(struct file
*file
, void *priv
,
543 struct v4l2_format
*f
)
545 struct v4l2_pix_format_mplane
*pix
= &f
->fmt
.pix_mp
;
546 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
547 struct vb2_queue
*vq
;
548 struct mtk_q_data
*q_data
;
551 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
555 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
557 pix
->width
= q_data
->coded_width
;
558 pix
->height
= q_data
->coded_height
;
559 pix
->pixelformat
= q_data
->fmt
->fourcc
;
560 pix
->field
= q_data
->field
;
561 pix
->num_planes
= q_data
->fmt
->num_planes
;
562 for (i
= 0; i
< pix
->num_planes
; i
++) {
563 pix
->plane_fmt
[i
].bytesperline
= q_data
->bytesperline
[i
];
564 pix
->plane_fmt
[i
].sizeimage
= q_data
->sizeimage
[i
];
565 memset(&(pix
->plane_fmt
[i
].reserved
[0]), 0x0,
566 sizeof(pix
->plane_fmt
[i
].reserved
));
570 pix
->colorspace
= ctx
->colorspace
;
571 pix
->ycbcr_enc
= ctx
->ycbcr_enc
;
572 pix
->quantization
= ctx
->quantization
;
573 pix
->xfer_func
= ctx
->xfer_func
;
578 static int vidioc_try_fmt_vid_cap_mplane(struct file
*file
, void *priv
,
579 struct v4l2_format
*f
)
581 const struct mtk_video_fmt
*fmt
;
582 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
584 fmt
= mtk_venc_find_format(f
);
586 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[CAP_FMT_IDX
].fourcc
;
587 fmt
= mtk_venc_find_format(f
);
589 f
->fmt
.pix_mp
.colorspace
= ctx
->colorspace
;
590 f
->fmt
.pix_mp
.ycbcr_enc
= ctx
->ycbcr_enc
;
591 f
->fmt
.pix_mp
.quantization
= ctx
->quantization
;
592 f
->fmt
.pix_mp
.xfer_func
= ctx
->xfer_func
;
594 return vidioc_try_fmt(f
, fmt
);
597 static int vidioc_try_fmt_vid_out_mplane(struct file
*file
, void *priv
,
598 struct v4l2_format
*f
)
600 const struct mtk_video_fmt
*fmt
;
602 fmt
= mtk_venc_find_format(f
);
604 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[OUT_FMT_IDX
].fourcc
;
605 fmt
= mtk_venc_find_format(f
);
607 if (!f
->fmt
.pix_mp
.colorspace
) {
608 f
->fmt
.pix_mp
.colorspace
= V4L2_COLORSPACE_REC709
;
609 f
->fmt
.pix_mp
.ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
610 f
->fmt
.pix_mp
.quantization
= V4L2_QUANTIZATION_DEFAULT
;
611 f
->fmt
.pix_mp
.xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
614 return vidioc_try_fmt(f
, fmt
);
617 static int vidioc_venc_g_selection(struct file
*file
, void *priv
,
618 struct v4l2_selection
*s
)
620 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
621 struct mtk_q_data
*q_data
;
623 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
626 q_data
= mtk_venc_get_q_data(ctx
, s
->type
);
631 case V4L2_SEL_TGT_CROP_DEFAULT
:
632 case V4L2_SEL_TGT_CROP_BOUNDS
:
635 s
->r
.width
= q_data
->coded_width
;
636 s
->r
.height
= q_data
->coded_height
;
638 case V4L2_SEL_TGT_CROP
:
641 s
->r
.width
= q_data
->visible_width
;
642 s
->r
.height
= q_data
->visible_height
;
651 static int vidioc_venc_s_selection(struct file
*file
, void *priv
,
652 struct v4l2_selection
*s
)
654 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
655 struct mtk_q_data
*q_data
;
657 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
660 q_data
= mtk_venc_get_q_data(ctx
, s
->type
);
665 case V4L2_SEL_TGT_CROP
:
666 /* Only support crop from (0,0) */
669 s
->r
.width
= min(s
->r
.width
, q_data
->coded_width
);
670 s
->r
.height
= min(s
->r
.height
, q_data
->coded_height
);
671 q_data
->visible_width
= s
->r
.width
;
672 q_data
->visible_height
= s
->r
.height
;
680 static int vidioc_venc_qbuf(struct file
*file
, void *priv
,
681 struct v4l2_buffer
*buf
)
683 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
685 if (ctx
->state
== MTK_STATE_ABORT
) {
686 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
691 return v4l2_m2m_qbuf(file
, ctx
->m2m_ctx
, buf
);
694 static int vidioc_venc_dqbuf(struct file
*file
, void *priv
,
695 struct v4l2_buffer
*buf
)
697 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
699 if (ctx
->state
== MTK_STATE_ABORT
) {
700 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
705 return v4l2_m2m_dqbuf(file
, ctx
->m2m_ctx
, buf
);
708 const struct v4l2_ioctl_ops mtk_venc_ioctl_ops
= {
709 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
710 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
712 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
713 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
714 .vidioc_qbuf
= vidioc_venc_qbuf
,
715 .vidioc_dqbuf
= vidioc_venc_dqbuf
,
717 .vidioc_querycap
= vidioc_venc_querycap
,
718 .vidioc_enum_fmt_vid_cap
= vidioc_enum_fmt_vid_cap
,
719 .vidioc_enum_fmt_vid_out
= vidioc_enum_fmt_vid_out
,
720 .vidioc_enum_framesizes
= vidioc_enum_framesizes
,
722 .vidioc_try_fmt_vid_cap_mplane
= vidioc_try_fmt_vid_cap_mplane
,
723 .vidioc_try_fmt_vid_out_mplane
= vidioc_try_fmt_vid_out_mplane
,
724 .vidioc_expbuf
= v4l2_m2m_ioctl_expbuf
,
725 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
726 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
728 .vidioc_s_parm
= vidioc_venc_s_parm
,
729 .vidioc_g_parm
= vidioc_venc_g_parm
,
730 .vidioc_s_fmt_vid_cap_mplane
= vidioc_venc_s_fmt_cap
,
731 .vidioc_s_fmt_vid_out_mplane
= vidioc_venc_s_fmt_out
,
733 .vidioc_g_fmt_vid_cap_mplane
= vidioc_venc_g_fmt
,
734 .vidioc_g_fmt_vid_out_mplane
= vidioc_venc_g_fmt
,
736 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
737 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
739 .vidioc_g_selection
= vidioc_venc_g_selection
,
740 .vidioc_s_selection
= vidioc_venc_s_selection
,
743 static int vb2ops_venc_queue_setup(struct vb2_queue
*vq
,
744 unsigned int *nbuffers
,
745 unsigned int *nplanes
,
746 unsigned int sizes
[],
747 struct device
*alloc_devs
[])
749 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vq
);
750 struct mtk_q_data
*q_data
;
753 q_data
= mtk_venc_get_q_data(ctx
, vq
->type
);
759 for (i
= 0; i
< *nplanes
; i
++)
760 if (sizes
[i
] < q_data
->sizeimage
[i
])
763 *nplanes
= q_data
->fmt
->num_planes
;
764 for (i
= 0; i
< *nplanes
; i
++)
765 sizes
[i
] = q_data
->sizeimage
[i
];
771 static int vb2ops_venc_buf_prepare(struct vb2_buffer
*vb
)
773 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
774 struct mtk_q_data
*q_data
;
777 q_data
= mtk_venc_get_q_data(ctx
, vb
->vb2_queue
->type
);
779 for (i
= 0; i
< q_data
->fmt
->num_planes
; i
++) {
780 if (vb2_plane_size(vb
, i
) < q_data
->sizeimage
[i
]) {
781 mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
782 i
, vb2_plane_size(vb
, i
),
783 q_data
->sizeimage
[i
]);
791 static void vb2ops_venc_buf_queue(struct vb2_buffer
*vb
)
793 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
794 struct vb2_v4l2_buffer
*vb2_v4l2
=
795 container_of(vb
, struct vb2_v4l2_buffer
, vb2_buf
);
797 struct mtk_video_enc_buf
*mtk_buf
=
798 container_of(vb2_v4l2
, struct mtk_video_enc_buf
,
801 if ((vb
->vb2_queue
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) &&
802 (ctx
->param_change
!= MTK_ENCODE_PARAM_NONE
)) {
803 mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x",
805 vb2_v4l2
->vb2_buf
.index
,
807 mtk_buf
->param_change
= ctx
->param_change
;
808 mtk_buf
->enc_params
= ctx
->enc_params
;
809 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
812 v4l2_m2m_buf_queue(ctx
->m2m_ctx
, to_vb2_v4l2_buffer(vb
));
815 static int vb2ops_venc_start_streaming(struct vb2_queue
*q
, unsigned int count
)
817 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
818 struct venc_enc_param param
;
822 /* Once state turn into MTK_STATE_ABORT, we need stop_streaming
825 if ((ctx
->state
== MTK_STATE_ABORT
) || (ctx
->state
== MTK_STATE_FREE
)) {
830 /* Do the initialization when both start_streaming have been called */
831 if (V4L2_TYPE_IS_OUTPUT(q
->type
)) {
832 if (!vb2_start_streaming_called(&ctx
->m2m_ctx
->cap_q_ctx
.q
))
835 if (!vb2_start_streaming_called(&ctx
->m2m_ctx
->out_q_ctx
.q
))
839 mtk_venc_set_param(ctx
, ¶m
);
840 ret
= venc_if_set_param(ctx
, VENC_SET_PARAM_ENC
, ¶m
);
842 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
843 ctx
->state
= MTK_STATE_ABORT
;
846 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
848 if ((ctx
->q_data
[MTK_Q_DATA_DST
].fmt
->fourcc
== V4L2_PIX_FMT_H264
) &&
849 (ctx
->enc_params
.seq_hdr_mode
!=
850 V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
)) {
851 ret
= venc_if_set_param(ctx
,
852 VENC_SET_PARAM_PREPEND_HEADER
,
855 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
856 ctx
->state
= MTK_STATE_ABORT
;
859 ctx
->state
= MTK_STATE_HEADER
;
865 for (i
= 0; i
< q
->num_buffers
; ++i
) {
866 struct vb2_buffer
*buf
= vb2_get_buffer(q
, i
);
869 * FIXME: This check is not needed as only active buffers
870 * can be marked as done.
872 if (buf
->state
== VB2_BUF_STATE_ACTIVE
) {
873 mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED",
876 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(buf
),
877 VB2_BUF_STATE_QUEUED
);
884 static void vb2ops_venc_stop_streaming(struct vb2_queue
*q
)
886 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
887 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
890 mtk_v4l2_debug(2, "[%d]-> type=%d", ctx
->id
, q
->type
);
892 if (q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) {
893 while ((dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
))) {
894 dst_buf
->vb2_buf
.planes
[0].bytesused
= 0;
895 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_ERROR
);
898 while ((src_buf
= v4l2_m2m_src_buf_remove(ctx
->m2m_ctx
)))
899 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_ERROR
);
902 if ((q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
903 vb2_is_streaming(&ctx
->m2m_ctx
->out_q_ctx
.q
)) ||
904 (q
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
&&
905 vb2_is_streaming(&ctx
->m2m_ctx
->cap_q_ctx
.q
))) {
906 mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d",
908 vb2_is_streaming(&ctx
->m2m_ctx
->out_q_ctx
.q
),
909 vb2_is_streaming(&ctx
->m2m_ctx
->cap_q_ctx
.q
));
913 /* Release the encoder if both streams are stopped. */
914 ret
= venc_if_deinit(ctx
);
916 mtk_v4l2_err("venc_if_deinit failed=%d", ret
);
918 ctx
->state
= MTK_STATE_FREE
;
921 static const struct vb2_ops mtk_venc_vb2_ops
= {
922 .queue_setup
= vb2ops_venc_queue_setup
,
923 .buf_prepare
= vb2ops_venc_buf_prepare
,
924 .buf_queue
= vb2ops_venc_buf_queue
,
925 .wait_prepare
= vb2_ops_wait_prepare
,
926 .wait_finish
= vb2_ops_wait_finish
,
927 .start_streaming
= vb2ops_venc_start_streaming
,
928 .stop_streaming
= vb2ops_venc_stop_streaming
,
931 static int mtk_venc_encode_header(void *priv
)
933 struct mtk_vcodec_ctx
*ctx
= priv
;
935 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
936 struct mtk_vcodec_mem bs_buf
;
937 struct venc_done_result enc_result
;
939 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
941 mtk_v4l2_debug(1, "No dst buffer");
945 bs_buf
.va
= vb2_plane_vaddr(&dst_buf
->vb2_buf
, 0);
946 bs_buf
.dma_addr
= vb2_dma_contig_plane_dma_addr(&dst_buf
->vb2_buf
, 0);
947 bs_buf
.size
= (size_t)dst_buf
->vb2_buf
.planes
[0].length
;
950 "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu",
952 dst_buf
->vb2_buf
.index
, bs_buf
.va
,
953 (u64
)bs_buf
.dma_addr
,
956 ret
= venc_if_encode(ctx
,
957 VENC_START_OPT_ENCODE_SEQUENCE_HEADER
,
958 NULL
, &bs_buf
, &enc_result
);
961 dst_buf
->vb2_buf
.planes
[0].bytesused
= 0;
962 ctx
->state
= MTK_STATE_ABORT
;
963 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_ERROR
);
964 mtk_v4l2_err("venc_if_encode failed=%d", ret
);
967 src_buf
= v4l2_m2m_next_src_buf(ctx
->m2m_ctx
);
969 dst_buf
->vb2_buf
.timestamp
= src_buf
->vb2_buf
.timestamp
;
970 dst_buf
->timecode
= src_buf
->timecode
;
972 mtk_v4l2_err("No timestamp for the header buffer.");
975 ctx
->state
= MTK_STATE_HEADER
;
976 dst_buf
->vb2_buf
.planes
[0].bytesused
= enc_result
.bs_size
;
977 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_DONE
);
982 static int mtk_venc_param_change(struct mtk_vcodec_ctx
*ctx
)
984 struct venc_enc_param enc_prm
;
985 struct vb2_v4l2_buffer
*vb2_v4l2
= v4l2_m2m_next_src_buf(ctx
->m2m_ctx
);
986 struct mtk_video_enc_buf
*mtk_buf
=
987 container_of(vb2_v4l2
, struct mtk_video_enc_buf
,
992 memset(&enc_prm
, 0, sizeof(enc_prm
));
993 if (mtk_buf
->param_change
== MTK_ENCODE_PARAM_NONE
)
996 if (mtk_buf
->param_change
& MTK_ENCODE_PARAM_BITRATE
) {
997 enc_prm
.bitrate
= mtk_buf
->enc_params
.bitrate
;
998 mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d",
1000 vb2_v4l2
->vb2_buf
.index
,
1002 ret
|= venc_if_set_param(ctx
,
1003 VENC_SET_PARAM_ADJUST_BITRATE
,
1006 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_FRAMERATE
) {
1007 enc_prm
.frm_rate
= mtk_buf
->enc_params
.framerate_num
/
1008 mtk_buf
->enc_params
.framerate_denom
;
1009 mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d",
1011 vb2_v4l2
->vb2_buf
.index
,
1013 ret
|= venc_if_set_param(ctx
,
1014 VENC_SET_PARAM_ADJUST_FRAMERATE
,
1017 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_GOP_SIZE
) {
1018 enc_prm
.gop_size
= mtk_buf
->enc_params
.gop_size
;
1019 mtk_v4l2_debug(1, "change param intra period=%d",
1021 ret
|= venc_if_set_param(ctx
,
1022 VENC_SET_PARAM_GOP_SIZE
,
1025 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_FORCE_INTRA
) {
1026 mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d",
1028 vb2_v4l2
->vb2_buf
.index
,
1029 mtk_buf
->enc_params
.force_intra
);
1030 if (mtk_buf
->enc_params
.force_intra
)
1031 ret
|= venc_if_set_param(ctx
,
1032 VENC_SET_PARAM_FORCE_INTRA
,
1036 mtk_buf
->param_change
= MTK_ENCODE_PARAM_NONE
;
1039 ctx
->state
= MTK_STATE_ABORT
;
1040 mtk_v4l2_err("venc_if_set_param %d failed=%d",
1041 mtk_buf
->param_change
, ret
);
1049 * v4l2_m2m_streamoff() holds dev_mutex and waits mtk_venc_worker()
1050 * to call v4l2_m2m_job_finish().
1051 * If mtk_venc_worker() tries to acquire dev_mutex, it will deadlock.
1052 * So this function must not try to acquire dev->dev_mutex.
1053 * This means v4l2 ioctls and mtk_venc_worker() can run at the same time.
1054 * mtk_venc_worker() should be carefully implemented to avoid bugs.
1056 static void mtk_venc_worker(struct work_struct
*work
)
1058 struct mtk_vcodec_ctx
*ctx
= container_of(work
, struct mtk_vcodec_ctx
,
1060 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
1061 struct venc_frm_buf frm_buf
;
1062 struct mtk_vcodec_mem bs_buf
;
1063 struct venc_done_result enc_result
;
1066 /* check dst_buf, dst_buf may be removed in device_run
1067 * to stored encdoe header so we need check dst_buf and
1068 * call job_finish here to prevent recursion
1070 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
1072 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
1076 src_buf
= v4l2_m2m_src_buf_remove(ctx
->m2m_ctx
);
1077 memset(&frm_buf
, 0, sizeof(frm_buf
));
1078 for (i
= 0; i
< src_buf
->vb2_buf
.num_planes
; i
++) {
1079 frm_buf
.fb_addr
[i
].dma_addr
=
1080 vb2_dma_contig_plane_dma_addr(&src_buf
->vb2_buf
, i
);
1081 frm_buf
.fb_addr
[i
].size
=
1082 (size_t)src_buf
->vb2_buf
.planes
[i
].length
;
1084 bs_buf
.va
= vb2_plane_vaddr(&dst_buf
->vb2_buf
, 0);
1085 bs_buf
.dma_addr
= vb2_dma_contig_plane_dma_addr(&dst_buf
->vb2_buf
, 0);
1086 bs_buf
.size
= (size_t)dst_buf
->vb2_buf
.planes
[0].length
;
1089 "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu",
1090 (u64
)frm_buf
.fb_addr
[0].dma_addr
,
1091 frm_buf
.fb_addr
[0].size
,
1092 (u64
)frm_buf
.fb_addr
[1].dma_addr
,
1093 frm_buf
.fb_addr
[1].size
,
1094 (u64
)frm_buf
.fb_addr
[2].dma_addr
,
1095 frm_buf
.fb_addr
[2].size
);
1097 ret
= venc_if_encode(ctx
, VENC_START_OPT_ENCODE_FRAME
,
1098 &frm_buf
, &bs_buf
, &enc_result
);
1100 dst_buf
->vb2_buf
.timestamp
= src_buf
->vb2_buf
.timestamp
;
1101 dst_buf
->timecode
= src_buf
->timecode
;
1103 if (enc_result
.is_key_frm
)
1104 dst_buf
->flags
|= V4L2_BUF_FLAG_KEYFRAME
;
1107 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_ERROR
);
1108 dst_buf
->vb2_buf
.planes
[0].bytesused
= 0;
1109 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_ERROR
);
1110 mtk_v4l2_err("venc_if_encode failed=%d", ret
);
1112 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_DONE
);
1113 dst_buf
->vb2_buf
.planes
[0].bytesused
= enc_result
.bs_size
;
1114 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_DONE
);
1115 mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
1116 enc_result
.bs_size
);
1119 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
1121 mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
1122 src_buf
->vb2_buf
.index
, dst_buf
->vb2_buf
.index
, ret
,
1123 enc_result
.bs_size
);
1126 static void m2mops_venc_device_run(void *priv
)
1128 struct mtk_vcodec_ctx
*ctx
= priv
;
1130 if ((ctx
->q_data
[MTK_Q_DATA_DST
].fmt
->fourcc
== V4L2_PIX_FMT_H264
) &&
1131 (ctx
->state
!= MTK_STATE_HEADER
)) {
1132 /* encode h264 sps/pps header */
1133 mtk_venc_encode_header(ctx
);
1134 queue_work(ctx
->dev
->encode_workqueue
, &ctx
->encode_work
);
1138 mtk_venc_param_change(ctx
);
1139 queue_work(ctx
->dev
->encode_workqueue
, &ctx
->encode_work
);
1142 static int m2mops_venc_job_ready(void *m2m_priv
)
1144 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
1146 if (ctx
->state
== MTK_STATE_ABORT
|| ctx
->state
== MTK_STATE_FREE
) {
1147 mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.",
1148 ctx
->id
, ctx
->state
);
1155 static void m2mops_venc_job_abort(void *priv
)
1157 struct mtk_vcodec_ctx
*ctx
= priv
;
1159 ctx
->state
= MTK_STATE_ABORT
;
1162 const struct v4l2_m2m_ops mtk_venc_m2m_ops
= {
1163 .device_run
= m2mops_venc_device_run
,
1164 .job_ready
= m2mops_venc_job_ready
,
1165 .job_abort
= m2mops_venc_job_abort
,
1168 void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx
*ctx
)
1170 struct mtk_q_data
*q_data
;
1172 ctx
->m2m_ctx
->q_lock
= &ctx
->dev
->dev_mutex
;
1173 ctx
->fh
.m2m_ctx
= ctx
->m2m_ctx
;
1174 ctx
->fh
.ctrl_handler
= &ctx
->ctrl_hdl
;
1175 INIT_WORK(&ctx
->encode_work
, mtk_venc_worker
);
1177 ctx
->colorspace
= V4L2_COLORSPACE_REC709
;
1178 ctx
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
1179 ctx
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
1180 ctx
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
1182 q_data
= &ctx
->q_data
[MTK_Q_DATA_SRC
];
1183 memset(q_data
, 0, sizeof(struct mtk_q_data
));
1184 q_data
->visible_width
= DFT_CFG_WIDTH
;
1185 q_data
->visible_height
= DFT_CFG_HEIGHT
;
1186 q_data
->coded_width
= DFT_CFG_WIDTH
;
1187 q_data
->coded_height
= DFT_CFG_HEIGHT
;
1188 q_data
->field
= V4L2_FIELD_NONE
;
1190 q_data
->fmt
= &mtk_video_formats
[OUT_FMT_IDX
];
1192 v4l_bound_align_image(&q_data
->coded_width
,
1195 &q_data
->coded_height
,
1197 MTK_VENC_MAX_H
, 5, 6);
1199 if (q_data
->coded_width
< DFT_CFG_WIDTH
&&
1200 (q_data
->coded_width
+ 16) <= MTK_VENC_MAX_W
)
1201 q_data
->coded_width
+= 16;
1202 if (q_data
->coded_height
< DFT_CFG_HEIGHT
&&
1203 (q_data
->coded_height
+ 32) <= MTK_VENC_MAX_H
)
1204 q_data
->coded_height
+= 32;
1206 q_data
->sizeimage
[0] =
1207 q_data
->coded_width
* q_data
->coded_height
+
1208 ((ALIGN(q_data
->coded_width
, 16) * 2) * 16);
1209 q_data
->bytesperline
[0] = q_data
->coded_width
;
1210 q_data
->sizeimage
[1] =
1211 (q_data
->coded_width
* q_data
->coded_height
) / 2 +
1212 (ALIGN(q_data
->coded_width
, 16) * 16);
1213 q_data
->bytesperline
[1] = q_data
->coded_width
;
1215 q_data
= &ctx
->q_data
[MTK_Q_DATA_DST
];
1216 memset(q_data
, 0, sizeof(struct mtk_q_data
));
1217 q_data
->coded_width
= DFT_CFG_WIDTH
;
1218 q_data
->coded_height
= DFT_CFG_HEIGHT
;
1219 q_data
->fmt
= &mtk_video_formats
[CAP_FMT_IDX
];
1220 q_data
->field
= V4L2_FIELD_NONE
;
1221 ctx
->q_data
[MTK_Q_DATA_DST
].sizeimage
[0] =
1222 DFT_CFG_WIDTH
* DFT_CFG_HEIGHT
;
1223 ctx
->q_data
[MTK_Q_DATA_DST
].bytesperline
[0] = 0;
1227 int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx
*ctx
)
1229 const struct v4l2_ctrl_ops
*ops
= &mtk_vcodec_enc_ctrl_ops
;
1230 struct v4l2_ctrl_handler
*handler
= &ctx
->ctrl_hdl
;
1232 v4l2_ctrl_handler_init(handler
, MTK_MAX_CTRLS_HINT
);
1234 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_BITRATE
,
1235 1, 4000000, 1, 4000000);
1236 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_B_FRAMES
,
1238 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
,
1240 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_MAX_QP
,
1242 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
,
1244 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
1246 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
,
1248 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
,
1250 v4l2_ctrl_new_std_menu(handler
, ops
,
1251 V4L2_CID_MPEG_VIDEO_HEADER_MODE
,
1252 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME
,
1253 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
);
1254 v4l2_ctrl_new_std_menu(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_PROFILE
,
1255 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
,
1256 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
);
1257 v4l2_ctrl_new_std_menu(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_LEVEL
,
1258 V4L2_MPEG_VIDEO_H264_LEVEL_4_2
,
1259 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0
);
1260 if (handler
->error
) {
1261 mtk_v4l2_err("Init control handler fail %d",
1263 return handler
->error
;
1266 v4l2_ctrl_handler_setup(&ctx
->ctrl_hdl
);
1271 int mtk_vcodec_enc_queue_init(void *priv
, struct vb2_queue
*src_vq
,
1272 struct vb2_queue
*dst_vq
)
1274 struct mtk_vcodec_ctx
*ctx
= priv
;
1277 /* Note: VB2_USERPTR works with dma-contig because mt8173
1279 * https://patchwork.kernel.org/patch/8335461/
1280 * https://patchwork.kernel.org/patch/7596181/
1282 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1283 src_vq
->io_modes
= VB2_DMABUF
| VB2_MMAP
| VB2_USERPTR
;
1284 src_vq
->drv_priv
= ctx
;
1285 src_vq
->buf_struct_size
= sizeof(struct mtk_video_enc_buf
);
1286 src_vq
->ops
= &mtk_venc_vb2_ops
;
1287 src_vq
->mem_ops
= &vb2_dma_contig_memops
;
1288 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1289 src_vq
->lock
= &ctx
->dev
->dev_mutex
;
1290 src_vq
->dev
= &ctx
->dev
->plat_dev
->dev
;
1292 ret
= vb2_queue_init(src_vq
);
1296 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1297 dst_vq
->io_modes
= VB2_DMABUF
| VB2_MMAP
| VB2_USERPTR
;
1298 dst_vq
->drv_priv
= ctx
;
1299 dst_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
1300 dst_vq
->ops
= &mtk_venc_vb2_ops
;
1301 dst_vq
->mem_ops
= &vb2_dma_contig_memops
;
1302 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1303 dst_vq
->lock
= &ctx
->dev
->dev_mutex
;
1304 dst_vq
->dev
= &ctx
->dev
->plat_dev
->dev
;
1306 return vb2_queue_init(dst_vq
);
1309 int mtk_venc_unlock(struct mtk_vcodec_ctx
*ctx
)
1311 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1313 mutex_unlock(&dev
->enc_mutex
);
1317 int mtk_venc_lock(struct mtk_vcodec_ctx
*ctx
)
1319 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1321 mutex_lock(&dev
->enc_mutex
);
1325 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx
*ctx
)
1327 int ret
= venc_if_deinit(ctx
);
1330 mtk_v4l2_err("venc_if_deinit failed=%d", ret
);
1332 ctx
->state
= MTK_STATE_FREE
;