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
27 #define MTK_DEFAULT_FRAMERATE_NUM 1001
28 #define MTK_DEFAULT_FRAMERATE_DENOM 30000
30 static void mtk_venc_worker(struct work_struct
*work
);
32 static const struct v4l2_frmsize_stepwise mtk_venc_framesizes
= {
33 MTK_VENC_MIN_W
, MTK_VENC_MAX_W
, 16,
34 MTK_VENC_MIN_H
, MTK_VENC_MAX_H
, 16,
37 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_venc_framesizes)
39 static int vidioc_venc_s_ctrl(struct v4l2_ctrl
*ctrl
)
41 struct mtk_vcodec_ctx
*ctx
= ctrl_to_ctx(ctrl
);
42 struct mtk_enc_params
*p
= &ctx
->enc_params
;
46 case V4L2_CID_MPEG_VIDEO_BITRATE
:
47 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d",
49 p
->bitrate
= ctrl
->val
;
50 ctx
->param_change
|= MTK_ENCODE_PARAM_BITRATE
;
52 case V4L2_CID_MPEG_VIDEO_B_FRAMES
:
53 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d",
55 p
->num_b_frame
= ctrl
->val
;
57 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
:
58 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d",
60 p
->rc_frame
= ctrl
->val
;
62 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP
:
63 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d",
65 p
->h264_max_qp
= ctrl
->val
;
67 case V4L2_CID_MPEG_VIDEO_HEADER_MODE
:
68 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d",
70 p
->seq_hdr_mode
= ctrl
->val
;
72 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
:
73 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d",
77 case V4L2_CID_MPEG_VIDEO_H264_PROFILE
:
78 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d",
80 p
->h264_profile
= ctrl
->val
;
82 case V4L2_CID_MPEG_VIDEO_H264_LEVEL
:
83 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d",
85 p
->h264_level
= ctrl
->val
;
87 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
:
88 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d",
90 p
->intra_period
= ctrl
->val
;
91 ctx
->param_change
|= MTK_ENCODE_PARAM_INTRA_PERIOD
;
93 case V4L2_CID_MPEG_VIDEO_GOP_SIZE
:
94 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d",
96 p
->gop_size
= ctrl
->val
;
97 ctx
->param_change
|= MTK_ENCODE_PARAM_GOP_SIZE
;
99 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
:
100 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME");
102 ctx
->param_change
|= MTK_ENCODE_PARAM_FORCE_INTRA
;
112 static const struct v4l2_ctrl_ops mtk_vcodec_enc_ctrl_ops
= {
113 .s_ctrl
= vidioc_venc_s_ctrl
,
116 static int vidioc_enum_fmt(struct v4l2_fmtdesc
*f
,
117 const struct mtk_video_fmt
*formats
,
120 if (f
->index
>= num_formats
)
123 f
->pixelformat
= formats
[f
->index
].fourcc
;
124 memset(f
->reserved
, 0, sizeof(f
->reserved
));
129 static const struct mtk_video_fmt
*
130 mtk_venc_find_format(u32 fourcc
, const struct mtk_vcodec_enc_pdata
*pdata
)
132 const struct mtk_video_fmt
*fmt
;
135 for (k
= 0; k
< pdata
->num_capture_formats
; k
++) {
136 fmt
= &pdata
->capture_formats
[k
];
137 if (fmt
->fourcc
== fourcc
)
141 for (k
= 0; k
< pdata
->num_output_formats
; k
++) {
142 fmt
= &pdata
->output_formats
[k
];
143 if (fmt
->fourcc
== fourcc
)
150 static int vidioc_enum_framesizes(struct file
*file
, void *fh
,
151 struct v4l2_frmsizeenum
*fsize
)
153 const struct mtk_video_fmt
*fmt
;
155 if (fsize
->index
!= 0)
158 fmt
= mtk_venc_find_format(fsize
->pixel_format
,
159 fh_to_ctx(fh
)->dev
->venc_pdata
);
163 fsize
->type
= V4L2_FRMSIZE_TYPE_STEPWISE
;
164 fsize
->stepwise
= mtk_venc_framesizes
;
169 static int vidioc_enum_fmt_vid_cap(struct file
*file
, void *priv
,
170 struct v4l2_fmtdesc
*f
)
172 const struct mtk_vcodec_enc_pdata
*pdata
=
173 fh_to_ctx(priv
)->dev
->venc_pdata
;
175 return vidioc_enum_fmt(f
, pdata
->capture_formats
,
176 pdata
->num_capture_formats
);
179 static int vidioc_enum_fmt_vid_out(struct file
*file
, void *priv
,
180 struct v4l2_fmtdesc
*f
)
182 const struct mtk_vcodec_enc_pdata
*pdata
=
183 fh_to_ctx(priv
)->dev
->venc_pdata
;
185 return vidioc_enum_fmt(f
, pdata
->output_formats
,
186 pdata
->num_output_formats
);
189 static int vidioc_venc_querycap(struct file
*file
, void *priv
,
190 struct v4l2_capability
*cap
)
192 strscpy(cap
->driver
, MTK_VCODEC_ENC_NAME
, sizeof(cap
->driver
));
193 strscpy(cap
->bus_info
, MTK_PLATFORM_STR
, sizeof(cap
->bus_info
));
194 strscpy(cap
->card
, MTK_PLATFORM_STR
, sizeof(cap
->card
));
199 static int vidioc_venc_s_parm(struct file
*file
, void *priv
,
200 struct v4l2_streamparm
*a
)
202 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
203 struct v4l2_fract
*timeperframe
= &a
->parm
.output
.timeperframe
;
205 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
208 if (timeperframe
->numerator
== 0 || timeperframe
->denominator
== 0) {
209 timeperframe
->numerator
= MTK_DEFAULT_FRAMERATE_NUM
;
210 timeperframe
->denominator
= MTK_DEFAULT_FRAMERATE_DENOM
;
213 ctx
->enc_params
.framerate_num
= timeperframe
->denominator
;
214 ctx
->enc_params
.framerate_denom
= timeperframe
->numerator
;
215 ctx
->param_change
|= MTK_ENCODE_PARAM_FRAMERATE
;
217 a
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
222 static int vidioc_venc_g_parm(struct file
*file
, void *priv
,
223 struct v4l2_streamparm
*a
)
225 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
227 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
230 a
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
231 a
->parm
.output
.timeperframe
.denominator
=
232 ctx
->enc_params
.framerate_num
;
233 a
->parm
.output
.timeperframe
.numerator
=
234 ctx
->enc_params
.framerate_denom
;
239 static struct mtk_q_data
*mtk_venc_get_q_data(struct mtk_vcodec_ctx
*ctx
,
240 enum v4l2_buf_type type
)
242 if (V4L2_TYPE_IS_OUTPUT(type
))
243 return &ctx
->q_data
[MTK_Q_DATA_SRC
];
245 return &ctx
->q_data
[MTK_Q_DATA_DST
];
248 /* V4L2 specification suggests the driver corrects the format struct if any of
249 * the dimensions is unsupported
251 static int vidioc_try_fmt(struct v4l2_format
*f
,
252 const struct mtk_video_fmt
*fmt
)
254 struct v4l2_pix_format_mplane
*pix_fmt_mp
= &f
->fmt
.pix_mp
;
257 pix_fmt_mp
->field
= V4L2_FIELD_NONE
;
259 if (f
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) {
260 pix_fmt_mp
->num_planes
= 1;
261 pix_fmt_mp
->plane_fmt
[0].bytesperline
= 0;
262 } else if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) {
265 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
268 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
272 /* find next closer width align 16, heign align 32, size align
275 tmp_w
= pix_fmt_mp
->width
;
276 tmp_h
= pix_fmt_mp
->height
;
277 v4l_bound_align_image(&pix_fmt_mp
->width
,
282 MTK_VENC_MAX_H
, 5, 6);
284 if (pix_fmt_mp
->width
< tmp_w
&&
285 (pix_fmt_mp
->width
+ 16) <= MTK_VENC_MAX_W
)
286 pix_fmt_mp
->width
+= 16;
287 if (pix_fmt_mp
->height
< tmp_h
&&
288 (pix_fmt_mp
->height
+ 32) <= MTK_VENC_MAX_H
)
289 pix_fmt_mp
->height
+= 32;
292 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d %d",
293 tmp_w
, tmp_h
, pix_fmt_mp
->width
,
295 pix_fmt_mp
->plane_fmt
[0].sizeimage
,
296 pix_fmt_mp
->plane_fmt
[1].sizeimage
);
298 pix_fmt_mp
->num_planes
= fmt
->num_planes
;
299 pix_fmt_mp
->plane_fmt
[0].sizeimage
=
300 pix_fmt_mp
->width
* pix_fmt_mp
->height
+
301 ((ALIGN(pix_fmt_mp
->width
, 16) * 2) * 16);
302 pix_fmt_mp
->plane_fmt
[0].bytesperline
= pix_fmt_mp
->width
;
304 if (pix_fmt_mp
->num_planes
== 2) {
305 pix_fmt_mp
->plane_fmt
[1].sizeimage
=
306 (pix_fmt_mp
->width
* pix_fmt_mp
->height
) / 2 +
307 (ALIGN(pix_fmt_mp
->width
, 16) * 16);
308 pix_fmt_mp
->plane_fmt
[2].sizeimage
= 0;
309 pix_fmt_mp
->plane_fmt
[1].bytesperline
=
311 pix_fmt_mp
->plane_fmt
[2].bytesperline
= 0;
312 } else if (pix_fmt_mp
->num_planes
== 3) {
313 pix_fmt_mp
->plane_fmt
[1].sizeimage
=
314 pix_fmt_mp
->plane_fmt
[2].sizeimage
=
315 (pix_fmt_mp
->width
* pix_fmt_mp
->height
) / 4 +
316 ((ALIGN(pix_fmt_mp
->width
, 16) / 2) * 16);
317 pix_fmt_mp
->plane_fmt
[1].bytesperline
=
318 pix_fmt_mp
->plane_fmt
[2].bytesperline
=
319 pix_fmt_mp
->width
/ 2;
323 for (i
= 0; i
< pix_fmt_mp
->num_planes
; i
++)
324 memset(&(pix_fmt_mp
->plane_fmt
[i
].reserved
[0]), 0x0,
325 sizeof(pix_fmt_mp
->plane_fmt
[0].reserved
));
327 pix_fmt_mp
->flags
= 0;
328 memset(&pix_fmt_mp
->reserved
, 0x0,
329 sizeof(pix_fmt_mp
->reserved
));
334 static void mtk_venc_set_param(struct mtk_vcodec_ctx
*ctx
,
335 struct venc_enc_param
*param
)
337 struct mtk_q_data
*q_data_src
= &ctx
->q_data
[MTK_Q_DATA_SRC
];
338 struct mtk_enc_params
*enc_params
= &ctx
->enc_params
;
340 switch (q_data_src
->fmt
->fourcc
) {
341 case V4L2_PIX_FMT_YUV420M
:
342 param
->input_yuv_fmt
= VENC_YUV_FORMAT_I420
;
344 case V4L2_PIX_FMT_YVU420M
:
345 param
->input_yuv_fmt
= VENC_YUV_FORMAT_YV12
;
347 case V4L2_PIX_FMT_NV12M
:
348 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV12
;
350 case V4L2_PIX_FMT_NV21M
:
351 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV21
;
354 mtk_v4l2_err("Unsupported fourcc =%d", q_data_src
->fmt
->fourcc
);
357 param
->h264_profile
= enc_params
->h264_profile
;
358 param
->h264_level
= enc_params
->h264_level
;
360 /* Config visible resolution */
361 param
->width
= q_data_src
->visible_width
;
362 param
->height
= q_data_src
->visible_height
;
363 /* Config coded resolution */
364 param
->buf_width
= q_data_src
->coded_width
;
365 param
->buf_height
= q_data_src
->coded_height
;
366 param
->frm_rate
= enc_params
->framerate_num
/
367 enc_params
->framerate_denom
;
368 param
->intra_period
= enc_params
->intra_period
;
369 param
->gop_size
= enc_params
->gop_size
;
370 param
->bitrate
= enc_params
->bitrate
;
373 "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d",
374 param
->input_yuv_fmt
, param
->h264_profile
,
375 param
->h264_level
, param
->width
, param
->height
,
376 param
->buf_width
, param
->buf_height
,
377 param
->frm_rate
, param
->bitrate
,
378 param
->gop_size
, param
->intra_period
);
381 static int vidioc_venc_s_fmt_cap(struct file
*file
, void *priv
,
382 struct v4l2_format
*f
)
384 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
385 const struct mtk_vcodec_enc_pdata
*pdata
= ctx
->dev
->venc_pdata
;
386 struct vb2_queue
*vq
;
387 struct mtk_q_data
*q_data
;
389 const struct mtk_video_fmt
*fmt
;
391 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
393 mtk_v4l2_err("fail to get vq");
397 if (vb2_is_busy(vq
)) {
398 mtk_v4l2_err("queue busy");
402 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
404 mtk_v4l2_err("fail to get q data");
408 fmt
= mtk_venc_find_format(f
->fmt
.pix
.pixelformat
, pdata
);
410 fmt
= &ctx
->dev
->venc_pdata
->capture_formats
[0];
411 f
->fmt
.pix
.pixelformat
= fmt
->fourcc
;
415 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
419 q_data
->coded_width
= f
->fmt
.pix_mp
.width
;
420 q_data
->coded_height
= f
->fmt
.pix_mp
.height
;
421 q_data
->field
= f
->fmt
.pix_mp
.field
;
423 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
424 struct v4l2_plane_pix_format
*plane_fmt
;
426 plane_fmt
= &f
->fmt
.pix_mp
.plane_fmt
[i
];
427 q_data
->bytesperline
[i
] = plane_fmt
->bytesperline
;
428 q_data
->sizeimage
[i
] = plane_fmt
->sizeimage
;
431 if (ctx
->state
== MTK_STATE_FREE
) {
432 ret
= venc_if_init(ctx
, q_data
->fmt
->fourcc
);
434 mtk_v4l2_err("venc_if_init failed=%d, codec type=%x",
435 ret
, q_data
->fmt
->fourcc
);
438 ctx
->state
= MTK_STATE_INIT
;
444 static int vidioc_venc_s_fmt_out(struct file
*file
, void *priv
,
445 struct v4l2_format
*f
)
447 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
448 const struct mtk_vcodec_enc_pdata
*pdata
= ctx
->dev
->venc_pdata
;
449 struct vb2_queue
*vq
;
450 struct mtk_q_data
*q_data
;
452 const struct mtk_video_fmt
*fmt
;
453 struct v4l2_pix_format_mplane
*pix_fmt_mp
= &f
->fmt
.pix_mp
;
455 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
457 mtk_v4l2_err("fail to get vq");
461 if (vb2_is_busy(vq
)) {
462 mtk_v4l2_err("queue busy");
466 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
468 mtk_v4l2_err("fail to get q data");
472 fmt
= mtk_venc_find_format(f
->fmt
.pix
.pixelformat
, pdata
);
474 fmt
= &ctx
->dev
->venc_pdata
->output_formats
[0];
475 f
->fmt
.pix
.pixelformat
= fmt
->fourcc
;
478 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
481 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
485 q_data
->visible_width
= f
->fmt
.pix_mp
.width
;
486 q_data
->visible_height
= f
->fmt
.pix_mp
.height
;
488 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
492 q_data
->coded_width
= f
->fmt
.pix_mp
.width
;
493 q_data
->coded_height
= f
->fmt
.pix_mp
.height
;
495 q_data
->field
= f
->fmt
.pix_mp
.field
;
496 ctx
->colorspace
= f
->fmt
.pix_mp
.colorspace
;
497 ctx
->ycbcr_enc
= f
->fmt
.pix_mp
.ycbcr_enc
;
498 ctx
->quantization
= f
->fmt
.pix_mp
.quantization
;
499 ctx
->xfer_func
= f
->fmt
.pix_mp
.xfer_func
;
501 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
502 struct v4l2_plane_pix_format
*plane_fmt
;
504 plane_fmt
= &f
->fmt
.pix_mp
.plane_fmt
[i
];
505 q_data
->bytesperline
[i
] = plane_fmt
->bytesperline
;
506 q_data
->sizeimage
[i
] = plane_fmt
->sizeimage
;
512 static int vidioc_venc_g_fmt(struct file
*file
, void *priv
,
513 struct v4l2_format
*f
)
515 struct v4l2_pix_format_mplane
*pix
= &f
->fmt
.pix_mp
;
516 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
517 struct vb2_queue
*vq
;
518 struct mtk_q_data
*q_data
;
521 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
525 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
527 pix
->width
= q_data
->coded_width
;
528 pix
->height
= q_data
->coded_height
;
529 pix
->pixelformat
= q_data
->fmt
->fourcc
;
530 pix
->field
= q_data
->field
;
531 pix
->num_planes
= q_data
->fmt
->num_planes
;
532 for (i
= 0; i
< pix
->num_planes
; i
++) {
533 pix
->plane_fmt
[i
].bytesperline
= q_data
->bytesperline
[i
];
534 pix
->plane_fmt
[i
].sizeimage
= q_data
->sizeimage
[i
];
535 memset(&(pix
->plane_fmt
[i
].reserved
[0]), 0x0,
536 sizeof(pix
->plane_fmt
[i
].reserved
));
540 pix
->colorspace
= ctx
->colorspace
;
541 pix
->ycbcr_enc
= ctx
->ycbcr_enc
;
542 pix
->quantization
= ctx
->quantization
;
543 pix
->xfer_func
= ctx
->xfer_func
;
548 static int vidioc_try_fmt_vid_cap_mplane(struct file
*file
, void *priv
,
549 struct v4l2_format
*f
)
551 const struct mtk_video_fmt
*fmt
;
552 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
553 const struct mtk_vcodec_enc_pdata
*pdata
= ctx
->dev
->venc_pdata
;
555 fmt
= mtk_venc_find_format(f
->fmt
.pix
.pixelformat
, pdata
);
557 fmt
= &ctx
->dev
->venc_pdata
->capture_formats
[0];
558 f
->fmt
.pix
.pixelformat
= fmt
->fourcc
;
560 f
->fmt
.pix_mp
.colorspace
= ctx
->colorspace
;
561 f
->fmt
.pix_mp
.ycbcr_enc
= ctx
->ycbcr_enc
;
562 f
->fmt
.pix_mp
.quantization
= ctx
->quantization
;
563 f
->fmt
.pix_mp
.xfer_func
= ctx
->xfer_func
;
565 return vidioc_try_fmt(f
, fmt
);
568 static int vidioc_try_fmt_vid_out_mplane(struct file
*file
, void *priv
,
569 struct v4l2_format
*f
)
571 const struct mtk_video_fmt
*fmt
;
572 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
573 const struct mtk_vcodec_enc_pdata
*pdata
= ctx
->dev
->venc_pdata
;
575 fmt
= mtk_venc_find_format(f
->fmt
.pix
.pixelformat
, pdata
);
577 fmt
= &ctx
->dev
->venc_pdata
->output_formats
[0];
578 f
->fmt
.pix
.pixelformat
= fmt
->fourcc
;
580 if (!f
->fmt
.pix_mp
.colorspace
) {
581 f
->fmt
.pix_mp
.colorspace
= V4L2_COLORSPACE_REC709
;
582 f
->fmt
.pix_mp
.ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
583 f
->fmt
.pix_mp
.quantization
= V4L2_QUANTIZATION_DEFAULT
;
584 f
->fmt
.pix_mp
.xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
587 return vidioc_try_fmt(f
, fmt
);
590 static int vidioc_venc_g_selection(struct file
*file
, void *priv
,
591 struct v4l2_selection
*s
)
593 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
594 struct mtk_q_data
*q_data
;
596 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
599 q_data
= mtk_venc_get_q_data(ctx
, s
->type
);
604 case V4L2_SEL_TGT_CROP_DEFAULT
:
605 case V4L2_SEL_TGT_CROP_BOUNDS
:
608 s
->r
.width
= q_data
->coded_width
;
609 s
->r
.height
= q_data
->coded_height
;
611 case V4L2_SEL_TGT_CROP
:
614 s
->r
.width
= q_data
->visible_width
;
615 s
->r
.height
= q_data
->visible_height
;
624 static int vidioc_venc_s_selection(struct file
*file
, void *priv
,
625 struct v4l2_selection
*s
)
627 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
628 struct mtk_q_data
*q_data
;
630 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
633 q_data
= mtk_venc_get_q_data(ctx
, s
->type
);
638 case V4L2_SEL_TGT_CROP
:
639 /* Only support crop from (0,0) */
642 s
->r
.width
= min(s
->r
.width
, q_data
->coded_width
);
643 s
->r
.height
= min(s
->r
.height
, q_data
->coded_height
);
644 q_data
->visible_width
= s
->r
.width
;
645 q_data
->visible_height
= s
->r
.height
;
653 static int vidioc_venc_qbuf(struct file
*file
, void *priv
,
654 struct v4l2_buffer
*buf
)
656 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
658 if (ctx
->state
== MTK_STATE_ABORT
) {
659 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
664 return v4l2_m2m_qbuf(file
, ctx
->m2m_ctx
, buf
);
667 static int vidioc_venc_dqbuf(struct file
*file
, void *priv
,
668 struct v4l2_buffer
*buf
)
670 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
672 if (ctx
->state
== MTK_STATE_ABORT
) {
673 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
678 return v4l2_m2m_dqbuf(file
, ctx
->m2m_ctx
, buf
);
681 const struct v4l2_ioctl_ops mtk_venc_ioctl_ops
= {
682 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
683 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
685 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
686 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
687 .vidioc_qbuf
= vidioc_venc_qbuf
,
688 .vidioc_dqbuf
= vidioc_venc_dqbuf
,
690 .vidioc_querycap
= vidioc_venc_querycap
,
691 .vidioc_enum_fmt_vid_cap
= vidioc_enum_fmt_vid_cap
,
692 .vidioc_enum_fmt_vid_out
= vidioc_enum_fmt_vid_out
,
693 .vidioc_enum_framesizes
= vidioc_enum_framesizes
,
695 .vidioc_try_fmt_vid_cap_mplane
= vidioc_try_fmt_vid_cap_mplane
,
696 .vidioc_try_fmt_vid_out_mplane
= vidioc_try_fmt_vid_out_mplane
,
697 .vidioc_expbuf
= v4l2_m2m_ioctl_expbuf
,
698 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
699 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
701 .vidioc_s_parm
= vidioc_venc_s_parm
,
702 .vidioc_g_parm
= vidioc_venc_g_parm
,
703 .vidioc_s_fmt_vid_cap_mplane
= vidioc_venc_s_fmt_cap
,
704 .vidioc_s_fmt_vid_out_mplane
= vidioc_venc_s_fmt_out
,
706 .vidioc_g_fmt_vid_cap_mplane
= vidioc_venc_g_fmt
,
707 .vidioc_g_fmt_vid_out_mplane
= vidioc_venc_g_fmt
,
709 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
710 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
712 .vidioc_g_selection
= vidioc_venc_g_selection
,
713 .vidioc_s_selection
= vidioc_venc_s_selection
,
716 static int vb2ops_venc_queue_setup(struct vb2_queue
*vq
,
717 unsigned int *nbuffers
,
718 unsigned int *nplanes
,
719 unsigned int sizes
[],
720 struct device
*alloc_devs
[])
722 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vq
);
723 struct mtk_q_data
*q_data
;
726 q_data
= mtk_venc_get_q_data(ctx
, vq
->type
);
732 for (i
= 0; i
< *nplanes
; i
++)
733 if (sizes
[i
] < q_data
->sizeimage
[i
])
736 *nplanes
= q_data
->fmt
->num_planes
;
737 for (i
= 0; i
< *nplanes
; i
++)
738 sizes
[i
] = q_data
->sizeimage
[i
];
744 static int vb2ops_venc_buf_prepare(struct vb2_buffer
*vb
)
746 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
747 struct mtk_q_data
*q_data
;
750 q_data
= mtk_venc_get_q_data(ctx
, vb
->vb2_queue
->type
);
752 for (i
= 0; i
< q_data
->fmt
->num_planes
; i
++) {
753 if (vb2_plane_size(vb
, i
) < q_data
->sizeimage
[i
]) {
754 mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
755 i
, vb2_plane_size(vb
, i
),
756 q_data
->sizeimage
[i
]);
764 static void vb2ops_venc_buf_queue(struct vb2_buffer
*vb
)
766 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
767 struct vb2_v4l2_buffer
*vb2_v4l2
=
768 container_of(vb
, struct vb2_v4l2_buffer
, vb2_buf
);
770 struct mtk_video_enc_buf
*mtk_buf
=
771 container_of(vb2_v4l2
, struct mtk_video_enc_buf
,
774 if ((vb
->vb2_queue
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) &&
775 (ctx
->param_change
!= MTK_ENCODE_PARAM_NONE
)) {
776 mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x",
778 vb2_v4l2
->vb2_buf
.index
,
780 mtk_buf
->param_change
= ctx
->param_change
;
781 mtk_buf
->enc_params
= ctx
->enc_params
;
782 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
785 v4l2_m2m_buf_queue(ctx
->m2m_ctx
, to_vb2_v4l2_buffer(vb
));
788 static int vb2ops_venc_start_streaming(struct vb2_queue
*q
, unsigned int count
)
790 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
791 struct venc_enc_param param
;
795 /* Once state turn into MTK_STATE_ABORT, we need stop_streaming
798 if ((ctx
->state
== MTK_STATE_ABORT
) || (ctx
->state
== MTK_STATE_FREE
)) {
803 /* Do the initialization when both start_streaming have been called */
804 if (V4L2_TYPE_IS_OUTPUT(q
->type
)) {
805 if (!vb2_start_streaming_called(&ctx
->m2m_ctx
->cap_q_ctx
.q
))
808 if (!vb2_start_streaming_called(&ctx
->m2m_ctx
->out_q_ctx
.q
))
812 mtk_venc_set_param(ctx
, ¶m
);
813 ret
= venc_if_set_param(ctx
, VENC_SET_PARAM_ENC
, ¶m
);
815 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
816 ctx
->state
= MTK_STATE_ABORT
;
819 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
821 if ((ctx
->q_data
[MTK_Q_DATA_DST
].fmt
->fourcc
== V4L2_PIX_FMT_H264
) &&
822 (ctx
->enc_params
.seq_hdr_mode
!=
823 V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
)) {
824 ret
= venc_if_set_param(ctx
,
825 VENC_SET_PARAM_PREPEND_HEADER
,
828 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
829 ctx
->state
= MTK_STATE_ABORT
;
832 ctx
->state
= MTK_STATE_HEADER
;
838 for (i
= 0; i
< q
->num_buffers
; ++i
) {
839 struct vb2_buffer
*buf
= vb2_get_buffer(q
, i
);
842 * FIXME: This check is not needed as only active buffers
843 * can be marked as done.
845 if (buf
->state
== VB2_BUF_STATE_ACTIVE
) {
846 mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED",
849 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(buf
),
850 VB2_BUF_STATE_QUEUED
);
857 static void vb2ops_venc_stop_streaming(struct vb2_queue
*q
)
859 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
860 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
863 mtk_v4l2_debug(2, "[%d]-> type=%d", ctx
->id
, q
->type
);
865 if (q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) {
866 while ((dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
))) {
867 dst_buf
->vb2_buf
.planes
[0].bytesused
= 0;
868 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_ERROR
);
871 while ((src_buf
= v4l2_m2m_src_buf_remove(ctx
->m2m_ctx
)))
872 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_ERROR
);
875 if ((q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
876 vb2_is_streaming(&ctx
->m2m_ctx
->out_q_ctx
.q
)) ||
877 (q
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
&&
878 vb2_is_streaming(&ctx
->m2m_ctx
->cap_q_ctx
.q
))) {
879 mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d",
881 vb2_is_streaming(&ctx
->m2m_ctx
->out_q_ctx
.q
),
882 vb2_is_streaming(&ctx
->m2m_ctx
->cap_q_ctx
.q
));
886 /* Release the encoder if both streams are stopped. */
887 ret
= venc_if_deinit(ctx
);
889 mtk_v4l2_err("venc_if_deinit failed=%d", ret
);
891 ctx
->state
= MTK_STATE_FREE
;
894 static int vb2ops_venc_buf_out_validate(struct vb2_buffer
*vb
)
896 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
898 vbuf
->field
= V4L2_FIELD_NONE
;
902 static const struct vb2_ops mtk_venc_vb2_ops
= {
903 .queue_setup
= vb2ops_venc_queue_setup
,
904 .buf_out_validate
= vb2ops_venc_buf_out_validate
,
905 .buf_prepare
= vb2ops_venc_buf_prepare
,
906 .buf_queue
= vb2ops_venc_buf_queue
,
907 .wait_prepare
= vb2_ops_wait_prepare
,
908 .wait_finish
= vb2_ops_wait_finish
,
909 .start_streaming
= vb2ops_venc_start_streaming
,
910 .stop_streaming
= vb2ops_venc_stop_streaming
,
913 static int mtk_venc_encode_header(void *priv
)
915 struct mtk_vcodec_ctx
*ctx
= priv
;
917 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
918 struct mtk_vcodec_mem bs_buf
;
919 struct venc_done_result enc_result
;
921 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
923 mtk_v4l2_debug(1, "No dst buffer");
927 bs_buf
.va
= vb2_plane_vaddr(&dst_buf
->vb2_buf
, 0);
928 bs_buf
.dma_addr
= vb2_dma_contig_plane_dma_addr(&dst_buf
->vb2_buf
, 0);
929 bs_buf
.size
= (size_t)dst_buf
->vb2_buf
.planes
[0].length
;
932 "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu",
934 dst_buf
->vb2_buf
.index
, bs_buf
.va
,
935 (u64
)bs_buf
.dma_addr
,
938 ret
= venc_if_encode(ctx
,
939 VENC_START_OPT_ENCODE_SEQUENCE_HEADER
,
940 NULL
, &bs_buf
, &enc_result
);
943 dst_buf
->vb2_buf
.planes
[0].bytesused
= 0;
944 ctx
->state
= MTK_STATE_ABORT
;
945 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_ERROR
);
946 mtk_v4l2_err("venc_if_encode failed=%d", ret
);
949 src_buf
= v4l2_m2m_next_src_buf(ctx
->m2m_ctx
);
951 dst_buf
->vb2_buf
.timestamp
= src_buf
->vb2_buf
.timestamp
;
952 dst_buf
->timecode
= src_buf
->timecode
;
954 mtk_v4l2_err("No timestamp for the header buffer.");
957 ctx
->state
= MTK_STATE_HEADER
;
958 dst_buf
->vb2_buf
.planes
[0].bytesused
= enc_result
.bs_size
;
959 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_DONE
);
964 static int mtk_venc_param_change(struct mtk_vcodec_ctx
*ctx
)
966 struct venc_enc_param enc_prm
;
967 struct vb2_v4l2_buffer
*vb2_v4l2
= v4l2_m2m_next_src_buf(ctx
->m2m_ctx
);
968 struct mtk_video_enc_buf
*mtk_buf
=
969 container_of(vb2_v4l2
, struct mtk_video_enc_buf
,
974 memset(&enc_prm
, 0, sizeof(enc_prm
));
975 if (mtk_buf
->param_change
== MTK_ENCODE_PARAM_NONE
)
978 if (mtk_buf
->param_change
& MTK_ENCODE_PARAM_BITRATE
) {
979 enc_prm
.bitrate
= mtk_buf
->enc_params
.bitrate
;
980 mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d",
982 vb2_v4l2
->vb2_buf
.index
,
984 ret
|= venc_if_set_param(ctx
,
985 VENC_SET_PARAM_ADJUST_BITRATE
,
988 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_FRAMERATE
) {
989 enc_prm
.frm_rate
= mtk_buf
->enc_params
.framerate_num
/
990 mtk_buf
->enc_params
.framerate_denom
;
991 mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d",
993 vb2_v4l2
->vb2_buf
.index
,
995 ret
|= venc_if_set_param(ctx
,
996 VENC_SET_PARAM_ADJUST_FRAMERATE
,
999 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_GOP_SIZE
) {
1000 enc_prm
.gop_size
= mtk_buf
->enc_params
.gop_size
;
1001 mtk_v4l2_debug(1, "change param intra period=%d",
1003 ret
|= venc_if_set_param(ctx
,
1004 VENC_SET_PARAM_GOP_SIZE
,
1007 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_FORCE_INTRA
) {
1008 mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d",
1010 vb2_v4l2
->vb2_buf
.index
,
1011 mtk_buf
->enc_params
.force_intra
);
1012 if (mtk_buf
->enc_params
.force_intra
)
1013 ret
|= venc_if_set_param(ctx
,
1014 VENC_SET_PARAM_FORCE_INTRA
,
1018 mtk_buf
->param_change
= MTK_ENCODE_PARAM_NONE
;
1021 ctx
->state
= MTK_STATE_ABORT
;
1022 mtk_v4l2_err("venc_if_set_param %d failed=%d",
1023 mtk_buf
->param_change
, ret
);
1031 * v4l2_m2m_streamoff() holds dev_mutex and waits mtk_venc_worker()
1032 * to call v4l2_m2m_job_finish().
1033 * If mtk_venc_worker() tries to acquire dev_mutex, it will deadlock.
1034 * So this function must not try to acquire dev->dev_mutex.
1035 * This means v4l2 ioctls and mtk_venc_worker() can run at the same time.
1036 * mtk_venc_worker() should be carefully implemented to avoid bugs.
1038 static void mtk_venc_worker(struct work_struct
*work
)
1040 struct mtk_vcodec_ctx
*ctx
= container_of(work
, struct mtk_vcodec_ctx
,
1042 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
1043 struct venc_frm_buf frm_buf
;
1044 struct mtk_vcodec_mem bs_buf
;
1045 struct venc_done_result enc_result
;
1048 /* check dst_buf, dst_buf may be removed in device_run
1049 * to stored encdoe header so we need check dst_buf and
1050 * call job_finish here to prevent recursion
1052 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
1054 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
1058 src_buf
= v4l2_m2m_src_buf_remove(ctx
->m2m_ctx
);
1059 memset(&frm_buf
, 0, sizeof(frm_buf
));
1060 for (i
= 0; i
< src_buf
->vb2_buf
.num_planes
; i
++) {
1061 frm_buf
.fb_addr
[i
].dma_addr
=
1062 vb2_dma_contig_plane_dma_addr(&src_buf
->vb2_buf
, i
);
1063 frm_buf
.fb_addr
[i
].size
=
1064 (size_t)src_buf
->vb2_buf
.planes
[i
].length
;
1066 bs_buf
.va
= vb2_plane_vaddr(&dst_buf
->vb2_buf
, 0);
1067 bs_buf
.dma_addr
= vb2_dma_contig_plane_dma_addr(&dst_buf
->vb2_buf
, 0);
1068 bs_buf
.size
= (size_t)dst_buf
->vb2_buf
.planes
[0].length
;
1071 "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu",
1072 (u64
)frm_buf
.fb_addr
[0].dma_addr
,
1073 frm_buf
.fb_addr
[0].size
,
1074 (u64
)frm_buf
.fb_addr
[1].dma_addr
,
1075 frm_buf
.fb_addr
[1].size
,
1076 (u64
)frm_buf
.fb_addr
[2].dma_addr
,
1077 frm_buf
.fb_addr
[2].size
);
1079 ret
= venc_if_encode(ctx
, VENC_START_OPT_ENCODE_FRAME
,
1080 &frm_buf
, &bs_buf
, &enc_result
);
1082 dst_buf
->vb2_buf
.timestamp
= src_buf
->vb2_buf
.timestamp
;
1083 dst_buf
->timecode
= src_buf
->timecode
;
1085 if (enc_result
.is_key_frm
)
1086 dst_buf
->flags
|= V4L2_BUF_FLAG_KEYFRAME
;
1089 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_ERROR
);
1090 dst_buf
->vb2_buf
.planes
[0].bytesused
= 0;
1091 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_ERROR
);
1092 mtk_v4l2_err("venc_if_encode failed=%d", ret
);
1094 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_DONE
);
1095 dst_buf
->vb2_buf
.planes
[0].bytesused
= enc_result
.bs_size
;
1096 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_DONE
);
1097 mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
1098 enc_result
.bs_size
);
1101 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
1103 mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
1104 src_buf
->vb2_buf
.index
, dst_buf
->vb2_buf
.index
, ret
,
1105 enc_result
.bs_size
);
1108 static void m2mops_venc_device_run(void *priv
)
1110 struct mtk_vcodec_ctx
*ctx
= priv
;
1112 if ((ctx
->q_data
[MTK_Q_DATA_DST
].fmt
->fourcc
== V4L2_PIX_FMT_H264
) &&
1113 (ctx
->state
!= MTK_STATE_HEADER
)) {
1114 /* encode h264 sps/pps header */
1115 mtk_venc_encode_header(ctx
);
1116 queue_work(ctx
->dev
->encode_workqueue
, &ctx
->encode_work
);
1120 mtk_venc_param_change(ctx
);
1121 queue_work(ctx
->dev
->encode_workqueue
, &ctx
->encode_work
);
1124 static int m2mops_venc_job_ready(void *m2m_priv
)
1126 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
1128 if (ctx
->state
== MTK_STATE_ABORT
|| ctx
->state
== MTK_STATE_FREE
) {
1129 mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.",
1130 ctx
->id
, ctx
->state
);
1137 static void m2mops_venc_job_abort(void *priv
)
1139 struct mtk_vcodec_ctx
*ctx
= priv
;
1141 ctx
->state
= MTK_STATE_ABORT
;
1144 const struct v4l2_m2m_ops mtk_venc_m2m_ops
= {
1145 .device_run
= m2mops_venc_device_run
,
1146 .job_ready
= m2mops_venc_job_ready
,
1147 .job_abort
= m2mops_venc_job_abort
,
1150 void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx
*ctx
)
1152 struct mtk_q_data
*q_data
;
1154 ctx
->m2m_ctx
->q_lock
= &ctx
->dev
->dev_mutex
;
1155 ctx
->fh
.m2m_ctx
= ctx
->m2m_ctx
;
1156 ctx
->fh
.ctrl_handler
= &ctx
->ctrl_hdl
;
1157 INIT_WORK(&ctx
->encode_work
, mtk_venc_worker
);
1159 ctx
->colorspace
= V4L2_COLORSPACE_REC709
;
1160 ctx
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
1161 ctx
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
1162 ctx
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
1164 q_data
= &ctx
->q_data
[MTK_Q_DATA_SRC
];
1165 memset(q_data
, 0, sizeof(struct mtk_q_data
));
1166 q_data
->visible_width
= DFT_CFG_WIDTH
;
1167 q_data
->visible_height
= DFT_CFG_HEIGHT
;
1168 q_data
->coded_width
= DFT_CFG_WIDTH
;
1169 q_data
->coded_height
= DFT_CFG_HEIGHT
;
1170 q_data
->field
= V4L2_FIELD_NONE
;
1172 q_data
->fmt
= &ctx
->dev
->venc_pdata
->output_formats
[0];
1174 v4l_bound_align_image(&q_data
->coded_width
,
1177 &q_data
->coded_height
,
1179 MTK_VENC_MAX_H
, 5, 6);
1181 if (q_data
->coded_width
< DFT_CFG_WIDTH
&&
1182 (q_data
->coded_width
+ 16) <= MTK_VENC_MAX_W
)
1183 q_data
->coded_width
+= 16;
1184 if (q_data
->coded_height
< DFT_CFG_HEIGHT
&&
1185 (q_data
->coded_height
+ 32) <= MTK_VENC_MAX_H
)
1186 q_data
->coded_height
+= 32;
1188 q_data
->sizeimage
[0] =
1189 q_data
->coded_width
* q_data
->coded_height
+
1190 ((ALIGN(q_data
->coded_width
, 16) * 2) * 16);
1191 q_data
->bytesperline
[0] = q_data
->coded_width
;
1192 q_data
->sizeimage
[1] =
1193 (q_data
->coded_width
* q_data
->coded_height
) / 2 +
1194 (ALIGN(q_data
->coded_width
, 16) * 16);
1195 q_data
->bytesperline
[1] = q_data
->coded_width
;
1197 q_data
= &ctx
->q_data
[MTK_Q_DATA_DST
];
1198 memset(q_data
, 0, sizeof(struct mtk_q_data
));
1199 q_data
->coded_width
= DFT_CFG_WIDTH
;
1200 q_data
->coded_height
= DFT_CFG_HEIGHT
;
1201 q_data
->fmt
= &ctx
->dev
->venc_pdata
->capture_formats
[0];
1202 q_data
->field
= V4L2_FIELD_NONE
;
1203 ctx
->q_data
[MTK_Q_DATA_DST
].sizeimage
[0] =
1204 DFT_CFG_WIDTH
* DFT_CFG_HEIGHT
;
1205 ctx
->q_data
[MTK_Q_DATA_DST
].bytesperline
[0] = 0;
1207 ctx
->enc_params
.framerate_num
= MTK_DEFAULT_FRAMERATE_NUM
;
1208 ctx
->enc_params
.framerate_denom
= MTK_DEFAULT_FRAMERATE_DENOM
;
1211 int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx
*ctx
)
1213 const struct v4l2_ctrl_ops
*ops
= &mtk_vcodec_enc_ctrl_ops
;
1214 struct v4l2_ctrl_handler
*handler
= &ctx
->ctrl_hdl
;
1216 v4l2_ctrl_handler_init(handler
, MTK_MAX_CTRLS_HINT
);
1218 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT
,
1220 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_BITRATE
,
1221 ctx
->dev
->venc_pdata
->min_bitrate
,
1222 ctx
->dev
->venc_pdata
->max_bitrate
, 1, 4000000);
1223 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_B_FRAMES
,
1225 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
,
1227 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_MAX_QP
,
1229 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
,
1231 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
1233 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
,
1235 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
,
1237 v4l2_ctrl_new_std_menu(handler
, ops
,
1238 V4L2_CID_MPEG_VIDEO_HEADER_MODE
,
1239 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME
,
1240 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
);
1241 v4l2_ctrl_new_std_menu(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_PROFILE
,
1242 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
,
1243 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
);
1244 v4l2_ctrl_new_std_menu(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_LEVEL
,
1245 V4L2_MPEG_VIDEO_H264_LEVEL_4_2
,
1246 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0
);
1247 if (handler
->error
) {
1248 mtk_v4l2_err("Init control handler fail %d",
1250 return handler
->error
;
1253 v4l2_ctrl_handler_setup(&ctx
->ctrl_hdl
);
1258 int mtk_vcodec_enc_queue_init(void *priv
, struct vb2_queue
*src_vq
,
1259 struct vb2_queue
*dst_vq
)
1261 struct mtk_vcodec_ctx
*ctx
= priv
;
1264 /* Note: VB2_USERPTR works with dma-contig because mt8173
1266 * https://patchwork.kernel.org/patch/8335461/
1267 * https://patchwork.kernel.org/patch/7596181/
1269 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1270 src_vq
->io_modes
= VB2_DMABUF
| VB2_MMAP
| VB2_USERPTR
;
1271 src_vq
->drv_priv
= ctx
;
1272 src_vq
->buf_struct_size
= sizeof(struct mtk_video_enc_buf
);
1273 src_vq
->ops
= &mtk_venc_vb2_ops
;
1274 src_vq
->mem_ops
= &vb2_dma_contig_memops
;
1275 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1276 src_vq
->lock
= &ctx
->dev
->dev_mutex
;
1277 src_vq
->dev
= &ctx
->dev
->plat_dev
->dev
;
1279 ret
= vb2_queue_init(src_vq
);
1283 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1284 dst_vq
->io_modes
= VB2_DMABUF
| VB2_MMAP
| VB2_USERPTR
;
1285 dst_vq
->drv_priv
= ctx
;
1286 dst_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
1287 dst_vq
->ops
= &mtk_venc_vb2_ops
;
1288 dst_vq
->mem_ops
= &vb2_dma_contig_memops
;
1289 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1290 dst_vq
->lock
= &ctx
->dev
->dev_mutex
;
1291 dst_vq
->dev
= &ctx
->dev
->plat_dev
->dev
;
1293 return vb2_queue_init(dst_vq
);
1296 int mtk_venc_unlock(struct mtk_vcodec_ctx
*ctx
)
1298 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1300 mutex_unlock(&dev
->enc_mutex
);
1304 int mtk_venc_lock(struct mtk_vcodec_ctx
*ctx
)
1306 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1308 mutex_lock(&dev
->enc_mutex
);
1312 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx
*ctx
)
1314 int ret
= venc_if_deinit(ctx
);
1317 mtk_v4l2_err("venc_if_deinit failed=%d", ret
);
1319 ctx
->state
= MTK_STATE_FREE
;