1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright 2020-2021 NXP
4 */
5
6 #include <linux/init.h>
7 #include <linux/interconnect.h>
8 #include <linux/ioctl.h>
9 #include <linux/list.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/delay.h>
13 #include <linux/videodev2.h>
14 #include <linux/ktime.h>
15 #include <linux/rational.h>
16 #include <linux/vmalloc.h>
17 #include <media/v4l2-device.h>
18 #include <media/v4l2-event.h>
19 #include <media/v4l2-mem2mem.h>
20 #include <media/v4l2-ioctl.h>
21 #include <media/videobuf2-v4l2.h>
22 #include <media/videobuf2-dma-contig.h>
23 #include <media/videobuf2-vmalloc.h>
24 #include "vpu.h"
25 #include "vpu_defs.h"
26 #include "vpu_core.h"
27 #include "vpu_helpers.h"
28 #include "vpu_v4l2.h"
29 #include "vpu_cmds.h"
30 #include "vpu_rpc.h"
31
32 #define VENC_OUTPUT_ENABLE BIT(0)
33 #define VENC_CAPTURE_ENABLE BIT(1)
34 #define VENC_ENABLE_MASK (VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
35 #define VENC_MAX_BUF_CNT 8
36 #define VENC_MIN_BUFFER_OUT 6
37 #define VENC_MIN_BUFFER_CAP 6
38
39 struct venc_t {
40 struct vpu_encode_params params;
41 u32 request_key_frame;
42 u32 input_ready;
43 u32 cpb_size;
44 bool bitrate_change;
45
46 struct vpu_buffer enc[VENC_MAX_BUF_CNT];
47 struct vpu_buffer ref[VENC_MAX_BUF_CNT];
48 struct vpu_buffer act[VENC_MAX_BUF_CNT];
49 struct list_head frames;
50 u32 frame_count;
51 u32 encode_count;
52 u32 ready_count;
53 u32 enable;
54 u32 stopped;
55 u32 memory_resource_configured;
56
57 u32 skipped_count;
58 u32 skipped_bytes;
59
60 wait_queue_head_t wq;
61 };
62
63 struct venc_frame_t {
64 struct list_head list;
65 struct vpu_enc_pic_info info;
66 u32 bytesused;
67 s64 timestamp;
68 };
69
70 static const struct vpu_format venc_formats[] = {
71 {
72 .pixfmt = V4L2_PIX_FMT_NV12M,
73 .mem_planes = 2,
74 .comp_planes = 2,
75 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
76 .sibling = V4L2_PIX_FMT_NV12,
77 },
78 {
79 .pixfmt = V4L2_PIX_FMT_NV12,
80 .mem_planes = 1,
81 .comp_planes = 2,
82 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
83 .sibling = V4L2_PIX_FMT_NV12M,
84 },
85 {
86 .pixfmt = V4L2_PIX_FMT_H264,
87 .mem_planes = 1,
88 .comp_planes = 1,
89 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
90 .flags = V4L2_FMT_FLAG_COMPRESSED
91 },
92 {0, 0, 0, 0},
93 };
94
venc_querycap(struct file * file,void * fh,struct v4l2_capability * cap)95 static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
96 {
97 strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
98 strscpy(cap->card, "amphion vpu encoder", sizeof(cap->card));
99 strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
100
101 return 0;
102 }
103
venc_enum_fmt(struct file * file,void * fh,struct v4l2_fmtdesc * f)104 static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
105 {
106 struct vpu_inst *inst = to_inst(file);
107 const struct vpu_format *fmt;
108
109 memset(f->reserved, 0, sizeof(f->reserved));
110 fmt = vpu_helper_enum_format(inst, f->type, f->index);
111 if (!fmt)
112 return -EINVAL;
113
114 f->pixelformat = fmt->pixfmt;
115 f->flags = fmt->flags;
116
117 return 0;
118 }
119
venc_enum_framesizes(struct file * file,void * fh,struct v4l2_frmsizeenum * fsize)120 static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)
121 {
122 struct vpu_inst *inst = to_inst(file);
123 const struct vpu_core_resources *res;
124
125 if (!fsize || fsize->index)
126 return -EINVAL;
127
128 if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))
129 return -EINVAL;
130
131 res = vpu_get_resource(inst);
132 if (!res)
133 return -EINVAL;
134 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
135 fsize->stepwise.max_width = res->max_width;
136 fsize->stepwise.max_height = res->max_height;
137 fsize->stepwise.min_width = res->min_width;
138 fsize->stepwise.min_height = res->min_height;
139 fsize->stepwise.step_width = res->step_width;
140 fsize->stepwise.step_height = res->step_height;
141
142 return 0;
143 }
144
venc_enum_frameintervals(struct file * file,void * fh,struct v4l2_frmivalenum * fival)145 static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)
146 {
147 struct vpu_inst *inst = to_inst(file);
148 const struct vpu_core_resources *res;
149
150 if (!fival || fival->index)
151 return -EINVAL;
152
153 if (!vpu_helper_find_format(inst, 0, fival->pixel_format))
154 return -EINVAL;
155
156 if (!fival->width || !fival->height)
157 return -EINVAL;
158
159 res = vpu_get_resource(inst);
160 if (!res)
161 return -EINVAL;
162 if (fival->width < res->min_width || fival->width > res->max_width ||
163 fival->height < res->min_height || fival->height > res->max_height)
164 return -EINVAL;
165
166 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
167 fival->stepwise.min.numerator = 1;
168 fival->stepwise.min.denominator = USHRT_MAX;
169 fival->stepwise.max.numerator = USHRT_MAX;
170 fival->stepwise.max.denominator = 1;
171 fival->stepwise.step.numerator = 1;
172 fival->stepwise.step.denominator = 1;
173
174 return 0;
175 }
176
venc_g_fmt(struct file * file,void * fh,struct v4l2_format * f)177 static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
178 {
179 struct vpu_inst *inst = to_inst(file);
180 struct venc_t *venc = inst->priv;
181 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
182 struct vpu_format *cur_fmt;
183 int i;
184
185 cur_fmt = vpu_get_format(inst, f->type);
186
187 pixmp->pixelformat = cur_fmt->pixfmt;
188 pixmp->num_planes = cur_fmt->mem_planes;
189 pixmp->width = cur_fmt->width;
190 pixmp->height = cur_fmt->height;
191 pixmp->field = cur_fmt->field;
192 pixmp->flags = cur_fmt->flags;
193 for (i = 0; i < pixmp->num_planes; i++) {
194 pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
195 pixmp->plane_fmt[i].sizeimage = vpu_get_fmt_plane_size(cur_fmt, i);
196 }
197
198 f->fmt.pix_mp.colorspace = venc->params.color.primaries;
199 f->fmt.pix_mp.xfer_func = venc->params.color.transfer;
200 f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;
201 f->fmt.pix_mp.quantization = venc->params.color.full_range;
202
203 return 0;
204 }
205
venc_try_fmt(struct file * file,void * fh,struct v4l2_format * f)206 static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
207 {
208 struct vpu_inst *inst = to_inst(file);
209 struct vpu_format fmt;
210
211 vpu_try_fmt_common(inst, f, &fmt);
212
213 return 0;
214 }
215
venc_s_fmt(struct file * file,void * fh,struct v4l2_format * f)216 static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
217 {
218 struct vpu_inst *inst = to_inst(file);
219 struct vpu_format fmt;
220 struct vpu_format *cur_fmt;
221 struct vb2_queue *q;
222 struct venc_t *venc = inst->priv;
223 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
224
225 q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
226 if (!q)
227 return -EINVAL;
228 if (vb2_is_busy(q))
229 return -EBUSY;
230
231 if (vpu_try_fmt_common(inst, f, &fmt))
232 return -EINVAL;
233
234 cur_fmt = vpu_get_format(inst, f->type);
235
236 memcpy(cur_fmt, &fmt, sizeof(*cur_fmt));
237
238 if (V4L2_TYPE_IS_OUTPUT(f->type)) {
239 venc->params.input_format = cur_fmt->pixfmt;
240 venc->params.src_stride = cur_fmt->bytesperline[0];
241 venc->params.src_width = cur_fmt->width;
242 venc->params.src_height = cur_fmt->height;
243 venc->params.crop.left = 0;
244 venc->params.crop.top = 0;
245 venc->params.crop.width = cur_fmt->width;
246 venc->params.crop.height = cur_fmt->height;
247 } else {
248 venc->params.codec_format = cur_fmt->pixfmt;
249 venc->params.out_width = cur_fmt->width;
250 venc->params.out_height = cur_fmt->height;
251 }
252
253 if (V4L2_TYPE_IS_OUTPUT(f->type)) {
254 venc->params.color.primaries = pix_mp->colorspace;
255 venc->params.color.transfer = pix_mp->xfer_func;
256 venc->params.color.matrix = pix_mp->ycbcr_enc;
257 venc->params.color.full_range = pix_mp->quantization;
258 }
259
260 pix_mp->colorspace = venc->params.color.primaries;
261 pix_mp->xfer_func = venc->params.color.transfer;
262 pix_mp->ycbcr_enc = venc->params.color.matrix;
263 pix_mp->quantization = venc->params.color.full_range;
264
265 return 0;
266 }
267
venc_g_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)268 static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
269 {
270 struct vpu_inst *inst = to_inst(file);
271 struct venc_t *venc = inst->priv;
272 struct v4l2_fract *timeperframe;
273
274 if (!parm)
275 return -EINVAL;
276
277 if (!V4L2_TYPE_IS_OUTPUT(parm->type))
278 return -EINVAL;
279
280 if (!vpu_helper_check_type(inst, parm->type))
281 return -EINVAL;
282
283 timeperframe = &parm->parm.capture.timeperframe;
284 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
285 parm->parm.capture.readbuffers = 0;
286 timeperframe->numerator = venc->params.frame_rate.numerator;
287 timeperframe->denominator = venc->params.frame_rate.denominator;
288
289 return 0;
290 }
291
venc_s_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)292 static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
293 {
294 struct vpu_inst *inst = to_inst(file);
295 struct venc_t *venc = inst->priv;
296 struct v4l2_fract *timeperframe;
297 unsigned long n, d;
298
299 if (!parm)
300 return -EINVAL;
301
302 if (!V4L2_TYPE_IS_OUTPUT(parm->type))
303 return -EINVAL;
304
305 if (!vpu_helper_check_type(inst, parm->type))
306 return -EINVAL;
307
308 timeperframe = &parm->parm.capture.timeperframe;
309 if (!timeperframe->numerator)
310 timeperframe->numerator = venc->params.frame_rate.numerator;
311 if (!timeperframe->denominator)
312 timeperframe->denominator = venc->params.frame_rate.denominator;
313
314 venc->params.frame_rate.numerator = timeperframe->numerator;
315 venc->params.frame_rate.denominator = timeperframe->denominator;
316
317 rational_best_approximation(venc->params.frame_rate.numerator,
318 venc->params.frame_rate.denominator,
319 venc->params.frame_rate.numerator,
320 venc->params.frame_rate.denominator,
321 &n, &d);
322 venc->params.frame_rate.numerator = n;
323 venc->params.frame_rate.denominator = d;
324
325 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
326 memset(parm->parm.capture.reserved, 0, sizeof(parm->parm.capture.reserved));
327
328 return 0;
329 }
330
venc_g_selection(struct file * file,void * fh,struct v4l2_selection * s)331 static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
332 {
333 struct vpu_inst *inst = to_inst(file);
334 struct venc_t *venc = inst->priv;
335
336 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
337 return -EINVAL;
338
339 switch (s->target) {
340 case V4L2_SEL_TGT_CROP_DEFAULT:
341 case V4L2_SEL_TGT_CROP_BOUNDS:
342 s->r.left = 0;
343 s->r.top = 0;
344 s->r.width = inst->out_format.width;
345 s->r.height = inst->out_format.height;
346 break;
347 case V4L2_SEL_TGT_CROP:
348 s->r = venc->params.crop;
349 break;
350 default:
351 return -EINVAL;
352 }
353
354 return 0;
355 }
356
venc_valid_crop(struct venc_t * venc,const struct vpu_core_resources * res)357 static int venc_valid_crop(struct venc_t *venc, const struct vpu_core_resources *res)
358 {
359 struct v4l2_rect *rect = NULL;
360 u32 min_width;
361 u32 min_height;
362 u32 src_width;
363 u32 src_height;
364
365 rect = &venc->params.crop;
366 min_width = res->min_width;
367 min_height = res->min_height;
368 src_width = venc->params.src_width;
369 src_height = venc->params.src_height;
370
371 if (rect->width == 0 || rect->height == 0)
372 return -EINVAL;
373 if (rect->left > src_width - min_width || rect->top > src_height - min_height)
374 return -EINVAL;
375
376 rect->width = min(rect->width, src_width - rect->left);
377 rect->width = max_t(u32, rect->width, min_width);
378
379 rect->height = min(rect->height, src_height - rect->top);
380 rect->height = max_t(u32, rect->height, min_height);
381
382 return 0;
383 }
384
venc_s_selection(struct file * file,void * fh,struct v4l2_selection * s)385 static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
386 {
387 struct vpu_inst *inst = to_inst(file);
388 const struct vpu_core_resources *res;
389 struct venc_t *venc = inst->priv;
390
391 res = vpu_get_resource(inst);
392 if (!res)
393 return -EINVAL;
394
395 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
396 return -EINVAL;
397 if (s->target != V4L2_SEL_TGT_CROP)
398 return -EINVAL;
399
400 venc->params.crop.left = ALIGN(s->r.left, res->step_width);
401 venc->params.crop.top = ALIGN(s->r.top, res->step_height);
402 venc->params.crop.width = ALIGN(s->r.width, res->step_width);
403 venc->params.crop.height = ALIGN(s->r.height, res->step_height);
404 if (venc_valid_crop(venc, res)) {
405 venc->params.crop.left = 0;
406 venc->params.crop.top = 0;
407 venc->params.crop.width = venc->params.src_width;
408 venc->params.crop.height = venc->params.src_height;
409 }
410
411 inst->crop = venc->params.crop;
412
413 return 0;
414 }
415
venc_drain(struct vpu_inst * inst)416 static int venc_drain(struct vpu_inst *inst)
417 {
418 struct venc_t *venc = inst->priv;
419 int ret;
420
421 if (!inst->fh.m2m_ctx)
422 return 0;
423
424 if (inst->state != VPU_CODEC_STATE_DRAIN)
425 return 0;
426
427 if (!vpu_is_source_empty(inst))
428 return 0;
429
430 if (!venc->input_ready)
431 return 0;
432
433 venc->input_ready = false;
434 vpu_trace(inst->dev, "[%d]\n", inst->id);
435 ret = vpu_session_stop(inst);
436 if (ret)
437 return ret;
438 inst->state = VPU_CODEC_STATE_STOP;
439 wake_up_all(&venc->wq);
440
441 return 0;
442 }
443
venc_request_eos(struct vpu_inst * inst)444 static int venc_request_eos(struct vpu_inst *inst)
445 {
446 inst->state = VPU_CODEC_STATE_DRAIN;
447 venc_drain(inst);
448
449 return 0;
450 }
451
venc_encoder_cmd(struct file * file,void * fh,struct v4l2_encoder_cmd * cmd)452 static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)
453 {
454 struct vpu_inst *inst = to_inst(file);
455 int ret;
456
457 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
458 if (ret)
459 return ret;
460
461 vpu_inst_lock(inst);
462 if (cmd->cmd == V4L2_ENC_CMD_STOP) {
463 if (inst->state == VPU_CODEC_STATE_DEINIT)
464 vpu_set_last_buffer_dequeued(inst, true);
465 else
466 venc_request_eos(inst);
467 }
468 vpu_inst_unlock(inst);
469
470 return 0;
471 }
472
venc_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)473 static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
474 {
475 switch (sub->type) {
476 case V4L2_EVENT_EOS:
477 return v4l2_event_subscribe(fh, sub, 0, NULL);
478 case V4L2_EVENT_CTRL:
479 return v4l2_ctrl_subscribe_event(fh, sub);
480 default:
481 return -EINVAL;
482 }
483 }
484
485 static const struct v4l2_ioctl_ops venc_ioctl_ops = {
486 .vidioc_querycap = venc_querycap,
487 .vidioc_enum_fmt_vid_cap = venc_enum_fmt,
488 .vidioc_enum_fmt_vid_out = venc_enum_fmt,
489 .vidioc_enum_framesizes = venc_enum_framesizes,
490 .vidioc_enum_frameintervals = venc_enum_frameintervals,
491 .vidioc_g_fmt_vid_cap_mplane = venc_g_fmt,
492 .vidioc_g_fmt_vid_out_mplane = venc_g_fmt,
493 .vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,
494 .vidioc_try_fmt_vid_out_mplane = venc_try_fmt,
495 .vidioc_s_fmt_vid_cap_mplane = venc_s_fmt,
496 .vidioc_s_fmt_vid_out_mplane = venc_s_fmt,
497 .vidioc_g_parm = venc_g_parm,
498 .vidioc_s_parm = venc_s_parm,
499 .vidioc_g_selection = venc_g_selection,
500 .vidioc_s_selection = venc_s_selection,
501 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
502 .vidioc_encoder_cmd = venc_encoder_cmd,
503 .vidioc_subscribe_event = venc_subscribe_event,
504 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
505 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
506 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
507 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
508 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
509 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
510 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
511 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
512 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
513 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
514 };
515
venc_op_s_ctrl(struct v4l2_ctrl * ctrl)516 static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
517 {
518 struct vpu_inst *inst = ctrl_to_inst(ctrl);
519 struct venc_t *venc = inst->priv;
520 int ret = 0;
521
522 switch (ctrl->id) {
523 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
524 venc->params.profile = ctrl->val;
525 break;
526 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
527 venc->params.level = ctrl->val;
528 break;
529 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
530 venc->params.rc_enable = ctrl->val;
531 break;
532 case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
533 venc->params.rc_mode = ctrl->val;
534 break;
535 case V4L2_CID_MPEG_VIDEO_BITRATE:
536 if (ctrl->val != venc->params.bitrate)
537 venc->bitrate_change = true;
538 venc->params.bitrate = ctrl->val;
539 break;
540 case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
541 venc->params.bitrate_max = ctrl->val;
542 break;
543 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
544 venc->params.gop_length = ctrl->val;
545 break;
546 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
547 venc->params.bframes = ctrl->val;
548 break;
549 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
550 venc->params.i_frame_qp = ctrl->val;
551 break;
552 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
553 venc->params.p_frame_qp = ctrl->val;
554 break;
555 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
556 venc->params.b_frame_qp = ctrl->val;
557 break;
558 case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
559 venc->request_key_frame = 1;
560 break;
561 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
562 venc->cpb_size = ctrl->val * 1024;
563 break;
564 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
565 venc->params.sar.enable = ctrl->val;
566 break;
567 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
568 venc->params.sar.idc = ctrl->val;
569 break;
570 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
571 venc->params.sar.width = ctrl->val;
572 break;
573 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
574 venc->params.sar.height = ctrl->val;
575 break;
576 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
577 break;
578 default:
579 ret = -EINVAL;
580 break;
581 }
582
583 return ret;
584 }
585
586 static const struct v4l2_ctrl_ops venc_ctrl_ops = {
587 .s_ctrl = venc_op_s_ctrl,
588 .g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
589 };
590
venc_ctrl_init(struct vpu_inst * inst)591 static int venc_ctrl_init(struct vpu_inst *inst)
592 {
593 struct v4l2_ctrl *ctrl;
594 int ret;
595
596 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
597 if (ret)
598 return ret;
599
600 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
601 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
602 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
603 ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
604 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
605 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
606 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
607
608 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
609 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
610 V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
611 0x0,
612 V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
613
614 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
615 V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1);
616
617 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
618 V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
619 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
620 ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
621 (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)),
622 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
623
624 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
625 V4L2_CID_MPEG_VIDEO_BITRATE,
626 BITRATE_MIN,
627 BITRATE_MAX,
628 BITRATE_STEP,
629 BITRATE_DEFAULT);
630
631 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
632 V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
633 BITRATE_MIN, BITRATE_MAX,
634 BITRATE_STEP,
635 BITRATE_DEFAULT_PEAK);
636
637 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
638 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 8000, 1, 30);
639
640 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
641 V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
642
643 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
644 V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
645 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
646 V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
647 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
648 V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
649 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
650 V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
651 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
652 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
653 if (ctrl)
654 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
655 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
656 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
657 if (ctrl)
658 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
659
660 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
661 V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);
662
663 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
664 V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);
665 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
666 V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
667 V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
668 0x0,
669 V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
670 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
671 V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
672 0, USHRT_MAX, 1, 1);
673 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
674 V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
675 0, USHRT_MAX, 1, 1);
676 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
677 V4L2_CID_MPEG_VIDEO_HEADER_MODE,
678 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
679 ~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
680 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
681
682 v4l2_ctrl_new_std(&inst->ctrl_handler, NULL,
683 V4L2_CID_MPEG_VIDEO_AVERAGE_QP, 0, 51, 1, 0);
684
685 if (inst->ctrl_handler.error) {
686 ret = inst->ctrl_handler.error;
687 v4l2_ctrl_handler_free(&inst->ctrl_handler);
688 return ret;
689 }
690
691 ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
692 if (ret) {
693 dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
694 v4l2_ctrl_handler_free(&inst->ctrl_handler);
695 return ret;
696 }
697
698 return 0;
699 }
700
venc_check_ready(struct vpu_inst * inst,unsigned int type)701 static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)
702 {
703 struct venc_t *venc = inst->priv;
704
705 if (V4L2_TYPE_IS_OUTPUT(type)) {
706 if (vpu_helper_get_free_space(inst) < venc->cpb_size)
707 return false;
708 return venc->input_ready;
709 }
710
711 if (list_empty(&venc->frames))
712 return false;
713 return true;
714 }
715
venc_get_enable_mask(u32 type)716 static u32 venc_get_enable_mask(u32 type)
717 {
718 if (V4L2_TYPE_IS_OUTPUT(type))
719 return VENC_OUTPUT_ENABLE;
720 else
721 return VENC_CAPTURE_ENABLE;
722 }
723
venc_set_enable(struct venc_t * venc,u32 type,int enable)724 static void venc_set_enable(struct venc_t *venc, u32 type, int enable)
725 {
726 u32 mask = venc_get_enable_mask(type);
727
728 if (enable)
729 venc->enable |= mask;
730 else
731 venc->enable &= ~mask;
732 }
733
venc_get_enable(struct venc_t * venc,u32 type)734 static u32 venc_get_enable(struct venc_t *venc, u32 type)
735 {
736 return venc->enable & venc_get_enable_mask(type);
737 }
738
venc_input_done(struct vpu_inst * inst)739 static void venc_input_done(struct vpu_inst *inst)
740 {
741 struct venc_t *venc = inst->priv;
742
743 vpu_inst_lock(inst);
744 venc->input_ready = true;
745 vpu_process_output_buffer(inst);
746 if (inst->state == VPU_CODEC_STATE_DRAIN)
747 venc_drain(inst);
748 vpu_inst_unlock(inst);
749 }
750
751 /*
752 * It's hardware limitation, that there may be several bytes
753 * redundant data at the beginning of frame.
754 * For android platform, the redundant data may cause cts test fail
755 * So driver will strip them
756 */
venc_precheck_encoded_frame(struct vpu_inst * inst,struct venc_frame_t * frame)757 static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)
758 {
759 struct venc_t *venc;
760 int skipped;
761
762 if (!frame || !frame->bytesused)
763 return -EINVAL;
764
765 venc = inst->priv;
766 skipped = vpu_helper_find_startcode(&inst->stream_buffer,
767 inst->cap_format.pixfmt,
768 frame->info.wptr - inst->stream_buffer.phys,
769 frame->bytesused);
770 if (skipped > 0) {
771 frame->bytesused -= skipped;
772 frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,
773 frame->info.wptr, skipped);
774 venc->skipped_bytes += skipped;
775 venc->skipped_count++;
776 }
777
778 return 0;
779 }
780
venc_get_one_encoded_frame(struct vpu_inst * inst,struct venc_frame_t * frame,struct vb2_v4l2_buffer * vbuf)781 static int venc_get_one_encoded_frame(struct vpu_inst *inst,
782 struct venc_frame_t *frame,
783 struct vb2_v4l2_buffer *vbuf)
784 {
785 struct venc_t *venc = inst->priv;
786 struct vb2_v4l2_buffer *src_buf;
787
788 if (!vbuf)
789 return -EAGAIN;
790
791 src_buf = vpu_find_buf_by_sequence(inst, inst->out_format.type, frame->info.frame_id);
792 if (src_buf) {
793 v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true);
794 vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
795 v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, src_buf);
796 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
797 } else {
798 vbuf->vb2_buf.timestamp = frame->info.timestamp;
799 }
800 if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
801 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
802 return 0;
803 }
804 if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {
805 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
806 return -ENOMEM;
807 }
808
809 venc_precheck_encoded_frame(inst, frame);
810
811 if (frame->bytesused) {
812 u32 rptr = frame->info.wptr;
813 void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
814
815 vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,
816 &rptr, frame->bytesused, dst);
817 vpu_iface_update_stream_buffer(inst, rptr, 0);
818 }
819 vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
820 vbuf->sequence = frame->info.frame_id;
821 vbuf->field = inst->cap_format.field;
822 vbuf->flags |= frame->info.pic_type;
823 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
824 vpu_set_buffer_average_qp(vbuf, frame->info.average_qp);
825 dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
826 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
827 venc->ready_count++;
828
829 if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
830 dev_dbg(inst->dev, "[%d][%d]key frame\n", inst->id, frame->info.frame_id);
831
832 return 0;
833 }
834
venc_get_encoded_frames(struct vpu_inst * inst)835 static int venc_get_encoded_frames(struct vpu_inst *inst)
836 {
837 struct venc_t *venc;
838 struct venc_frame_t *frame;
839 struct venc_frame_t *tmp;
840
841 if (!inst->fh.m2m_ctx)
842 return 0;
843 venc = inst->priv;
844 list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
845 if (venc_get_one_encoded_frame(inst, frame,
846 v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
847 break;
848 list_del_init(&frame->list);
849 vfree(frame);
850 }
851
852 return 0;
853 }
854
venc_frame_encoded(struct vpu_inst * inst,void * arg)855 static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
856 {
857 struct vpu_enc_pic_info *info = arg;
858 struct venc_frame_t *frame;
859 struct venc_t *venc;
860 int ret = 0;
861
862 if (!info)
863 return -EINVAL;
864 venc = inst->priv;
865 frame = vzalloc(sizeof(*frame));
866 if (!frame)
867 return -ENOMEM;
868
869 memcpy(&frame->info, info, sizeof(frame->info));
870 frame->bytesused = info->frame_size;
871
872 vpu_inst_lock(inst);
873 list_add_tail(&frame->list, &venc->frames);
874 venc->encode_count++;
875 venc_get_encoded_frames(inst);
876 vpu_inst_unlock(inst);
877
878 return ret;
879 }
880
venc_set_last_buffer_dequeued(struct vpu_inst * inst)881 static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
882 {
883 struct venc_t *venc = inst->priv;
884
885 if (venc->stopped && list_empty(&venc->frames))
886 vpu_set_last_buffer_dequeued(inst, true);
887 }
888
venc_stop_done(struct vpu_inst * inst)889 static void venc_stop_done(struct vpu_inst *inst)
890 {
891 struct venc_t *venc = inst->priv;
892
893 vpu_inst_lock(inst);
894 venc->stopped = true;
895 venc_set_last_buffer_dequeued(inst);
896 vpu_inst_unlock(inst);
897
898 wake_up_all(&venc->wq);
899 }
900
venc_event_notify(struct vpu_inst * inst,u32 event,void * data)901 static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
902 {
903 }
904
venc_release(struct vpu_inst * inst)905 static void venc_release(struct vpu_inst *inst)
906 {
907 }
908
venc_cleanup(struct vpu_inst * inst)909 static void venc_cleanup(struct vpu_inst *inst)
910 {
911 struct venc_t *venc;
912
913 if (!inst)
914 return;
915
916 venc = inst->priv;
917 vfree(venc);
918 inst->priv = NULL;
919 vfree(inst);
920 }
921
venc_start_session(struct vpu_inst * inst,u32 type)922 static int venc_start_session(struct vpu_inst *inst, u32 type)
923 {
924 struct venc_t *venc = inst->priv;
925 int stream_buffer_size;
926 int ret;
927
928 venc_set_enable(venc, type, 1);
929 if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)
930 return 0;
931
932 vpu_iface_init_instance(inst);
933 stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
934 if (stream_buffer_size > 0) {
935 inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);
936 ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
937 if (ret)
938 goto error;
939
940 inst->use_stream_buffer = true;
941 vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
942 }
943
944 ret = vpu_iface_set_encode_params(inst, &venc->params, 0);
945 if (ret)
946 goto error;
947
948 venc->memory_resource_configured = false;
949 ret = vpu_session_configure_codec(inst);
950 if (ret)
951 goto error;
952
953 if (!venc->memory_resource_configured) {
954 vb2_queue_error(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx));
955 vb2_queue_error(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx));
956 ret = -ENOMEM;
957 goto error;
958 }
959
960 inst->state = VPU_CODEC_STATE_CONFIGURED;
961 /*vpu_iface_config_memory_resource*/
962
963 /*config enc expert mode parameter*/
964 ret = vpu_iface_set_encode_params(inst, &venc->params, 1);
965 if (ret)
966 goto error;
967
968 ret = vpu_session_start(inst);
969 if (ret)
970 goto error;
971 inst->state = VPU_CODEC_STATE_STARTED;
972
973 venc->bitrate_change = false;
974 venc->input_ready = true;
975 venc->frame_count = 0;
976 venc->encode_count = 0;
977 venc->ready_count = 0;
978 venc->stopped = false;
979 vpu_process_output_buffer(inst);
980 if (venc->frame_count == 0)
981 dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id);
982
983 return 0;
984 error:
985 venc_set_enable(venc, type, 0);
986 inst->state = VPU_CODEC_STATE_DEINIT;
987
988 vpu_free_dma(&inst->stream_buffer);
989 return ret;
990 }
991
venc_cleanup_mem_resource(struct vpu_inst * inst)992 static void venc_cleanup_mem_resource(struct vpu_inst *inst)
993 {
994 struct venc_t *venc;
995 u32 i;
996
997 venc = inst->priv;
998 venc->memory_resource_configured = false;
999
1000 for (i = 0; i < ARRAY_SIZE(venc->enc); i++)
1001 vpu_free_dma(&venc->enc[i]);
1002 for (i = 0; i < ARRAY_SIZE(venc->ref); i++)
1003 vpu_free_dma(&venc->ref[i]);
1004 }
1005
venc_request_mem_resource(struct vpu_inst * inst,u32 enc_frame_size,u32 enc_frame_num,u32 ref_frame_size,u32 ref_frame_num,u32 act_frame_size,u32 act_frame_num)1006 static void venc_request_mem_resource(struct vpu_inst *inst,
1007 u32 enc_frame_size,
1008 u32 enc_frame_num,
1009 u32 ref_frame_size,
1010 u32 ref_frame_num,
1011 u32 act_frame_size,
1012 u32 act_frame_num)
1013 {
1014 struct venc_t *venc;
1015 u32 i;
1016 int ret;
1017
1018 venc = inst->priv;
1019 if (enc_frame_num > ARRAY_SIZE(venc->enc)) {
1020 dev_err(inst->dev, "[%d] enc num(%d) is out of range\n", inst->id, enc_frame_num);
1021 return;
1022 }
1023 if (ref_frame_num > ARRAY_SIZE(venc->ref)) {
1024 dev_err(inst->dev, "[%d] ref num(%d) is out of range\n", inst->id, ref_frame_num);
1025 return;
1026 }
1027 if (act_frame_num > ARRAY_SIZE(venc->act)) {
1028 dev_err(inst->dev, "[%d] act num(%d) is out of range\n", inst->id, act_frame_num);
1029 return;
1030 }
1031
1032 for (i = 0; i < enc_frame_num; i++) {
1033 venc->enc[i].length = enc_frame_size;
1034 ret = vpu_alloc_dma(inst->core, &venc->enc[i]);
1035 if (ret) {
1036 venc_cleanup_mem_resource(inst);
1037 return;
1038 }
1039 }
1040 for (i = 0; i < ref_frame_num; i++) {
1041 venc->ref[i].length = ref_frame_size;
1042 ret = vpu_alloc_dma(inst->core, &venc->ref[i]);
1043 if (ret) {
1044 venc_cleanup_mem_resource(inst);
1045 return;
1046 }
1047 }
1048 if (act_frame_num != 1 || act_frame_size > inst->act.length) {
1049 venc_cleanup_mem_resource(inst);
1050 return;
1051 }
1052 venc->act[0].length = act_frame_size;
1053 venc->act[0].phys = inst->act.phys;
1054 venc->act[0].virt = inst->act.virt;
1055
1056 for (i = 0; i < enc_frame_num; i++)
1057 vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);
1058 for (i = 0; i < ref_frame_num; i++)
1059 vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);
1060 for (i = 0; i < act_frame_num; i++)
1061 vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);
1062 venc->memory_resource_configured = true;
1063 }
1064
venc_cleanup_frames(struct venc_t * venc)1065 static void venc_cleanup_frames(struct venc_t *venc)
1066 {
1067 struct venc_frame_t *frame;
1068 struct venc_frame_t *tmp;
1069
1070 list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
1071 list_del_init(&frame->list);
1072 vfree(frame);
1073 }
1074 }
1075
venc_stop_session(struct vpu_inst * inst,u32 type)1076 static int venc_stop_session(struct vpu_inst *inst, u32 type)
1077 {
1078 struct venc_t *venc = inst->priv;
1079
1080 venc_set_enable(venc, type, 0);
1081 if (venc->enable & VENC_ENABLE_MASK)
1082 return 0;
1083
1084 if (inst->state == VPU_CODEC_STATE_DEINIT)
1085 return 0;
1086
1087 if (inst->state != VPU_CODEC_STATE_STOP)
1088 venc_request_eos(inst);
1089
1090 call_void_vop(inst, wait_prepare);
1091 if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {
1092 set_bit(inst->id, &inst->core->hang_mask);
1093 vpu_session_debug(inst);
1094 }
1095 call_void_vop(inst, wait_finish);
1096
1097 inst->state = VPU_CODEC_STATE_DEINIT;
1098 venc_cleanup_frames(inst->priv);
1099 vpu_free_dma(&inst->stream_buffer);
1100 venc_cleanup_mem_resource(inst);
1101
1102 return 0;
1103 }
1104
venc_process_output(struct vpu_inst * inst,struct vb2_buffer * vb)1105 static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
1106 {
1107 struct venc_t *venc = inst->priv;
1108 struct vb2_v4l2_buffer *vbuf;
1109 u32 flags;
1110
1111 if (inst->state == VPU_CODEC_STATE_DEINIT)
1112 return -EINVAL;
1113
1114 vbuf = to_vb2_v4l2_buffer(vb);
1115 if (inst->state == VPU_CODEC_STATE_STARTED)
1116 inst->state = VPU_CODEC_STATE_ACTIVE;
1117
1118 flags = vbuf->flags;
1119 if (venc->request_key_frame) {
1120 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
1121 venc->request_key_frame = 0;
1122 }
1123 if (venc->bitrate_change) {
1124 vpu_session_update_parameters(inst, &venc->params);
1125 venc->bitrate_change = false;
1126 }
1127 dev_dbg(inst->dev, "[%d][INPUT TS]%32lld\n", inst->id, vb->timestamp);
1128 vpu_iface_input_frame(inst, vb);
1129 vbuf->flags = flags;
1130 venc->input_ready = false;
1131 venc->frame_count++;
1132 vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
1133
1134 return 0;
1135 }
1136
venc_process_capture(struct vpu_inst * inst,struct vb2_buffer * vb)1137 static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
1138 {
1139 struct venc_t *venc;
1140 struct venc_frame_t *frame = NULL;
1141 struct vb2_v4l2_buffer *vbuf;
1142 int ret;
1143
1144 venc = inst->priv;
1145 if (list_empty(&venc->frames))
1146 return -EINVAL;
1147
1148 frame = list_first_entry(&venc->frames, struct venc_frame_t, list);
1149 vbuf = to_vb2_v4l2_buffer(vb);
1150 v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
1151 ret = venc_get_one_encoded_frame(inst, frame, vbuf);
1152 if (ret)
1153 return ret;
1154
1155 list_del_init(&frame->list);
1156 vfree(frame);
1157 return 0;
1158 }
1159
venc_on_queue_empty(struct vpu_inst * inst,u32 type)1160 static void venc_on_queue_empty(struct vpu_inst *inst, u32 type)
1161 {
1162 struct venc_t *venc = inst->priv;
1163
1164 if (V4L2_TYPE_IS_OUTPUT(type))
1165 return;
1166
1167 if (venc->stopped)
1168 venc_set_last_buffer_dequeued(inst);
1169 }
1170
venc_get_debug_info(struct vpu_inst * inst,char * str,u32 size,u32 i)1171 static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
1172 {
1173 struct venc_t *venc = inst->priv;
1174 int num = -1;
1175
1176 switch (i) {
1177 case 0:
1178 num = scnprintf(str, size, "profile = %d\n", venc->params.profile);
1179 break;
1180 case 1:
1181 num = scnprintf(str, size, "level = %d\n", venc->params.level);
1182 break;
1183 case 2:
1184 num = scnprintf(str, size, "fps = %d/%d\n",
1185 venc->params.frame_rate.numerator,
1186 venc->params.frame_rate.denominator);
1187 break;
1188 case 3:
1189 num = scnprintf(str, size, "%d x %d -> %d x %d\n",
1190 venc->params.src_width,
1191 venc->params.src_height,
1192 venc->params.out_width,
1193 venc->params.out_height);
1194 break;
1195 case 4:
1196 num = scnprintf(str, size, "(%d, %d) %d x %d\n",
1197 venc->params.crop.left,
1198 venc->params.crop.top,
1199 venc->params.crop.width,
1200 venc->params.crop.height);
1201 break;
1202 case 5:
1203 num = scnprintf(str, size,
1204 "enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",
1205 venc->enable,
1206 venc->frame_count, venc->encode_count,
1207 venc->ready_count,
1208 venc->stopped);
1209 break;
1210 case 6:
1211 num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);
1212 break;
1213 case 7:
1214 num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);
1215 break;
1216 case 8:
1217 num = scnprintf(str, size, "rc: %s, mode = %d, bitrate = %d(%d), qp = %d\n",
1218 venc->params.rc_enable ? "enable" : "disable",
1219 venc->params.rc_mode,
1220 venc->params.bitrate,
1221 venc->params.bitrate_max,
1222 venc->params.i_frame_qp);
1223 break;
1224 case 9:
1225 num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",
1226 venc->params.sar.enable,
1227 venc->params.sar.idc,
1228 venc->params.sar.width,
1229 venc->params.sar.height);
1230
1231 break;
1232 case 10:
1233 num = scnprintf(str, size,
1234 "colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",
1235 venc->params.color.primaries,
1236 venc->params.color.transfer,
1237 venc->params.color.matrix,
1238 venc->params.color.full_range);
1239 break;
1240 case 11:
1241 num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",
1242 venc->skipped_count, venc->skipped_bytes);
1243 break;
1244 default:
1245 break;
1246 }
1247
1248 return num;
1249 }
1250
1251 static struct vpu_inst_ops venc_inst_ops = {
1252 .ctrl_init = venc_ctrl_init,
1253 .check_ready = venc_check_ready,
1254 .input_done = venc_input_done,
1255 .get_one_frame = venc_frame_encoded,
1256 .stop_done = venc_stop_done,
1257 .event_notify = venc_event_notify,
1258 .release = venc_release,
1259 .cleanup = venc_cleanup,
1260 .start = venc_start_session,
1261 .mem_request = venc_request_mem_resource,
1262 .stop = venc_stop_session,
1263 .process_output = venc_process_output,
1264 .process_capture = venc_process_capture,
1265 .on_queue_empty = venc_on_queue_empty,
1266 .get_debug_info = venc_get_debug_info,
1267 .wait_prepare = vpu_inst_unlock,
1268 .wait_finish = vpu_inst_lock,
1269 };
1270
venc_init(struct file * file)1271 static void venc_init(struct file *file)
1272 {
1273 struct vpu_inst *inst = to_inst(file);
1274 struct venc_t *venc;
1275 struct v4l2_format f;
1276 struct v4l2_streamparm parm;
1277
1278 venc = inst->priv;
1279 venc->params.qp_min = 1;
1280 venc->params.qp_max = 51;
1281 venc->params.qp_min_i = 1;
1282 venc->params.qp_max_i = 51;
1283 venc->params.bitrate_min = BITRATE_MIN;
1284
1285 memset(&f, 0, sizeof(f));
1286 f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1287 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
1288 f.fmt.pix_mp.width = 1280;
1289 f.fmt.pix_mp.height = 720;
1290 f.fmt.pix_mp.field = V4L2_FIELD_NONE;
1291 venc_s_fmt(file, &inst->fh, &f);
1292
1293 memset(&f, 0, sizeof(f));
1294 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1295 f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
1296 f.fmt.pix_mp.width = 1280;
1297 f.fmt.pix_mp.height = 720;
1298 f.fmt.pix_mp.field = V4L2_FIELD_NONE;
1299 venc_s_fmt(file, &inst->fh, &f);
1300
1301 memset(&parm, 0, sizeof(parm));
1302 parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1303 parm.parm.capture.timeperframe.numerator = 1;
1304 parm.parm.capture.timeperframe.denominator = 30;
1305 venc_s_parm(file, &inst->fh, &parm);
1306 }
1307
venc_open(struct file * file)1308 static int venc_open(struct file *file)
1309 {
1310 struct vpu_inst *inst;
1311 struct venc_t *venc;
1312 int ret;
1313
1314 inst = vzalloc(sizeof(*inst));
1315 if (!inst)
1316 return -ENOMEM;
1317
1318 venc = vzalloc(sizeof(*venc));
1319 if (!venc) {
1320 vfree(inst);
1321 return -ENOMEM;
1322 }
1323
1324 inst->ops = &venc_inst_ops;
1325 inst->formats = venc_formats;
1326 inst->type = VPU_CORE_TYPE_ENC;
1327 inst->priv = venc;
1328 INIT_LIST_HEAD(&venc->frames);
1329 init_waitqueue_head(&venc->wq);
1330
1331 ret = vpu_v4l2_open(file, inst);
1332 if (ret)
1333 return ret;
1334
1335 inst->min_buffer_out = VENC_MIN_BUFFER_OUT;
1336 inst->min_buffer_cap = VENC_MIN_BUFFER_CAP;
1337 venc_init(file);
1338
1339 return 0;
1340 }
1341
1342 static const struct v4l2_file_operations venc_fops = {
1343 .owner = THIS_MODULE,
1344 .open = venc_open,
1345 .release = vpu_v4l2_close,
1346 .unlocked_ioctl = video_ioctl2,
1347 .poll = v4l2_m2m_fop_poll,
1348 .mmap = v4l2_m2m_fop_mmap,
1349 };
1350
venc_get_ioctl_ops(void)1351 const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void)
1352 {
1353 return &venc_ioctl_ops;
1354 }
1355
venc_get_fops(void)1356 const struct v4l2_file_operations *venc_get_fops(void)
1357 {
1358 return &venc_fops;
1359 }
1360