1 /* GStreamer
2  * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23 
24 #include <gst/check/gstcheck.h>
25 
26 #include <gst/gl/gstglsl.h>
27 
28 #include <stdio.h>
29 
30 static void
setup(void)31 setup (void)
32 {
33 }
34 
35 static void
teardown(void)36 teardown (void)
37 {
38 }
39 
40 /* *INDENT-OFF* */
41 static const struct {GstGLSLVersion version; const gchar * name;} glsl_versions[] = {
42   {GST_GLSL_VERSION_100, "100"},
43   {GST_GLSL_VERSION_110, "110"},
44   {GST_GLSL_VERSION_120, "120"},
45   {GST_GLSL_VERSION_130, "130"},
46   {GST_GLSL_VERSION_140, "140"},
47   {GST_GLSL_VERSION_150, "150"},
48   {GST_GLSL_VERSION_300, "300"},
49   {GST_GLSL_VERSION_310, "310"},
50   {GST_GLSL_VERSION_320, "320"},
51   {GST_GLSL_VERSION_330, "330"},
52   {GST_GLSL_VERSION_400, "400"},
53   {GST_GLSL_VERSION_410, "410"},
54   {GST_GLSL_VERSION_420, "420"},
55   {GST_GLSL_VERSION_430, "430"},
56   {GST_GLSL_VERSION_440, "440"},
57   {GST_GLSL_VERSION_450, "450"},
58 };
59 
60 static const struct {GstGLSLProfile profile; const gchar * name;} glsl_profiles[] = {
61   {GST_GLSL_PROFILE_ES, "es"},
62   {GST_GLSL_PROFILE_CORE, "core"},
63   {GST_GLSL_PROFILE_COMPATIBILITY, "compatibility"},
64 };
65 
66 struct version_profile_s
67 {
68   GstGLSLVersion version;
69   GstGLSLProfile profile;
70   const gchar * name;
71 };
72 
73 static const struct version_profile_s glsl_version_profiles_valid[] = {
74   {GST_GLSL_VERSION_100, GST_GLSL_PROFILE_ES, "100"},
75   {GST_GLSL_VERSION_110, GST_GLSL_PROFILE_COMPATIBILITY, "110"},
76   {GST_GLSL_VERSION_120, GST_GLSL_PROFILE_COMPATIBILITY, "120"},
77   {GST_GLSL_VERSION_130, GST_GLSL_PROFILE_COMPATIBILITY, "130"},
78   {GST_GLSL_VERSION_140, GST_GLSL_PROFILE_COMPATIBILITY, "140"},
79   {GST_GLSL_VERSION_150, GST_GLSL_PROFILE_CORE, "150 core"},
80   {GST_GLSL_VERSION_150, GST_GLSL_PROFILE_COMPATIBILITY, "150 compatibility"},
81   {GST_GLSL_VERSION_300, GST_GLSL_PROFILE_ES, "300 es"},
82   {GST_GLSL_VERSION_310, GST_GLSL_PROFILE_ES, "310 es"},
83   {GST_GLSL_VERSION_320, GST_GLSL_PROFILE_ES, "320 es"},
84   {GST_GLSL_VERSION_330, GST_GLSL_PROFILE_CORE, "330 core"},
85   {GST_GLSL_VERSION_330, GST_GLSL_PROFILE_COMPATIBILITY, "330 compatibility"},
86   {GST_GLSL_VERSION_400, GST_GLSL_PROFILE_CORE, "400 core"},
87   {GST_GLSL_VERSION_400, GST_GLSL_PROFILE_COMPATIBILITY, "400 compatibility"},
88   {GST_GLSL_VERSION_410, GST_GLSL_PROFILE_CORE, "410 core"},
89   {GST_GLSL_VERSION_410, GST_GLSL_PROFILE_COMPATIBILITY, "410 compatibility"},
90   {GST_GLSL_VERSION_420, GST_GLSL_PROFILE_CORE, "420 core"},
91   {GST_GLSL_VERSION_420, GST_GLSL_PROFILE_COMPATIBILITY, "420 compatibility"},
92   {GST_GLSL_VERSION_430, GST_GLSL_PROFILE_CORE, "430 core"},
93   {GST_GLSL_VERSION_430, GST_GLSL_PROFILE_COMPATIBILITY, "430 compatibility"},
94   {GST_GLSL_VERSION_440, GST_GLSL_PROFILE_CORE, "440 core"},
95   {GST_GLSL_VERSION_440, GST_GLSL_PROFILE_COMPATIBILITY, "440 compatibility"},
96   {GST_GLSL_VERSION_450, GST_GLSL_PROFILE_CORE, "450 core"},
97   {GST_GLSL_VERSION_450, GST_GLSL_PROFILE_COMPATIBILITY, "450 compatibility"},
98 };
99 
100 /* combinations that produce different results between serializing/deserializing
101  * due to default values being imposed */
102 static const struct version_profile_s glsl_version_profiles_valid_serialize[] = {
103   {GST_GLSL_VERSION_100, GST_GLSL_PROFILE_NONE, "100"},
104   {GST_GLSL_VERSION_110, GST_GLSL_PROFILE_NONE, "110"},
105   {GST_GLSL_VERSION_120, GST_GLSL_PROFILE_NONE, "120"},
106   {GST_GLSL_VERSION_130, GST_GLSL_PROFILE_NONE, "130"},
107   {GST_GLSL_VERSION_140, GST_GLSL_PROFILE_NONE, "140"},
108   {GST_GLSL_VERSION_150, GST_GLSL_PROFILE_NONE, "150"},
109   {GST_GLSL_VERSION_330, GST_GLSL_PROFILE_NONE, "330"},
110   {GST_GLSL_VERSION_400, GST_GLSL_PROFILE_NONE, "400"},
111   {GST_GLSL_VERSION_410, GST_GLSL_PROFILE_NONE, "410"},
112   {GST_GLSL_VERSION_420, GST_GLSL_PROFILE_NONE, "420"},
113   {GST_GLSL_VERSION_430, GST_GLSL_PROFILE_NONE, "430"},
114   {GST_GLSL_VERSION_440, GST_GLSL_PROFILE_NONE, "440"},
115   {GST_GLSL_VERSION_450, GST_GLSL_PROFILE_NONE, "450"},
116 };
117 static const struct version_profile_s glsl_version_profiles_valid_deserialize[] = {
118   {GST_GLSL_VERSION_100, GST_GLSL_PROFILE_ES, "100"},
119   {GST_GLSL_VERSION_110, GST_GLSL_PROFILE_COMPATIBILITY, "110"},
120   {GST_GLSL_VERSION_120, GST_GLSL_PROFILE_COMPATIBILITY, "120"},
121   {GST_GLSL_VERSION_130, GST_GLSL_PROFILE_COMPATIBILITY, "130"},
122   {GST_GLSL_VERSION_140, GST_GLSL_PROFILE_COMPATIBILITY, "140"},
123   {GST_GLSL_VERSION_150, GST_GLSL_PROFILE_CORE, "150"},
124   {GST_GLSL_VERSION_330, GST_GLSL_PROFILE_CORE, "330"},
125   {GST_GLSL_VERSION_400, GST_GLSL_PROFILE_CORE, "400"},
126   {GST_GLSL_VERSION_410, GST_GLSL_PROFILE_CORE, "410"},
127   {GST_GLSL_VERSION_420, GST_GLSL_PROFILE_CORE, "420"},
128   {GST_GLSL_VERSION_430, GST_GLSL_PROFILE_CORE, "430"},
129   {GST_GLSL_VERSION_440, GST_GLSL_PROFILE_CORE, "440"},
130   {GST_GLSL_VERSION_450, GST_GLSL_PROFILE_CORE, "450"},
131 };
132 
133 static const gchar * invalid_deserialize_glsl[] = {
134   "",
135   " \t\r\n",
136   "ael dja",
137   "es",
138   "core",
139   "compatibility",
140   "1000",
141   "100 es",
142   "100 core",
143   "100 compatibility",
144   "150 es",
145   "300 core",
146   "300 compatibility",
147   "310 core",
148   "310 compatibility",
149   "320 core",
150   "320 compatibility",
151   "330 es",
152 };
153 
154 static const struct {GstGLSLVersion version; GstGLSLProfile profile;} invalid_serialize_glsl[] = {
155   {GST_GLSL_VERSION_100, GST_GLSL_PROFILE_CORE},
156   {GST_GLSL_VERSION_100, GST_GLSL_PROFILE_COMPATIBILITY},
157   {GST_GLSL_VERSION_110, GST_GLSL_PROFILE_ES},
158   {GST_GLSL_VERSION_110, GST_GLSL_PROFILE_CORE},
159   {GST_GLSL_VERSION_120, GST_GLSL_PROFILE_ES},
160   {GST_GLSL_VERSION_120, GST_GLSL_PROFILE_CORE},
161   {GST_GLSL_VERSION_130, GST_GLSL_PROFILE_ES},
162   {GST_GLSL_VERSION_130, GST_GLSL_PROFILE_CORE},
163   {GST_GLSL_VERSION_140, GST_GLSL_PROFILE_ES},
164   {GST_GLSL_VERSION_140, GST_GLSL_PROFILE_CORE},
165   {GST_GLSL_VERSION_150, GST_GLSL_PROFILE_ES},
166   {GST_GLSL_VERSION_300, GST_GLSL_PROFILE_NONE},
167   {GST_GLSL_VERSION_300, GST_GLSL_PROFILE_CORE},
168   {GST_GLSL_VERSION_300, GST_GLSL_PROFILE_COMPATIBILITY},
169   {GST_GLSL_VERSION_310, GST_GLSL_PROFILE_NONE},
170   {GST_GLSL_VERSION_310, GST_GLSL_PROFILE_CORE},
171   {GST_GLSL_VERSION_310, GST_GLSL_PROFILE_COMPATIBILITY},
172   {GST_GLSL_VERSION_320, GST_GLSL_PROFILE_NONE},
173   {GST_GLSL_VERSION_320, GST_GLSL_PROFILE_CORE},
174   {GST_GLSL_VERSION_320, GST_GLSL_PROFILE_COMPATIBILITY},
175   {GST_GLSL_VERSION_330, GST_GLSL_PROFILE_ES},
176   {GST_GLSL_VERSION_400, GST_GLSL_PROFILE_ES},
177   {GST_GLSL_VERSION_410, GST_GLSL_PROFILE_ES},
178   {GST_GLSL_VERSION_420, GST_GLSL_PROFILE_ES},
179   {GST_GLSL_VERSION_430, GST_GLSL_PROFILE_ES},
180   {GST_GLSL_VERSION_440, GST_GLSL_PROFILE_ES},
181   {GST_GLSL_VERSION_450, GST_GLSL_PROFILE_ES},
182 };
183 
184 static const struct {const gchar *name; gboolean succeed; GstGLSLVersion version; GstGLSLProfile profile;} glsl_str_map[] = {
185   {"//#version 100\n", FALSE, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE},
186   {"/*\n#version 100*/\n", FALSE, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE},
187   {"/*\r#version 100*/", FALSE, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE},
188   {"#\rversion 100", FALSE, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE},
189   {"#\nversion 100", FALSE, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE},
190   {"\t#version 100", FALSE, GST_GLSL_VERSION_NONE, GST_GLSL_PROFILE_NONE},
191   {"//\r#version 100", TRUE, GST_GLSL_VERSION_100, GST_GLSL_PROFILE_ES},
192   {"//\n#version 100", TRUE, GST_GLSL_VERSION_100, GST_GLSL_PROFILE_ES},
193   {"# \tversion 100", TRUE, GST_GLSL_VERSION_100, GST_GLSL_PROFILE_ES},
194   {"\n#version 100", TRUE, GST_GLSL_VERSION_100, GST_GLSL_PROFILE_ES},
195   {"\r#version 100", TRUE, GST_GLSL_VERSION_100, GST_GLSL_PROFILE_ES},
196 };
197 /* *INDENT-ON* */
198 
GST_START_TEST(test_serialization)199 GST_START_TEST (test_serialization)
200 {
201   gint i;
202 
203   /* versions */
204   for (i = 0; i < G_N_ELEMENTS (glsl_versions); i++) {
205     GstGLSLVersion version;
206     const gchar *version_s;
207 
208     version_s = gst_glsl_version_to_string (glsl_versions[i].version);
209     fail_unless (g_strcmp0 (version_s, glsl_versions[i].name) == 0, "%s != %s",
210         version_s, glsl_versions[i].name);
211     version = gst_glsl_version_from_string (glsl_versions[i].name);
212     fail_unless (version == glsl_versions[i].version, "%s != %s",
213         gst_glsl_version_to_string (glsl_versions[i].version),
214         gst_glsl_version_to_string (version));
215   }
216 
217   /* profiles */
218   for (i = 0; i < G_N_ELEMENTS (glsl_profiles); i++) {
219     GstGLSLProfile profile;
220     const gchar *profile_s;
221 
222     profile_s = gst_glsl_profile_to_string (glsl_profiles[i].profile);
223     fail_unless (g_strcmp0 (profile_s, glsl_profiles[i].name) == 0, "%s != %s",
224         profile_s, glsl_profiles[i].name);
225     profile = gst_glsl_profile_from_string (glsl_profiles[i].name);
226     fail_unless (profile == glsl_profiles[i].profile, "%s != %s",
227         gst_glsl_profile_to_string (glsl_profiles[i].profile),
228         gst_glsl_profile_to_string (profile));
229   }
230 
231   for (i = 0; i < G_N_ELEMENTS (glsl_version_profiles_valid); i++) {
232     gchar *version_profile_s;
233     GstGLSLVersion version;
234     GstGLSLProfile profile;
235 
236     version_profile_s =
237         gst_glsl_version_profile_to_string (glsl_version_profiles_valid
238         [i].version, glsl_version_profiles_valid[i].profile);
239     fail_unless (g_strcmp0 (version_profile_s,
240             glsl_version_profiles_valid[i].name) == 0, "%s != %s",
241         version_profile_s, glsl_version_profiles_valid[i].name);
242     fail_unless (gst_glsl_version_profile_from_string
243         (glsl_version_profiles_valid[i].name, &version, &profile),
244         "Failed to parse %s", glsl_version_profiles_valid[i].name);
245     fail_unless (profile == glsl_version_profiles_valid[i].profile
246         && version == glsl_version_profiles_valid[i].version, "%s != %s %s",
247         glsl_version_profiles_valid[i].name,
248         gst_glsl_version_to_string (version),
249         gst_glsl_profile_to_string (profile));
250     g_free (version_profile_s);
251   }
252 
253   for (i = 0; i < G_N_ELEMENTS (glsl_version_profiles_valid_serialize); i++) {
254     gchar *version_profile_s;
255 
256     version_profile_s =
257         gst_glsl_version_profile_to_string
258         (glsl_version_profiles_valid_serialize[i].version,
259         glsl_version_profiles_valid_serialize[i].profile);
260     fail_unless (g_strcmp0 (version_profile_s,
261             glsl_version_profiles_valid_serialize[i].name) == 0, "%s != %s",
262         version_profile_s, glsl_version_profiles_valid_serialize[i].name);
263     g_free (version_profile_s);
264   }
265 
266   for (i = 0; i < G_N_ELEMENTS (glsl_version_profiles_valid_deserialize); i++) {
267     GstGLSLVersion version;
268     GstGLSLProfile profile;
269 
270     fail_unless (gst_glsl_version_profile_from_string
271         (glsl_version_profiles_valid_deserialize[i].name, &version, &profile),
272         "Failed to parse %s", glsl_version_profiles_valid_deserialize[i].name);
273     fail_unless (profile == glsl_version_profiles_valid_deserialize[i].profile
274         && version == glsl_version_profiles_valid_deserialize[i].version,
275         "%s != %s %s", glsl_version_profiles_valid_deserialize[i].name,
276         gst_glsl_version_to_string (version),
277         gst_glsl_profile_to_string (profile));
278   }
279 
280   /* failures */
281   for (i = 0; i < G_N_ELEMENTS (invalid_deserialize_glsl); i++) {
282     GstGLSLVersion version;
283     GstGLSLProfile profile;
284 
285     fail_if (gst_glsl_version_profile_from_string (invalid_deserialize_glsl[i],
286             &version, &profile),
287         "successfully deserialized %s into %s %s (should have failed)",
288         invalid_deserialize_glsl[i], gst_glsl_version_to_string (version),
289         gst_glsl_profile_to_string (profile));
290   }
291 
292   /* failures */
293   for (i = 0; i < G_N_ELEMENTS (invalid_serialize_glsl); i++) {
294     gchar *version_profile_s;
295 
296     version_profile_s =
297         gst_glsl_version_profile_to_string (invalid_serialize_glsl[i].version,
298         invalid_serialize_glsl[i].profile);
299 
300     fail_if (version_profile_s != NULL,
301         "successfully serialized %s from %s %s (should have failed)",
302         version_profile_s,
303         gst_glsl_version_to_string (invalid_serialize_glsl[i].version),
304         gst_glsl_profile_to_string (invalid_serialize_glsl[i].profile));
305 
306     g_free (version_profile_s);
307   }
308 
309   /* map strings to version/profile */
310   for (i = 0; i < G_N_ELEMENTS (glsl_str_map); i++) {
311     GstGLSLVersion version;
312     GstGLSLProfile profile;
313 
314     fail_unless (glsl_str_map[i].succeed ==
315         gst_glsl_string_get_version_profile (glsl_str_map[i].name, &version,
316             &profile), "Incorrect result for parsing \'%s\': %s",
317         glsl_str_map[i].name, glsl_str_map[i].succeed ? "false" : "true");
318     if (glsl_str_map[i].succeed) {
319       fail_unless (version == glsl_str_map[i].version, "With %s: %s != %s",
320           glsl_str_map[i].name,
321           gst_glsl_version_to_string (glsl_str_map[i].version),
322           gst_glsl_version_to_string (version));
323       fail_unless (profile == glsl_str_map[i].profile, "With %s: %s != %s",
324           glsl_str_map[i].name,
325           gst_glsl_profile_to_string (glsl_str_map[i].profile),
326           gst_glsl_profile_to_string (profile));
327     }
328   }
329 
330   /* special ones */
331   {
332     GstGLSLVersion version;
333     GstGLSLProfile profile;
334     gchar *version_profile_s;
335 
336     version_profile_s =
337         gst_glsl_version_profile_to_string (GST_GLSL_VERSION_100,
338         GST_GLSL_PROFILE_ES);
339     fail_unless (g_strcmp0 (version_profile_s, "100") == 0, "%s != 100",
340         version_profile_s);
341     g_free (version_profile_s);
342 
343     version_profile_s =
344         gst_glsl_version_profile_to_string (GST_GLSL_VERSION_100,
345         GST_GLSL_PROFILE_NONE);
346     fail_unless (g_strcmp0 (version_profile_s, "100") == 0, "%s != 100",
347         version_profile_s);
348     g_free (version_profile_s);
349 
350     fail_unless (gst_glsl_version_profile_from_string ("100", &version,
351             &profile));
352     fail_unless (version == GST_GLSL_VERSION_100
353         && profile == GST_GLSL_PROFILE_ES, "100 != %s %s",
354         gst_glsl_version_to_string (version),
355         gst_glsl_profile_to_string (profile));
356   }
357 }
358 
359 GST_END_TEST;
360 
361 static Suite *
gst_gl_upload_suite(void)362 gst_gl_upload_suite (void)
363 {
364   Suite *s = suite_create ("GstGLSL");
365   TCase *tc_chain = tcase_create ("glsl");
366 
367   suite_add_tcase (s, tc_chain);
368   tcase_add_checked_fixture (tc_chain, setup, teardown);
369   tcase_add_test (tc_chain, test_serialization);
370 
371   return s;
372 }
373 
374 GST_CHECK_MAIN (gst_gl_upload);
375