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