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