|
1 /* GStreamer |
|
2 * |
|
3 * unit test for streamheader handling |
|
4 * |
|
5 * Copyright (C) 2007 Thomas Vander Stichele <thomas at apestaart dot org> |
|
6 * |
|
7 * This library is free software; you can redistribute it and/or |
|
8 * modify it under the terms of the GNU Library General Public |
|
9 * License as published by the Free Software Foundation; either |
|
10 * version 2 of the License, or (at your option) any later version. |
|
11 * |
|
12 * This library is distributed in the hope that it will be useful, |
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
15 * Library General Public License for more details. |
|
16 * |
|
17 * You should have received a copy of the GNU Library General Public |
|
18 * License along with this library; if not, write to the |
|
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
20 * Boston, MA 02111-1307, USA. |
|
21 */ |
|
22 |
|
23 #ifdef HAVE_CONFIG_H |
|
24 #include "config.h" |
|
25 #endif |
|
26 |
|
27 #include <unistd.h> |
|
28 |
|
29 #include <gst/check/gstcheck.h> |
|
30 #include <gst/check/gstbufferstraw.h> |
|
31 |
|
32 #ifndef GST_DISABLE_PARSE |
|
33 |
|
34 /* this tests a gdp-serialized tag from audiotestsrc being sent only once |
|
35 * to clients of multifdsink */ |
|
36 |
|
37 static int n_tags = 0; |
|
38 |
|
39 static gboolean |
|
40 tag_event_probe_cb (GstPad * pad, GstEvent * event, GMainLoop * loop) |
|
41 { |
|
42 switch (GST_EVENT_TYPE (event)) { |
|
43 case GST_EVENT_TAG: |
|
44 { |
|
45 ++n_tags; |
|
46 fail_if (n_tags > 1, "More than 1 tag received"); |
|
47 break; |
|
48 } |
|
49 case GST_EVENT_EOS: |
|
50 { |
|
51 g_main_loop_quit (loop); |
|
52 break; |
|
53 } |
|
54 default: |
|
55 break; |
|
56 } |
|
57 |
|
58 return TRUE; |
|
59 } |
|
60 |
|
61 GST_START_TEST (test_multifdsink_gdp_tag) |
|
62 { |
|
63 GstElement *p1, *p2; |
|
64 GstElement *src, *sink, *depay; |
|
65 GstPad *pad; |
|
66 GMainLoop *loop; |
|
67 int pfd[2]; |
|
68 |
|
69 loop = g_main_loop_new (NULL, FALSE); |
|
70 |
|
71 p1 = gst_parse_launch ("audiotestsrc num-buffers=10 ! gdppay" |
|
72 " ! multifdsink name=p1sink", NULL); |
|
73 fail_if (p1 == NULL); |
|
74 p2 = gst_parse_launch ("fdsrc name=p2src ! gdpdepay name=depay" |
|
75 " ! fakesink name=p2sink signal-handoffs=True", NULL); |
|
76 fail_if (p2 == NULL); |
|
77 |
|
78 fail_if (pipe (pfd) == -1); |
|
79 |
|
80 |
|
81 gst_element_set_state (p1, GST_STATE_READY); |
|
82 |
|
83 sink = gst_bin_get_by_name (GST_BIN (p1), "p1sink"); |
|
84 g_signal_emit_by_name (sink, "add", pfd[1], NULL); |
|
85 gst_object_unref (sink); |
|
86 |
|
87 src = gst_bin_get_by_name (GST_BIN (p2), "p2src"); |
|
88 g_object_set (G_OBJECT (src), "fd", pfd[0], NULL); |
|
89 gst_object_unref (src); |
|
90 |
|
91 depay = gst_bin_get_by_name (GST_BIN (p2), "depay"); |
|
92 fail_if (depay == NULL); |
|
93 |
|
94 pad = gst_element_get_pad (depay, "src"); |
|
95 fail_unless (pad != NULL, "Could not get pad out of depay"); |
|
96 gst_object_unref (depay); |
|
97 |
|
98 gst_pad_add_event_probe (pad, G_CALLBACK (tag_event_probe_cb), loop); |
|
99 |
|
100 gst_element_set_state (p1, GST_STATE_PLAYING); |
|
101 gst_element_set_state (p2, GST_STATE_PLAYING); |
|
102 |
|
103 g_main_loop_run (loop); |
|
104 |
|
105 assert_equals_int (n_tags, 1); |
|
106 } |
|
107 |
|
108 GST_END_TEST; |
|
109 |
|
110 /* this tests gdp-serialized Vorbis header pages being sent only once |
|
111 * to clients of multifdsink; the gdp depayloader should deserialize |
|
112 * exactly three in_caps buffers for the three header packets */ |
|
113 |
|
114 static int n_in_caps = 0; |
|
115 |
|
116 static gboolean |
|
117 buffer_probe_cb (GstPad * pad, GstBuffer * buffer) |
|
118 { |
|
119 if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_IN_CAPS)) { |
|
120 GstCaps *caps; |
|
121 GstStructure *s; |
|
122 const GValue *sh; |
|
123 GArray *buffers; |
|
124 GstBuffer *buf; |
|
125 int i; |
|
126 gboolean found = FALSE; |
|
127 |
|
128 n_in_caps++; |
|
129 |
|
130 caps = gst_buffer_get_caps (buffer); |
|
131 s = gst_caps_get_structure (caps, 0); |
|
132 fail_unless (gst_structure_has_field (s, "streamheader")); |
|
133 sh = gst_structure_get_value (s, "streamheader"); |
|
134 buffers = g_value_peek_pointer (sh); |
|
135 assert_equals_int (buffers->len, 3); |
|
136 |
|
137 |
|
138 for (i = 0; i < 3; ++i) { |
|
139 GValue *val; |
|
140 |
|
141 val = &g_array_index (buffers, GValue, i); |
|
142 buf = g_value_peek_pointer (val); |
|
143 fail_unless (GST_IS_BUFFER (buf)); |
|
144 if (GST_BUFFER_SIZE (buf) == GST_BUFFER_SIZE (buffer)) { |
|
145 if (memcmp (GST_BUFFER_DATA (buf), GST_BUFFER_DATA (buffer), |
|
146 GST_BUFFER_SIZE (buffer)) == 0) { |
|
147 found = TRUE; |
|
148 } |
|
149 } |
|
150 } |
|
151 fail_unless (found, "Did not find incoming IN_CAPS buffer %p on caps", |
|
152 buffer); |
|
153 } |
|
154 |
|
155 return TRUE; |
|
156 } |
|
157 |
|
158 GST_START_TEST (test_multifdsink_gdp_vorbisenc) |
|
159 { |
|
160 GstElement *p1, *p2; |
|
161 GstElement *src, *sink, *depay; |
|
162 GstPad *pad; |
|
163 GMainLoop *loop; |
|
164 int pfd[2]; |
|
165 |
|
166 loop = g_main_loop_new (NULL, FALSE); |
|
167 |
|
168 p1 = gst_parse_launch ("audiotestsrc num-buffers=10 ! audioconvert " |
|
169 " ! vorbisenc ! gdppay ! multifdsink name=p1sink", NULL); |
|
170 fail_if (p1 == NULL); |
|
171 p2 = gst_parse_launch ("fdsrc name=p2src ! gdpdepay name=depay" |
|
172 " ! fakesink name=p2sink signal-handoffs=True", NULL); |
|
173 fail_if (p2 == NULL); |
|
174 |
|
175 fail_if (pipe (pfd) == -1); |
|
176 |
|
177 |
|
178 gst_element_set_state (p1, GST_STATE_READY); |
|
179 |
|
180 sink = gst_bin_get_by_name (GST_BIN (p1), "p1sink"); |
|
181 g_signal_emit_by_name (sink, "add", pfd[1], NULL); |
|
182 gst_object_unref (sink); |
|
183 |
|
184 src = gst_bin_get_by_name (GST_BIN (p2), "p2src"); |
|
185 g_object_set (G_OBJECT (src), "fd", pfd[0], NULL); |
|
186 gst_object_unref (src); |
|
187 |
|
188 depay = gst_bin_get_by_name (GST_BIN (p2), "depay"); |
|
189 fail_if (depay == NULL); |
|
190 |
|
191 pad = gst_element_get_pad (depay, "src"); |
|
192 fail_unless (pad != NULL, "Could not get pad out of depay"); |
|
193 gst_object_unref (depay); |
|
194 |
|
195 gst_pad_add_event_probe (pad, G_CALLBACK (tag_event_probe_cb), loop); |
|
196 gst_pad_add_buffer_probe (pad, G_CALLBACK (buffer_probe_cb), NULL); |
|
197 |
|
198 gst_element_set_state (p1, GST_STATE_PLAYING); |
|
199 gst_element_set_state (p2, GST_STATE_PLAYING); |
|
200 |
|
201 g_main_loop_run (loop); |
|
202 |
|
203 assert_equals_int (n_in_caps, 3); |
|
204 } |
|
205 |
|
206 GST_END_TEST; |
|
207 |
|
208 |
|
209 #endif /* #ifndef GST_DISABLE_PARSE */ |
|
210 |
|
211 static Suite * |
|
212 streamheader_suite (void) |
|
213 { |
|
214 Suite *s = suite_create ("streamheader"); |
|
215 TCase *tc_chain = tcase_create ("general"); |
|
216 |
|
217 suite_add_tcase (s, tc_chain); |
|
218 #ifndef GST_DISABLE_PARSE |
|
219 tcase_add_test (tc_chain, test_multifdsink_gdp_tag); |
|
220 #ifdef HAVE_CPU_PPC64 |
|
221 g_print ("\n\n***** skipping test test_multifdsink_gdp_vorbisenc. May fail " |
|
222 "on PPC64 due to compiler bug. See bug #348114 for details\n\n\n"); |
|
223 if (0) /* this avoids the 'function not used' warning */ |
|
224 #endif |
|
225 tcase_add_test (tc_chain, test_multifdsink_gdp_vorbisenc); |
|
226 #endif |
|
227 |
|
228 return s; |
|
229 } |
|
230 |
|
231 int |
|
232 main (int argc, char **argv) |
|
233 { |
|
234 int nf; |
|
235 |
|
236 Suite *s = streamheader_suite (); |
|
237 SRunner *sr = srunner_create (s); |
|
238 |
|
239 gst_check_init (&argc, &argv); |
|
240 |
|
241 srunner_run_all (sr, CK_NORMAL); |
|
242 nf = srunner_ntests_failed (sr); |
|
243 srunner_free (sr); |
|
244 |
|
245 return nf; |
|
246 } |