• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include <glib.h>
28 
29 #ifdef G_OS_WIN32
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <io.h>
33 #include <fcntl.h>
34 #define pipe(fds) _pipe(fds,4096,O_BINARY)
35 #else
36 #include <unistd.h>
37 #endif
38 
39 #include <gio/gio.h>
40 #include <gst/check/gstcheck.h>
41 #include <gst/check/gstbufferstraw.h>
42 
43 #ifndef GST_DISABLE_PARSE
44 
45 /* this tests a gdp-serialized tag from audiotestsrc being sent only once
46  * to clients of multifdsink */
47 
48 static int n_tags = 0;
49 
50 static GstPadProbeReturn
tag_event_probe_cb(GstPad * pad,GstPadProbeInfo * info,gpointer user_data)51 tag_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
52 {
53   GMainLoop *loop = user_data;
54   GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
55 
56   switch (GST_EVENT_TYPE (event)) {
57     case GST_EVENT_TAG:
58     {
59       ++n_tags;
60       fail_if (n_tags > 1, "More than 1 tag received");
61       break;
62     }
63     case GST_EVENT_EOS:
64     {
65       g_main_loop_quit (loop);
66       break;
67     }
68     default:
69       break;
70   }
71 
72   return GST_PAD_PROBE_OK;
73 }
74 
GST_START_TEST(test_multifdsink_gdp_tag)75 GST_START_TEST (test_multifdsink_gdp_tag)
76 {
77   GstElement *p1, *p2;
78   GstElement *src, *sink, *depay;
79   GstPad *pad;
80   GMainLoop *loop;
81   int pfd[2];
82 
83   loop = g_main_loop_new (NULL, FALSE);
84 
85   p1 = gst_parse_launch ("audiotestsrc num-buffers=10 ! gdppay"
86       " ! multifdsink name=p1sink", NULL);
87   fail_if (p1 == NULL);
88   p2 = gst_parse_launch ("fdsrc name=p2src ! gdpdepay name=depay"
89       " ! fakesink name=p2sink signal-handoffs=True", NULL);
90   fail_if (p2 == NULL);
91 
92   fail_if (pipe (pfd) == -1);
93 
94   gst_element_set_state (p1, GST_STATE_READY);
95 
96   sink = gst_bin_get_by_name (GST_BIN (p1), "p1sink");
97   g_signal_emit_by_name (sink, "add", pfd[1], NULL);    ///s[1]
98   gst_object_unref (sink);
99 
100   src = gst_bin_get_by_name (GST_BIN (p2), "p2src");
101   g_object_set (G_OBJECT (src), "fd", pfd[0], NULL);
102   gst_object_unref (src);
103 
104   depay = gst_bin_get_by_name (GST_BIN (p2), "depay");
105   fail_if (depay == NULL);
106 
107   pad = gst_element_get_static_pad (depay, "src");
108   fail_unless (pad != NULL, "Could not get pad out of depay");
109   gst_object_unref (depay);
110 
111   gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
112       tag_event_probe_cb, loop, NULL);
113 
114   gst_element_set_state (p1, GST_STATE_PLAYING);
115   gst_element_set_state (p2, GST_STATE_PLAYING);
116 
117   g_main_loop_run (loop);
118 
119   assert_equals_int (n_tags, 1);
120 
121   gst_element_set_state (p1, GST_STATE_NULL);
122   gst_object_unref (p1);
123   gst_element_set_state (p2, GST_STATE_NULL);
124   gst_object_unref (p2);
125 }
126 
127 GST_END_TEST;
128 
129 #ifdef HAVE_VORBIS
130 /* this tests gdp-serialized Vorbis header pages being sent only once
131  * to clients of multifdsink; the gdp depayloader should deserialize
132  * exactly three in_caps buffers for the three header packets */
133 
134 static int n_in_caps = 0;
135 
136 static GstPadProbeReturn
buffer_probe_cb(GstPad * pad,GstPadProbeInfo * info,gpointer user_data)137 buffer_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
138 {
139   GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
140   GstMapInfo map;
141 
142   gst_buffer_map (buffer, &map, GST_MAP_READ);
143 
144   if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER)) {
145     GstCaps *caps;
146     GstStructure *s;
147     const GValue *sh;
148     GArray *buffers;
149     GstBuffer *buf;
150     int i;
151     gboolean found = FALSE;
152 
153     n_in_caps++;
154 
155     caps = gst_pad_get_current_caps (pad);
156     s = gst_caps_get_structure (caps, 0);
157     fail_unless (gst_structure_has_field (s, "streamheader"));
158     sh = gst_structure_get_value (s, "streamheader");
159     buffers = g_value_peek_pointer (sh);
160     assert_equals_int (buffers->len, 3);
161 
162     for (i = 0; i < 3; ++i) {
163       GValue *val;
164       GstMapInfo map2;
165 
166       val = &g_array_index (buffers, GValue, i);
167       buf = g_value_peek_pointer (val);
168       fail_unless (GST_IS_BUFFER (buf));
169 
170       gst_buffer_map (buf, &map2, GST_MAP_READ);
171       if (map2.size == map.size) {
172         if (memcmp (map2.data, map.data, map.size) == 0) {
173           found = TRUE;
174         }
175       }
176       gst_buffer_unmap (buf, &map2);
177     }
178     fail_unless (found, "Did not find incoming HEADER buffer %p on caps",
179         buffer);
180 
181     gst_caps_unref (caps);
182   }
183   gst_buffer_unmap (buffer, &map);
184 
185   return TRUE;
186 }
187 
GST_START_TEST(test_multifdsink_gdp_vorbisenc)188 GST_START_TEST (test_multifdsink_gdp_vorbisenc)
189 {
190   GstElement *p1, *p2;
191   GstElement *src, *sink, *depay;
192   GstPad *pad;
193   GMainLoop *loop;
194   int pfd[2];
195 
196   loop = g_main_loop_new (NULL, FALSE);
197 
198   p1 = gst_parse_launch ("audiotestsrc num-buffers=10 ! audioconvert "
199       " ! vorbisenc ! gdppay ! multifdsink name=p1sink", NULL);
200   fail_if (p1 == NULL);
201   p2 = gst_parse_launch ("fdsrc name=p2src ! gdpdepay name=depay"
202       " ! fakesink name=p2sink signal-handoffs=True", NULL);
203   fail_if (p2 == NULL);
204 
205   fail_if (pipe (pfd) == -1);
206 
207   gst_element_set_state (p1, GST_STATE_READY);
208 
209   sink = gst_bin_get_by_name (GST_BIN (p1), "p1sink");
210   g_signal_emit_by_name (sink, "add", pfd[1], NULL);
211   gst_object_unref (sink);
212 
213   src = gst_bin_get_by_name (GST_BIN (p2), "p2src");
214   g_object_set (G_OBJECT (src), "fd", pfd[0], NULL);
215   gst_object_unref (src);
216 
217   depay = gst_bin_get_by_name (GST_BIN (p2), "depay");
218   fail_if (depay == NULL);
219 
220   pad = gst_element_get_static_pad (depay, "src");
221   fail_unless (pad != NULL, "Could not get pad out of depay");
222   gst_object_unref (depay);
223 
224   gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
225       tag_event_probe_cb, loop, NULL);
226   gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, buffer_probe_cb, NULL,
227       NULL);
228 
229   gst_element_set_state (p1, GST_STATE_PLAYING);
230   gst_element_set_state (p2, GST_STATE_PLAYING);
231 
232   g_main_loop_run (loop);
233 
234   assert_equals_int (n_in_caps, 3);
235 
236   gst_element_set_state (p1, GST_STATE_NULL);
237   gst_object_unref (p1);
238   gst_element_set_state (p2, GST_STATE_NULL);
239   gst_object_unref (p2);
240 }
241 
242 GST_END_TEST;
243 #endif /* HAVE_VORBIS */
244 
245 #endif /* #ifndef GST_DISABLE_PARSE */
246 
247 static Suite *
streamheader_suite(void)248 streamheader_suite (void)
249 {
250   Suite *s = suite_create ("streamheader");
251   TCase *tc_chain = tcase_create ("general");
252 
253   suite_add_tcase (s, tc_chain);
254 #ifndef GST_DISABLE_PARSE
255   tcase_add_test (tc_chain, test_multifdsink_gdp_tag);
256 #ifdef HAVE_VORBIS
257   tcase_add_test (tc_chain, test_multifdsink_gdp_vorbisenc);
258 #endif
259 #endif
260 
261   return s;
262 }
263 
264 GST_CHECK_MAIN (streamheader);
265