1 /*
2 * Copyright (C) 2017 Collabora Inc.
3 * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "gstv4l2h264codec.h"
27
28 #include <gst/gst.h>
29 #include "ext/v4l2-controls.h"
30
31
32 static gint
v4l2_profile_from_string(const gchar * profile)33 v4l2_profile_from_string (const gchar * profile)
34 {
35 gint v4l2_profile = -1;
36
37 if (g_str_equal (profile, "baseline")) {
38 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
39 } else if (g_str_equal (profile, "constrained-baseline")) {
40 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
41 } else if (g_str_equal (profile, "main")) {
42 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
43 } else if (g_str_equal (profile, "extended")) {
44 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED;
45 } else if (g_str_equal (profile, "high")) {
46 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
47 } else if (g_str_equal (profile, "high-10")) {
48 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
49 } else if (g_str_equal (profile, "high-4:2:2")) {
50 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422;
51 } else if (g_str_equal (profile, "high-4:4:4")) {
52 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE;
53 } else if (g_str_equal (profile, "high-10-intra")) {
54 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA;
55 } else if (g_str_equal (profile, "high-4:2:2-intra")) {
56 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA;
57 } else if (g_str_equal (profile, "high-4:4:4-intra")) {
58 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA;
59 } else if (g_str_equal (profile, "cavlc-4:4:4-intra")) {
60 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA;
61 } else if (g_str_equal (profile, "scalable-baseline")) {
62 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE;
63 } else if (g_str_equal (profile, "scalable-high")) {
64 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH;
65 } else if (g_str_equal (profile, "scalable-high-intra")) {
66 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA;
67 } else if (g_str_equal (profile, "stereo-high")) {
68 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH;
69 } else if (g_str_equal (profile, "multiview-high")) {
70 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH;
71 } else if (g_str_equal (profile, "constrained-high")) {
72 v4l2_profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
73 } else {
74 GST_WARNING ("Unsupported profile string '%s'", profile);
75 }
76
77 return v4l2_profile;
78 }
79
80 static const gchar *
v4l2_profile_to_string(gint v4l2_profile)81 v4l2_profile_to_string (gint v4l2_profile)
82 {
83 switch (v4l2_profile) {
84 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
85 return "baseline";
86 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
87 return "constrained-baseline";
88 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
89 return "main";
90 case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
91 return "extended";
92 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
93 return "high";
94 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
95 return "high-10";
96 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
97 return "high-4:2:2";
98 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
99 return "high-4:4:4";
100 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
101 return "high-10-intra";
102 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
103 return "high-4:2:2-intra";
104 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
105 return "high-4:4:4-intra";
106 case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
107 return "cavlc-4:4:4-intra";
108 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
109 return "scalable-baseline";
110 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
111 return "scalable-high";
112 case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
113 return "scalable-high-intra";
114 case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
115 return "stereo-high";
116 case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
117 return "multiview-high";
118 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
119 return "constrained-high";
120 default:
121 GST_WARNING ("Unsupported V4L2 profile %i", v4l2_profile);
122 break;
123 }
124
125 return NULL;
126 }
127
128 static gint
v4l2_level_from_string(const gchar * level)129 v4l2_level_from_string (const gchar * level)
130 {
131 gint v4l2_level = -1;
132
133 if (g_str_equal (level, "1"))
134 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
135 else if (g_str_equal (level, "1b"))
136 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
137 else if (g_str_equal (level, "1.1"))
138 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
139 else if (g_str_equal (level, "1.2"))
140 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
141 else if (g_str_equal (level, "1.3"))
142 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
143 else if (g_str_equal (level, "2"))
144 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
145 else if (g_str_equal (level, "2.1"))
146 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
147 else if (g_str_equal (level, "2.2"))
148 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
149 else if (g_str_equal (level, "3"))
150 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
151 else if (g_str_equal (level, "3.1"))
152 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
153 else if (g_str_equal (level, "3.2"))
154 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
155 else if (g_str_equal (level, "4"))
156 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
157 else if (g_str_equal (level, "4.1"))
158 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
159 else if (g_str_equal (level, "4.2"))
160 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
161 else if (g_str_equal (level, "5"))
162 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
163 else if (g_str_equal (level, "5.1"))
164 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
165 else if (g_str_equal (level, "5.2"))
166 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
167 else if (g_str_equal (level, "6"))
168 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_6_0;
169 else if (g_str_equal (level, "6.1"))
170 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_6_1;
171 else if (g_str_equal (level, "6.2"))
172 v4l2_level = V4L2_MPEG_VIDEO_H264_LEVEL_6_2;
173 else
174 GST_WARNING ("Unsupported level '%s'", level);
175
176 return v4l2_level;
177 }
178
179 static const gchar *
v4l2_level_to_string(gint v4l2_level)180 v4l2_level_to_string (gint v4l2_level)
181 {
182 switch (v4l2_level) {
183 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
184 return "1";
185 case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
186 return "1b";
187 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
188 return "1.1";
189 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
190 return "1.2";
191 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
192 return "1.3";
193 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
194 return "2";
195 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
196 return "2.1";
197 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
198 return "2.2";
199 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
200 return "3";
201 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
202 return "3.1";
203 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
204 return "3.2";
205 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
206 return "4";
207 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
208 return "4.1";
209 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
210 return "4.2";
211 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
212 return "5";
213 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
214 return "5.1";
215 case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
216 return "5.2";
217 case V4L2_MPEG_VIDEO_H264_LEVEL_6_0:
218 return "6";
219 case V4L2_MPEG_VIDEO_H264_LEVEL_6_1:
220 return "6.1";
221 case V4L2_MPEG_VIDEO_H264_LEVEL_6_2:
222 return "6.2";
223 default:
224 GST_WARNING ("Unsupported V4L2 level %i", v4l2_level);
225 break;
226 }
227
228 return NULL;
229 }
230
231 const GstV4l2Codec *
gst_v4l2_h264_get_codec(void)232 gst_v4l2_h264_get_codec (void)
233 {
234 static GstV4l2Codec *codec = NULL;
235 if (g_once_init_enter (&codec)) {
236 static GstV4l2Codec c;
237 c.profile_cid = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
238 c.profile_to_string = v4l2_profile_to_string;
239 c.profile_from_string = v4l2_profile_from_string;
240 c.level_cid = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
241 c.level_to_string = v4l2_level_to_string;
242 c.level_from_string = v4l2_level_from_string;
243 g_once_init_leave (&codec, &c);
244 }
245 return codec;
246 }
247