• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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