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