1 // SPDX-License-Identifier: GPL-2.0+
2 /* Decoder for virtio video device.
4 * Copyright 2020 OpenSynergy GmbH.
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.
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.
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/>.
20 #include <linux/version.h>
21 #include <media/v4l2-event.h>
22 #include <media/v4l2-ioctl.h>
24 #include "virtio_video.h"
26 static int virtio_video_dec_start_streaming(struct vb2_queue *vq,
29 struct virtio_video_stream *stream = vb2_get_drv_priv(vq);
31 if (virtio_video_state(stream) == STREAM_STATE_ERROR)
34 if (!V4L2_TYPE_IS_OUTPUT(vq->type) &&
35 virtio_video_state(stream) >= STREAM_STATE_INIT)
36 virtio_video_state_update(stream, STREAM_STATE_RUNNING);
41 static void virtio_video_dec_stop_streaming(struct vb2_queue *vq)
44 struct virtio_video_stream *stream = vb2_get_drv_priv(vq);
46 if (V4L2_TYPE_IS_OUTPUT(vq->type))
47 queue_type = VIRTIO_VIDEO_QUEUE_TYPE_INPUT;
49 queue_type = VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT;
51 virtio_video_queue_release_buffers(stream, queue_type);
52 vb2_wait_for_all_buffers(vq);
55 static const struct vb2_ops virtio_video_dec_qops = {
56 .queue_setup = virtio_video_queue_setup,
57 .buf_init = virtio_video_buf_init,
58 .buf_cleanup = virtio_video_buf_cleanup,
59 .buf_queue = virtio_video_buf_queue,
60 .start_streaming = virtio_video_dec_start_streaming,
61 .stop_streaming = virtio_video_dec_stop_streaming,
62 .wait_prepare = vb2_ops_wait_prepare,
63 .wait_finish = vb2_ops_wait_finish,
66 static int virtio_video_dec_g_ctrl(struct v4l2_ctrl *ctrl)
69 struct virtio_video_stream *stream = ctrl2stream(ctrl);
71 if (virtio_video_state(stream) == STREAM_STATE_ERROR)
75 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
76 if (virtio_video_state(stream) >=
77 STREAM_STATE_DYNAMIC_RES_CHANGE)
78 ctrl->val = stream->out_info.min_buffers;
90 static const struct v4l2_ctrl_ops virtio_video_dec_ctrl_ops = {
91 .g_volatile_ctrl = virtio_video_dec_g_ctrl,
94 int virtio_video_dec_init_ctrls(struct virtio_video_stream *stream)
96 struct v4l2_ctrl *ctrl;
98 v4l2_ctrl_handler_init(&stream->ctrl_handler, 2);
100 ctrl = v4l2_ctrl_new_std(&stream->ctrl_handler,
101 &virtio_video_dec_ctrl_ops,
102 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
103 MIN_BUFS_MIN, MIN_BUFS_MAX, MIN_BUFS_STEP,
107 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
109 if (stream->ctrl_handler.error)
110 return stream->ctrl_handler.error;
112 (void)v4l2_ctrl_new_std(&stream->ctrl_handler, NULL,
113 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
114 MIN_BUFS_MIN, MIN_BUFS_MAX, MIN_BUFS_STEP,
115 stream->in_info.min_buffers);
117 if (stream->ctrl_handler.error)
118 return stream->ctrl_handler.error;
120 v4l2_ctrl_handler_setup(&stream->ctrl_handler);
125 int virtio_video_dec_init_queues(void *priv, struct vb2_queue *src_vq,
126 struct vb2_queue *dst_vq)
129 struct virtio_video_stream *stream = priv;
130 struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
131 struct device *dev = vvd->v4l2_dev.dev;
133 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
134 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
135 src_vq->drv_priv = stream;
136 src_vq->buf_struct_size = sizeof(struct virtio_video_buffer);
137 src_vq->ops = &virtio_video_dec_qops;
138 src_vq->mem_ops = virtio_video_mem_ops(vvd);
139 src_vq->min_buffers_needed = stream->in_info.min_buffers;
140 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
141 src_vq->lock = &stream->vq_mutex;
142 src_vq->gfp_flags = virtio_video_gfp_flags(vvd);
145 ret = vb2_queue_init(src_vq);
149 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
150 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
151 dst_vq->drv_priv = stream;
152 dst_vq->buf_struct_size = sizeof(struct virtio_video_buffer);
153 dst_vq->ops = &virtio_video_dec_qops;
154 dst_vq->mem_ops = virtio_video_mem_ops(vvd);
155 dst_vq->min_buffers_needed = stream->out_info.min_buffers;
156 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
157 dst_vq->lock = &stream->vq_mutex;
158 dst_vq->gfp_flags = virtio_video_gfp_flags(vvd);
161 return vb2_queue_init(dst_vq);
164 static int virtio_video_try_decoder_cmd(struct file *file, void *fh,
165 struct v4l2_decoder_cmd *cmd)
167 struct virtio_video_stream *stream = file2stream(file);
168 struct virtio_video_device *vvd = video_drvdata(file);
170 if (virtio_video_state(stream) == STREAM_STATE_ERROR)
173 if (virtio_video_state(stream) == STREAM_STATE_DRAIN)
177 case V4L2_DEC_CMD_STOP:
178 case V4L2_DEC_CMD_START:
179 if (cmd->flags != 0) {
180 v4l2_err(&vvd->v4l2_dev, "flags=%u are not supported",
192 static int virtio_video_decoder_cmd(struct file *file, void *fh,
193 struct v4l2_decoder_cmd *cmd)
196 struct vb2_queue *src_vq, *dst_vq;
197 struct virtio_video_stream *stream = file2stream(file);
198 struct virtio_video_device *vvd = video_drvdata(file);
200 ret = virtio_video_try_decoder_cmd(file, fh, cmd);
204 dst_vq = v4l2_m2m_get_vq(stream->fh.m2m_ctx,
205 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
208 case V4L2_DEC_CMD_START:
209 vb2_clear_last_buffer_dequeued(dst_vq);
211 case V4L2_DEC_CMD_STOP:
212 src_vq = v4l2_m2m_get_vq(stream->fh.m2m_ctx,
213 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
215 if (!vb2_is_streaming(src_vq)) {
216 v4l2_dbg(1, vvd->debug,
217 &vvd->v4l2_dev, "output is not streaming\n");
221 if (!vb2_is_streaming(dst_vq)) {
222 v4l2_dbg(1, vvd->debug,
223 &vvd->v4l2_dev, "capture is not streaming\n");
227 ret = virtio_video_cmd_stream_drain(vvd, stream->stream_id);
229 v4l2_err(&vvd->v4l2_dev, "failed to drain stream\n");
233 virtio_video_state_update(stream, STREAM_STATE_DRAIN);
242 static int virtio_video_dec_enum_fmt_vid_cap(struct file *file, void *fh,
243 struct v4l2_fmtdesc *f)
245 struct virtio_video_stream *stream = file2stream(file);
246 struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
247 struct video_format_info *info;
248 struct video_format *fmt;
249 unsigned long input_mask = 0;
250 int idx = 0, bit_num = 0;
252 if (virtio_video_state(stream) == STREAM_STATE_ERROR)
255 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
258 if (f->index >= vvd->num_output_fmts)
261 info = &stream->in_info;
262 list_for_each_entry(fmt, &vvd->input_fmt_list, formats_list_entry) {
263 if (info->fourcc_format == fmt->desc.format) {
264 input_mask = fmt->desc.mask;
272 list_for_each_entry(fmt, &vvd->output_fmt_list, formats_list_entry) {
273 if (test_bit(bit_num, &input_mask)) {
274 if (f->index == idx) {
275 f->pixelformat = fmt->desc.format;
286 int virtio_video_dec_enum_fmt_vid_out(struct file *file, void *fh,
287 struct v4l2_fmtdesc *f)
289 struct virtio_video_stream *stream = file2stream(file);
290 struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
291 struct video_format *fmt;
294 if (virtio_video_state(stream) == STREAM_STATE_ERROR)
297 if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
300 if (f->index >= vvd->num_input_fmts)
303 list_for_each_entry(fmt, &vvd->input_fmt_list, formats_list_entry) {
304 if (f->index == idx) {
305 f->pixelformat = fmt->desc.format;
313 static int virtio_video_dec_s_fmt(struct file *file, void *fh,
314 struct v4l2_format *f)
317 struct virtio_video_stream *stream = file2stream(file);
319 ret = virtio_video_s_fmt(file, fh, f);
323 if (V4L2_TYPE_IS_OUTPUT(f->type)) {
324 if (virtio_video_state(stream) == STREAM_STATE_IDLE)
325 virtio_video_state_update(stream, STREAM_STATE_INIT);
331 static int virtio_video_dec_s_selection(struct file *file, void *fh,
332 struct v4l2_selection *sel)
334 struct virtio_video_stream *stream = file2stream(file);
335 struct virtio_video_device *vvd = to_virtio_vd(stream->video_dev);
338 if (V4L2_TYPE_IS_OUTPUT(sel->type))
341 switch (sel->target) {
342 case V4L2_SEL_TGT_COMPOSE:
343 stream->out_info.crop.top = sel->r.top;
344 stream->out_info.crop.left = sel->r.left;
345 stream->out_info.crop.width = sel->r.width;
346 stream->out_info.crop.height = sel->r.height;
352 ret = virtio_video_cmd_set_params(vvd, stream, &stream->out_info,
353 VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT);
357 return virtio_video_cmd_get_params(vvd, stream,
358 VIRTIO_VIDEO_QUEUE_TYPE_OUTPUT);
361 static const struct v4l2_ioctl_ops virtio_video_dec_ioctl_ops = {
362 .vidioc_querycap = virtio_video_querycap,
364 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0))
365 .vidioc_enum_fmt_vid_cap = virtio_video_dec_enum_fmt_vid_cap,
366 .vidioc_enum_fmt_vid_out = virtio_video_dec_enum_fmt_vid_out,
368 .vidioc_enum_fmt_vid_cap_mplane = virtio_video_dec_enum_fmt_vid_cap,
369 .vidioc_enum_fmt_vid_out_mplane = virtio_video_dec_enum_fmt_vid_out,
371 .vidioc_g_fmt_vid_cap_mplane = virtio_video_g_fmt,
372 .vidioc_s_fmt_vid_cap_mplane = virtio_video_dec_s_fmt,
374 .vidioc_g_fmt_vid_out_mplane = virtio_video_g_fmt,
375 .vidioc_s_fmt_vid_out_mplane = virtio_video_dec_s_fmt,
377 .vidioc_g_selection = virtio_video_g_selection,
378 .vidioc_s_selection = virtio_video_dec_s_selection,
380 .vidioc_try_decoder_cmd = virtio_video_try_decoder_cmd,
381 .vidioc_decoder_cmd = virtio_video_decoder_cmd,
382 .vidioc_enum_frameintervals = virtio_video_enum_framemintervals,
383 .vidioc_enum_framesizes = virtio_video_enum_framesizes,
385 .vidioc_reqbufs = virtio_video_reqbufs,
386 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
387 .vidioc_qbuf = virtio_video_qbuf,
388 .vidioc_dqbuf = virtio_video_dqbuf,
389 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
390 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
391 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
393 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
394 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
396 .vidioc_subscribe_event = virtio_video_subscribe_event,
397 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
400 void *virtio_video_dec_get_fmt_list(struct virtio_video_device *vvd)
402 return &vvd->input_fmt_list;
405 static struct virtio_video_device_ops virtio_video_dec_ops = {
406 .init_ctrls = virtio_video_dec_init_ctrls,
407 .init_queues = virtio_video_dec_init_queues,
408 .get_fmt_list = virtio_video_dec_get_fmt_list,
411 int virtio_video_dec_init(struct virtio_video_device *vvd)
414 struct video_device *vd = &vvd->video_dev;
416 vd->ioctl_ops = &virtio_video_dec_ioctl_ops;
417 vvd->ops = &virtio_video_dec_ops;
419 num = strscpy(vd->name, "stateful-decoder", sizeof(vd->name));