]> Git Repo - linux.git/blob - drivers/media/platform/amphion/venc.c
Linux 6.14-rc3
[linux.git] / drivers / media / platform / amphion / venc.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
734 static u32 venc_get_enable(struct venc_t *venc, u32 type)
735 {
736         return venc->enable & venc_get_enable_mask(type);
737 }
738
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  */
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
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
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
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
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
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
901 static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
902 {
903 }
904
905 static void venc_release(struct vpu_inst *inst)
906 {
907 }
908
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
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
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
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
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
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
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
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
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
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
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
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
1351 const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void)
1352 {
1353         return &venc_ioctl_ops;
1354 }
1355
1356 const struct v4l2_file_operations *venc_get_fops(void)
1357 {
1358         return &venc_fops;
1359 }
This page took 0.109147 seconds and 4 git commands to generate.