ac487053a318bf56cc148c7b75e74f2baf7a02cf
[AGL/meta-agl-devel.git] / meta-egvirt / recipes-kernel / kernel-module-virtio-video / files / virtio_video_helpers.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /* Driver 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 "virtio_video.h"
21
22 struct virtio_video_convert_table {
23         uint32_t virtio_value;
24         uint32_t v4l2_value;
25 };
26
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 },
43         { 0 },
44 };
45
46 uint32_t virtio_video_level_to_v4l2(uint32_t level)
47 {
48         size_t idx;
49
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;
53         }
54
55         return 0;
56 }
57
58 uint32_t virtio_video_v4l2_level_to_virtio(uint32_t v4l2_level)
59 {
60         size_t idx;
61
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;
65         }
66
67         return 0;
68 }
69
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 },
91         { 0 },
92 };
93
94 uint32_t virtio_video_profile_to_v4l2(uint32_t profile)
95 {
96         size_t idx;
97
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;
101         }
102
103         return 0;
104 }
105
106 uint32_t virtio_video_v4l2_profile_to_virtio(uint32_t v4l2_profile)
107 {
108         size_t idx;
109
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;
113         }
114
115         return 0;
116 }
117
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 },
132         { 0 },
133 };
134
135 uint32_t virtio_video_format_to_v4l2(uint32_t format)
136 {
137         size_t idx;
138
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;
142         }
143
144         return 0;
145 }
146
147 uint32_t virtio_video_v4l2_format_to_virtio(uint32_t v4l2_format)
148 {
149         size_t idx;
150
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;
154         }
155
156         return 0;
157 }
158
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 },
163         { 0 },
164 };
165
166 uint32_t virtio_video_control_to_v4l2(uint32_t control)
167 {
168         size_t idx;
169
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;
173         }
174
175         return 0;
176 }
177
178 uint32_t virtio_video_v4l2_control_to_virtio(uint32_t v4l2_control)
179 {
180         size_t idx;
181
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;
185         }
186
187         return 0;
188 }
189
190 uint32_t virtio_video_get_format_from_virtio_profile(uint32_t virtio_profile)
191 {
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;
204
205         return 0;
206 }
207
208 struct video_format *virtio_video_find_video_format(struct list_head *fmts_list,
209                                                     uint32_t format)
210 {
211         struct video_format *fmt = NULL;
212
213         list_for_each_entry(fmt, fmts_list, formats_list_entry) {
214                 if (fmt->desc.format == format)
215                         return fmt;
216         }
217
218         return NULL;
219 }
220
221 void virtio_video_format_from_info(struct video_format_info *info,
222                                    struct v4l2_pix_format_mplane *pix_mp)
223 {
224         int i;
225
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));
236
237         pix_mp->num_planes = info->num_planes;
238         pix_mp->pixelformat = info->fourcc_format;
239
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;
245         }
246 }
247
248 void virtio_video_format_fill_default_info(struct video_format_info *dst_info,
249                                           struct video_format_info *src_info)
250 {
251         memcpy(dst_info, src_info, sizeof(*dst_info));
252 }
253
254 void virtio_video_pix_fmt_sp2mp(const struct v4l2_pix_format *pix,
255                                 struct v4l2_pix_format_mplane *pix_mp)
256 {
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;
272 }
273
274 void virtio_video_pix_fmt_mp2sp(const struct v4l2_pix_format_mplane *pix_mp,
275                                 struct v4l2_pix_format *pix)
276 {
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;
284         pix->priv = 0;
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;
289 }