66730bdb53180c770af2c1ae11533a43ad0c7bf5
[AGL/meta-agl-devel.git] / meta-egvirt / recipes-kernel / kernel-module-virtio-video / files / virtio_video_enc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Encoder for virtio video device.
3  *
4  * Copyright 2020 OpenSynergy GmbH.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/version.h>
21 #include <media/v4l2-event.h>
22 #include <media/v4l2-ioctl.h>
23
24 #include "virtio_video.h"
25
26 static int virtio_video_enc_start_streaming(struct vb2_queue *vq,
27                                             unsigned int count)
28 {
29         struct virtio_video_stream *stream = vb2_get_drv_priv(vq);
30         bool input_queue = V4L2_TYPE_IS_OUTPUT(vq->type);
31
32         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
33                 return -EIO;
34
35         if (virtio_video_state(stream) == STREAM_STATE_INIT ||
36             (!input_queue &&
37              virtio_video_state(stream) == STREAM_STATE_RESET) ||
38             (input_queue &&
39              virtio_video_state(stream) == STREAM_STATE_STOPPED))
40                 virtio_video_state_update(stream, STREAM_STATE_RUNNING);
41
42         return 0;
43 }
44
45 static void virtio_video_enc_stop_streaming(struct vb2_queue *vq)
46 {
47         int ret, queue_type;
48         struct virtio_video_stream *stream = vb2_get_drv_priv(vq);
49
50         if (V4L2_TYPE_IS_OUTPUT(vq->type))
51                 queue_type = VIRTIO_VIDEO_QUEUE_TYPE_INPUT;
52         else
53                 queue_type = VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT;
54
55         ret = virtio_video_queue_release_buffers(stream, queue_type);
56         if (ret)
57                 return;
58
59         vb2_wait_for_all_buffers(vq);
60
61         if (V4L2_TYPE_IS_OUTPUT(vq->type))
62                 virtio_video_state_update(stream, STREAM_STATE_STOPPED);
63         else
64                 virtio_video_state_update(stream, STREAM_STATE_RESET);
65 }
66
67 static const struct vb2_ops virtio_video_enc_qops = {
68         .queue_setup     = virtio_video_queue_setup,
69         .buf_init        = virtio_video_buf_init,
70         .buf_cleanup     = virtio_video_buf_cleanup,
71         .buf_queue       = virtio_video_buf_queue,
72         .start_streaming = virtio_video_enc_start_streaming,
73         .stop_streaming  = virtio_video_enc_stop_streaming,
74         .wait_prepare    = vb2_ops_wait_prepare,
75         .wait_finish     = vb2_ops_wait_finish,
76 };
77
78 static int virtio_video_enc_s_ctrl(struct v4l2_ctrl *ctrl)
79 {
80         int ret = 0;
81         struct virtio_video_stream *stream = ctrl2stream(ctrl);
82         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
83         uint32_t control, value;
84
85         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
86                 return -EIO;
87
88         control = virtio_video_v4l2_control_to_virtio(ctrl->id);
89
90         switch (ctrl->id) {
91         case V4L2_CID_MPEG_VIDEO_BITRATE:
92                 ret = virtio_video_cmd_set_control(vvd, stream->stream_id,
93                                                    control, ctrl->val);
94                 break;
95         case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
96                 value = virtio_video_v4l2_level_to_virtio(ctrl->val);
97                 ret = virtio_video_cmd_set_control(vvd, stream->stream_id,
98                                                    control, value);
99                 break;
100         case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
101                 value = virtio_video_v4l2_profile_to_virtio(ctrl->val);
102                 ret = virtio_video_cmd_set_control(vvd, stream->stream_id,
103                                                    control, value);
104                 break;
105         default:
106                 ret = -EINVAL;
107                 break;
108         }
109
110         return ret;
111 }
112
113 static int virtio_video_enc_g_ctrl(struct v4l2_ctrl *ctrl)
114 {
115         int ret = 0;
116         struct virtio_video_stream *stream = ctrl2stream(ctrl);
117
118         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
119                 return -EIO;
120
121         switch (ctrl->id) {
122         case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
123                 if (virtio_video_state(stream) >= STREAM_STATE_INIT)
124                         ctrl->val = stream->in_info.min_buffers;
125                 else
126                         ctrl->val = 0;
127                 break;
128         default:
129                 ret = -EINVAL;
130                 break;
131         }
132
133         return ret;
134 }
135
136 static const struct v4l2_ctrl_ops virtio_video_enc_ctrl_ops = {
137         .g_volatile_ctrl        = virtio_video_enc_g_ctrl,
138         .s_ctrl                 = virtio_video_enc_s_ctrl,
139 };
140
141 int virtio_video_enc_init_ctrls(struct virtio_video_stream *stream)
142 {
143         struct v4l2_ctrl *ctrl;
144         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
145         struct video_control_format *c_fmt = NULL;
146
147         v4l2_ctrl_handler_init(&stream->ctrl_handler, 1);
148
149         ctrl = v4l2_ctrl_new_std(&stream->ctrl_handler,
150                                 &virtio_video_enc_ctrl_ops,
151                                 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
152                                 MIN_BUFS_MIN, MIN_BUFS_MAX, MIN_BUFS_STEP,
153                                 MIN_BUFS_DEF);
154
155         if (ctrl)
156                 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
157
158         list_for_each_entry(c_fmt, &vvd->controls_fmt_list,
159                             controls_list_entry) {
160                 switch (c_fmt->format) {
161                 case V4L2_PIX_FMT_H264:
162                         if (c_fmt->profile)
163                                 v4l2_ctrl_new_std_menu
164                                         (&stream->ctrl_handler,
165                                          &virtio_video_enc_ctrl_ops,
166                                          V4L2_CID_MPEG_VIDEO_H264_PROFILE,
167                                          c_fmt->profile->max,
168                                          c_fmt->profile->skip_mask,
169                                          c_fmt->profile->min);
170
171                         if (c_fmt->level)
172                                 v4l2_ctrl_new_std_menu
173                                         (&stream->ctrl_handler,
174                                          &virtio_video_enc_ctrl_ops,
175                                          V4L2_CID_MPEG_VIDEO_H264_LEVEL,
176                                          c_fmt->level->max,
177                                          c_fmt->level->skip_mask,
178                                          c_fmt->level->min);
179                         break;
180                 default:
181                         v4l2_dbg(1, vvd->debug,
182                                  &vvd->v4l2_dev, "unsupported format\n");
183                         break;
184                 }
185         }
186
187         if (stream->control.bitrate) {
188                 v4l2_ctrl_new_std(&stream->ctrl_handler,
189                                   &virtio_video_enc_ctrl_ops,
190                                   V4L2_CID_MPEG_VIDEO_BITRATE,
191                                   1, S32_MAX,
192                                   1, stream->control.bitrate);
193         }
194
195         if (stream->ctrl_handler.error)
196                 return stream->ctrl_handler.error;
197
198         v4l2_ctrl_handler_setup(&stream->ctrl_handler);
199
200         return 0;
201 }
202
203 int virtio_video_enc_init_queues(void *priv, struct vb2_queue *src_vq,
204                                  struct vb2_queue *dst_vq)
205 {
206         int ret;
207         struct virtio_video_stream *stream = priv;
208         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
209         struct device *dev = vvd->v4l2_dev.dev;
210
211         src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
212         src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
213         src_vq->drv_priv = stream;
214         src_vq->buf_struct_size = sizeof(struct virtio_video_buffer);
215         src_vq->ops = &virtio_video_enc_qops;
216         src_vq->mem_ops = virtio_video_mem_ops(vvd);
217         src_vq->min_buffers_needed = stream->in_info.min_buffers;
218         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
219         src_vq->lock = &stream->vq_mutex;
220         src_vq->gfp_flags = virtio_video_gfp_flags(vvd);
221         src_vq->dev = dev;
222
223         ret = vb2_queue_init(src_vq);
224         if (ret)
225                 return ret;
226
227         dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
228         dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
229         dst_vq->drv_priv = stream;
230         dst_vq->buf_struct_size = sizeof(struct virtio_video_buffer);
231         dst_vq->ops = &virtio_video_enc_qops;
232         dst_vq->mem_ops = virtio_video_mem_ops(vvd);
233         dst_vq->min_buffers_needed = stream->out_info.min_buffers;
234         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
235         dst_vq->lock = &stream->vq_mutex;
236         dst_vq->gfp_flags = virtio_video_gfp_flags(vvd);
237         dst_vq->dev = dev;
238
239         return vb2_queue_init(dst_vq);
240 }
241
242 static int virtio_video_try_encoder_cmd(struct file *file, void *fh,
243                                         struct v4l2_encoder_cmd *cmd)
244 {
245         struct virtio_video_stream *stream = file2stream(file);
246         struct virtio_video_device *vvd = video_drvdata(file);
247
248         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
249                 return -EIO;
250
251         if (virtio_video_state(stream) == STREAM_STATE_DRAIN)
252                 return -EBUSY;
253
254         switch (cmd->cmd) {
255         case V4L2_ENC_CMD_STOP:
256         case V4L2_ENC_CMD_START:
257                 if (cmd->flags != 0) {
258                         v4l2_err(&vvd->v4l2_dev, "flags=%u are not supported",
259                                  cmd->flags);
260                         return -EINVAL;
261                 }
262                 break;
263         default:
264                 return -EINVAL;
265         }
266
267         return 0;
268 }
269
270 static int virtio_video_encoder_cmd(struct file *file, void *fh,
271                                     struct v4l2_encoder_cmd *cmd)
272 {
273         int ret;
274         struct vb2_queue *src_vq, *dst_vq;
275         struct virtio_video_stream *stream = file2stream(file);
276         struct virtio_video_device *vvd = video_drvdata(file);
277
278         ret = virtio_video_try_encoder_cmd(file, fh, cmd);
279         if (ret < 0)
280                 return ret;
281
282         dst_vq = v4l2_m2m_get_vq(stream->fh.m2m_ctx,
283                                  V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
284
285         switch (cmd->cmd) {
286         case V4L2_ENC_CMD_START:
287                 vb2_clear_last_buffer_dequeued(dst_vq);
288                 virtio_video_state_update(stream, STREAM_STATE_RUNNING);
289                 break;
290         case V4L2_ENC_CMD_STOP:
291                 src_vq = v4l2_m2m_get_vq(stream->fh.m2m_ctx,
292                                          V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
293
294                 if (!vb2_is_streaming(src_vq)) {
295                         v4l2_dbg(1, vvd->debug,
296                                  &vvd->v4l2_dev, "output is not streaming\n");
297                         return 0;
298                 }
299
300                 if (!vb2_is_streaming(dst_vq)) {
301                         v4l2_dbg(1, vvd->debug,
302                                  &vvd->v4l2_dev, "capture is not streaming\n");
303                         return 0;
304                 }
305
306                 ret = virtio_video_cmd_stream_drain(vvd, stream->stream_id);
307                 if (ret) {
308                         v4l2_err(&vvd->v4l2_dev, "failed to drain stream\n");
309                         return ret;
310                 }
311
312                 virtio_video_state_update(stream, STREAM_STATE_DRAIN);
313                 break;
314         default:
315                 return -EINVAL;
316         }
317
318         return 0;
319 }
320
321 static int virtio_video_enc_enum_fmt_vid_cap(struct file *file, void *fh,
322                                              struct v4l2_fmtdesc *f)
323 {
324         struct virtio_video_stream *stream = file2stream(file);
325         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
326         struct video_format *fmt;
327         int idx = 0;
328
329         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
330                 return -EIO;
331
332         if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
333                 return -EINVAL;
334
335         if (f->index >= vvd->num_output_fmts)
336                 return -EINVAL;
337
338         list_for_each_entry(fmt, &vvd->output_fmt_list, formats_list_entry) {
339                 if (f->index == idx) {
340                         f->pixelformat = fmt->desc.format;
341                         return 0;
342                 }
343                 idx++;
344         }
345         return -EINVAL;
346 }
347
348 static int virtio_video_enc_enum_fmt_vid_out(struct file *file, void *fh,
349                                              struct v4l2_fmtdesc *f)
350 {
351         struct virtio_video_stream *stream = file2stream(file);
352         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
353         struct video_format_info *info = NULL;
354         struct video_format *fmt = NULL;
355         unsigned long output_mask = 0;
356         int idx = 0, bit_num = 0;
357
358         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
359                 return -EIO;
360
361         if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
362                 return -EINVAL;
363
364         if (f->index >= vvd->num_input_fmts)
365                 return -EINVAL;
366
367         info = &stream->out_info;
368         list_for_each_entry(fmt, &vvd->output_fmt_list, formats_list_entry) {
369                 if (info->fourcc_format == fmt->desc.format) {
370                         output_mask = fmt->desc.mask;
371                         break;
372                 }
373         }
374
375         if (output_mask == 0)
376                 return -EINVAL;
377
378         list_for_each_entry(fmt, &vvd->input_fmt_list, formats_list_entry) {
379                 if (test_bit(bit_num, &output_mask)) {
380                         if (f->index == idx) {
381                                 f->pixelformat = fmt->desc.format;
382                                 return 0;
383                         }
384                         idx++;
385                 }
386                 bit_num++;
387         }
388         return -EINVAL;
389 }
390
391 static int virtio_video_enc_s_fmt(struct file *file, void *fh,
392                                   struct v4l2_format *f)
393 {
394         int ret;
395         struct virtio_video_stream *stream = file2stream(file);
396
397         ret = virtio_video_s_fmt(file, fh, f);
398         if (ret)
399                 return ret;
400
401         if (!V4L2_TYPE_IS_OUTPUT(f->type)) {
402                 if (virtio_video_state(stream) == STREAM_STATE_IDLE)
403                         virtio_video_state_update(stream, STREAM_STATE_INIT);
404         }
405
406         return 0;
407 }
408
409 static int virtio_video_enc_try_framerate(struct virtio_video_stream *stream,
410                                           unsigned int fps)
411 {
412         int rate_idx;
413         struct video_format_frame *frame = NULL;
414
415         if (stream->current_frame == NULL)
416                 return -EINVAL;
417
418         frame = stream->current_frame;
419         for (rate_idx = 0; rate_idx < frame->frame.num_rates; rate_idx++) {
420                 struct virtio_video_format_range *frame_rate =
421                         &frame->frame_rates[rate_idx];
422
423                 if (within_range(frame_rate->min, fps, frame_rate->max))
424                         return 0;
425         }
426
427         return -EINVAL;
428 }
429
430 static void virtio_video_timeperframe_from_info(struct video_format_info *info,
431                                                 struct v4l2_fract *timeperframe)
432 {
433         timeperframe->numerator = 1;
434         timeperframe->denominator = info->frame_rate;
435 }
436
437 static int virtio_video_enc_g_parm(struct file *file, void *priv,
438                                    struct v4l2_streamparm *a)
439 {
440         struct virtio_video_stream *stream = file2stream(file);
441         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
442         struct v4l2_outputparm *out = &a->parm.output;
443         struct v4l2_fract *timeperframe = &out->timeperframe;
444
445         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
446                 return -EIO;
447
448         if (!V4L2_TYPE_IS_OUTPUT(a->type)) {
449                 v4l2_err(&vvd->v4l2_dev,
450                          "getting FPS is only possible for the output queue\n");
451                 return -EINVAL;
452         }
453
454         out->capability = V4L2_CAP_TIMEPERFRAME;
455         virtio_video_timeperframe_from_info(&stream->in_info, timeperframe);
456
457         return 0;
458 }
459
460 static int virtio_video_enc_s_parm(struct file *file, void *priv,
461                                    struct v4l2_streamparm *a)
462 {
463         int ret;
464         u64 frame_interval, frame_rate;
465         struct video_format_info info;
466         struct virtio_video_stream *stream = file2stream(file);
467         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
468         struct v4l2_outputparm *out = &a->parm.output;
469         struct v4l2_fract *timeperframe = &out->timeperframe;
470
471         if (virtio_video_state(stream) == STREAM_STATE_ERROR)
472                 return -EIO;
473
474         if (V4L2_TYPE_IS_OUTPUT(a->type)) {
475                 frame_interval = timeperframe->numerator * (u64)USEC_PER_SEC;
476                 do_div(frame_interval, timeperframe->denominator);
477                 if (!frame_interval)
478                         return -EINVAL;
479
480                 frame_rate = (u64)USEC_PER_SEC;
481                 do_div(frame_rate, frame_interval);
482         } else {
483                 v4l2_err(&vvd->v4l2_dev,
484                          "setting FPS is only possible for the output queue\n");
485                 return -EINVAL;
486         }
487
488         ret = virtio_video_enc_try_framerate(stream, frame_rate);
489         if (ret)
490                 return ret;
491
492         virtio_video_format_fill_default_info(&info, &stream->in_info);
493         info.frame_rate = frame_rate;
494
495         virtio_video_cmd_set_params(vvd, stream, &info,
496                                     VIRTIO_VIDEO_QUEUE_TYPE_INPUT);
497         virtio_video_stream_get_params(vvd, stream);
498
499         out->capability = V4L2_CAP_TIMEPERFRAME;
500         virtio_video_timeperframe_from_info(&stream->in_info, timeperframe);
501
502         return 0;
503 }
504
505 static int virtio_video_enc_s_selection(struct file *file, void *fh,
506                                         struct v4l2_selection *sel)
507 {
508         struct virtio_video_stream *stream = file2stream(file);
509         struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
510         int ret;
511
512         if (!V4L2_TYPE_IS_OUTPUT(sel->type))
513                 return -EINVAL;
514
515         switch (sel->target) {
516         case V4L2_SEL_TGT_CROP:
517                 stream->in_info.crop.top = sel->r.top;
518                 stream->in_info.crop.left = sel->r.left;
519                 stream->in_info.crop.width = sel->r.width;
520                 stream->in_info.crop.height = sel->r.height;
521                 break;
522         default:
523                 return -EINVAL;
524         }
525
526         ret = virtio_video_cmd_set_params(vvd, stream,  &stream->in_info,
527                                           VIRTIO_VIDEO_QUEUE_TYPE_INPUT);
528         if (ret)
529                 return -EINVAL;
530
531         return virtio_video_cmd_get_params(vvd, stream,
532                                            VIRTIO_VIDEO_QUEUE_TYPE_INPUT);
533 }
534
535 static const struct v4l2_ioctl_ops virtio_video_enc_ioctl_ops = {
536         .vidioc_querycap        = virtio_video_querycap,
537
538 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
539         .vidioc_enum_fmt_vid_cap        = virtio_video_enc_enum_fmt_vid_cap,
540         .vidioc_enum_fmt_vid_out        = virtio_video_enc_enum_fmt_vid_out,
541 #else
542         .vidioc_enum_fmt_vid_cap_mplane = virtio_video_enc_enum_fmt_vid_cap,
543         .vidioc_enum_fmt_vid_out_mplane = virtio_video_enc_enum_fmt_vid_out,
544 #endif
545         .vidioc_g_fmt_vid_cap_mplane    = virtio_video_g_fmt,
546         .vidioc_s_fmt_vid_cap_mplane    = virtio_video_enc_s_fmt,
547
548         .vidioc_g_fmt_vid_out_mplane    = virtio_video_g_fmt,
549         .vidioc_s_fmt_vid_out_mplane    = virtio_video_enc_s_fmt,
550
551         .vidioc_try_encoder_cmd = virtio_video_try_encoder_cmd,
552         .vidioc_encoder_cmd     = virtio_video_encoder_cmd,
553         .vidioc_enum_frameintervals = virtio_video_enum_framemintervals,
554         .vidioc_enum_framesizes = virtio_video_enum_framesizes,
555
556         .vidioc_g_selection = virtio_video_g_selection,
557         .vidioc_s_selection = virtio_video_enc_s_selection,
558
559         .vidioc_reqbufs         = virtio_video_reqbufs,
560         .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
561         .vidioc_qbuf            = virtio_video_qbuf,
562         .vidioc_dqbuf           = virtio_video_dqbuf,
563         .vidioc_prepare_buf     = v4l2_m2m_ioctl_prepare_buf,
564         .vidioc_create_bufs     = v4l2_m2m_ioctl_create_bufs,
565         .vidioc_expbuf          = v4l2_m2m_ioctl_expbuf,
566
567         .vidioc_streamon        = v4l2_m2m_ioctl_streamon,
568         .vidioc_streamoff       = v4l2_m2m_ioctl_streamoff,
569
570         .vidioc_s_parm          = virtio_video_enc_s_parm,
571         .vidioc_g_parm          = virtio_video_enc_g_parm,
572
573         .vidioc_subscribe_event = virtio_video_subscribe_event,
574         .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
575 };
576
577 void *virtio_video_enc_get_fmt_list(struct virtio_video_device *vvd)
578 {
579         return &vvd->output_fmt_list;
580 }
581
582 static struct virtio_video_device_ops virtio_video_enc_ops = {
583         .init_ctrls = virtio_video_enc_init_ctrls,
584         .init_queues = virtio_video_enc_init_queues,
585         .get_fmt_list = virtio_video_enc_get_fmt_list,
586 };
587
588 int virtio_video_enc_init(struct virtio_video_device *vvd)
589 {
590         ssize_t num;
591         struct video_device *vd = &vvd->video_dev;
592
593         vd->ioctl_ops = &virtio_video_enc_ioctl_ops;
594         vvd->ops = &virtio_video_enc_ops;
595
596         num = strscpy(vd->name, "stateful-encoder", sizeof(vd->name));
597         if (num < 0)
598                 return num;
599
600         return 0;
601 }