1 // SPDX-License-Identifier: GPL-2.0+
2 /* Driver 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 "virtio_video.h"
22 struct virtio_video_convert_table {
23 uint32_t virtio_value;
27 static struct virtio_video_convert_table level_table[] = {
28 { VIRTIO_VIDEO_LEVEL_H264_1_0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0 },
29 { VIRTIO_VIDEO_LEVEL_H264_1_1, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 },
30 { VIRTIO_VIDEO_LEVEL_H264_1_2, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 },
31 { VIRTIO_VIDEO_LEVEL_H264_1_3, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 },
32 { VIRTIO_VIDEO_LEVEL_H264_2_0, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 },
33 { VIRTIO_VIDEO_LEVEL_H264_2_1, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 },
34 { VIRTIO_VIDEO_LEVEL_H264_2_2, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 },
35 { VIRTIO_VIDEO_LEVEL_H264_3_0, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 },
36 { VIRTIO_VIDEO_LEVEL_H264_3_1, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 },
37 { VIRTIO_VIDEO_LEVEL_H264_3_2, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 },
38 { VIRTIO_VIDEO_LEVEL_H264_4_0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 },
39 { VIRTIO_VIDEO_LEVEL_H264_4_1, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 },
40 { VIRTIO_VIDEO_LEVEL_H264_4_2, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 },
41 { VIRTIO_VIDEO_LEVEL_H264_5_0, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 },
42 { VIRTIO_VIDEO_LEVEL_H264_5_1, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
46 uint32_t virtio_video_level_to_v4l2(uint32_t level)
50 for (idx = 0; idx < ARRAY_SIZE(level_table); idx++) {
51 if (level_table[idx].virtio_value == level)
52 return level_table[idx].v4l2_value;
58 uint32_t virtio_video_v4l2_level_to_virtio(uint32_t v4l2_level)
62 for (idx = 0; idx < ARRAY_SIZE(level_table); idx++) {
63 if (level_table[idx].v4l2_value == v4l2_level)
64 return level_table[idx].virtio_value;
70 static struct virtio_video_convert_table profile_table[] = {
71 { VIRTIO_VIDEO_PROFILE_H264_BASELINE,
72 V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE },
73 { VIRTIO_VIDEO_PROFILE_H264_MAIN, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN },
74 { VIRTIO_VIDEO_PROFILE_H264_EXTENDED,
75 V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED },
76 { VIRTIO_VIDEO_PROFILE_H264_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH },
77 { VIRTIO_VIDEO_PROFILE_H264_HIGH10PROFILE,
78 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 },
79 { VIRTIO_VIDEO_PROFILE_H264_HIGH422PROFILE,
80 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422},
81 { VIRTIO_VIDEO_PROFILE_H264_HIGH444PREDICTIVEPROFILE,
82 V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE },
83 { VIRTIO_VIDEO_PROFILE_H264_SCALABLEBASELINE,
84 V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE },
85 { VIRTIO_VIDEO_PROFILE_H264_SCALABLEHIGH,
86 V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH },
87 { VIRTIO_VIDEO_PROFILE_H264_STEREOHIGH,
88 V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH },
89 { VIRTIO_VIDEO_PROFILE_H264_MULTIVIEWHIGH,
90 V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH },
94 uint32_t virtio_video_profile_to_v4l2(uint32_t profile)
98 for (idx = 0; idx < ARRAY_SIZE(profile_table); idx++) {
99 if (profile_table[idx].virtio_value == profile)
100 return profile_table[idx].v4l2_value;
106 uint32_t virtio_video_v4l2_profile_to_virtio(uint32_t v4l2_profile)
110 for (idx = 0; idx < ARRAY_SIZE(profile_table); idx++) {
111 if (profile_table[idx].v4l2_value == v4l2_profile)
112 return profile_table[idx].virtio_value;
118 static struct virtio_video_convert_table format_table[] = {
119 { VIRTIO_VIDEO_FORMAT_ARGB8888, V4L2_PIX_FMT_ARGB32 },
120 { VIRTIO_VIDEO_FORMAT_BGRA8888, V4L2_PIX_FMT_ABGR32 },
121 { VIRTIO_VIDEO_FORMAT_RGBA8888, V4L2_PIX_FMT_RGB32 },
122 { VIRTIO_VIDEO_FORMAT_NV12, V4L2_PIX_FMT_NV12 },
123 { VIRTIO_VIDEO_FORMAT_YUV420, V4L2_PIX_FMT_YUV420 },
124 { VIRTIO_VIDEO_FORMAT_YVU420, V4L2_PIX_FMT_YVU420 },
125 { VIRTIO_VIDEO_FORMAT_YUV422, V4L2_PIX_FMT_YUYV },
126 { VIRTIO_VIDEO_FORMAT_MPEG2, V4L2_PIX_FMT_MPEG2 },
127 { VIRTIO_VIDEO_FORMAT_MPEG4, V4L2_PIX_FMT_MPEG4 },
128 { VIRTIO_VIDEO_FORMAT_H264, V4L2_PIX_FMT_H264 },
129 { VIRTIO_VIDEO_FORMAT_HEVC, V4L2_PIX_FMT_HEVC },
130 { VIRTIO_VIDEO_FORMAT_VP8, V4L2_PIX_FMT_VP8 },
131 { VIRTIO_VIDEO_FORMAT_VP9, V4L2_PIX_FMT_VP9 },
135 uint32_t virtio_video_format_to_v4l2(uint32_t format)
139 for (idx = 0; idx < ARRAY_SIZE(format_table); idx++) {
140 if (format_table[idx].virtio_value == format)
141 return format_table[idx].v4l2_value;
147 uint32_t virtio_video_v4l2_format_to_virtio(uint32_t v4l2_format)
151 for (idx = 0; idx < ARRAY_SIZE(format_table); idx++) {
152 if (format_table[idx].v4l2_value == v4l2_format)
153 return format_table[idx].virtio_value;
159 static struct virtio_video_convert_table control_table[] = {
160 { VIRTIO_VIDEO_CONTROL_BITRATE, V4L2_CID_MPEG_VIDEO_BITRATE },
161 { VIRTIO_VIDEO_CONTROL_PROFILE, V4L2_CID_MPEG_VIDEO_H264_PROFILE },
162 { VIRTIO_VIDEO_CONTROL_LEVEL, V4L2_CID_MPEG_VIDEO_H264_LEVEL },
166 uint32_t virtio_video_control_to_v4l2(uint32_t control)
170 for (idx = 0; idx < ARRAY_SIZE(control_table); idx++) {
171 if (control_table[idx].virtio_value == control)
172 return control_table[idx].v4l2_value;
178 uint32_t virtio_video_v4l2_control_to_virtio(uint32_t v4l2_control)
182 for (idx = 0; idx < ARRAY_SIZE(control_table); idx++) {
183 if (control_table[idx].v4l2_value == v4l2_control)
184 return control_table[idx].virtio_value;
190 uint32_t virtio_video_get_format_from_virtio_profile(uint32_t virtio_profile)
192 if (virtio_profile >= VIRTIO_VIDEO_PROFILE_H264_MIN &&
193 virtio_profile <= VIRTIO_VIDEO_PROFILE_H264_MAX)
194 return VIRTIO_VIDEO_FORMAT_H264;
195 else if (virtio_profile >= VIRTIO_VIDEO_PROFILE_HEVC_MIN &&
196 virtio_profile <= VIRTIO_VIDEO_PROFILE_HEVC_MAX)
197 return VIRTIO_VIDEO_FORMAT_HEVC;
198 else if (virtio_profile >= VIRTIO_VIDEO_PROFILE_VP8_MIN &&
199 virtio_profile <= VIRTIO_VIDEO_PROFILE_VP8_MAX)
200 return VIRTIO_VIDEO_FORMAT_VP8;
201 else if (virtio_profile >= VIRTIO_VIDEO_PROFILE_VP9_MIN &&
202 virtio_profile <= VIRTIO_VIDEO_PROFILE_VP9_MAX)
203 return VIRTIO_VIDEO_FORMAT_VP9;
208 struct video_format *virtio_video_find_video_format(struct list_head *fmts_list,
211 struct video_format *fmt = NULL;
213 list_for_each_entry(fmt, fmts_list, formats_list_entry) {
214 if (fmt->desc.format == format)
221 void virtio_video_format_from_info(struct video_format_info *info,
222 struct v4l2_pix_format_mplane *pix_mp)
226 pix_mp->width = info->frame_width;
227 pix_mp->height = info->frame_height;
228 pix_mp->field = V4L2_FIELD_NONE;
229 pix_mp->colorspace = V4L2_COLORSPACE_REC709;
230 pix_mp->xfer_func = 0;
231 pix_mp->ycbcr_enc = 0;
232 pix_mp->quantization = 0;
233 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
234 memset(pix_mp->plane_fmt[0].reserved, 0,
235 sizeof(pix_mp->plane_fmt[0].reserved));
237 pix_mp->num_planes = info->num_planes;
238 pix_mp->pixelformat = info->fourcc_format;
240 for (i = 0; i < info->num_planes; i++) {
241 pix_mp->plane_fmt[i].bytesperline =
242 info->plane_format[i].stride;
243 pix_mp->plane_fmt[i].sizeimage =
244 info->plane_format[i].plane_size;
248 void virtio_video_format_fill_default_info(struct video_format_info *dst_info,
249 struct video_format_info *src_info)
251 memcpy(dst_info, src_info, sizeof(*dst_info));
254 void virtio_video_pix_fmt_sp2mp(const struct v4l2_pix_format *pix,
255 struct v4l2_pix_format_mplane *pix_mp)
257 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
258 memset(&pix_mp->plane_fmt[0].reserved, 0,
259 sizeof(pix_mp->plane_fmt[0].reserved));
260 pix_mp->num_planes = 1;
261 pix_mp->width = pix->width;
262 pix_mp->height = pix->height;
263 pix_mp->pixelformat = pix->pixelformat;
264 pix_mp->field = pix->field;
265 pix_mp->plane_fmt[0].bytesperline = pix->bytesperline;
266 pix_mp->plane_fmt[0].sizeimage = pix->sizeimage;
267 pix_mp->colorspace = pix->colorspace;
268 pix_mp->flags = pix->flags;
269 pix_mp->ycbcr_enc = pix->ycbcr_enc;
270 pix_mp->quantization = pix->quantization;
271 pix_mp->xfer_func = pix->xfer_func;
274 void virtio_video_pix_fmt_mp2sp(const struct v4l2_pix_format_mplane *pix_mp,
275 struct v4l2_pix_format *pix)
277 pix->width = pix_mp->width;
278 pix->height = pix_mp->height;
279 pix->pixelformat = pix_mp->pixelformat;
280 pix->field = pix_mp->field;
281 pix->bytesperline = pix_mp->plane_fmt[0].bytesperline;
282 pix->sizeimage = pix_mp->plane_fmt[0].sizeimage;
283 pix->colorspace = pix_mp->colorspace;
285 pix->flags = pix_mp->flags;
286 pix->ycbcr_enc = pix_mp->ycbcr_enc;
287 pix->quantization = pix_mp->quantization;
288 pix->xfer_func = pix_mp->xfer_func;