1 /* GStreamer
2 * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.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 #include <gst/check/gstcheck.h>
21
22 static gboolean
bus_cb(GstBus * bus,GstMessage * message,gpointer data)23 bus_cb (GstBus * bus, GstMessage * message, gpointer data)
24 {
25 GMainLoop *loop = (GMainLoop *) data;
26 switch (GST_MESSAGE_TYPE (message)) {
27 case GST_MESSAGE_ERROR:{
28 GError *err = NULL;
29 gchar *debug = NULL;
30
31 gst_message_parse_error (message, &err, &debug);
32
33 GST_ERROR ("Error: %s : %s", err->message, debug);
34 g_error_free (err);
35 g_free (debug);
36
37 fail_if (TRUE, "failed");
38 g_main_loop_quit (loop);
39 }
40 break;
41 case GST_MESSAGE_EOS:
42 g_main_loop_quit (loop);
43 break;
44 default:
45 break;
46 }
47 return TRUE;
48 }
49
50 static void
run_convert_pipelne(const gchar * in_format,const gchar * out_format)51 run_convert_pipelne (const gchar * in_format, const gchar * out_format)
52 {
53 GstBus *bus;
54 GMainLoop *loop = g_main_loop_new (NULL, FALSE);
55 gchar *pipeline_str =
56 g_strdup_printf ("videotestsrc num-buffers=1 is-live=true ! "
57 "video/x-raw,format=%s,framerate=3/1 ! cudaupload ! "
58 "cudaconvert ! cudadownload ! video/x-raw,format=%s ! "
59 "videoconvert ! autovideosink", in_format, out_format);
60 GstElement *pipeline;
61
62 pipeline = gst_parse_launch (pipeline_str, NULL);
63 fail_unless (pipeline != NULL);
64 g_free (pipeline_str);
65
66 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
67 gst_bus_add_watch (bus, (GstBusFunc) bus_cb, loop);
68
69 gst_element_set_state (pipeline, GST_STATE_PLAYING);
70 g_main_loop_run (loop);
71 gst_element_set_state (pipeline, GST_STATE_NULL);
72
73 gst_bus_remove_watch (bus);
74 gst_object_unref (bus);
75 gst_object_unref (pipeline);
76 g_main_loop_unref (loop);
77 }
78
GST_START_TEST(test_convert_yuv_yuv)79 GST_START_TEST (test_convert_yuv_yuv)
80 {
81 const gchar *format_list[] = {
82 "I420", "YV12", "NV12", "NV21", "P010_10LE", "I420_10LE",
83 "Y444", "Y444_16LE",
84 };
85
86 gint i, j;
87
88 for (i = 0; i < G_N_ELEMENTS (format_list); i++) {
89 for (j = 0; j < G_N_ELEMENTS (format_list); j++) {
90 if (i == j)
91 continue;
92
93 GST_DEBUG ("run conversion %s to %s", format_list[i], format_list[j]);
94 run_convert_pipelne (format_list[i], format_list[j]);
95 }
96 }
97 }
98
99 GST_END_TEST;
100
GST_START_TEST(test_convert_yuv_rgb)101 GST_START_TEST (test_convert_yuv_rgb)
102 {
103 const gchar *in_format_list[] = {
104 "I420", "YV12", "NV12", "NV21", "P010_10LE", "I420_10LE",
105 "Y444", "Y444_16LE",
106 };
107 const gchar *out_format_list[] = {
108 "BGRA", "RGBA", "RGBx", "BGRx", "ARGB", "ABGR", "RGB", "BGR", "BGR10A2_LE",
109 "RGB10A2_LE",
110 };
111
112 gint i, j;
113
114 for (i = 0; i < G_N_ELEMENTS (in_format_list); i++) {
115 for (j = 0; j < G_N_ELEMENTS (out_format_list); j++) {
116 GST_DEBUG ("run conversion %s to %s", in_format_list[i],
117 out_format_list[j]);
118 run_convert_pipelne (in_format_list[i], out_format_list[j]);
119 }
120 }
121 }
122
123 GST_END_TEST;
124
GST_START_TEST(test_convert_rgb_yuv)125 GST_START_TEST (test_convert_rgb_yuv)
126 {
127 const gchar *in_format_list[] = {
128 "BGRA", "RGBA", "RGBx", "BGRx", "ARGB", "ABGR", "RGB", "BGR", "BGR10A2_LE",
129 "RGB10A2_LE",
130 };
131 const gchar *out_format_list[] = {
132 "I420", "YV12", "NV12", "NV21", "P010_10LE", "I420_10LE",
133 "Y444", "Y444_16LE",
134 };
135
136 gint i, j;
137
138 for (i = 0; i < G_N_ELEMENTS (in_format_list); i++) {
139 for (j = 0; j < G_N_ELEMENTS (out_format_list); j++) {
140 GST_DEBUG ("run conversion %s to %s", in_format_list[i],
141 out_format_list[j]);
142 run_convert_pipelne (in_format_list[i], out_format_list[j]);
143 }
144 }
145 }
146
147 GST_END_TEST;
148
GST_START_TEST(test_convert_rgb_rgb)149 GST_START_TEST (test_convert_rgb_rgb)
150 {
151 const gchar *format_list[] = {
152 "BGRA", "RGBA", "RGBx", "BGRx", "ARGB", "ABGR", "RGB", "BGR", "BGR10A2_LE",
153 "RGB10A2_LE",
154 };
155
156 gint i, j;
157
158 for (i = 0; i < G_N_ELEMENTS (format_list); i++) {
159 for (j = 0; j < G_N_ELEMENTS (format_list); j++) {
160 if (i == j)
161 continue;
162
163 GST_DEBUG ("run conversion %s to %s", format_list[i], format_list[j]);
164 run_convert_pipelne (format_list[i], format_list[j]);
165 }
166 }
167 }
168
169 GST_END_TEST;
170
171 static gboolean
check_cuda_convert_available(void)172 check_cuda_convert_available (void)
173 {
174 gboolean ret = TRUE;
175 GstElement *upload;
176
177 upload = gst_element_factory_make ("cudaconvert", NULL);
178 if (!upload) {
179 GST_WARNING ("cudaconvert is not available, possibly driver load failure");
180 return FALSE;
181 }
182
183 gst_object_unref (upload);
184
185 return ret;
186 }
187
188 static Suite *
cudaconvert_suite(void)189 cudaconvert_suite (void)
190 {
191 Suite *s;
192 TCase *tc_chain;
193
194 /* HACK: cuda device init/deinit with fork seems to problematic */
195 g_setenv ("CK_FORK", "no", TRUE);
196
197 s = suite_create ("cudaconvert");
198 tc_chain = tcase_create ("general");
199
200 suite_add_tcase (s, tc_chain);
201
202 if (!check_cuda_convert_available ()) {
203 GST_DEBUG ("Skip cudaconvert test since cannot open device");
204 goto end;
205 }
206
207 tcase_add_test (tc_chain, test_convert_yuv_yuv);
208 tcase_add_test (tc_chain, test_convert_yuv_rgb);
209 tcase_add_test (tc_chain, test_convert_rgb_yuv);
210 tcase_add_test (tc_chain, test_convert_rgb_rgb);
211
212 end:
213 return s;
214 }
215
216 GST_CHECK_MAIN (cudaconvert);
217