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
;
246 a
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
251 static int vidioc_venc_g_parm(struct file
*file
, void *priv
,
252 struct v4l2_streamparm
*a
)
254 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
256 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
259 a
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
260 a
->parm
.output
.timeperframe
.denominator
=
261 ctx
->enc_params
.framerate_num
;
262 a
->parm
.output
.timeperframe
.numerator
=
263 ctx
->enc_params
.framerate_denom
;
268 static struct mtk_q_data
*mtk_venc_get_q_data(struct mtk_vcodec_ctx
*ctx
,
269 enum v4l2_buf_type type
)
271 if (V4L2_TYPE_IS_OUTPUT(type
))
272 return &ctx
->q_data
[MTK_Q_DATA_SRC
];
274 return &ctx
->q_data
[MTK_Q_DATA_DST
];
277 static struct mtk_video_fmt
*mtk_venc_find_format(struct v4l2_format
*f
)
279 struct mtk_video_fmt
*fmt
;
282 for (k
= 0; k
< NUM_FORMATS
; k
++) {
283 fmt
= &mtk_video_formats
[k
];
284 if (fmt
->fourcc
== f
->fmt
.pix
.pixelformat
)
291 /* V4L2 specification suggests the driver corrects the format struct if any of
292 * the dimensions is unsupported
294 static int vidioc_try_fmt(struct v4l2_format
*f
, struct mtk_video_fmt
*fmt
)
296 struct v4l2_pix_format_mplane
*pix_fmt_mp
= &f
->fmt
.pix_mp
;
299 pix_fmt_mp
->field
= V4L2_FIELD_NONE
;
301 if (f
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) {
302 pix_fmt_mp
->num_planes
= 1;
303 pix_fmt_mp
->plane_fmt
[0].bytesperline
= 0;
304 } else if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) {
307 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
310 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
314 /* find next closer width align 16, heign align 32, size align
317 tmp_w
= pix_fmt_mp
->width
;
318 tmp_h
= pix_fmt_mp
->height
;
319 v4l_bound_align_image(&pix_fmt_mp
->width
,
324 MTK_VENC_MAX_H
, 5, 6);
326 if (pix_fmt_mp
->width
< tmp_w
&&
327 (pix_fmt_mp
->width
+ 16) <= MTK_VENC_MAX_W
)
328 pix_fmt_mp
->width
+= 16;
329 if (pix_fmt_mp
->height
< tmp_h
&&
330 (pix_fmt_mp
->height
+ 32) <= MTK_VENC_MAX_H
)
331 pix_fmt_mp
->height
+= 32;
334 "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d %d",
335 tmp_w
, tmp_h
, pix_fmt_mp
->width
,
337 pix_fmt_mp
->plane_fmt
[0].sizeimage
,
338 pix_fmt_mp
->plane_fmt
[1].sizeimage
);
340 pix_fmt_mp
->num_planes
= fmt
->num_planes
;
341 pix_fmt_mp
->plane_fmt
[0].sizeimage
=
342 pix_fmt_mp
->width
* pix_fmt_mp
->height
+
343 ((ALIGN(pix_fmt_mp
->width
, 16) * 2) * 16);
344 pix_fmt_mp
->plane_fmt
[0].bytesperline
= pix_fmt_mp
->width
;
346 if (pix_fmt_mp
->num_planes
== 2) {
347 pix_fmt_mp
->plane_fmt
[1].sizeimage
=
348 (pix_fmt_mp
->width
* pix_fmt_mp
->height
) / 2 +
349 (ALIGN(pix_fmt_mp
->width
, 16) * 16);
350 pix_fmt_mp
->plane_fmt
[2].sizeimage
= 0;
351 pix_fmt_mp
->plane_fmt
[1].bytesperline
=
353 pix_fmt_mp
->plane_fmt
[2].bytesperline
= 0;
354 } else if (pix_fmt_mp
->num_planes
== 3) {
355 pix_fmt_mp
->plane_fmt
[1].sizeimage
=
356 pix_fmt_mp
->plane_fmt
[2].sizeimage
=
357 (pix_fmt_mp
->width
* pix_fmt_mp
->height
) / 4 +
358 ((ALIGN(pix_fmt_mp
->width
, 16) / 2) * 16);
359 pix_fmt_mp
->plane_fmt
[1].bytesperline
=
360 pix_fmt_mp
->plane_fmt
[2].bytesperline
=
361 pix_fmt_mp
->width
/ 2;
365 for (i
= 0; i
< pix_fmt_mp
->num_planes
; i
++)
366 memset(&(pix_fmt_mp
->plane_fmt
[i
].reserved
[0]), 0x0,
367 sizeof(pix_fmt_mp
->plane_fmt
[0].reserved
));
369 pix_fmt_mp
->flags
= 0;
370 memset(&pix_fmt_mp
->reserved
, 0x0,
371 sizeof(pix_fmt_mp
->reserved
));
376 static void mtk_venc_set_param(struct mtk_vcodec_ctx
*ctx
,
377 struct venc_enc_param
*param
)
379 struct mtk_q_data
*q_data_src
= &ctx
->q_data
[MTK_Q_DATA_SRC
];
380 struct mtk_enc_params
*enc_params
= &ctx
->enc_params
;
382 switch (q_data_src
->fmt
->fourcc
) {
383 case V4L2_PIX_FMT_YUV420M
:
384 param
->input_yuv_fmt
= VENC_YUV_FORMAT_I420
;
386 case V4L2_PIX_FMT_YVU420M
:
387 param
->input_yuv_fmt
= VENC_YUV_FORMAT_YV12
;
389 case V4L2_PIX_FMT_NV12M
:
390 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV12
;
392 case V4L2_PIX_FMT_NV21M
:
393 param
->input_yuv_fmt
= VENC_YUV_FORMAT_NV21
;
396 mtk_v4l2_err("Unsupport fourcc =%d", q_data_src
->fmt
->fourcc
);
399 param
->h264_profile
= enc_params
->h264_profile
;
400 param
->h264_level
= enc_params
->h264_level
;
402 /* Config visible resolution */
403 param
->width
= q_data_src
->visible_width
;
404 param
->height
= q_data_src
->visible_height
;
405 /* Config coded resolution */
406 param
->buf_width
= q_data_src
->coded_width
;
407 param
->buf_height
= q_data_src
->coded_height
;
408 param
->frm_rate
= enc_params
->framerate_num
/
409 enc_params
->framerate_denom
;
410 param
->intra_period
= enc_params
->intra_period
;
411 param
->gop_size
= enc_params
->gop_size
;
412 param
->bitrate
= enc_params
->bitrate
;
415 "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d",
416 param
->input_yuv_fmt
, param
->h264_profile
,
417 param
->h264_level
, param
->width
, param
->height
,
418 param
->buf_width
, param
->buf_height
,
419 param
->frm_rate
, param
->bitrate
,
420 param
->gop_size
, param
->intra_period
);
423 static int vidioc_venc_s_fmt_cap(struct file
*file
, void *priv
,
424 struct v4l2_format
*f
)
426 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
427 struct vb2_queue
*vq
;
428 struct mtk_q_data
*q_data
;
430 struct mtk_video_fmt
*fmt
;
432 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
434 mtk_v4l2_err("fail to get vq");
438 if (vb2_is_busy(vq
)) {
439 mtk_v4l2_err("queue busy");
443 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
445 mtk_v4l2_err("fail to get q data");
449 fmt
= mtk_venc_find_format(f
);
451 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[CAP_FMT_IDX
].fourcc
;
452 fmt
= mtk_venc_find_format(f
);
456 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
460 q_data
->coded_width
= f
->fmt
.pix_mp
.width
;
461 q_data
->coded_height
= f
->fmt
.pix_mp
.height
;
462 q_data
->field
= f
->fmt
.pix_mp
.field
;
464 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
465 struct v4l2_plane_pix_format
*plane_fmt
;
467 plane_fmt
= &f
->fmt
.pix_mp
.plane_fmt
[i
];
468 q_data
->bytesperline
[i
] = plane_fmt
->bytesperline
;
469 q_data
->sizeimage
[i
] = plane_fmt
->sizeimage
;
472 if (ctx
->state
== MTK_STATE_FREE
) {
473 ret
= venc_if_init(ctx
, q_data
->fmt
->fourcc
);
475 mtk_v4l2_err("venc_if_init failed=%d, codec type=%x",
476 ret
, q_data
->fmt
->fourcc
);
479 ctx
->state
= MTK_STATE_INIT
;
485 static int vidioc_venc_s_fmt_out(struct file
*file
, void *priv
,
486 struct v4l2_format
*f
)
488 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
489 struct vb2_queue
*vq
;
490 struct mtk_q_data
*q_data
;
492 struct mtk_video_fmt
*fmt
;
493 struct v4l2_pix_format_mplane
*pix_fmt_mp
= &f
->fmt
.pix_mp
;
495 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
497 mtk_v4l2_err("fail to get vq");
501 if (vb2_is_busy(vq
)) {
502 mtk_v4l2_err("queue busy");
506 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
508 mtk_v4l2_err("fail to get q data");
512 fmt
= mtk_venc_find_format(f
);
514 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[OUT_FMT_IDX
].fourcc
;
515 fmt
= mtk_venc_find_format(f
);
518 pix_fmt_mp
->height
= clamp(pix_fmt_mp
->height
,
521 pix_fmt_mp
->width
= clamp(pix_fmt_mp
->width
,
525 q_data
->visible_width
= f
->fmt
.pix_mp
.width
;
526 q_data
->visible_height
= f
->fmt
.pix_mp
.height
;
528 ret
= vidioc_try_fmt(f
, q_data
->fmt
);
532 q_data
->coded_width
= f
->fmt
.pix_mp
.width
;
533 q_data
->coded_height
= f
->fmt
.pix_mp
.height
;
535 q_data
->field
= f
->fmt
.pix_mp
.field
;
536 ctx
->colorspace
= f
->fmt
.pix_mp
.colorspace
;
537 ctx
->ycbcr_enc
= f
->fmt
.pix_mp
.ycbcr_enc
;
538 ctx
->quantization
= f
->fmt
.pix_mp
.quantization
;
539 ctx
->xfer_func
= f
->fmt
.pix_mp
.xfer_func
;
541 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
542 struct v4l2_plane_pix_format
*plane_fmt
;
544 plane_fmt
= &f
->fmt
.pix_mp
.plane_fmt
[i
];
545 q_data
->bytesperline
[i
] = plane_fmt
->bytesperline
;
546 q_data
->sizeimage
[i
] = plane_fmt
->sizeimage
;
552 static int vidioc_venc_g_fmt(struct file
*file
, void *priv
,
553 struct v4l2_format
*f
)
555 struct v4l2_pix_format_mplane
*pix
= &f
->fmt
.pix_mp
;
556 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
557 struct vb2_queue
*vq
;
558 struct mtk_q_data
*q_data
;
561 vq
= v4l2_m2m_get_vq(ctx
->m2m_ctx
, f
->type
);
565 q_data
= mtk_venc_get_q_data(ctx
, f
->type
);
567 pix
->width
= q_data
->coded_width
;
568 pix
->height
= q_data
->coded_height
;
569 pix
->pixelformat
= q_data
->fmt
->fourcc
;
570 pix
->field
= q_data
->field
;
571 pix
->num_planes
= q_data
->fmt
->num_planes
;
572 for (i
= 0; i
< pix
->num_planes
; i
++) {
573 pix
->plane_fmt
[i
].bytesperline
= q_data
->bytesperline
[i
];
574 pix
->plane_fmt
[i
].sizeimage
= q_data
->sizeimage
[i
];
575 memset(&(pix
->plane_fmt
[i
].reserved
[0]), 0x0,
576 sizeof(pix
->plane_fmt
[i
].reserved
));
580 pix
->colorspace
= ctx
->colorspace
;
581 pix
->ycbcr_enc
= ctx
->ycbcr_enc
;
582 pix
->quantization
= ctx
->quantization
;
583 pix
->xfer_func
= ctx
->xfer_func
;
588 static int vidioc_try_fmt_vid_cap_mplane(struct file
*file
, void *priv
,
589 struct v4l2_format
*f
)
591 struct mtk_video_fmt
*fmt
;
592 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
594 fmt
= mtk_venc_find_format(f
);
596 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[CAP_FMT_IDX
].fourcc
;
597 fmt
= mtk_venc_find_format(f
);
599 f
->fmt
.pix_mp
.colorspace
= ctx
->colorspace
;
600 f
->fmt
.pix_mp
.ycbcr_enc
= ctx
->ycbcr_enc
;
601 f
->fmt
.pix_mp
.quantization
= ctx
->quantization
;
602 f
->fmt
.pix_mp
.xfer_func
= ctx
->xfer_func
;
604 return vidioc_try_fmt(f
, fmt
);
607 static int vidioc_try_fmt_vid_out_mplane(struct file
*file
, void *priv
,
608 struct v4l2_format
*f
)
610 struct mtk_video_fmt
*fmt
;
612 fmt
= mtk_venc_find_format(f
);
614 f
->fmt
.pix
.pixelformat
= mtk_video_formats
[OUT_FMT_IDX
].fourcc
;
615 fmt
= mtk_venc_find_format(f
);
617 if (!f
->fmt
.pix_mp
.colorspace
) {
618 f
->fmt
.pix_mp
.colorspace
= V4L2_COLORSPACE_REC709
;
619 f
->fmt
.pix_mp
.ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
620 f
->fmt
.pix_mp
.quantization
= V4L2_QUANTIZATION_DEFAULT
;
621 f
->fmt
.pix_mp
.xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
624 return vidioc_try_fmt(f
, fmt
);
627 static int vidioc_venc_g_selection(struct file
*file
, void *priv
,
628 struct v4l2_selection
*s
)
630 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
631 struct mtk_q_data
*q_data
;
633 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
636 q_data
= mtk_venc_get_q_data(ctx
, s
->type
);
641 case V4L2_SEL_TGT_CROP_DEFAULT
:
642 case V4L2_SEL_TGT_CROP_BOUNDS
:
645 s
->r
.width
= q_data
->coded_width
;
646 s
->r
.height
= q_data
->coded_height
;
648 case V4L2_SEL_TGT_CROP
:
651 s
->r
.width
= q_data
->visible_width
;
652 s
->r
.height
= q_data
->visible_height
;
661 static int vidioc_venc_s_selection(struct file
*file
, void *priv
,
662 struct v4l2_selection
*s
)
664 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
665 struct mtk_q_data
*q_data
;
667 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
670 q_data
= mtk_venc_get_q_data(ctx
, s
->type
);
675 case V4L2_SEL_TGT_CROP
:
676 /* Only support crop from (0,0) */
679 s
->r
.width
= min(s
->r
.width
, q_data
->coded_width
);
680 s
->r
.height
= min(s
->r
.height
, q_data
->coded_height
);
681 q_data
->visible_width
= s
->r
.width
;
682 q_data
->visible_height
= s
->r
.height
;
690 static int vidioc_venc_qbuf(struct file
*file
, void *priv
,
691 struct v4l2_buffer
*buf
)
693 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
695 if (ctx
->state
== MTK_STATE_ABORT
) {
696 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
701 return v4l2_m2m_qbuf(file
, ctx
->m2m_ctx
, buf
);
704 static int vidioc_venc_dqbuf(struct file
*file
, void *priv
,
705 struct v4l2_buffer
*buf
)
707 struct mtk_vcodec_ctx
*ctx
= fh_to_ctx(priv
);
709 if (ctx
->state
== MTK_STATE_ABORT
) {
710 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
715 return v4l2_m2m_dqbuf(file
, ctx
->m2m_ctx
, buf
);
718 const struct v4l2_ioctl_ops mtk_venc_ioctl_ops
= {
719 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
720 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
722 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
723 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
724 .vidioc_qbuf
= vidioc_venc_qbuf
,
725 .vidioc_dqbuf
= vidioc_venc_dqbuf
,
727 .vidioc_querycap
= vidioc_venc_querycap
,
728 .vidioc_enum_fmt_vid_cap_mplane
= vidioc_enum_fmt_vid_cap_mplane
,
729 .vidioc_enum_fmt_vid_out_mplane
= vidioc_enum_fmt_vid_out_mplane
,
730 .vidioc_enum_framesizes
= vidioc_enum_framesizes
,
732 .vidioc_try_fmt_vid_cap_mplane
= vidioc_try_fmt_vid_cap_mplane
,
733 .vidioc_try_fmt_vid_out_mplane
= vidioc_try_fmt_vid_out_mplane
,
734 .vidioc_expbuf
= v4l2_m2m_ioctl_expbuf
,
735 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
736 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
738 .vidioc_s_parm
= vidioc_venc_s_parm
,
739 .vidioc_g_parm
= vidioc_venc_g_parm
,
740 .vidioc_s_fmt_vid_cap_mplane
= vidioc_venc_s_fmt_cap
,
741 .vidioc_s_fmt_vid_out_mplane
= vidioc_venc_s_fmt_out
,
743 .vidioc_g_fmt_vid_cap_mplane
= vidioc_venc_g_fmt
,
744 .vidioc_g_fmt_vid_out_mplane
= vidioc_venc_g_fmt
,
746 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
747 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
749 .vidioc_g_selection
= vidioc_venc_g_selection
,
750 .vidioc_s_selection
= vidioc_venc_s_selection
,
753 static int vb2ops_venc_queue_setup(struct vb2_queue
*vq
,
754 unsigned int *nbuffers
,
755 unsigned int *nplanes
,
756 unsigned int sizes
[],
757 struct device
*alloc_devs
[])
759 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vq
);
760 struct mtk_q_data
*q_data
;
763 q_data
= mtk_venc_get_q_data(ctx
, vq
->type
);
769 for (i
= 0; i
< *nplanes
; i
++)
770 if (sizes
[i
] < q_data
->sizeimage
[i
])
773 *nplanes
= q_data
->fmt
->num_planes
;
774 for (i
= 0; i
< *nplanes
; i
++)
775 sizes
[i
] = q_data
->sizeimage
[i
];
781 static int vb2ops_venc_buf_prepare(struct vb2_buffer
*vb
)
783 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
784 struct mtk_q_data
*q_data
;
787 q_data
= mtk_venc_get_q_data(ctx
, vb
->vb2_queue
->type
);
789 for (i
= 0; i
< q_data
->fmt
->num_planes
; i
++) {
790 if (vb2_plane_size(vb
, i
) < q_data
->sizeimage
[i
]) {
791 mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
792 i
, vb2_plane_size(vb
, i
),
793 q_data
->sizeimage
[i
]);
801 static void vb2ops_venc_buf_queue(struct vb2_buffer
*vb
)
803 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
804 struct vb2_v4l2_buffer
*vb2_v4l2
=
805 container_of(vb
, struct vb2_v4l2_buffer
, vb2_buf
);
807 struct mtk_video_enc_buf
*mtk_buf
=
808 container_of(vb2_v4l2
, struct mtk_video_enc_buf
, vb
);
810 if ((vb
->vb2_queue
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) &&
811 (ctx
->param_change
!= MTK_ENCODE_PARAM_NONE
)) {
812 mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x",
814 mtk_buf
->vb
.vb2_buf
.index
,
816 mtk_buf
->param_change
= ctx
->param_change
;
817 mtk_buf
->enc_params
= ctx
->enc_params
;
818 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
821 v4l2_m2m_buf_queue(ctx
->m2m_ctx
, to_vb2_v4l2_buffer(vb
));
824 static int vb2ops_venc_start_streaming(struct vb2_queue
*q
, unsigned int count
)
826 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
827 struct venc_enc_param param
;
831 /* Once state turn into MTK_STATE_ABORT, we need stop_streaming
834 if ((ctx
->state
== MTK_STATE_ABORT
) || (ctx
->state
== MTK_STATE_FREE
)) {
839 /* Do the initialization when both start_streaming have been called */
840 if (V4L2_TYPE_IS_OUTPUT(q
->type
)) {
841 if (!vb2_start_streaming_called(&ctx
->m2m_ctx
->cap_q_ctx
.q
))
844 if (!vb2_start_streaming_called(&ctx
->m2m_ctx
->out_q_ctx
.q
))
848 mtk_venc_set_param(ctx
, ¶m
);
849 ret
= venc_if_set_param(ctx
, VENC_SET_PARAM_ENC
, ¶m
);
851 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
852 ctx
->state
= MTK_STATE_ABORT
;
855 ctx
->param_change
= MTK_ENCODE_PARAM_NONE
;
857 if ((ctx
->q_data
[MTK_Q_DATA_DST
].fmt
->fourcc
== V4L2_PIX_FMT_H264
) &&
858 (ctx
->enc_params
.seq_hdr_mode
!=
859 V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
)) {
860 ret
= venc_if_set_param(ctx
,
861 VENC_SET_PARAM_PREPEND_HEADER
,
864 mtk_v4l2_err("venc_if_set_param failed=%d", ret
);
865 ctx
->state
= MTK_STATE_ABORT
;
868 ctx
->state
= MTK_STATE_HEADER
;
874 for (i
= 0; i
< q
->num_buffers
; ++i
) {
875 if (q
->bufs
[i
]->state
== VB2_BUF_STATE_ACTIVE
) {
876 mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED",
878 (int)q
->bufs
[i
]->state
);
879 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q
->bufs
[i
]),
880 VB2_BUF_STATE_QUEUED
);
887 static void vb2ops_venc_stop_streaming(struct vb2_queue
*q
)
889 struct mtk_vcodec_ctx
*ctx
= vb2_get_drv_priv(q
);
890 struct vb2_buffer
*src_buf
, *dst_buf
;
893 mtk_v4l2_debug(2, "[%d]-> type=%d", ctx
->id
, q
->type
);
895 if (q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) {
896 while ((dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
))) {
897 dst_buf
->planes
[0].bytesused
= 0;
898 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf
),
899 VB2_BUF_STATE_ERROR
);
902 while ((src_buf
= v4l2_m2m_src_buf_remove(ctx
->m2m_ctx
)))
903 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf
),
904 VB2_BUF_STATE_ERROR
);
907 if ((q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
908 vb2_is_streaming(&ctx
->m2m_ctx
->out_q_ctx
.q
)) ||
909 (q
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
&&
910 vb2_is_streaming(&ctx
->m2m_ctx
->cap_q_ctx
.q
))) {
911 mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d",
913 vb2_is_streaming(&ctx
->m2m_ctx
->out_q_ctx
.q
),
914 vb2_is_streaming(&ctx
->m2m_ctx
->cap_q_ctx
.q
));
918 /* Release the encoder if both streams are stopped. */
919 ret
= venc_if_deinit(ctx
);
921 mtk_v4l2_err("venc_if_deinit failed=%d", ret
);
923 ctx
->state
= MTK_STATE_FREE
;
926 static const struct vb2_ops mtk_venc_vb2_ops
= {
927 .queue_setup
= vb2ops_venc_queue_setup
,
928 .buf_prepare
= vb2ops_venc_buf_prepare
,
929 .buf_queue
= vb2ops_venc_buf_queue
,
930 .wait_prepare
= vb2_ops_wait_prepare
,
931 .wait_finish
= vb2_ops_wait_finish
,
932 .start_streaming
= vb2ops_venc_start_streaming
,
933 .stop_streaming
= vb2ops_venc_stop_streaming
,
936 static int mtk_venc_encode_header(void *priv
)
938 struct mtk_vcodec_ctx
*ctx
= priv
;
940 struct vb2_buffer
*src_buf
, *dst_buf
;
941 struct vb2_v4l2_buffer
*dst_vb2_v4l2
, *src_vb2_v4l2
;
942 struct mtk_vcodec_mem bs_buf
;
943 struct venc_done_result enc_result
;
945 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
947 mtk_v4l2_debug(1, "No dst buffer");
951 bs_buf
.va
= vb2_plane_vaddr(dst_buf
, 0);
952 bs_buf
.dma_addr
= vb2_dma_contig_plane_dma_addr(dst_buf
, 0);
953 bs_buf
.size
= (size_t)dst_buf
->planes
[0].length
;
956 "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu",
958 dst_buf
->index
, bs_buf
.va
,
959 (u64
)bs_buf
.dma_addr
,
962 ret
= venc_if_encode(ctx
,
963 VENC_START_OPT_ENCODE_SEQUENCE_HEADER
,
964 NULL
, &bs_buf
, &enc_result
);
967 dst_buf
->planes
[0].bytesused
= 0;
968 ctx
->state
= MTK_STATE_ABORT
;
969 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf
),
970 VB2_BUF_STATE_ERROR
);
971 mtk_v4l2_err("venc_if_encode failed=%d", ret
);
974 src_buf
= v4l2_m2m_next_src_buf(ctx
->m2m_ctx
);
976 src_vb2_v4l2
= to_vb2_v4l2_buffer(src_buf
);
977 dst_vb2_v4l2
= to_vb2_v4l2_buffer(dst_buf
);
978 dst_buf
->timestamp
= src_buf
->timestamp
;
979 dst_vb2_v4l2
->timecode
= src_vb2_v4l2
->timecode
;
981 mtk_v4l2_err("No timestamp for the header buffer.");
984 ctx
->state
= MTK_STATE_HEADER
;
985 dst_buf
->planes
[0].bytesused
= enc_result
.bs_size
;
986 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf
), VB2_BUF_STATE_DONE
);
991 static int mtk_venc_param_change(struct mtk_vcodec_ctx
*ctx
)
993 struct venc_enc_param enc_prm
;
994 struct vb2_buffer
*vb
= v4l2_m2m_next_src_buf(ctx
->m2m_ctx
);
995 struct vb2_v4l2_buffer
*vb2_v4l2
=
996 container_of(vb
, struct vb2_v4l2_buffer
, vb2_buf
);
997 struct mtk_video_enc_buf
*mtk_buf
=
998 container_of(vb2_v4l2
, struct mtk_video_enc_buf
, vb
);
1002 memset(&enc_prm
, 0, sizeof(enc_prm
));
1003 if (mtk_buf
->param_change
== MTK_ENCODE_PARAM_NONE
)
1006 if (mtk_buf
->param_change
& MTK_ENCODE_PARAM_BITRATE
) {
1007 enc_prm
.bitrate
= mtk_buf
->enc_params
.bitrate
;
1008 mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d",
1010 mtk_buf
->vb
.vb2_buf
.index
,
1012 ret
|= venc_if_set_param(ctx
,
1013 VENC_SET_PARAM_ADJUST_BITRATE
,
1016 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_FRAMERATE
) {
1017 enc_prm
.frm_rate
= mtk_buf
->enc_params
.framerate_num
/
1018 mtk_buf
->enc_params
.framerate_denom
;
1019 mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d",
1021 mtk_buf
->vb
.vb2_buf
.index
,
1023 ret
|= venc_if_set_param(ctx
,
1024 VENC_SET_PARAM_ADJUST_FRAMERATE
,
1027 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_GOP_SIZE
) {
1028 enc_prm
.gop_size
= mtk_buf
->enc_params
.gop_size
;
1029 mtk_v4l2_debug(1, "change param intra period=%d",
1031 ret
|= venc_if_set_param(ctx
,
1032 VENC_SET_PARAM_GOP_SIZE
,
1035 if (!ret
&& mtk_buf
->param_change
& MTK_ENCODE_PARAM_FORCE_INTRA
) {
1036 mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d",
1038 mtk_buf
->vb
.vb2_buf
.index
,
1039 mtk_buf
->enc_params
.force_intra
);
1040 if (mtk_buf
->enc_params
.force_intra
)
1041 ret
|= venc_if_set_param(ctx
,
1042 VENC_SET_PARAM_FORCE_INTRA
,
1046 mtk_buf
->param_change
= MTK_ENCODE_PARAM_NONE
;
1049 ctx
->state
= MTK_STATE_ABORT
;
1050 mtk_v4l2_err("venc_if_set_param %d failed=%d",
1051 mtk_buf
->param_change
, ret
);
1059 * v4l2_m2m_streamoff() holds dev_mutex and waits mtk_venc_worker()
1060 * to call v4l2_m2m_job_finish().
1061 * If mtk_venc_worker() tries to acquire dev_mutex, it will deadlock.
1062 * So this function must not try to acquire dev->dev_mutex.
1063 * This means v4l2 ioctls and mtk_venc_worker() can run at the same time.
1064 * mtk_venc_worker() should be carefully implemented to avoid bugs.
1066 static void mtk_venc_worker(struct work_struct
*work
)
1068 struct mtk_vcodec_ctx
*ctx
= container_of(work
, struct mtk_vcodec_ctx
,
1070 struct vb2_buffer
*src_buf
, *dst_buf
;
1071 struct venc_frm_buf frm_buf
;
1072 struct mtk_vcodec_mem bs_buf
;
1073 struct venc_done_result enc_result
;
1075 struct vb2_v4l2_buffer
*dst_vb2_v4l2
, *src_vb2_v4l2
;
1077 /* check dst_buf, dst_buf may be removed in device_run
1078 * to stored encdoe header so we need check dst_buf and
1079 * call job_finish here to prevent recursion
1081 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->m2m_ctx
);
1083 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
1087 src_buf
= v4l2_m2m_src_buf_remove(ctx
->m2m_ctx
);
1088 memset(&frm_buf
, 0, sizeof(frm_buf
));
1089 for (i
= 0; i
< src_buf
->num_planes
; i
++) {
1090 frm_buf
.fb_addr
[i
].va
= vb2_plane_vaddr(src_buf
, i
);
1091 frm_buf
.fb_addr
[i
].dma_addr
=
1092 vb2_dma_contig_plane_dma_addr(src_buf
, i
);
1093 frm_buf
.fb_addr
[i
].size
=
1094 (size_t)src_buf
->planes
[i
].length
;
1096 bs_buf
.va
= vb2_plane_vaddr(dst_buf
, 0);
1097 bs_buf
.dma_addr
= vb2_dma_contig_plane_dma_addr(dst_buf
, 0);
1098 bs_buf
.size
= (size_t)dst_buf
->planes
[0].length
;
1101 "Framebuf VA=%p PA=%llx Size=0x%zx;VA=%p PA=0x%llx Size=0x%zx;VA=%p PA=0x%llx Size=%zu",
1102 frm_buf
.fb_addr
[0].va
,
1103 (u64
)frm_buf
.fb_addr
[0].dma_addr
,
1104 frm_buf
.fb_addr
[0].size
,
1105 frm_buf
.fb_addr
[1].va
,
1106 (u64
)frm_buf
.fb_addr
[1].dma_addr
,
1107 frm_buf
.fb_addr
[1].size
,
1108 frm_buf
.fb_addr
[2].va
,
1109 (u64
)frm_buf
.fb_addr
[2].dma_addr
,
1110 frm_buf
.fb_addr
[2].size
);
1112 ret
= venc_if_encode(ctx
, VENC_START_OPT_ENCODE_FRAME
,
1113 &frm_buf
, &bs_buf
, &enc_result
);
1115 src_vb2_v4l2
= to_vb2_v4l2_buffer(src_buf
);
1116 dst_vb2_v4l2
= to_vb2_v4l2_buffer(dst_buf
);
1118 dst_buf
->timestamp
= src_buf
->timestamp
;
1119 dst_vb2_v4l2
->timecode
= src_vb2_v4l2
->timecode
;
1121 if (enc_result
.is_key_frm
)
1122 dst_vb2_v4l2
->flags
|= V4L2_BUF_FLAG_KEYFRAME
;
1125 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf
),
1126 VB2_BUF_STATE_ERROR
);
1127 dst_buf
->planes
[0].bytesused
= 0;
1128 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf
),
1129 VB2_BUF_STATE_ERROR
);
1130 mtk_v4l2_err("venc_if_encode failed=%d", ret
);
1132 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(src_buf
),
1133 VB2_BUF_STATE_DONE
);
1134 dst_buf
->planes
[0].bytesused
= enc_result
.bs_size
;
1135 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf
),
1136 VB2_BUF_STATE_DONE
);
1137 mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
1138 enc_result
.bs_size
);
1141 v4l2_m2m_job_finish(ctx
->dev
->m2m_dev_enc
, ctx
->m2m_ctx
);
1143 mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
1144 src_buf
->index
, dst_buf
->index
, ret
,
1145 enc_result
.bs_size
);
1148 static void m2mops_venc_device_run(void *priv
)
1150 struct mtk_vcodec_ctx
*ctx
= priv
;
1152 if ((ctx
->q_data
[MTK_Q_DATA_DST
].fmt
->fourcc
== V4L2_PIX_FMT_H264
) &&
1153 (ctx
->state
!= MTK_STATE_HEADER
)) {
1154 /* encode h264 sps/pps header */
1155 mtk_venc_encode_header(ctx
);
1156 queue_work(ctx
->dev
->encode_workqueue
, &ctx
->encode_work
);
1160 mtk_venc_param_change(ctx
);
1161 queue_work(ctx
->dev
->encode_workqueue
, &ctx
->encode_work
);
1164 static int m2mops_venc_job_ready(void *m2m_priv
)
1166 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
1168 if (ctx
->state
== MTK_STATE_ABORT
|| ctx
->state
== MTK_STATE_FREE
) {
1169 mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.",
1170 ctx
->id
, ctx
->state
);
1177 static void m2mops_venc_job_abort(void *priv
)
1179 struct mtk_vcodec_ctx
*ctx
= priv
;
1181 ctx
->state
= MTK_STATE_ABORT
;
1184 static void m2mops_venc_lock(void *m2m_priv
)
1186 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
1188 mutex_lock(&ctx
->dev
->dev_mutex
);
1191 static void m2mops_venc_unlock(void *m2m_priv
)
1193 struct mtk_vcodec_ctx
*ctx
= m2m_priv
;
1195 mutex_unlock(&ctx
->dev
->dev_mutex
);
1198 const struct v4l2_m2m_ops mtk_venc_m2m_ops
= {
1199 .device_run
= m2mops_venc_device_run
,
1200 .job_ready
= m2mops_venc_job_ready
,
1201 .job_abort
= m2mops_venc_job_abort
,
1202 .lock
= m2mops_venc_lock
,
1203 .unlock
= m2mops_venc_unlock
,
1206 void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx
*ctx
)
1208 struct mtk_q_data
*q_data
;
1210 ctx
->m2m_ctx
->q_lock
= &ctx
->dev
->dev_mutex
;
1211 ctx
->fh
.m2m_ctx
= ctx
->m2m_ctx
;
1212 ctx
->fh
.ctrl_handler
= &ctx
->ctrl_hdl
;
1213 INIT_WORK(&ctx
->encode_work
, mtk_venc_worker
);
1215 ctx
->colorspace
= V4L2_COLORSPACE_REC709
;
1216 ctx
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
1217 ctx
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
1218 ctx
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
1220 q_data
= &ctx
->q_data
[MTK_Q_DATA_SRC
];
1221 memset(q_data
, 0, sizeof(struct mtk_q_data
));
1222 q_data
->visible_width
= DFT_CFG_WIDTH
;
1223 q_data
->visible_height
= DFT_CFG_HEIGHT
;
1224 q_data
->coded_width
= DFT_CFG_WIDTH
;
1225 q_data
->coded_height
= DFT_CFG_HEIGHT
;
1226 q_data
->field
= V4L2_FIELD_NONE
;
1228 q_data
->fmt
= &mtk_video_formats
[OUT_FMT_IDX
];
1230 v4l_bound_align_image(&q_data
->coded_width
,
1233 &q_data
->coded_height
,
1235 MTK_VENC_MAX_H
, 5, 6);
1237 if (q_data
->coded_width
< DFT_CFG_WIDTH
&&
1238 (q_data
->coded_width
+ 16) <= MTK_VENC_MAX_W
)
1239 q_data
->coded_width
+= 16;
1240 if (q_data
->coded_height
< DFT_CFG_HEIGHT
&&
1241 (q_data
->coded_height
+ 32) <= MTK_VENC_MAX_H
)
1242 q_data
->coded_height
+= 32;
1244 q_data
->sizeimage
[0] =
1245 q_data
->coded_width
* q_data
->coded_height
+
1246 ((ALIGN(q_data
->coded_width
, 16) * 2) * 16);
1247 q_data
->bytesperline
[0] = q_data
->coded_width
;
1248 q_data
->sizeimage
[1] =
1249 (q_data
->coded_width
* q_data
->coded_height
) / 2 +
1250 (ALIGN(q_data
->coded_width
, 16) * 16);
1251 q_data
->bytesperline
[1] = q_data
->coded_width
;
1253 q_data
= &ctx
->q_data
[MTK_Q_DATA_DST
];
1254 memset(q_data
, 0, sizeof(struct mtk_q_data
));
1255 q_data
->coded_width
= DFT_CFG_WIDTH
;
1256 q_data
->coded_height
= DFT_CFG_HEIGHT
;
1257 q_data
->fmt
= &mtk_video_formats
[CAP_FMT_IDX
];
1258 q_data
->field
= V4L2_FIELD_NONE
;
1259 ctx
->q_data
[MTK_Q_DATA_DST
].sizeimage
[0] =
1260 DFT_CFG_WIDTH
* DFT_CFG_HEIGHT
;
1261 ctx
->q_data
[MTK_Q_DATA_DST
].bytesperline
[0] = 0;
1265 int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx
*ctx
)
1267 const struct v4l2_ctrl_ops
*ops
= &mtk_vcodec_enc_ctrl_ops
;
1268 struct v4l2_ctrl_handler
*handler
= &ctx
->ctrl_hdl
;
1270 v4l2_ctrl_handler_init(handler
, MTK_MAX_CTRLS_HINT
);
1272 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_BITRATE
,
1273 1, 4000000, 1, 4000000);
1274 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_B_FRAMES
,
1276 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
,
1278 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_MAX_QP
,
1280 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD
,
1282 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_GOP_SIZE
,
1284 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE
,
1286 v4l2_ctrl_new_std(handler
, ops
, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME
,
1288 v4l2_ctrl_new_std_menu(handler
, ops
,
1289 V4L2_CID_MPEG_VIDEO_HEADER_MODE
,
1290 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME
,
1291 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE
);
1292 v4l2_ctrl_new_std_menu(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_PROFILE
,
1293 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
,
1294 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH
);
1295 v4l2_ctrl_new_std_menu(handler
, ops
, V4L2_CID_MPEG_VIDEO_H264_LEVEL
,
1296 V4L2_MPEG_VIDEO_H264_LEVEL_4_2
,
1297 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0
);
1298 if (handler
->error
) {
1299 mtk_v4l2_err("Init control handler fail %d",
1301 return handler
->error
;
1304 v4l2_ctrl_handler_setup(&ctx
->ctrl_hdl
);
1309 int mtk_vcodec_enc_queue_init(void *priv
, struct vb2_queue
*src_vq
,
1310 struct vb2_queue
*dst_vq
)
1312 struct mtk_vcodec_ctx
*ctx
= priv
;
1315 /* Note: VB2_USERPTR works with dma-contig because mt8173
1317 * https://patchwork.kernel.org/patch/8335461/
1318 * https://patchwork.kernel.org/patch/7596181/
1320 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1321 src_vq
->io_modes
= VB2_DMABUF
| VB2_MMAP
| VB2_USERPTR
;
1322 src_vq
->drv_priv
= ctx
;
1323 src_vq
->buf_struct_size
= sizeof(struct mtk_video_enc_buf
);
1324 src_vq
->ops
= &mtk_venc_vb2_ops
;
1325 src_vq
->mem_ops
= &vb2_dma_contig_memops
;
1326 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1327 src_vq
->lock
= &ctx
->dev
->dev_mutex
;
1328 src_vq
->dev
= &ctx
->dev
->plat_dev
->dev
;
1330 ret
= vb2_queue_init(src_vq
);
1334 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1335 dst_vq
->io_modes
= VB2_DMABUF
| VB2_MMAP
| VB2_USERPTR
;
1336 dst_vq
->drv_priv
= ctx
;
1337 dst_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
1338 dst_vq
->ops
= &mtk_venc_vb2_ops
;
1339 dst_vq
->mem_ops
= &vb2_dma_contig_memops
;
1340 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1341 dst_vq
->lock
= &ctx
->dev
->dev_mutex
;
1342 dst_vq
->dev
= &ctx
->dev
->plat_dev
->dev
;
1344 return vb2_queue_init(dst_vq
);
1347 int mtk_venc_unlock(struct mtk_vcodec_ctx
*ctx
)
1349 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1351 mutex_unlock(&dev
->enc_mutex
);
1355 int mtk_venc_lock(struct mtk_vcodec_ctx
*ctx
)
1357 struct mtk_vcodec_dev
*dev
= ctx
->dev
;
1359 mutex_lock(&dev
->enc_mutex
);
1363 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx
*ctx
)
1365 int ret
= venc_if_deinit(ctx
);
1368 mtk_v4l2_err("venc_if_deinit failed=%d", ret
);
1370 ctx
->state
= MTK_STATE_FREE
;