1
2
3
4
5
6
7
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>
12#include <linux/pm_runtime.h>
13
14#include "mtk_vcodec_drv.h"
15#include "mtk_vcodec_enc.h"
16#include "mtk_vcodec_intr.h"
17#include "mtk_vcodec_util.h"
18#include "venc_drv_if.h"
19
20#define MTK_VENC_MIN_W 160U
21#define MTK_VENC_MIN_H 128U
22#define MTK_VENC_HD_MAX_W 1920U
23#define MTK_VENC_HD_MAX_H 1088U
24#define MTK_VENC_4K_MAX_W 3840U
25#define MTK_VENC_4K_MAX_H 2176U
26
27#define DFT_CFG_WIDTH MTK_VENC_MIN_W
28#define DFT_CFG_HEIGHT MTK_VENC_MIN_H
29#define MTK_MAX_CTRLS_HINT 20
30
31#define MTK_DEFAULT_FRAMERATE_NUM 1001
32#define MTK_DEFAULT_FRAMERATE_DENOM 30000
33#define MTK_VENC_4K_CAPABILITY_ENABLE BIT(0)
34
35static void mtk_venc_worker(struct work_struct *work);
36
37static const struct v4l2_frmsize_stepwise mtk_venc_hd_framesizes = {
38 MTK_VENC_MIN_W, MTK_VENC_HD_MAX_W, 16,
39 MTK_VENC_MIN_H, MTK_VENC_HD_MAX_H, 16,
40};
41
42static const struct v4l2_frmsize_stepwise mtk_venc_4k_framesizes = {
43 MTK_VENC_MIN_W, MTK_VENC_4K_MAX_W, 16,
44 MTK_VENC_MIN_H, MTK_VENC_4K_MAX_H, 16,
45};
46
47static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl)
48{
49 struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
50 struct mtk_enc_params *p = &ctx->enc_params;
51 int ret = 0;
52
53 switch (ctrl->id) {
54 case V4L2_CID_MPEG_VIDEO_BITRATE:
55 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d",
56 ctrl->val);
57 p->bitrate = ctrl->val;
58 ctx->param_change |= MTK_ENCODE_PARAM_BITRATE;
59 break;
60 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
61 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d",
62 ctrl->val);
63 p->num_b_frame = ctrl->val;
64 break;
65 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
66 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d",
67 ctrl->val);
68 p->rc_frame = ctrl->val;
69 break;
70 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
71 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d",
72 ctrl->val);
73 p->h264_max_qp = ctrl->val;
74 break;
75 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
76 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d",
77 ctrl->val);
78 p->seq_hdr_mode = ctrl->val;
79 break;
80 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
81 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d",
82 ctrl->val);
83 p->rc_mb = ctrl->val;
84 break;
85 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
86 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d",
87 ctrl->val);
88 p->h264_profile = ctrl->val;
89 break;
90 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
91 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d",
92 ctrl->val);
93 p->h264_level = ctrl->val;
94 break;
95 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
96 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d",
97 ctrl->val);
98 p->intra_period = ctrl->val;
99 ctx->param_change |= MTK_ENCODE_PARAM_INTRA_PERIOD;
100 break;
101 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
102 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d",
103 ctrl->val);
104 p->gop_size = ctrl->val;
105 ctx->param_change |= MTK_ENCODE_PARAM_GOP_SIZE;
106 break;
107 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
108
109
110
111
112 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_VP8_PROFILE val = %d", ctrl->val);
113 break;
114 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
115 mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME");
116 p->force_intra = 1;
117 ctx->param_change |= MTK_ENCODE_PARAM_FORCE_INTRA;
118 break;
119 default:
120 ret = -EINVAL;
121 break;
122 }
123
124 return ret;
125}
126
127static const struct v4l2_ctrl_ops mtk_vcodec_enc_ctrl_ops = {
128 .s_ctrl = vidioc_venc_s_ctrl,
129};
130
131static int vidioc_enum_fmt(struct v4l2_fmtdesc *f,
132 const struct mtk_video_fmt *formats,
133 size_t num_formats)
134{
135 if (f->index >= num_formats)
136 return -EINVAL;
137
138 f->pixelformat = formats[f->index].fourcc;
139
140 return 0;
141}
142
143static const struct mtk_video_fmt *
144mtk_venc_find_format(u32 fourcc, const struct mtk_vcodec_enc_pdata *pdata)
145{
146 const struct mtk_video_fmt *fmt;
147 unsigned int k;
148
149 for (k = 0; k < pdata->num_capture_formats; k++) {
150 fmt = &pdata->capture_formats[k];
151 if (fmt->fourcc == fourcc)
152 return fmt;
153 }
154
155 for (k = 0; k < pdata->num_output_formats; k++) {
156 fmt = &pdata->output_formats[k];
157 if (fmt->fourcc == fourcc)
158 return fmt;
159 }
160
161 return NULL;
162}
163
164static int vidioc_enum_framesizes(struct file *file, void *fh,
165 struct v4l2_frmsizeenum *fsize)
166{
167 const struct mtk_video_fmt *fmt;
168 struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
169
170 if (fsize->index != 0)
171 return -EINVAL;
172
173 fmt = mtk_venc_find_format(fsize->pixel_format,
174 ctx->dev->venc_pdata);
175 if (!fmt)
176 return -EINVAL;
177
178 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
179
180 if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE)
181 fsize->stepwise = mtk_venc_4k_framesizes;
182 else
183 fsize->stepwise = mtk_venc_hd_framesizes;
184
185 return 0;
186}
187
188static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
189 struct v4l2_fmtdesc *f)
190{
191 const struct mtk_vcodec_enc_pdata *pdata =
192 fh_to_ctx(priv)->dev->venc_pdata;
193
194 return vidioc_enum_fmt(f, pdata->capture_formats,
195 pdata->num_capture_formats);
196}
197
198static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
199 struct v4l2_fmtdesc *f)
200{
201 const struct mtk_vcodec_enc_pdata *pdata =
202 fh_to_ctx(priv)->dev->venc_pdata;
203
204 return vidioc_enum_fmt(f, pdata->output_formats,
205 pdata->num_output_formats);
206}
207
208static int vidioc_venc_querycap(struct file *file, void *priv,
209 struct v4l2_capability *cap)
210{
211 strscpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver));
212 strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
213 strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
214
215 return 0;
216}
217
218static int vidioc_venc_s_parm(struct file *file, void *priv,
219 struct v4l2_streamparm *a)
220{
221 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
222 struct v4l2_fract *timeperframe = &a->parm.output.timeperframe;
223
224 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
225 return -EINVAL;
226
227 if (timeperframe->numerator == 0 || timeperframe->denominator == 0) {
228 timeperframe->numerator = MTK_DEFAULT_FRAMERATE_NUM;
229 timeperframe->denominator = MTK_DEFAULT_FRAMERATE_DENOM;
230 }
231
232 ctx->enc_params.framerate_num = timeperframe->denominator;
233 ctx->enc_params.framerate_denom = timeperframe->numerator;
234 ctx->param_change |= MTK_ENCODE_PARAM_FRAMERATE;
235
236 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
237
238 return 0;
239}
240
241static int vidioc_venc_g_parm(struct file *file, void *priv,
242 struct v4l2_streamparm *a)
243{
244 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
245
246 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
247 return -EINVAL;
248
249 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
250 a->parm.output.timeperframe.denominator =
251 ctx->enc_params.framerate_num;
252 a->parm.output.timeperframe.numerator =
253 ctx->enc_params.framerate_denom;
254
255 return 0;
256}
257
258static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx,
259 enum v4l2_buf_type type)
260{
261 if (V4L2_TYPE_IS_OUTPUT(type))
262 return &ctx->q_data[MTK_Q_DATA_SRC];
263
264 return &ctx->q_data[MTK_Q_DATA_DST];
265}
266
267static void vidioc_try_fmt_cap(struct v4l2_format *f)
268{
269 f->fmt.pix_mp.field = V4L2_FIELD_NONE;
270 f->fmt.pix_mp.num_planes = 1;
271 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
272 f->fmt.pix_mp.flags = 0;
273}
274
275
276
277
278static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
279 const struct mtk_video_fmt *fmt)
280{
281 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
282 int tmp_w, tmp_h;
283 unsigned int max_width, max_height;
284
285 pix_fmt_mp->field = V4L2_FIELD_NONE;
286
287 if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE) {
288 max_width = MTK_VENC_4K_MAX_W;
289 max_height = MTK_VENC_4K_MAX_H;
290 } else {
291 max_width = MTK_VENC_HD_MAX_W;
292 max_height = MTK_VENC_HD_MAX_H;
293 }
294
295 pix_fmt_mp->height = clamp(pix_fmt_mp->height, MTK_VENC_MIN_H, max_height);
296 pix_fmt_mp->width = clamp(pix_fmt_mp->width, MTK_VENC_MIN_W, max_width);
297
298
299
300
301 tmp_w = pix_fmt_mp->width;
302 tmp_h = pix_fmt_mp->height;
303 v4l_bound_align_image(&pix_fmt_mp->width,
304 MTK_VENC_MIN_W,
305 max_width, 4,
306 &pix_fmt_mp->height,
307 MTK_VENC_MIN_H,
308 max_height, 5, 6);
309
310 if (pix_fmt_mp->width < tmp_w && (pix_fmt_mp->width + 16) <= max_width)
311 pix_fmt_mp->width += 16;
312 if (pix_fmt_mp->height < tmp_h && (pix_fmt_mp->height + 32) <= max_height)
313 pix_fmt_mp->height += 32;
314
315 mtk_v4l2_debug(0, "before resize w=%d, h=%d, after resize w=%d, h=%d, sizeimage=%d %d",
316 tmp_w, tmp_h, pix_fmt_mp->width,
317 pix_fmt_mp->height,
318 pix_fmt_mp->plane_fmt[0].sizeimage,
319 pix_fmt_mp->plane_fmt[1].sizeimage);
320
321 pix_fmt_mp->num_planes = fmt->num_planes;
322 pix_fmt_mp->plane_fmt[0].sizeimage =
323 pix_fmt_mp->width * pix_fmt_mp->height +
324 ((ALIGN(pix_fmt_mp->width, 16) * 2) * 16);
325 pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
326
327 if (pix_fmt_mp->num_planes == 2) {
328 pix_fmt_mp->plane_fmt[1].sizeimage =
329 (pix_fmt_mp->width * pix_fmt_mp->height) / 2 +
330 (ALIGN(pix_fmt_mp->width, 16) * 16);
331 pix_fmt_mp->plane_fmt[2].sizeimage = 0;
332 pix_fmt_mp->plane_fmt[1].bytesperline =
333 pix_fmt_mp->width;
334 pix_fmt_mp->plane_fmt[2].bytesperline = 0;
335 } else if (pix_fmt_mp->num_planes == 3) {
336 pix_fmt_mp->plane_fmt[1].sizeimage =
337 pix_fmt_mp->plane_fmt[2].sizeimage =
338 (pix_fmt_mp->width * pix_fmt_mp->height) / 4 +
339 ((ALIGN(pix_fmt_mp->width, 16) / 2) * 16);
340 pix_fmt_mp->plane_fmt[1].bytesperline =
341 pix_fmt_mp->plane_fmt[2].bytesperline =
342 pix_fmt_mp->width / 2;
343 }
344
345 pix_fmt_mp->flags = 0;
346
347 return 0;
348}
349
350static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx,
351 struct venc_enc_param *param)
352{
353 struct mtk_q_data *q_data_src = &ctx->q_data[MTK_Q_DATA_SRC];
354 struct mtk_enc_params *enc_params = &ctx->enc_params;
355
356 switch (q_data_src->fmt->fourcc) {
357 case V4L2_PIX_FMT_YUV420M:
358 param->input_yuv_fmt = VENC_YUV_FORMAT_I420;
359 break;
360 case V4L2_PIX_FMT_YVU420M:
361 param->input_yuv_fmt = VENC_YUV_FORMAT_YV12;
362 break;
363 case V4L2_PIX_FMT_NV12M:
364 param->input_yuv_fmt = VENC_YUV_FORMAT_NV12;
365 break;
366 case V4L2_PIX_FMT_NV21M:
367 param->input_yuv_fmt = VENC_YUV_FORMAT_NV21;
368 break;
369 default:
370 mtk_v4l2_err("Unsupported fourcc =%d", q_data_src->fmt->fourcc);
371 break;
372 }
373 param->h264_profile = enc_params->h264_profile;
374 param->h264_level = enc_params->h264_level;
375
376
377 param->width = q_data_src->visible_width;
378 param->height = q_data_src->visible_height;
379
380 param->buf_width = q_data_src->coded_width;
381 param->buf_height = q_data_src->coded_height;
382 param->frm_rate = enc_params->framerate_num /
383 enc_params->framerate_denom;
384 param->intra_period = enc_params->intra_period;
385 param->gop_size = enc_params->gop_size;
386 param->bitrate = enc_params->bitrate;
387
388 mtk_v4l2_debug(0,
389 "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d",
390 param->input_yuv_fmt, param->h264_profile,
391 param->h264_level, param->width, param->height,
392 param->buf_width, param->buf_height,
393 param->frm_rate, param->bitrate,
394 param->gop_size, param->intra_period);
395}
396
397static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
398 struct v4l2_format *f)
399{
400 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
401 const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
402 struct vb2_queue *vq;
403 struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
404 int i, ret;
405 const struct mtk_video_fmt *fmt;
406
407 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
408 if (!vq) {
409 mtk_v4l2_err("fail to get vq");
410 return -EINVAL;
411 }
412
413 if (vb2_is_busy(vq)) {
414 mtk_v4l2_err("queue busy");
415 return -EBUSY;
416 }
417
418 fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
419 if (!fmt) {
420 fmt = &ctx->dev->venc_pdata->capture_formats[0];
421 f->fmt.pix.pixelformat = fmt->fourcc;
422 }
423
424 q_data->fmt = fmt;
425 vidioc_try_fmt_cap(f);
426
427 q_data->coded_width = f->fmt.pix_mp.width;
428 q_data->coded_height = f->fmt.pix_mp.height;
429 q_data->field = f->fmt.pix_mp.field;
430
431 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
432 struct v4l2_plane_pix_format *plane_fmt;
433
434 plane_fmt = &f->fmt.pix_mp.plane_fmt[i];
435 q_data->bytesperline[i] = plane_fmt->bytesperline;
436 q_data->sizeimage[i] = plane_fmt->sizeimage;
437 }
438
439 if (ctx->state == MTK_STATE_FREE) {
440 ret = venc_if_init(ctx, q_data->fmt->fourcc);
441 if (ret) {
442 mtk_v4l2_err("venc_if_init failed=%d, codec type=%x",
443 ret, q_data->fmt->fourcc);
444 return -EBUSY;
445 }
446 ctx->state = MTK_STATE_INIT;
447 }
448
449 return 0;
450}
451
452static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
453 struct v4l2_format *f)
454{
455 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
456 const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
457 struct vb2_queue *vq;
458 struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
459 int ret, i;
460 const struct mtk_video_fmt *fmt;
461
462 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
463 if (!vq) {
464 mtk_v4l2_err("fail to get vq");
465 return -EINVAL;
466 }
467
468 if (vb2_is_busy(vq)) {
469 mtk_v4l2_err("queue busy");
470 return -EBUSY;
471 }
472
473 fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
474 if (!fmt) {
475 fmt = &ctx->dev->venc_pdata->output_formats[0];
476 f->fmt.pix.pixelformat = fmt->fourcc;
477 }
478
479 ret = vidioc_try_fmt_out(ctx, f, fmt);
480 if (ret)
481 return ret;
482
483 q_data->fmt = fmt;
484 q_data->visible_width = f->fmt.pix_mp.width;
485 q_data->visible_height = f->fmt.pix_mp.height;
486 q_data->coded_width = f->fmt.pix_mp.width;
487 q_data->coded_height = f->fmt.pix_mp.height;
488
489 q_data->field = f->fmt.pix_mp.field;
490 ctx->colorspace = f->fmt.pix_mp.colorspace;
491 ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
492 ctx->quantization = f->fmt.pix_mp.quantization;
493 ctx->xfer_func = f->fmt.pix_mp.xfer_func;
494
495 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
496 struct v4l2_plane_pix_format *plane_fmt;
497
498 plane_fmt = &f->fmt.pix_mp.plane_fmt[i];
499 q_data->bytesperline[i] = plane_fmt->bytesperline;
500 q_data->sizeimage[i] = plane_fmt->sizeimage;
501 }
502
503 return 0;
504}
505
506static int vidioc_venc_g_fmt(struct file *file, void *priv,
507 struct v4l2_format *f)
508{
509 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
510 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
511 struct vb2_queue *vq;
512 struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
513 int i;
514
515 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
516 if (!vq)
517 return -EINVAL;
518
519
520 pix->width = q_data->coded_width;
521 pix->height = q_data->coded_height;
522 pix->pixelformat = q_data->fmt->fourcc;
523 pix->field = q_data->field;
524 pix->num_planes = q_data->fmt->num_planes;
525 for (i = 0; i < pix->num_planes; i++) {
526 pix->plane_fmt[i].bytesperline = q_data->bytesperline[i];
527 pix->plane_fmt[i].sizeimage = q_data->sizeimage[i];
528 }
529
530 pix->flags = 0;
531 pix->colorspace = ctx->colorspace;
532 pix->ycbcr_enc = ctx->ycbcr_enc;
533 pix->quantization = ctx->quantization;
534 pix->xfer_func = ctx->xfer_func;
535
536 return 0;
537}
538
539static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
540 struct v4l2_format *f)
541{
542 const struct mtk_video_fmt *fmt;
543 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
544 const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
545
546 fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
547 if (!fmt) {
548 fmt = &ctx->dev->venc_pdata->capture_formats[0];
549 f->fmt.pix.pixelformat = fmt->fourcc;
550 }
551 f->fmt.pix_mp.colorspace = ctx->colorspace;
552 f->fmt.pix_mp.ycbcr_enc = ctx->ycbcr_enc;
553 f->fmt.pix_mp.quantization = ctx->quantization;
554 f->fmt.pix_mp.xfer_func = ctx->xfer_func;
555
556 vidioc_try_fmt_cap(f);
557
558 return 0;
559}
560
561static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
562 struct v4l2_format *f)
563{
564 const struct mtk_video_fmt *fmt;
565 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
566 const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
567
568 fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
569 if (!fmt) {
570 fmt = &ctx->dev->venc_pdata->output_formats[0];
571 f->fmt.pix.pixelformat = fmt->fourcc;
572 }
573 if (!f->fmt.pix_mp.colorspace) {
574 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
575 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
576 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
577 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
578 }
579
580 return vidioc_try_fmt_out(ctx, f, fmt);
581}
582
583static int vidioc_venc_g_selection(struct file *file, void *priv,
584 struct v4l2_selection *s)
585{
586 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
587 struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
588
589 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
590 return -EINVAL;
591
592 switch (s->target) {
593 case V4L2_SEL_TGT_CROP_DEFAULT:
594 case V4L2_SEL_TGT_CROP_BOUNDS:
595 s->r.top = 0;
596 s->r.left = 0;
597 s->r.width = q_data->coded_width;
598 s->r.height = q_data->coded_height;
599 break;
600 case V4L2_SEL_TGT_CROP:
601 s->r.top = 0;
602 s->r.left = 0;
603 s->r.width = q_data->visible_width;
604 s->r.height = q_data->visible_height;
605 break;
606 default:
607 return -EINVAL;
608 }
609
610 return 0;
611}
612
613static int vidioc_venc_s_selection(struct file *file, void *priv,
614 struct v4l2_selection *s)
615{
616 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
617 struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
618
619 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
620 return -EINVAL;
621
622 switch (s->target) {
623 case V4L2_SEL_TGT_CROP:
624
625 s->r.top = 0;
626 s->r.left = 0;
627 s->r.width = min(s->r.width, q_data->coded_width);
628 s->r.height = min(s->r.height, q_data->coded_height);
629 q_data->visible_width = s->r.width;
630 q_data->visible_height = s->r.height;
631 break;
632 default:
633 return -EINVAL;
634 }
635 return 0;
636}
637
638static int vidioc_venc_qbuf(struct file *file, void *priv,
639 struct v4l2_buffer *buf)
640{
641 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
642
643 if (ctx->state == MTK_STATE_ABORT) {
644 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
645 ctx->id);
646 return -EIO;
647 }
648
649 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
650}
651
652static int vidioc_venc_dqbuf(struct file *file, void *priv,
653 struct v4l2_buffer *buf)
654{
655 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
656 int ret;
657
658 if (ctx->state == MTK_STATE_ABORT) {
659 mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
660 ctx->id);
661 return -EIO;
662 }
663
664 ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
665 if (ret)
666 return ret;
667
668
669
670
671
672
673
674
675
676 if (!V4L2_TYPE_IS_OUTPUT(buf->type) &&
677 buf->flags & V4L2_BUF_FLAG_LAST &&
678 buf->m.planes[0].bytesused == 0 &&
679 ctx->is_flushing) {
680
681
682
683
684 ctx->is_flushing = false;
685 }
686
687 return 0;
688}
689
690static int vidioc_encoder_cmd(struct file *file, void *priv,
691 struct v4l2_encoder_cmd *cmd)
692{
693 struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
694 struct vb2_queue *src_vq, *dst_vq;
695 int ret;
696
697 if (ctx->state == MTK_STATE_ABORT) {
698 mtk_v4l2_err("[%d] Call to CMD after unrecoverable error",
699 ctx->id);
700 return -EIO;
701 }
702
703 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, priv, cmd);
704 if (ret)
705 return ret;
706
707
708 if (ctx->is_flushing)
709 return -EBUSY;
710
711 mtk_v4l2_debug(1, "encoder cmd=%u", cmd->cmd);
712
713 dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
714 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
715 switch (cmd->cmd) {
716 case V4L2_ENC_CMD_STOP:
717 src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
718 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
719 if (!vb2_is_streaming(src_vq)) {
720 mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
721 return 0;
722 }
723 if (!vb2_is_streaming(dst_vq)) {
724 mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
725 return 0;
726 }
727 ctx->is_flushing = true;
728 v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
729 v4l2_m2m_try_schedule(ctx->m2m_ctx);
730 break;
731
732 case V4L2_ENC_CMD_START:
733 vb2_clear_last_buffer_dequeued(dst_vq);
734 break;
735
736 default:
737 return -EINVAL;
738 }
739
740 return 0;
741}
742
743const struct v4l2_ioctl_ops mtk_venc_ioctl_ops = {
744 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
745 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
746
747 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
748 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
749 .vidioc_qbuf = vidioc_venc_qbuf,
750 .vidioc_dqbuf = vidioc_venc_dqbuf,
751
752 .vidioc_querycap = vidioc_venc_querycap,
753 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
754 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
755 .vidioc_enum_framesizes = vidioc_enum_framesizes,
756
757 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
758 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
759 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
760 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
761 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
762
763 .vidioc_s_parm = vidioc_venc_s_parm,
764 .vidioc_g_parm = vidioc_venc_g_parm,
765 .vidioc_s_fmt_vid_cap_mplane = vidioc_venc_s_fmt_cap,
766 .vidioc_s_fmt_vid_out_mplane = vidioc_venc_s_fmt_out,
767
768 .vidioc_g_fmt_vid_cap_mplane = vidioc_venc_g_fmt,
769 .vidioc_g_fmt_vid_out_mplane = vidioc_venc_g_fmt,
770
771 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
772 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
773
774 .vidioc_g_selection = vidioc_venc_g_selection,
775 .vidioc_s_selection = vidioc_venc_s_selection,
776
777 .vidioc_encoder_cmd = vidioc_encoder_cmd,
778 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
779};
780
781static int vb2ops_venc_queue_setup(struct vb2_queue *vq,
782 unsigned int *nbuffers,
783 unsigned int *nplanes,
784 unsigned int sizes[],
785 struct device *alloc_devs[])
786{
787 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
788 struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vq->type);
789 unsigned int i;
790
791 if (q_data == NULL)
792 return -EINVAL;
793
794 if (*nplanes) {
795 for (i = 0; i < *nplanes; i++)
796 if (sizes[i] < q_data->sizeimage[i])
797 return -EINVAL;
798 } else {
799 *nplanes = q_data->fmt->num_planes;
800 for (i = 0; i < *nplanes; i++)
801 sizes[i] = q_data->sizeimage[i];
802 }
803
804 return 0;
805}
806
807static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb)
808{
809 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
810 struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type);
811 int i;
812
813 for (i = 0; i < q_data->fmt->num_planes; i++) {
814 if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
815 mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
816 i, vb2_plane_size(vb, i),
817 q_data->sizeimage[i]);
818 return -EINVAL;
819 }
820 }
821
822 return 0;
823}
824
825static void vb2ops_venc_buf_queue(struct vb2_buffer *vb)
826{
827 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
828 struct vb2_v4l2_buffer *vb2_v4l2 =
829 container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
830
831 struct mtk_video_enc_buf *mtk_buf =
832 container_of(vb2_v4l2, struct mtk_video_enc_buf,
833 m2m_buf.vb);
834
835 if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
836 (ctx->param_change != MTK_ENCODE_PARAM_NONE)) {
837 mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x",
838 ctx->id,
839 vb2_v4l2->vb2_buf.index,
840 ctx->param_change);
841 mtk_buf->param_change = ctx->param_change;
842 mtk_buf->enc_params = ctx->enc_params;
843 ctx->param_change = MTK_ENCODE_PARAM_NONE;
844 }
845
846 v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
847}
848
849static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
850{
851 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
852 struct venc_enc_param param;
853 int ret, pm_ret;
854 int i;
855
856
857
858
859 if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) {
860 ret = -EIO;
861 goto err_start_stream;
862 }
863
864
865 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
866 if (!vb2_start_streaming_called(&ctx->m2m_ctx->cap_q_ctx.q))
867 return 0;
868 } else {
869 if (!vb2_start_streaming_called(&ctx->m2m_ctx->out_q_ctx.q))
870 return 0;
871 }
872
873 ret = pm_runtime_resume_and_get(&ctx->dev->plat_dev->dev);
874 if (ret < 0) {
875 mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
876 goto err_start_stream;
877 }
878
879 mtk_venc_set_param(ctx, ¶m);
880 ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, ¶m);
881 if (ret) {
882 mtk_v4l2_err("venc_if_set_param failed=%d", ret);
883 ctx->state = MTK_STATE_ABORT;
884 goto err_set_param;
885 }
886 ctx->param_change = MTK_ENCODE_PARAM_NONE;
887
888 if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
889 (ctx->enc_params.seq_hdr_mode !=
890 V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE)) {
891 ret = venc_if_set_param(ctx,
892 VENC_SET_PARAM_PREPEND_HEADER,
893 NULL);
894 if (ret) {
895 mtk_v4l2_err("venc_if_set_param failed=%d", ret);
896 ctx->state = MTK_STATE_ABORT;
897 goto err_set_param;
898 }
899 ctx->state = MTK_STATE_HEADER;
900 }
901
902 return 0;
903
904err_set_param:
905 pm_ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
906 if (pm_ret < 0)
907 mtk_v4l2_err("pm_runtime_put fail %d", pm_ret);
908
909err_start_stream:
910 for (i = 0; i < q->num_buffers; ++i) {
911 struct vb2_buffer *buf = vb2_get_buffer(q, i);
912
913
914
915
916
917 if (buf->state == VB2_BUF_STATE_ACTIVE) {
918 mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED",
919 ctx->id, i, q->type,
920 (int)buf->state);
921 v4l2_m2m_buf_done(to_vb2_v4l2_buffer(buf),
922 VB2_BUF_STATE_QUEUED);
923 }
924 }
925
926 return ret;
927}
928
929static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
930{
931 struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
932 struct vb2_v4l2_buffer *src_buf, *dst_buf;
933 int ret;
934
935 mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type);
936
937 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
938 while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
939 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
940 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
941 }
942
943 if (ctx->is_flushing) {
944 struct v4l2_m2m_buffer *b, *n;
945
946 mtk_v4l2_debug(1, "STREAMOFF called while flushing");
947
948
949
950
951
952 v4l2_m2m_for_each_src_buf_safe(ctx->m2m_ctx, b, n) {
953 if (b == &ctx->empty_flush_buf) {
954 v4l2_m2m_src_buf_remove_by_buf(ctx->m2m_ctx, &b->vb);
955 break;
956 }
957 }
958 ctx->is_flushing = false;
959 }
960 } else {
961 while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
962 if (src_buf != &ctx->empty_flush_buf.vb)
963 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
964 }
965 if (ctx->is_flushing) {
966
967
968
969
970
971 v4l2_m2m_buf_queue(ctx->m2m_ctx,
972 &ctx->empty_flush_buf.vb);
973 }
974 }
975
976 if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
977 vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q)) ||
978 (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
979 vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q))) {
980 mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d",
981 ctx->id, q->type,
982 vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q),
983 vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q));
984 return;
985 }
986
987
988 ret = venc_if_deinit(ctx);
989 if (ret)
990 mtk_v4l2_err("venc_if_deinit failed=%d", ret);
991
992 ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
993 if (ret < 0)
994 mtk_v4l2_err("pm_runtime_put fail %d", ret);
995
996 ctx->state = MTK_STATE_FREE;
997}
998
999static int vb2ops_venc_buf_out_validate(struct vb2_buffer *vb)
1000{
1001 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1002
1003 vbuf->field = V4L2_FIELD_NONE;
1004 return 0;
1005}
1006
1007static const struct vb2_ops mtk_venc_vb2_ops = {
1008 .queue_setup = vb2ops_venc_queue_setup,
1009 .buf_out_validate = vb2ops_venc_buf_out_validate,
1010 .buf_prepare = vb2ops_venc_buf_prepare,
1011 .buf_queue = vb2ops_venc_buf_queue,
1012 .wait_prepare = vb2_ops_wait_prepare,
1013 .wait_finish = vb2_ops_wait_finish,
1014 .start_streaming = vb2ops_venc_start_streaming,
1015 .stop_streaming = vb2ops_venc_stop_streaming,
1016};
1017
1018static int mtk_venc_encode_header(void *priv)
1019{
1020 struct mtk_vcodec_ctx *ctx = priv;
1021 int ret;
1022 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1023 struct mtk_vcodec_mem bs_buf;
1024 struct venc_done_result enc_result;
1025
1026 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
1027 if (!dst_buf) {
1028 mtk_v4l2_debug(1, "No dst buffer");
1029 return -EINVAL;
1030 }
1031
1032 bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
1033 bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1034 bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
1035
1036 mtk_v4l2_debug(1,
1037 "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu",
1038 ctx->id,
1039 dst_buf->vb2_buf.index, bs_buf.va,
1040 (u64)bs_buf.dma_addr,
1041 bs_buf.size);
1042
1043 ret = venc_if_encode(ctx,
1044 VENC_START_OPT_ENCODE_SEQUENCE_HEADER,
1045 NULL, &bs_buf, &enc_result);
1046
1047 if (ret) {
1048 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
1049 ctx->state = MTK_STATE_ABORT;
1050 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1051 mtk_v4l2_err("venc_if_encode failed=%d", ret);
1052 return -EINVAL;
1053 }
1054 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
1055 if (src_buf) {
1056 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
1057 dst_buf->timecode = src_buf->timecode;
1058 } else {
1059 mtk_v4l2_err("No timestamp for the header buffer.");
1060 }
1061
1062 ctx->state = MTK_STATE_HEADER;
1063 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
1064 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
1065
1066 return 0;
1067}
1068
1069static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
1070{
1071 struct venc_enc_param enc_prm;
1072 struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
1073 struct mtk_video_enc_buf *mtk_buf;
1074 int ret = 0;
1075
1076
1077 if (vb2_v4l2 == &ctx->empty_flush_buf.vb)
1078 return 0;
1079
1080 mtk_buf = container_of(vb2_v4l2, struct mtk_video_enc_buf, m2m_buf.vb);
1081
1082 memset(&enc_prm, 0, sizeof(enc_prm));
1083 if (mtk_buf->param_change == MTK_ENCODE_PARAM_NONE)
1084 return 0;
1085
1086 if (mtk_buf->param_change & MTK_ENCODE_PARAM_BITRATE) {
1087 enc_prm.bitrate = mtk_buf->enc_params.bitrate;
1088 mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d",
1089 ctx->id,
1090 vb2_v4l2->vb2_buf.index,
1091 enc_prm.bitrate);
1092 ret |= venc_if_set_param(ctx,
1093 VENC_SET_PARAM_ADJUST_BITRATE,
1094 &enc_prm);
1095 }
1096 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FRAMERATE) {
1097 enc_prm.frm_rate = mtk_buf->enc_params.framerate_num /
1098 mtk_buf->enc_params.framerate_denom;
1099 mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d",
1100 ctx->id,
1101 vb2_v4l2->vb2_buf.index,
1102 enc_prm.frm_rate);
1103 ret |= venc_if_set_param(ctx,
1104 VENC_SET_PARAM_ADJUST_FRAMERATE,
1105 &enc_prm);
1106 }
1107 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_GOP_SIZE) {
1108 enc_prm.gop_size = mtk_buf->enc_params.gop_size;
1109 mtk_v4l2_debug(1, "change param intra period=%d",
1110 enc_prm.gop_size);
1111 ret |= venc_if_set_param(ctx,
1112 VENC_SET_PARAM_GOP_SIZE,
1113 &enc_prm);
1114 }
1115 if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) {
1116 mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d",
1117 ctx->id,
1118 vb2_v4l2->vb2_buf.index,
1119 mtk_buf->enc_params.force_intra);
1120 if (mtk_buf->enc_params.force_intra)
1121 ret |= venc_if_set_param(ctx,
1122 VENC_SET_PARAM_FORCE_INTRA,
1123 NULL);
1124 }
1125
1126 mtk_buf->param_change = MTK_ENCODE_PARAM_NONE;
1127
1128 if (ret) {
1129 ctx->state = MTK_STATE_ABORT;
1130 mtk_v4l2_err("venc_if_set_param %d failed=%d",
1131 mtk_buf->param_change, ret);
1132 return -1;
1133 }
1134
1135 return 0;
1136}
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146static void mtk_venc_worker(struct work_struct *work)
1147{
1148 struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx,
1149 encode_work);
1150 struct vb2_v4l2_buffer *src_buf, *dst_buf;
1151 struct venc_frm_buf frm_buf;
1152 struct mtk_vcodec_mem bs_buf;
1153 struct venc_done_result enc_result;
1154 int ret, i;
1155
1156
1157
1158
1159
1160 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
1161 if (!dst_buf) {
1162 v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
1163 return;
1164 }
1165
1166 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
1167
1168
1169
1170
1171
1172
1173 if (src_buf == &ctx->empty_flush_buf.vb) {
1174 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
1175 dst_buf->flags |= V4L2_BUF_FLAG_LAST;
1176 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
1177 v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
1178 return;
1179 }
1180
1181 memset(&frm_buf, 0, sizeof(frm_buf));
1182 for (i = 0; i < src_buf->vb2_buf.num_planes ; i++) {
1183 frm_buf.fb_addr[i].dma_addr =
1184 vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, i);
1185 frm_buf.fb_addr[i].size =
1186 (size_t)src_buf->vb2_buf.planes[i].length;
1187 }
1188 bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
1189 bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
1190 bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
1191
1192 mtk_v4l2_debug(2,
1193 "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu",
1194 (u64)frm_buf.fb_addr[0].dma_addr,
1195 frm_buf.fb_addr[0].size,
1196 (u64)frm_buf.fb_addr[1].dma_addr,
1197 frm_buf.fb_addr[1].size,
1198 (u64)frm_buf.fb_addr[2].dma_addr,
1199 frm_buf.fb_addr[2].size);
1200
1201 ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME,
1202 &frm_buf, &bs_buf, &enc_result);
1203
1204 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
1205 dst_buf->timecode = src_buf->timecode;
1206
1207 if (enc_result.is_key_frm)
1208 dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1209
1210 if (ret) {
1211 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
1212 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
1213 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
1214 mtk_v4l2_err("venc_if_encode failed=%d", ret);
1215 } else {
1216 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1217 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
1218 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
1219 mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
1220 enc_result.bs_size);
1221 }
1222
1223 v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
1224
1225 mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
1226 src_buf->vb2_buf.index, dst_buf->vb2_buf.index, ret,
1227 enc_result.bs_size);
1228}
1229
1230static void m2mops_venc_device_run(void *priv)
1231{
1232 struct mtk_vcodec_ctx *ctx = priv;
1233
1234 if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
1235 (ctx->state != MTK_STATE_HEADER)) {
1236
1237 mtk_venc_encode_header(ctx);
1238 queue_work(ctx->dev->encode_workqueue, &ctx->encode_work);
1239 return;
1240 }
1241
1242 mtk_venc_param_change(ctx);
1243 queue_work(ctx->dev->encode_workqueue, &ctx->encode_work);
1244}
1245
1246static int m2mops_venc_job_ready(void *m2m_priv)
1247{
1248 struct mtk_vcodec_ctx *ctx = m2m_priv;
1249
1250 if (ctx->state == MTK_STATE_ABORT || ctx->state == MTK_STATE_FREE) {
1251 mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.",
1252 ctx->id, ctx->state);
1253 return 0;
1254 }
1255
1256 return 1;
1257}
1258
1259static void m2mops_venc_job_abort(void *priv)
1260{
1261 struct mtk_vcodec_ctx *ctx = priv;
1262
1263 ctx->state = MTK_STATE_ABORT;
1264}
1265
1266const struct v4l2_m2m_ops mtk_venc_m2m_ops = {
1267 .device_run = m2mops_venc_device_run,
1268 .job_ready = m2mops_venc_job_ready,
1269 .job_abort = m2mops_venc_job_abort,
1270};
1271
1272void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx)
1273{
1274 struct mtk_q_data *q_data;
1275
1276 ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
1277 ctx->fh.m2m_ctx = ctx->m2m_ctx;
1278 ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
1279 INIT_WORK(&ctx->encode_work, mtk_venc_worker);
1280
1281 ctx->colorspace = V4L2_COLORSPACE_REC709;
1282 ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1283 ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
1284 ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
1285
1286 q_data = &ctx->q_data[MTK_Q_DATA_SRC];
1287 memset(q_data, 0, sizeof(struct mtk_q_data));
1288 q_data->visible_width = DFT_CFG_WIDTH;
1289 q_data->visible_height = DFT_CFG_HEIGHT;
1290 q_data->coded_width = DFT_CFG_WIDTH;
1291 q_data->coded_height = DFT_CFG_HEIGHT;
1292 q_data->field = V4L2_FIELD_NONE;
1293
1294 q_data->fmt = &ctx->dev->venc_pdata->output_formats[0];
1295
1296 v4l_bound_align_image(&q_data->coded_width,
1297 MTK_VENC_MIN_W,
1298 MTK_VENC_HD_MAX_W, 4,
1299 &q_data->coded_height,
1300 MTK_VENC_MIN_H,
1301 MTK_VENC_HD_MAX_H, 5, 6);
1302
1303 if (q_data->coded_width < DFT_CFG_WIDTH &&
1304 (q_data->coded_width + 16) <= MTK_VENC_HD_MAX_W)
1305 q_data->coded_width += 16;
1306 if (q_data->coded_height < DFT_CFG_HEIGHT &&
1307 (q_data->coded_height + 32) <= MTK_VENC_HD_MAX_H)
1308 q_data->coded_height += 32;
1309
1310 q_data->sizeimage[0] =
1311 q_data->coded_width * q_data->coded_height+
1312 ((ALIGN(q_data->coded_width, 16) * 2) * 16);
1313 q_data->bytesperline[0] = q_data->coded_width;
1314 q_data->sizeimage[1] =
1315 (q_data->coded_width * q_data->coded_height) / 2 +
1316 (ALIGN(q_data->coded_width, 16) * 16);
1317 q_data->bytesperline[1] = q_data->coded_width;
1318
1319 q_data = &ctx->q_data[MTK_Q_DATA_DST];
1320 memset(q_data, 0, sizeof(struct mtk_q_data));
1321 q_data->coded_width = DFT_CFG_WIDTH;
1322 q_data->coded_height = DFT_CFG_HEIGHT;
1323 q_data->fmt = &ctx->dev->venc_pdata->capture_formats[0];
1324 q_data->field = V4L2_FIELD_NONE;
1325 ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
1326 DFT_CFG_WIDTH * DFT_CFG_HEIGHT;
1327 ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = 0;
1328
1329 ctx->enc_params.framerate_num = MTK_DEFAULT_FRAMERATE_NUM;
1330 ctx->enc_params.framerate_denom = MTK_DEFAULT_FRAMERATE_DENOM;
1331}
1332
1333int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
1334{
1335 const struct v4l2_ctrl_ops *ops = &mtk_vcodec_enc_ctrl_ops;
1336 struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl;
1337 u8 h264_max_level;
1338
1339 if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE)
1340 h264_max_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
1341 else
1342 h264_max_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
1343
1344 v4l2_ctrl_handler_init(handler, MTK_MAX_CTRLS_HINT);
1345
1346 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
1347 1, 1, 1, 1);
1348 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE,
1349 ctx->dev->venc_pdata->min_bitrate,
1350 ctx->dev->venc_pdata->max_bitrate, 1, 4000000);
1351 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_B_FRAMES,
1352 0, 2, 1, 0);
1353 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
1354 0, 1, 1, 1);
1355 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
1356 0, 51, 1, 51);
1357 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
1358 0, 65535, 1, 0);
1359 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
1360 0, 65535, 1, 0);
1361 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
1362 0, 1, 1, 0);
1363 v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
1364 0, 0, 0, 0);
1365 v4l2_ctrl_new_std_menu(handler, ops,
1366 V4L2_CID_MPEG_VIDEO_HEADER_MODE,
1367 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
1368 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE);
1369 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE,
1370 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
1371 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
1372 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL,
1373 h264_max_level,
1374 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
1375 v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
1376 V4L2_MPEG_VIDEO_VP8_PROFILE_0, 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
1377
1378
1379 if (handler->error) {
1380 mtk_v4l2_err("Init control handler fail %d",
1381 handler->error);
1382 return handler->error;
1383 }
1384
1385 v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
1386
1387 return 0;
1388}
1389
1390int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
1391 struct vb2_queue *dst_vq)
1392{
1393 struct mtk_vcodec_ctx *ctx = priv;
1394 int ret;
1395
1396
1397
1398
1399
1400
1401 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1402 src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
1403 src_vq->drv_priv = ctx;
1404 src_vq->buf_struct_size = sizeof(struct mtk_video_enc_buf);
1405 src_vq->ops = &mtk_venc_vb2_ops;
1406 src_vq->mem_ops = &vb2_dma_contig_memops;
1407 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1408 src_vq->lock = &ctx->dev->dev_mutex;
1409 src_vq->dev = &ctx->dev->plat_dev->dev;
1410
1411 ret = vb2_queue_init(src_vq);
1412 if (ret)
1413 return ret;
1414
1415 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1416 dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
1417 dst_vq->drv_priv = ctx;
1418 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1419 dst_vq->ops = &mtk_venc_vb2_ops;
1420 dst_vq->mem_ops = &vb2_dma_contig_memops;
1421 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1422 dst_vq->lock = &ctx->dev->dev_mutex;
1423 dst_vq->dev = &ctx->dev->plat_dev->dev;
1424
1425 return vb2_queue_init(dst_vq);
1426}
1427
1428int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
1429{
1430 struct mtk_vcodec_dev *dev = ctx->dev;
1431
1432 mutex_unlock(&dev->enc_mutex);
1433 return 0;
1434}
1435
1436int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
1437{
1438 struct mtk_vcodec_dev *dev = ctx->dev;
1439
1440 mutex_lock(&dev->enc_mutex);
1441 return 0;
1442}
1443
1444void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
1445{
1446 int ret = venc_if_deinit(ctx);
1447
1448 if (ret)
1449 mtk_v4l2_err("venc_if_deinit failed=%d", ret);
1450
1451 ctx->state = MTK_STATE_FREE;
1452}
1453