.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2016 MediaTek Inc. |
---|
3 | 4 | * Author: PC Chen <pc.chen@mediatek.com> |
---|
4 | 5 | * Tiffany Lin <tiffany.lin@mediatek.com> |
---|
5 | | -* |
---|
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. |
---|
9 | | -* |
---|
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. |
---|
14 | 6 | */ |
---|
15 | 7 | |
---|
16 | 8 | #include <media/v4l2-event.h> |
---|
.. | .. |
---|
31 | 23 | #define DFT_CFG_WIDTH MTK_VENC_MIN_W |
---|
32 | 24 | #define DFT_CFG_HEIGHT MTK_VENC_MIN_H |
---|
33 | 25 | #define MTK_MAX_CTRLS_HINT 20 |
---|
34 | | -#define OUT_FMT_IDX 0 |
---|
35 | | -#define CAP_FMT_IDX 4 |
---|
36 | 26 | |
---|
| 27 | +#define MTK_DEFAULT_FRAMERATE_NUM 1001 |
---|
| 28 | +#define MTK_DEFAULT_FRAMERATE_DENOM 30000 |
---|
37 | 29 | |
---|
38 | 30 | static void mtk_venc_worker(struct work_struct *work); |
---|
39 | 31 | |
---|
40 | | -static struct mtk_video_fmt mtk_video_formats[] = { |
---|
41 | | - { |
---|
42 | | - .fourcc = V4L2_PIX_FMT_NV12M, |
---|
43 | | - .type = MTK_FMT_FRAME, |
---|
44 | | - .num_planes = 2, |
---|
45 | | - }, |
---|
46 | | - { |
---|
47 | | - .fourcc = V4L2_PIX_FMT_NV21M, |
---|
48 | | - .type = MTK_FMT_FRAME, |
---|
49 | | - .num_planes = 2, |
---|
50 | | - }, |
---|
51 | | - { |
---|
52 | | - .fourcc = V4L2_PIX_FMT_YUV420M, |
---|
53 | | - .type = MTK_FMT_FRAME, |
---|
54 | | - .num_planes = 3, |
---|
55 | | - }, |
---|
56 | | - { |
---|
57 | | - .fourcc = V4L2_PIX_FMT_YVU420M, |
---|
58 | | - .type = MTK_FMT_FRAME, |
---|
59 | | - .num_planes = 3, |
---|
60 | | - }, |
---|
61 | | - { |
---|
62 | | - .fourcc = V4L2_PIX_FMT_H264, |
---|
63 | | - .type = MTK_FMT_ENC, |
---|
64 | | - .num_planes = 1, |
---|
65 | | - }, |
---|
66 | | - { |
---|
67 | | - .fourcc = V4L2_PIX_FMT_VP8, |
---|
68 | | - .type = MTK_FMT_ENC, |
---|
69 | | - .num_planes = 1, |
---|
70 | | - }, |
---|
71 | | -}; |
---|
72 | | - |
---|
73 | | -#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats) |
---|
74 | | - |
---|
75 | | -static const struct mtk_codec_framesizes mtk_venc_framesizes[] = { |
---|
76 | | - { |
---|
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 }, |
---|
80 | | - }, |
---|
81 | | - { |
---|
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 }, |
---|
85 | | - }, |
---|
| 32 | +static const struct v4l2_frmsize_stepwise mtk_venc_framesizes = { |
---|
| 33 | + MTK_VENC_MIN_W, MTK_VENC_MAX_W, 16, |
---|
| 34 | + MTK_VENC_MIN_H, MTK_VENC_MAX_H, 16, |
---|
86 | 35 | }; |
---|
87 | 36 | |
---|
88 | 37 | #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_venc_framesizes) |
---|
.. | .. |
---|
164 | 113 | .s_ctrl = vidioc_venc_s_ctrl, |
---|
165 | 114 | }; |
---|
166 | 115 | |
---|
167 | | -static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) |
---|
| 116 | +static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, |
---|
| 117 | + const struct mtk_video_fmt *formats, |
---|
| 118 | + size_t num_formats) |
---|
168 | 119 | { |
---|
169 | | - struct mtk_video_fmt *fmt; |
---|
170 | | - int i, j = 0; |
---|
| 120 | + if (f->index >= num_formats) |
---|
| 121 | + return -EINVAL; |
---|
171 | 122 | |
---|
172 | | - for (i = 0; i < NUM_FORMATS; ++i) { |
---|
173 | | - if (output_queue && mtk_video_formats[i].type != MTK_FMT_FRAME) |
---|
174 | | - continue; |
---|
175 | | - if (!output_queue && mtk_video_formats[i].type != MTK_FMT_ENC) |
---|
176 | | - continue; |
---|
| 123 | + f->pixelformat = formats[f->index].fourcc; |
---|
| 124 | + memset(f->reserved, 0, sizeof(f->reserved)); |
---|
177 | 125 | |
---|
178 | | - if (j == f->index) { |
---|
179 | | - fmt = &mtk_video_formats[i]; |
---|
180 | | - f->pixelformat = fmt->fourcc; |
---|
181 | | - memset(f->reserved, 0, sizeof(f->reserved)); |
---|
182 | | - return 0; |
---|
183 | | - } |
---|
184 | | - ++j; |
---|
| 126 | + return 0; |
---|
| 127 | +} |
---|
| 128 | + |
---|
| 129 | +static const struct mtk_video_fmt * |
---|
| 130 | +mtk_venc_find_format(u32 fourcc, const struct mtk_vcodec_enc_pdata *pdata) |
---|
| 131 | +{ |
---|
| 132 | + const struct mtk_video_fmt *fmt; |
---|
| 133 | + unsigned int k; |
---|
| 134 | + |
---|
| 135 | + for (k = 0; k < pdata->num_capture_formats; k++) { |
---|
| 136 | + fmt = &pdata->capture_formats[k]; |
---|
| 137 | + if (fmt->fourcc == fourcc) |
---|
| 138 | + return fmt; |
---|
185 | 139 | } |
---|
186 | 140 | |
---|
187 | | - return -EINVAL; |
---|
| 141 | + for (k = 0; k < pdata->num_output_formats; k++) { |
---|
| 142 | + fmt = &pdata->output_formats[k]; |
---|
| 143 | + if (fmt->fourcc == fourcc) |
---|
| 144 | + return fmt; |
---|
| 145 | + } |
---|
| 146 | + |
---|
| 147 | + return NULL; |
---|
188 | 148 | } |
---|
189 | 149 | |
---|
190 | 150 | static int vidioc_enum_framesizes(struct file *file, void *fh, |
---|
191 | 151 | struct v4l2_frmsizeenum *fsize) |
---|
192 | 152 | { |
---|
193 | | - int i = 0; |
---|
| 153 | + const struct mtk_video_fmt *fmt; |
---|
194 | 154 | |
---|
195 | 155 | if (fsize->index != 0) |
---|
196 | 156 | return -EINVAL; |
---|
197 | 157 | |
---|
198 | | - for (i = 0; i < NUM_SUPPORTED_FRAMESIZE; ++i) { |
---|
199 | | - if (fsize->pixel_format != mtk_venc_framesizes[i].fourcc) |
---|
200 | | - continue; |
---|
| 158 | + fmt = mtk_venc_find_format(fsize->pixel_format, |
---|
| 159 | + fh_to_ctx(fh)->dev->venc_pdata); |
---|
| 160 | + if (!fmt) |
---|
| 161 | + return -EINVAL; |
---|
201 | 162 | |
---|
202 | | - fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; |
---|
203 | | - fsize->stepwise = mtk_venc_framesizes[i].stepwise; |
---|
204 | | - return 0; |
---|
205 | | - } |
---|
| 163 | + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; |
---|
| 164 | + fsize->stepwise = mtk_venc_framesizes; |
---|
206 | 165 | |
---|
207 | | - return -EINVAL; |
---|
| 166 | + return 0; |
---|
208 | 167 | } |
---|
209 | 168 | |
---|
210 | | -static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv, |
---|
211 | | - struct v4l2_fmtdesc *f) |
---|
| 169 | +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
---|
| 170 | + struct v4l2_fmtdesc *f) |
---|
212 | 171 | { |
---|
213 | | - return vidioc_enum_fmt(f, false); |
---|
| 172 | + const struct mtk_vcodec_enc_pdata *pdata = |
---|
| 173 | + fh_to_ctx(priv)->dev->venc_pdata; |
---|
| 174 | + |
---|
| 175 | + return vidioc_enum_fmt(f, pdata->capture_formats, |
---|
| 176 | + pdata->num_capture_formats); |
---|
214 | 177 | } |
---|
215 | 178 | |
---|
216 | | -static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov, |
---|
217 | | - struct v4l2_fmtdesc *f) |
---|
| 179 | +static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, |
---|
| 180 | + struct v4l2_fmtdesc *f) |
---|
218 | 181 | { |
---|
219 | | - return vidioc_enum_fmt(f, true); |
---|
| 182 | + const struct mtk_vcodec_enc_pdata *pdata = |
---|
| 183 | + fh_to_ctx(priv)->dev->venc_pdata; |
---|
| 184 | + |
---|
| 185 | + return vidioc_enum_fmt(f, pdata->output_formats, |
---|
| 186 | + pdata->num_output_formats); |
---|
220 | 187 | } |
---|
221 | 188 | |
---|
222 | 189 | static int vidioc_venc_querycap(struct file *file, void *priv, |
---|
223 | 190 | struct v4l2_capability *cap) |
---|
224 | 191 | { |
---|
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)); |
---|
| 192 | + strscpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver)); |
---|
| 193 | + strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info)); |
---|
| 194 | + strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card)); |
---|
228 | 195 | |
---|
229 | 196 | return 0; |
---|
230 | 197 | } |
---|
.. | .. |
---|
233 | 200 | struct v4l2_streamparm *a) |
---|
234 | 201 | { |
---|
235 | 202 | struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); |
---|
| 203 | + struct v4l2_fract *timeperframe = &a->parm.output.timeperframe; |
---|
236 | 204 | |
---|
237 | 205 | if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
---|
238 | 206 | return -EINVAL; |
---|
239 | 207 | |
---|
240 | | - ctx->enc_params.framerate_num = |
---|
241 | | - a->parm.output.timeperframe.denominator; |
---|
242 | | - ctx->enc_params.framerate_denom = |
---|
243 | | - a->parm.output.timeperframe.numerator; |
---|
| 208 | + if (timeperframe->numerator == 0 || timeperframe->denominator == 0) { |
---|
| 209 | + timeperframe->numerator = MTK_DEFAULT_FRAMERATE_NUM; |
---|
| 210 | + timeperframe->denominator = MTK_DEFAULT_FRAMERATE_DENOM; |
---|
| 211 | + } |
---|
| 212 | + |
---|
| 213 | + ctx->enc_params.framerate_num = timeperframe->denominator; |
---|
| 214 | + ctx->enc_params.framerate_denom = timeperframe->numerator; |
---|
244 | 215 | ctx->param_change |= MTK_ENCODE_PARAM_FRAMERATE; |
---|
245 | 216 | |
---|
246 | 217 | a->parm.output.capability = V4L2_CAP_TIMEPERFRAME; |
---|
.. | .. |
---|
274 | 245 | return &ctx->q_data[MTK_Q_DATA_DST]; |
---|
275 | 246 | } |
---|
276 | 247 | |
---|
277 | | -static struct mtk_video_fmt *mtk_venc_find_format(struct v4l2_format *f) |
---|
278 | | -{ |
---|
279 | | - struct mtk_video_fmt *fmt; |
---|
280 | | - unsigned int k; |
---|
281 | | - |
---|
282 | | - for (k = 0; k < NUM_FORMATS; k++) { |
---|
283 | | - fmt = &mtk_video_formats[k]; |
---|
284 | | - if (fmt->fourcc == f->fmt.pix.pixelformat) |
---|
285 | | - return fmt; |
---|
286 | | - } |
---|
287 | | - |
---|
288 | | - return NULL; |
---|
289 | | -} |
---|
290 | | - |
---|
291 | 248 | /* V4L2 specification suggests the driver corrects the format struct if any of |
---|
292 | 249 | * the dimensions is unsupported |
---|
293 | 250 | */ |
---|
294 | | -static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_video_fmt *fmt) |
---|
| 251 | +static int vidioc_try_fmt(struct v4l2_format *f, |
---|
| 252 | + const struct mtk_video_fmt *fmt) |
---|
295 | 253 | { |
---|
296 | 254 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
---|
297 | 255 | int i; |
---|
.. | .. |
---|
393 | 351 | param->input_yuv_fmt = VENC_YUV_FORMAT_NV21; |
---|
394 | 352 | break; |
---|
395 | 353 | default: |
---|
396 | | - mtk_v4l2_err("Unsupport fourcc =%d", q_data_src->fmt->fourcc); |
---|
| 354 | + mtk_v4l2_err("Unsupported fourcc =%d", q_data_src->fmt->fourcc); |
---|
397 | 355 | break; |
---|
398 | 356 | } |
---|
399 | 357 | param->h264_profile = enc_params->h264_profile; |
---|
.. | .. |
---|
424 | 382 | struct v4l2_format *f) |
---|
425 | 383 | { |
---|
426 | 384 | struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); |
---|
| 385 | + const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; |
---|
427 | 386 | struct vb2_queue *vq; |
---|
428 | 387 | struct mtk_q_data *q_data; |
---|
429 | 388 | int i, ret; |
---|
430 | | - struct mtk_video_fmt *fmt; |
---|
| 389 | + const struct mtk_video_fmt *fmt; |
---|
431 | 390 | |
---|
432 | 391 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
---|
433 | 392 | if (!vq) { |
---|
.. | .. |
---|
446 | 405 | return -EINVAL; |
---|
447 | 406 | } |
---|
448 | 407 | |
---|
449 | | - fmt = mtk_venc_find_format(f); |
---|
| 408 | + fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata); |
---|
450 | 409 | if (!fmt) { |
---|
451 | | - f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; |
---|
452 | | - fmt = mtk_venc_find_format(f); |
---|
| 410 | + fmt = &ctx->dev->venc_pdata->capture_formats[0]; |
---|
| 411 | + f->fmt.pix.pixelformat = fmt->fourcc; |
---|
453 | 412 | } |
---|
454 | 413 | |
---|
455 | 414 | q_data->fmt = fmt; |
---|
.. | .. |
---|
486 | 445 | struct v4l2_format *f) |
---|
487 | 446 | { |
---|
488 | 447 | struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); |
---|
| 448 | + const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; |
---|
489 | 449 | struct vb2_queue *vq; |
---|
490 | 450 | struct mtk_q_data *q_data; |
---|
491 | 451 | int ret, i; |
---|
492 | | - struct mtk_video_fmt *fmt; |
---|
| 452 | + const struct mtk_video_fmt *fmt; |
---|
493 | 453 | struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; |
---|
494 | 454 | |
---|
495 | 455 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
---|
.. | .. |
---|
509 | 469 | return -EINVAL; |
---|
510 | 470 | } |
---|
511 | 471 | |
---|
512 | | - fmt = mtk_venc_find_format(f); |
---|
| 472 | + fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata); |
---|
513 | 473 | if (!fmt) { |
---|
514 | | - f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; |
---|
515 | | - fmt = mtk_venc_find_format(f); |
---|
| 474 | + fmt = &ctx->dev->venc_pdata->output_formats[0]; |
---|
| 475 | + f->fmt.pix.pixelformat = fmt->fourcc; |
---|
516 | 476 | } |
---|
517 | 477 | |
---|
518 | 478 | pix_fmt_mp->height = clamp(pix_fmt_mp->height, |
---|
.. | .. |
---|
588 | 548 | static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv, |
---|
589 | 549 | struct v4l2_format *f) |
---|
590 | 550 | { |
---|
591 | | - struct mtk_video_fmt *fmt; |
---|
| 551 | + const struct mtk_video_fmt *fmt; |
---|
592 | 552 | struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); |
---|
| 553 | + const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; |
---|
593 | 554 | |
---|
594 | | - fmt = mtk_venc_find_format(f); |
---|
| 555 | + fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata); |
---|
595 | 556 | if (!fmt) { |
---|
596 | | - f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; |
---|
597 | | - fmt = mtk_venc_find_format(f); |
---|
| 557 | + fmt = &ctx->dev->venc_pdata->capture_formats[0]; |
---|
| 558 | + f->fmt.pix.pixelformat = fmt->fourcc; |
---|
598 | 559 | } |
---|
599 | 560 | f->fmt.pix_mp.colorspace = ctx->colorspace; |
---|
600 | 561 | f->fmt.pix_mp.ycbcr_enc = ctx->ycbcr_enc; |
---|
.. | .. |
---|
607 | 568 | static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, |
---|
608 | 569 | struct v4l2_format *f) |
---|
609 | 570 | { |
---|
610 | | - struct mtk_video_fmt *fmt; |
---|
| 571 | + const struct mtk_video_fmt *fmt; |
---|
| 572 | + struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); |
---|
| 573 | + const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata; |
---|
611 | 574 | |
---|
612 | | - fmt = mtk_venc_find_format(f); |
---|
| 575 | + fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata); |
---|
613 | 576 | if (!fmt) { |
---|
614 | | - f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; |
---|
615 | | - fmt = mtk_venc_find_format(f); |
---|
| 577 | + fmt = &ctx->dev->venc_pdata->output_formats[0]; |
---|
| 578 | + f->fmt.pix.pixelformat = fmt->fourcc; |
---|
616 | 579 | } |
---|
617 | 580 | if (!f->fmt.pix_mp.colorspace) { |
---|
618 | 581 | f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709; |
---|
.. | .. |
---|
725 | 688 | .vidioc_dqbuf = vidioc_venc_dqbuf, |
---|
726 | 689 | |
---|
727 | 690 | .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, |
---|
| 691 | + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, |
---|
| 692 | + .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, |
---|
730 | 693 | .vidioc_enum_framesizes = vidioc_enum_framesizes, |
---|
731 | 694 | |
---|
732 | 695 | .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane, |
---|
.. | .. |
---|
766 | 729 | return -EINVAL; |
---|
767 | 730 | |
---|
768 | 731 | if (*nplanes) { |
---|
| 732 | + if (*nplanes != q_data->fmt->num_planes) |
---|
| 733 | + return -EINVAL; |
---|
769 | 734 | for (i = 0; i < *nplanes; i++) |
---|
770 | 735 | if (sizes[i] < q_data->sizeimage[i]) |
---|
771 | 736 | return -EINVAL; |
---|
.. | .. |
---|
805 | 770 | container_of(vb, struct vb2_v4l2_buffer, vb2_buf); |
---|
806 | 771 | |
---|
807 | 772 | struct mtk_video_enc_buf *mtk_buf = |
---|
808 | | - container_of(vb2_v4l2, struct mtk_video_enc_buf, vb); |
---|
| 773 | + container_of(vb2_v4l2, struct mtk_video_enc_buf, |
---|
| 774 | + m2m_buf.vb); |
---|
809 | 775 | |
---|
810 | 776 | if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && |
---|
811 | 777 | (ctx->param_change != MTK_ENCODE_PARAM_NONE)) { |
---|
812 | 778 | mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x", |
---|
813 | 779 | ctx->id, |
---|
814 | | - mtk_buf->vb.vb2_buf.index, |
---|
| 780 | + vb2_v4l2->vb2_buf.index, |
---|
815 | 781 | ctx->param_change); |
---|
816 | 782 | mtk_buf->param_change = ctx->param_change; |
---|
817 | 783 | mtk_buf->enc_params = ctx->enc_params; |
---|
.. | .. |
---|
872 | 838 | |
---|
873 | 839 | err_set_param: |
---|
874 | 840 | for (i = 0; i < q->num_buffers; ++i) { |
---|
875 | | - if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) { |
---|
| 841 | + struct vb2_buffer *buf = vb2_get_buffer(q, i); |
---|
| 842 | + |
---|
| 843 | + /* |
---|
| 844 | + * FIXME: This check is not needed as only active buffers |
---|
| 845 | + * can be marked as done. |
---|
| 846 | + */ |
---|
| 847 | + if (buf->state == VB2_BUF_STATE_ACTIVE) { |
---|
876 | 848 | mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED", |
---|
877 | 849 | ctx->id, i, q->type, |
---|
878 | | - (int)q->bufs[i]->state); |
---|
879 | | - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(q->bufs[i]), |
---|
880 | | - VB2_BUF_STATE_QUEUED); |
---|
| 850 | + (int)buf->state); |
---|
| 851 | + v4l2_m2m_buf_done(to_vb2_v4l2_buffer(buf), |
---|
| 852 | + VB2_BUF_STATE_QUEUED); |
---|
881 | 853 | } |
---|
882 | 854 | } |
---|
883 | 855 | |
---|
.. | .. |
---|
887 | 859 | static void vb2ops_venc_stop_streaming(struct vb2_queue *q) |
---|
888 | 860 | { |
---|
889 | 861 | struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); |
---|
890 | | - struct vb2_buffer *src_buf, *dst_buf; |
---|
| 862 | + struct vb2_v4l2_buffer *src_buf, *dst_buf; |
---|
891 | 863 | int ret; |
---|
892 | 864 | |
---|
893 | 865 | mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type); |
---|
894 | 866 | |
---|
895 | 867 | if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { |
---|
896 | 868 | 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); |
---|
| 869 | + dst_buf->vb2_buf.planes[0].bytesused = 0; |
---|
| 870 | + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); |
---|
900 | 871 | } |
---|
901 | 872 | } else { |
---|
902 | 873 | 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); |
---|
| 874 | + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); |
---|
905 | 875 | } |
---|
906 | 876 | |
---|
907 | 877 | if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && |
---|
.. | .. |
---|
923 | 893 | ctx->state = MTK_STATE_FREE; |
---|
924 | 894 | } |
---|
925 | 895 | |
---|
| 896 | +static int vb2ops_venc_buf_out_validate(struct vb2_buffer *vb) |
---|
| 897 | +{ |
---|
| 898 | + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
---|
| 899 | + |
---|
| 900 | + vbuf->field = V4L2_FIELD_NONE; |
---|
| 901 | + return 0; |
---|
| 902 | +} |
---|
| 903 | + |
---|
926 | 904 | static const struct vb2_ops mtk_venc_vb2_ops = { |
---|
927 | 905 | .queue_setup = vb2ops_venc_queue_setup, |
---|
| 906 | + .buf_out_validate = vb2ops_venc_buf_out_validate, |
---|
928 | 907 | .buf_prepare = vb2ops_venc_buf_prepare, |
---|
929 | 908 | .buf_queue = vb2ops_venc_buf_queue, |
---|
930 | 909 | .wait_prepare = vb2_ops_wait_prepare, |
---|
.. | .. |
---|
937 | 916 | { |
---|
938 | 917 | struct mtk_vcodec_ctx *ctx = priv; |
---|
939 | 918 | int ret; |
---|
940 | | - struct vb2_buffer *src_buf, *dst_buf; |
---|
941 | | - struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; |
---|
| 919 | + struct vb2_v4l2_buffer *src_buf, *dst_buf; |
---|
942 | 920 | struct mtk_vcodec_mem bs_buf; |
---|
943 | 921 | struct venc_done_result enc_result; |
---|
944 | 922 | |
---|
.. | .. |
---|
948 | 926 | return -EINVAL; |
---|
949 | 927 | } |
---|
950 | 928 | |
---|
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; |
---|
| 929 | + bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); |
---|
| 930 | + bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); |
---|
| 931 | + bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length; |
---|
954 | 932 | |
---|
955 | 933 | mtk_v4l2_debug(1, |
---|
956 | 934 | "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu", |
---|
957 | 935 | ctx->id, |
---|
958 | | - dst_buf->index, bs_buf.va, |
---|
| 936 | + dst_buf->vb2_buf.index, bs_buf.va, |
---|
959 | 937 | (u64)bs_buf.dma_addr, |
---|
960 | 938 | bs_buf.size); |
---|
961 | 939 | |
---|
.. | .. |
---|
964 | 942 | NULL, &bs_buf, &enc_result); |
---|
965 | 943 | |
---|
966 | 944 | if (ret) { |
---|
967 | | - dst_buf->planes[0].bytesused = 0; |
---|
| 945 | + dst_buf->vb2_buf.planes[0].bytesused = 0; |
---|
968 | 946 | ctx->state = MTK_STATE_ABORT; |
---|
969 | | - v4l2_m2m_buf_done(to_vb2_v4l2_buffer(dst_buf), |
---|
970 | | - VB2_BUF_STATE_ERROR); |
---|
| 947 | + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); |
---|
971 | 948 | mtk_v4l2_err("venc_if_encode failed=%d", ret); |
---|
972 | 949 | return -EINVAL; |
---|
973 | 950 | } |
---|
974 | 951 | src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); |
---|
975 | 952 | if (src_buf) { |
---|
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; |
---|
| 953 | + dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; |
---|
| 954 | + dst_buf->timecode = src_buf->timecode; |
---|
980 | 955 | } else { |
---|
981 | 956 | mtk_v4l2_err("No timestamp for the header buffer."); |
---|
982 | 957 | } |
---|
983 | 958 | |
---|
984 | 959 | 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); |
---|
| 960 | + dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size; |
---|
| 961 | + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); |
---|
987 | 962 | |
---|
988 | 963 | return 0; |
---|
989 | 964 | } |
---|
.. | .. |
---|
991 | 966 | static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx) |
---|
992 | 967 | { |
---|
993 | 968 | 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); |
---|
| 969 | + struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx); |
---|
997 | 970 | struct mtk_video_enc_buf *mtk_buf = |
---|
998 | | - container_of(vb2_v4l2, struct mtk_video_enc_buf, vb); |
---|
| 971 | + container_of(vb2_v4l2, struct mtk_video_enc_buf, |
---|
| 972 | + m2m_buf.vb); |
---|
999 | 973 | |
---|
1000 | 974 | int ret = 0; |
---|
1001 | 975 | |
---|
.. | .. |
---|
1007 | 981 | enc_prm.bitrate = mtk_buf->enc_params.bitrate; |
---|
1008 | 982 | mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d", |
---|
1009 | 983 | ctx->id, |
---|
1010 | | - mtk_buf->vb.vb2_buf.index, |
---|
| 984 | + vb2_v4l2->vb2_buf.index, |
---|
1011 | 985 | enc_prm.bitrate); |
---|
1012 | 986 | ret |= venc_if_set_param(ctx, |
---|
1013 | 987 | VENC_SET_PARAM_ADJUST_BITRATE, |
---|
.. | .. |
---|
1018 | 992 | mtk_buf->enc_params.framerate_denom; |
---|
1019 | 993 | mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d", |
---|
1020 | 994 | ctx->id, |
---|
1021 | | - mtk_buf->vb.vb2_buf.index, |
---|
| 995 | + vb2_v4l2->vb2_buf.index, |
---|
1022 | 996 | enc_prm.frm_rate); |
---|
1023 | 997 | ret |= venc_if_set_param(ctx, |
---|
1024 | 998 | VENC_SET_PARAM_ADJUST_FRAMERATE, |
---|
.. | .. |
---|
1035 | 1009 | if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) { |
---|
1036 | 1010 | mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d", |
---|
1037 | 1011 | ctx->id, |
---|
1038 | | - mtk_buf->vb.vb2_buf.index, |
---|
| 1012 | + vb2_v4l2->vb2_buf.index, |
---|
1039 | 1013 | mtk_buf->enc_params.force_intra); |
---|
1040 | 1014 | if (mtk_buf->enc_params.force_intra) |
---|
1041 | 1015 | ret |= venc_if_set_param(ctx, |
---|
.. | .. |
---|
1067 | 1041 | { |
---|
1068 | 1042 | struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx, |
---|
1069 | 1043 | encode_work); |
---|
1070 | | - struct vb2_buffer *src_buf, *dst_buf; |
---|
| 1044 | + struct vb2_v4l2_buffer *src_buf, *dst_buf; |
---|
1071 | 1045 | struct venc_frm_buf frm_buf; |
---|
1072 | 1046 | struct mtk_vcodec_mem bs_buf; |
---|
1073 | 1047 | struct venc_done_result enc_result; |
---|
1074 | 1048 | int ret, i; |
---|
1075 | | - struct vb2_v4l2_buffer *dst_vb2_v4l2, *src_vb2_v4l2; |
---|
1076 | 1049 | |
---|
1077 | 1050 | /* check dst_buf, dst_buf may be removed in device_run |
---|
1078 | 1051 | * to stored encdoe header so we need check dst_buf and |
---|
.. | .. |
---|
1086 | 1059 | |
---|
1087 | 1060 | src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); |
---|
1088 | 1061 | 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); |
---|
| 1062 | + for (i = 0; i < src_buf->vb2_buf.num_planes ; i++) { |
---|
1091 | 1063 | frm_buf.fb_addr[i].dma_addr = |
---|
1092 | | - vb2_dma_contig_plane_dma_addr(src_buf, i); |
---|
| 1064 | + vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, i); |
---|
1093 | 1065 | frm_buf.fb_addr[i].size = |
---|
1094 | | - (size_t)src_buf->planes[i].length; |
---|
| 1066 | + (size_t)src_buf->vb2_buf.planes[i].length; |
---|
1095 | 1067 | } |
---|
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; |
---|
| 1068 | + bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0); |
---|
| 1069 | + bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0); |
---|
| 1070 | + bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length; |
---|
1099 | 1071 | |
---|
1100 | 1072 | mtk_v4l2_debug(2, |
---|
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, |
---|
| 1073 | + "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu", |
---|
1103 | 1074 | (u64)frm_buf.fb_addr[0].dma_addr, |
---|
1104 | 1075 | frm_buf.fb_addr[0].size, |
---|
1105 | | - frm_buf.fb_addr[1].va, |
---|
1106 | 1076 | (u64)frm_buf.fb_addr[1].dma_addr, |
---|
1107 | 1077 | frm_buf.fb_addr[1].size, |
---|
1108 | | - frm_buf.fb_addr[2].va, |
---|
1109 | 1078 | (u64)frm_buf.fb_addr[2].dma_addr, |
---|
1110 | 1079 | frm_buf.fb_addr[2].size); |
---|
1111 | 1080 | |
---|
1112 | 1081 | ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME, |
---|
1113 | 1082 | &frm_buf, &bs_buf, &enc_result); |
---|
1114 | 1083 | |
---|
1115 | | - src_vb2_v4l2 = to_vb2_v4l2_buffer(src_buf); |
---|
1116 | | - dst_vb2_v4l2 = to_vb2_v4l2_buffer(dst_buf); |
---|
1117 | | - |
---|
1118 | | - dst_buf->timestamp = src_buf->timestamp; |
---|
1119 | | - dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode; |
---|
| 1084 | + dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; |
---|
| 1085 | + dst_buf->timecode = src_buf->timecode; |
---|
1120 | 1086 | |
---|
1121 | 1087 | if (enc_result.is_key_frm) |
---|
1122 | | - dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME; |
---|
| 1088 | + dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME; |
---|
1123 | 1089 | |
---|
1124 | 1090 | if (ret) { |
---|
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); |
---|
| 1091 | + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); |
---|
| 1092 | + dst_buf->vb2_buf.planes[0].bytesused = 0; |
---|
| 1093 | + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR); |
---|
1130 | 1094 | mtk_v4l2_err("venc_if_encode failed=%d", ret); |
---|
1131 | 1095 | } else { |
---|
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); |
---|
| 1096 | + v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); |
---|
| 1097 | + dst_buf->vb2_buf.planes[0].bytesused = enc_result.bs_size; |
---|
| 1098 | + v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE); |
---|
1137 | 1099 | mtk_v4l2_debug(2, "venc_if_encode bs size=%d", |
---|
1138 | 1100 | enc_result.bs_size); |
---|
1139 | 1101 | } |
---|
.. | .. |
---|
1141 | 1103 | v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx); |
---|
1142 | 1104 | |
---|
1143 | 1105 | 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, |
---|
| 1106 | + src_buf->vb2_buf.index, dst_buf->vb2_buf.index, ret, |
---|
1145 | 1107 | enc_result.bs_size); |
---|
1146 | 1108 | } |
---|
1147 | 1109 | |
---|
.. | .. |
---|
1209 | 1171 | q_data->coded_height = DFT_CFG_HEIGHT; |
---|
1210 | 1172 | q_data->field = V4L2_FIELD_NONE; |
---|
1211 | 1173 | |
---|
1212 | | - q_data->fmt = &mtk_video_formats[OUT_FMT_IDX]; |
---|
| 1174 | + q_data->fmt = &ctx->dev->venc_pdata->output_formats[0]; |
---|
1213 | 1175 | |
---|
1214 | 1176 | v4l_bound_align_image(&q_data->coded_width, |
---|
1215 | 1177 | MTK_VENC_MIN_W, |
---|
.. | .. |
---|
1238 | 1200 | memset(q_data, 0, sizeof(struct mtk_q_data)); |
---|
1239 | 1201 | q_data->coded_width = DFT_CFG_WIDTH; |
---|
1240 | 1202 | q_data->coded_height = DFT_CFG_HEIGHT; |
---|
1241 | | - q_data->fmt = &mtk_video_formats[CAP_FMT_IDX]; |
---|
| 1203 | + q_data->fmt = &ctx->dev->venc_pdata->capture_formats[0]; |
---|
1242 | 1204 | q_data->field = V4L2_FIELD_NONE; |
---|
1243 | 1205 | ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] = |
---|
1244 | 1206 | DFT_CFG_WIDTH * DFT_CFG_HEIGHT; |
---|
1245 | 1207 | ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = 0; |
---|
1246 | 1208 | |
---|
| 1209 | + ctx->enc_params.framerate_num = MTK_DEFAULT_FRAMERATE_NUM; |
---|
| 1210 | + ctx->enc_params.framerate_denom = MTK_DEFAULT_FRAMERATE_DENOM; |
---|
1247 | 1211 | } |
---|
1248 | 1212 | |
---|
1249 | 1213 | int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx) |
---|
.. | .. |
---|
1253 | 1217 | |
---|
1254 | 1218 | v4l2_ctrl_handler_init(handler, MTK_MAX_CTRLS_HINT); |
---|
1255 | 1219 | |
---|
| 1220 | + v4l2_ctrl_new_std(handler, ops, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, |
---|
| 1221 | + 1, 1, 1, 1); |
---|
1256 | 1222 | v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE, |
---|
1257 | | - 1, 4000000, 1, 4000000); |
---|
| 1223 | + ctx->dev->venc_pdata->min_bitrate, |
---|
| 1224 | + ctx->dev->venc_pdata->max_bitrate, 1, 4000000); |
---|
1258 | 1225 | v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_B_FRAMES, |
---|
1259 | 1226 | 0, 2, 1, 0); |
---|
1260 | 1227 | v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, |
---|