1 /* GStreamer unit tests for the interleave element
2 * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
3 * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
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 /* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
22 * with newer GLib versions (>= 2.31.0) */
23 #define GLIB_DISABLE_DEPRECATION_WARNINGS
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_VALGRIND
30 # include <valgrind/valgrind.h>
31 #endif
32
33 #include <gst/check/gstcheck.h>
34 #include <gst/audio/audio.h>
35 #include <gst/audio/audio-enumtypes.h>
36
37 static void
gst_check_setup_events_interleave(GstPad * srcpad,GstElement * element,GstCaps * caps,GstFormat format,const gchar * stream_id)38 gst_check_setup_events_interleave (GstPad * srcpad, GstElement * element,
39 GstCaps * caps, GstFormat format, const gchar * stream_id)
40 {
41 GstSegment segment;
42
43 gst_segment_init (&segment, format);
44
45 fail_unless (gst_pad_push_event (srcpad,
46 gst_event_new_stream_start (stream_id)));
47 if (caps)
48 fail_unless (gst_pad_push_event (srcpad, gst_event_new_caps (caps)));
49 fail_unless (gst_pad_push_event (srcpad, gst_event_new_segment (&segment)));
50 }
51
GST_START_TEST(test_create_and_unref)52 GST_START_TEST (test_create_and_unref)
53 {
54 GstElement *interleave;
55
56 interleave = gst_element_factory_make ("interleave", NULL);
57 fail_unless (interleave != NULL);
58
59 gst_element_set_state (interleave, GST_STATE_NULL);
60 gst_object_unref (interleave);
61 }
62
63 GST_END_TEST;
64
GST_START_TEST(test_request_pads)65 GST_START_TEST (test_request_pads)
66 {
67 GstElement *interleave;
68 GstPad *pad1, *pad2;
69
70 interleave = gst_element_factory_make ("interleave", NULL);
71 fail_unless (interleave != NULL);
72
73 pad1 = gst_element_request_pad_simple (interleave, "sink_%u");
74 fail_unless (pad1 != NULL);
75 fail_unless_equals_string (GST_OBJECT_NAME (pad1), "sink_0");
76
77 pad2 = gst_element_request_pad_simple (interleave, "sink_%u");
78 fail_unless (pad2 != NULL);
79 fail_unless_equals_string (GST_OBJECT_NAME (pad2), "sink_1");
80
81 gst_element_release_request_pad (interleave, pad2);
82 gst_object_unref (pad2);
83 gst_element_release_request_pad (interleave, pad1);
84 gst_object_unref (pad1);
85
86 gst_element_set_state (interleave, GST_STATE_NULL);
87 gst_object_unref (interleave);
88 }
89
90 GST_END_TEST;
91
92 static GstPad **mysrcpads, *mysinkpad;
93 static GstBus *bus;
94 static GstElement *interleave;
95 static gint have_data;
96 static gfloat input[2];
97
98 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
99 GST_PAD_SINK,
100 GST_PAD_ALWAYS,
101 GST_STATIC_CAPS ("audio/x-raw, "
102 "format = (string) " GST_AUDIO_NE (F32) ", "
103 "channels = (int) 2, layout = (string) {interleaved, non-interleaved}, rate = (int) 48000"));
104
105 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
106 GST_PAD_SRC,
107 GST_PAD_ALWAYS,
108 GST_STATIC_CAPS ("audio/x-raw, "
109 "format = (string) " GST_AUDIO_NE (F32) ", "
110 "channels = (int) 1, layout = (string) interleaved, rate = (int) 48000"));
111
112 #define CAPS_48khz \
113 "audio/x-raw, " \
114 "format = (string) " GST_AUDIO_NE (F32) ", " \
115 "channels = (int) 1, layout = (string) non-interleaved," \
116 "rate = (int) 48000"
117
118 static GstFlowReturn
interleave_chain_func(GstPad * pad,GstObject * parent,GstBuffer * buffer)119 interleave_chain_func (GstPad * pad, GstObject * parent, GstBuffer * buffer)
120 {
121 GstMapInfo map;
122 gfloat *outdata;
123 gint i;
124
125 fail_unless (GST_IS_BUFFER (buffer));
126 gst_buffer_map (buffer, &map, GST_MAP_READ);
127 outdata = (gfloat *) map.data;
128 fail_unless_equals_int (map.size, 48000 * 2 * sizeof (gfloat));
129 fail_unless (outdata != NULL);
130
131 #ifdef HAVE_VALGRIND
132 if (!(RUNNING_ON_VALGRIND))
133 #endif
134 for (i = 0; i < 48000 * 2; i += 2) {
135 fail_unless_equals_float (outdata[i], input[0]);
136 fail_unless_equals_float (outdata[i + 1], input[1]);
137 }
138 gst_buffer_unmap (buffer, &map);
139 gst_buffer_unref (buffer);
140
141 have_data++;
142
143 return GST_FLOW_OK;
144 }
145
GST_START_TEST(test_interleave_2ch)146 GST_START_TEST (test_interleave_2ch)
147 {
148 GstElement *queue;
149 GstPad *sink0, *sink1, *src, *tmp;
150 GstCaps *caps;
151 gint i;
152 GstBuffer *inbuf;
153 gfloat *indata;
154 GstMapInfo map;
155
156 mysrcpads = g_new0 (GstPad *, 2);
157
158 have_data = 0;
159
160 interleave = gst_element_factory_make ("interleave", NULL);
161 fail_unless (interleave != NULL);
162
163 queue = gst_element_factory_make ("queue", "queue");
164 fail_unless (queue != NULL);
165
166 sink0 = gst_element_request_pad_simple (interleave, "sink_%u");
167 fail_unless (sink0 != NULL);
168 fail_unless_equals_string (GST_OBJECT_NAME (sink0), "sink_0");
169
170 sink1 = gst_element_request_pad_simple (interleave, "sink_%u");
171 fail_unless (sink1 != NULL);
172 fail_unless_equals_string (GST_OBJECT_NAME (sink1), "sink_1");
173
174 mysrcpads[0] = gst_pad_new_from_static_template (&srctemplate, "src0");
175 fail_unless (mysrcpads[0] != NULL);
176
177 caps = gst_caps_from_string (CAPS_48khz);
178 gst_pad_set_active (mysrcpads[0], TRUE);
179 gst_check_setup_events_interleave (mysrcpads[0], interleave, caps,
180 GST_FORMAT_TIME, "0");
181 gst_pad_use_fixed_caps (mysrcpads[0]);
182
183 mysrcpads[1] = gst_pad_new_from_static_template (&srctemplate, "src1");
184 fail_unless (mysrcpads[1] != NULL);
185
186 gst_pad_set_active (mysrcpads[1], TRUE);
187 gst_check_setup_events_interleave (mysrcpads[1], interleave, caps,
188 GST_FORMAT_TIME, "1");
189 gst_pad_use_fixed_caps (mysrcpads[1]);
190
191 tmp = gst_element_get_static_pad (queue, "sink");
192 fail_unless (gst_pad_link (mysrcpads[0], tmp) == GST_PAD_LINK_OK);
193 gst_object_unref (tmp);
194 tmp = gst_element_get_static_pad (queue, "src");
195 fail_unless (gst_pad_link (tmp, sink0) == GST_PAD_LINK_OK);
196 gst_object_unref (tmp);
197
198 fail_unless (gst_pad_link (mysrcpads[1], sink1) == GST_PAD_LINK_OK);
199
200 mysinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
201 fail_unless (mysinkpad != NULL);
202 gst_pad_set_chain_function (mysinkpad, interleave_chain_func);
203 gst_pad_set_active (mysinkpad, TRUE);
204
205 src = gst_element_get_static_pad (interleave, "src");
206 fail_unless (src != NULL);
207 fail_unless (gst_pad_link (src, mysinkpad) == GST_PAD_LINK_OK);
208 gst_object_unref (src);
209
210 bus = gst_bus_new ();
211 gst_element_set_bus (interleave, bus);
212
213 fail_unless (gst_element_set_state (interleave,
214 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
215 fail_unless (gst_element_set_state (queue,
216 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
217
218 input[0] = -1.0;
219 inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
220 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
221 indata = (gfloat *) map.data;
222 for (i = 0; i < 48000; i++)
223 indata[i] = -1.0;
224 gst_buffer_unmap (inbuf, &map);
225 fail_unless (gst_pad_push (mysrcpads[0], inbuf) == GST_FLOW_OK);
226
227 input[1] = 1.0;
228 inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
229 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
230 indata = (gfloat *) map.data;
231 for (i = 0; i < 48000; i++)
232 indata[i] = 1.0;
233 gst_buffer_unmap (inbuf, &map);
234 fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
235
236 inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
237 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
238 indata = (gfloat *) map.data;
239 for (i = 0; i < 48000; i++)
240 indata[i] = -1.0;
241 gst_buffer_unmap (inbuf, &map);
242 fail_unless (gst_pad_push (mysrcpads[0], inbuf) == GST_FLOW_OK);
243
244 inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
245 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
246 indata = (gfloat *) map.data;
247 for (i = 0; i < 48000; i++)
248 indata[i] = 1.0;
249 gst_buffer_unmap (inbuf, &map);
250 fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
251
252 fail_unless (have_data == 2);
253
254 gst_bus_set_flushing (bus, TRUE);
255 gst_element_set_state (interleave, GST_STATE_NULL);
256 gst_element_set_state (queue, GST_STATE_NULL);
257
258 gst_object_unref (mysrcpads[0]);
259 gst_object_unref (mysrcpads[1]);
260 gst_object_unref (mysinkpad);
261
262 gst_element_release_request_pad (interleave, sink0);
263 gst_object_unref (sink0);
264 gst_element_release_request_pad (interleave, sink1);
265 gst_object_unref (sink1);
266
267 gst_object_unref (interleave);
268 gst_object_unref (queue);
269 gst_object_unref (bus);
270 gst_caps_unref (caps);
271
272 g_free (mysrcpads);
273 }
274
275 GST_END_TEST;
276
GST_START_TEST(test_interleave_2ch_1eos)277 GST_START_TEST (test_interleave_2ch_1eos)
278 {
279 GstElement *queue;
280 GstPad *sink0, *sink1, *src, *tmp;
281 GstCaps *caps;
282 gint i;
283 GstBuffer *inbuf;
284 gfloat *indata;
285 GstMapInfo map;
286
287 mysrcpads = g_new0 (GstPad *, 2);
288
289 have_data = 0;
290
291 interleave = gst_element_factory_make ("interleave", NULL);
292 fail_unless (interleave != NULL);
293
294 queue = gst_element_factory_make ("queue", "queue");
295 fail_unless (queue != NULL);
296
297 sink0 = gst_element_request_pad_simple (interleave, "sink_%u");
298 fail_unless (sink0 != NULL);
299 fail_unless_equals_string (GST_OBJECT_NAME (sink0), "sink_0");
300
301 sink1 = gst_element_request_pad_simple (interleave, "sink_%u");
302 fail_unless (sink1 != NULL);
303 fail_unless_equals_string (GST_OBJECT_NAME (sink1), "sink_1");
304
305 mysrcpads[0] = gst_pad_new_from_static_template (&srctemplate, "src0");
306 fail_unless (mysrcpads[0] != NULL);
307
308 caps = gst_caps_from_string (CAPS_48khz);
309 gst_pad_set_active (mysrcpads[0], TRUE);
310 gst_check_setup_events_interleave (mysrcpads[0], interleave, caps,
311 GST_FORMAT_TIME, "0");
312 gst_pad_use_fixed_caps (mysrcpads[0]);
313
314 mysrcpads[1] = gst_pad_new_from_static_template (&srctemplate, "src1");
315 fail_unless (mysrcpads[1] != NULL);
316
317 gst_pad_set_active (mysrcpads[1], TRUE);
318 gst_check_setup_events_interleave (mysrcpads[1], interleave, caps,
319 GST_FORMAT_TIME, "1");
320 gst_pad_use_fixed_caps (mysrcpads[1]);
321
322 tmp = gst_element_get_static_pad (queue, "sink");
323 fail_unless (gst_pad_link (mysrcpads[0], tmp) == GST_PAD_LINK_OK);
324 gst_object_unref (tmp);
325 tmp = gst_element_get_static_pad (queue, "src");
326 fail_unless (gst_pad_link (tmp, sink0) == GST_PAD_LINK_OK);
327 gst_object_unref (tmp);
328
329 fail_unless (gst_pad_link (mysrcpads[1], sink1) == GST_PAD_LINK_OK);
330
331 mysinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
332 fail_unless (mysinkpad != NULL);
333 gst_pad_set_chain_function (mysinkpad, interleave_chain_func);
334 gst_pad_set_active (mysinkpad, TRUE);
335
336 src = gst_element_get_static_pad (interleave, "src");
337 fail_unless (src != NULL);
338 fail_unless (gst_pad_link (src, mysinkpad) == GST_PAD_LINK_OK);
339 gst_object_unref (src);
340
341 bus = gst_bus_new ();
342 gst_element_set_bus (interleave, bus);
343
344 fail_unless (gst_element_set_state (interleave,
345 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
346 fail_unless (gst_element_set_state (queue,
347 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
348
349 input[0] = -1.0;
350 inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
351 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
352 indata = (gfloat *) map.data;
353 for (i = 0; i < 48000; i++)
354 indata[i] = -1.0;
355 gst_buffer_unmap (inbuf, &map);
356 fail_unless (gst_pad_push (mysrcpads[0], inbuf) == GST_FLOW_OK);
357
358 input[1] = 1.0;
359 inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
360 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
361 indata = (gfloat *) map.data;
362 for (i = 0; i < 48000; i++)
363 indata[i] = 1.0;
364 gst_buffer_unmap (inbuf, &map);
365 fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
366
367 input[0] = 0.0;
368 gst_pad_push_event (mysrcpads[0], gst_event_new_eos ());
369
370 input[1] = 1.0;
371 inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
372 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
373 indata = (gfloat *) map.data;
374 for (i = 0; i < 48000; i++)
375 indata[i] = 1.0;
376 gst_buffer_unmap (inbuf, &map);
377 fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
378
379 fail_unless (have_data == 2);
380
381 gst_bus_set_flushing (bus, TRUE);
382 gst_element_set_state (interleave, GST_STATE_NULL);
383 gst_element_set_state (queue, GST_STATE_NULL);
384
385 gst_object_unref (mysrcpads[0]);
386 gst_object_unref (mysrcpads[1]);
387 gst_object_unref (mysinkpad);
388
389 gst_element_release_request_pad (interleave, sink0);
390 gst_object_unref (sink0);
391 gst_element_release_request_pad (interleave, sink1);
392 gst_object_unref (sink1);
393
394 gst_object_unref (interleave);
395 gst_object_unref (queue);
396 gst_object_unref (bus);
397 gst_caps_unref (caps);
398
399 g_free (mysrcpads);
400 }
401
402 GST_END_TEST;
403
404 static void
src_handoff_float32(GstElement * element,GstBuffer * buffer,GstPad * pad,gboolean interleaved,gpointer user_data)405 src_handoff_float32 (GstElement * element, GstBuffer * buffer, GstPad * pad,
406 gboolean interleaved, gpointer user_data)
407 {
408 gint n = GPOINTER_TO_INT (user_data);
409 gfloat *data;
410 gint i;
411 gsize size;
412 GstCaps *caps;
413 guint64 mask;
414 GstAudioChannelPosition pos;
415
416 switch (n) {
417 case 0:
418 case 1:
419 case 2:
420 pos = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
421 break;
422 case 3:
423 pos = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
424 break;
425 default:
426 pos = GST_AUDIO_CHANNEL_POSITION_INVALID;
427 break;
428 }
429
430 mask = G_GUINT64_CONSTANT (1) << pos;
431
432 caps = gst_caps_new_simple ("audio/x-raw",
433 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
434 "channels", G_TYPE_INT, 1,
435 "layout", G_TYPE_STRING, interleaved ? "interleaved" : "non-interleaved",
436 "channel-mask", GST_TYPE_BITMASK, mask, "rate", G_TYPE_INT, 48000, NULL);
437
438 gst_pad_set_caps (pad, caps);
439 gst_caps_unref (caps);
440
441 size = 48000 * sizeof (gfloat);
442 data = g_malloc (size);
443 for (i = 0; i < 48000; i++)
444 data[i] = (n % 2 == 0) ? -1.0 : 1.0;
445
446 gst_buffer_append_memory (buffer, gst_memory_new_wrapped (0, data,
447 size, 0, size, data, g_free));
448
449 GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
450 GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
451 GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
452 GST_BUFFER_DURATION (buffer) = GST_SECOND;
453 }
454
455 static void
src_handoff_float32_interleaved(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)456 src_handoff_float32_interleaved (GstElement * element, GstBuffer * buffer,
457 GstPad * pad, gpointer user_data)
458 {
459 src_handoff_float32 (element, buffer, pad, TRUE, user_data);
460 }
461
462 static void
src_handoff_float32_non_interleaved(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)463 src_handoff_float32_non_interleaved (GstElement * element, GstBuffer * buffer,
464 GstPad * pad, gpointer user_data)
465 {
466 src_handoff_float32 (element, buffer, pad, FALSE, user_data);
467 }
468
469 static void
sink_handoff_float32(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)470 sink_handoff_float32 (GstElement * element, GstBuffer * buffer, GstPad * pad,
471 gpointer user_data)
472 {
473 gint i;
474 GstMapInfo map;
475 gfloat *data;
476 GstCaps *caps, *ccaps;
477 gint n = GPOINTER_TO_INT (user_data);
478 guint64 mask;
479
480 fail_unless (GST_IS_BUFFER (buffer));
481 gst_buffer_map (buffer, &map, GST_MAP_READ);
482 data = (gfloat *) map.data;
483
484 fail_unless_equals_int (map.size, 48000 * 2 * sizeof (gfloat));
485 fail_unless_equals_int (GST_BUFFER_DURATION (buffer), GST_SECOND);
486
487 if (n == 0) {
488 GstAudioChannelPosition pos[2] =
489 { GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE };
490 gst_audio_channel_positions_to_mask (pos, 2, FALSE, &mask);
491 } else if (n == 1) {
492 GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
493 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
494 };
495 gst_audio_channel_positions_to_mask (pos, 2, FALSE, &mask);
496 } else if (n == 2) {
497 GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
498 GST_AUDIO_CHANNEL_POSITION_REAR_CENTER
499 };
500 gst_audio_channel_positions_to_mask (pos, 2, FALSE, &mask);
501 } else {
502 g_assert_not_reached ();
503 }
504
505 caps = gst_caps_new_simple ("audio/x-raw",
506 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
507 "channels", G_TYPE_INT, 2, "rate", G_TYPE_INT, 48000,
508 "layout", G_TYPE_STRING, "interleaved",
509 "channel-mask", GST_TYPE_BITMASK, mask, NULL);
510
511 ccaps = gst_pad_get_current_caps (pad);
512 fail_unless (gst_caps_is_equal (caps, ccaps));
513 gst_caps_unref (ccaps);
514 gst_caps_unref (caps);
515
516 #ifdef HAVE_VALGRIND
517 if (!(RUNNING_ON_VALGRIND))
518 #endif
519 for (i = 0; i < 48000 * 2; i += 2) {
520 fail_unless_equals_float (data[i], -1.0);
521 fail_unless_equals_float (data[i + 1], 1.0);
522 }
523 gst_buffer_unmap (buffer, &map);
524
525 have_data++;
526 }
527
528 static void
test_interleave_2ch_pipeline(gboolean interleaved)529 test_interleave_2ch_pipeline (gboolean interleaved)
530 {
531 GstElement *pipeline, *queue, *src1, *src2, *interleave, *sink;
532 GstPad *sinkpad0, *sinkpad1, *tmp, *tmp2;
533 GstMessage *msg;
534 void *src_handoff_float32 =
535 interleaved ? &src_handoff_float32_interleaved :
536 &src_handoff_float32_non_interleaved;
537
538 have_data = 0;
539
540 pipeline = (GstElement *) gst_pipeline_new ("pipeline");
541 fail_unless (pipeline != NULL);
542
543 src1 = gst_element_factory_make ("fakesrc", "src1");
544 fail_unless (src1 != NULL);
545 g_object_set (src1, "num-buffers", 4, NULL);
546 g_object_set (src1, "signal-handoffs", TRUE, NULL);
547 g_signal_connect (src1, "handoff", G_CALLBACK (src_handoff_float32),
548 GINT_TO_POINTER (0));
549 gst_bin_add (GST_BIN (pipeline), src1);
550
551 src2 = gst_element_factory_make ("fakesrc", "src2");
552 fail_unless (src2 != NULL);
553 g_object_set (src2, "num-buffers", 4, NULL);
554 g_object_set (src2, "signal-handoffs", TRUE, NULL);
555 g_signal_connect (src2, "handoff", G_CALLBACK (src_handoff_float32),
556 GINT_TO_POINTER (1));
557 gst_bin_add (GST_BIN (pipeline), src2);
558
559 queue = gst_element_factory_make ("queue", "queue");
560 fail_unless (queue != NULL);
561 gst_bin_add (GST_BIN (pipeline), queue);
562
563 interleave = gst_element_factory_make ("interleave", "interleave");
564 fail_unless (interleave != NULL);
565 gst_bin_add (GST_BIN (pipeline), gst_object_ref (interleave));
566
567 sinkpad0 = gst_element_request_pad_simple (interleave, "sink_%u");
568 fail_unless (sinkpad0 != NULL);
569 tmp = gst_element_get_static_pad (src1, "src");
570 fail_unless (gst_pad_link (tmp, sinkpad0) == GST_PAD_LINK_OK);
571 gst_object_unref (tmp);
572
573 sinkpad1 = gst_element_request_pad_simple (interleave, "sink_%u");
574 fail_unless (sinkpad1 != NULL);
575 tmp = gst_element_get_static_pad (src2, "src");
576 tmp2 = gst_element_get_static_pad (queue, "sink");
577 fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
578 gst_object_unref (tmp);
579 gst_object_unref (tmp2);
580 tmp = gst_element_get_static_pad (queue, "src");
581 fail_unless (gst_pad_link (tmp, sinkpad1) == GST_PAD_LINK_OK);
582 gst_object_unref (tmp);
583
584 sink = gst_element_factory_make ("fakesink", "sink");
585 fail_unless (sink != NULL);
586 g_object_set (sink, "signal-handoffs", TRUE, NULL);
587 g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff_float32),
588 GINT_TO_POINTER (0));
589 gst_bin_add (GST_BIN (pipeline), sink);
590 tmp = gst_element_get_static_pad (interleave, "src");
591 tmp2 = gst_element_get_static_pad (sink, "sink");
592 fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
593 gst_object_unref (tmp);
594 gst_object_unref (tmp2);
595
596 gst_element_set_state (pipeline, GST_STATE_PLAYING);
597
598 msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
599 gst_message_unref (msg);
600
601 fail_unless (have_data == 4);
602
603 gst_element_set_state (pipeline, GST_STATE_NULL);
604 gst_element_release_request_pad (interleave, sinkpad0);
605 gst_object_unref (sinkpad0);
606 gst_element_release_request_pad (interleave, sinkpad1);
607 gst_object_unref (sinkpad1);
608 gst_object_unref (interleave);
609 gst_object_unref (pipeline);
610 }
611
GST_START_TEST(test_interleave_2ch_pipeline_interleaved)612 GST_START_TEST (test_interleave_2ch_pipeline_interleaved)
613 {
614 test_interleave_2ch_pipeline (TRUE);
615 }
616
617 GST_END_TEST;
618
GST_START_TEST(test_interleave_2ch_pipeline_non_interleaved)619 GST_START_TEST (test_interleave_2ch_pipeline_non_interleaved)
620 {
621 test_interleave_2ch_pipeline (FALSE);
622 }
623
624 GST_END_TEST;
625
GST_START_TEST(test_interleave_2ch_pipeline_input_chanpos)626 GST_START_TEST (test_interleave_2ch_pipeline_input_chanpos)
627 {
628 GstElement *pipeline, *queue, *src1, *src2, *interleave, *sink;
629 GstPad *sinkpad0, *sinkpad1, *tmp, *tmp2;
630 GstMessage *msg;
631
632 have_data = 0;
633
634 pipeline = (GstElement *) gst_pipeline_new ("pipeline");
635 fail_unless (pipeline != NULL);
636
637 src1 = gst_element_factory_make ("fakesrc", "src1");
638 fail_unless (src1 != NULL);
639 g_object_set (src1, "num-buffers", 4, NULL);
640 g_object_set (src1, "signal-handoffs", TRUE, NULL);
641 g_signal_connect (src1, "handoff",
642 G_CALLBACK (src_handoff_float32_interleaved), GINT_TO_POINTER (2));
643 gst_bin_add (GST_BIN (pipeline), src1);
644
645 src2 = gst_element_factory_make ("fakesrc", "src2");
646 fail_unless (src2 != NULL);
647 g_object_set (src2, "num-buffers", 4, NULL);
648 g_object_set (src2, "signal-handoffs", TRUE, NULL);
649 g_signal_connect (src2, "handoff",
650 G_CALLBACK (src_handoff_float32_interleaved), GINT_TO_POINTER (3));
651 gst_bin_add (GST_BIN (pipeline), src2);
652
653 queue = gst_element_factory_make ("queue", "queue");
654 fail_unless (queue != NULL);
655 gst_bin_add (GST_BIN (pipeline), queue);
656
657 interleave = gst_element_factory_make ("interleave", "interleave");
658 fail_unless (interleave != NULL);
659 g_object_set (interleave, "channel-positions-from-input", TRUE, NULL);
660 gst_bin_add (GST_BIN (pipeline), gst_object_ref (interleave));
661
662 sinkpad0 = gst_element_request_pad_simple (interleave, "sink_%u");
663 fail_unless (sinkpad0 != NULL);
664 tmp = gst_element_get_static_pad (src1, "src");
665 fail_unless (gst_pad_link (tmp, sinkpad0) == GST_PAD_LINK_OK);
666 gst_object_unref (tmp);
667
668 sinkpad1 = gst_element_request_pad_simple (interleave, "sink_%u");
669 fail_unless (sinkpad1 != NULL);
670 tmp = gst_element_get_static_pad (src2, "src");
671 tmp2 = gst_element_get_static_pad (queue, "sink");
672 fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
673 gst_object_unref (tmp);
674 gst_object_unref (tmp2);
675 tmp = gst_element_get_static_pad (queue, "src");
676 fail_unless (gst_pad_link (tmp, sinkpad1) == GST_PAD_LINK_OK);
677 gst_object_unref (tmp);
678
679 sink = gst_element_factory_make ("fakesink", "sink");
680 fail_unless (sink != NULL);
681 g_object_set (sink, "signal-handoffs", TRUE, NULL);
682 g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff_float32),
683 GINT_TO_POINTER (1));
684 gst_bin_add (GST_BIN (pipeline), sink);
685 tmp = gst_element_get_static_pad (interleave, "src");
686 tmp2 = gst_element_get_static_pad (sink, "sink");
687 fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
688 gst_object_unref (tmp);
689 gst_object_unref (tmp2);
690
691 gst_element_set_state (pipeline, GST_STATE_PLAYING);
692
693 msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
694 gst_message_unref (msg);
695
696 fail_unless (have_data == 4);
697
698 gst_element_set_state (pipeline, GST_STATE_NULL);
699 gst_element_release_request_pad (interleave, sinkpad0);
700 gst_object_unref (sinkpad0);
701 gst_element_release_request_pad (interleave, sinkpad1);
702 gst_object_unref (sinkpad1);
703 gst_object_unref (interleave);
704 gst_object_unref (pipeline);
705 }
706
707 GST_END_TEST;
708
GST_START_TEST(test_interleave_2ch_pipeline_custom_chanpos)709 GST_START_TEST (test_interleave_2ch_pipeline_custom_chanpos)
710 {
711 GstElement *pipeline, *queue, *src1, *src2, *interleave, *sink;
712 GstPad *sinkpad0, *sinkpad1, *tmp, *tmp2;
713 GstMessage *msg;
714 GValueArray *arr;
715 GValue val = { 0, };
716
717 have_data = 0;
718
719 pipeline = (GstElement *) gst_pipeline_new ("pipeline");
720 fail_unless (pipeline != NULL);
721
722 src1 = gst_element_factory_make ("fakesrc", "src1");
723 fail_unless (src1 != NULL);
724 g_object_set (src1, "num-buffers", 4, NULL);
725 g_object_set (src1, "signal-handoffs", TRUE, NULL);
726 g_signal_connect (src1, "handoff",
727 G_CALLBACK (src_handoff_float32_interleaved), GINT_TO_POINTER (0));
728 gst_bin_add (GST_BIN (pipeline), src1);
729
730 src2 = gst_element_factory_make ("fakesrc", "src2");
731 fail_unless (src2 != NULL);
732 g_object_set (src2, "num-buffers", 4, NULL);
733 g_object_set (src2, "signal-handoffs", TRUE, NULL);
734 g_signal_connect (src2, "handoff",
735 G_CALLBACK (src_handoff_float32_interleaved), GINT_TO_POINTER (1));
736 gst_bin_add (GST_BIN (pipeline), src2);
737
738 queue = gst_element_factory_make ("queue", "queue");
739 fail_unless (queue != NULL);
740 gst_bin_add (GST_BIN (pipeline), queue);
741
742 interleave = gst_element_factory_make ("interleave", "interleave");
743 fail_unless (interleave != NULL);
744 g_object_set (interleave, "channel-positions-from-input", FALSE, NULL);
745 arr = g_value_array_new (2);
746
747 g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION);
748 g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER);
749 g_value_array_append (arr, &val);
750 g_value_reset (&val);
751 g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER);
752 g_value_array_append (arr, &val);
753 g_value_unset (&val);
754
755 g_object_set (interleave, "channel-positions", arr, NULL);
756 g_value_array_free (arr);
757 gst_bin_add (GST_BIN (pipeline), gst_object_ref (interleave));
758
759 sinkpad0 = gst_element_request_pad_simple (interleave, "sink_%u");
760 fail_unless (sinkpad0 != NULL);
761 tmp = gst_element_get_static_pad (src1, "src");
762 fail_unless (gst_pad_link (tmp, sinkpad0) == GST_PAD_LINK_OK);
763 gst_object_unref (tmp);
764
765 sinkpad1 = gst_element_request_pad_simple (interleave, "sink_%u");
766 fail_unless (sinkpad1 != NULL);
767 tmp = gst_element_get_static_pad (src2, "src");
768 tmp2 = gst_element_get_static_pad (queue, "sink");
769 fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
770 gst_object_unref (tmp);
771 gst_object_unref (tmp2);
772 tmp = gst_element_get_static_pad (queue, "src");
773 fail_unless (gst_pad_link (tmp, sinkpad1) == GST_PAD_LINK_OK);
774 gst_object_unref (tmp);
775
776 sink = gst_element_factory_make ("fakesink", "sink");
777 fail_unless (sink != NULL);
778 g_object_set (sink, "signal-handoffs", TRUE, NULL);
779 g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff_float32),
780 GINT_TO_POINTER (2));
781 gst_bin_add (GST_BIN (pipeline), sink);
782 tmp = gst_element_get_static_pad (interleave, "src");
783 tmp2 = gst_element_get_static_pad (sink, "sink");
784 fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
785 gst_object_unref (tmp);
786 gst_object_unref (tmp2);
787
788 gst_element_set_state (pipeline, GST_STATE_PLAYING);
789
790 msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
791 gst_message_unref (msg);
792
793 fail_unless (have_data == 4);
794
795 gst_element_set_state (pipeline, GST_STATE_NULL);
796 gst_element_release_request_pad (interleave, sinkpad0);
797 gst_object_unref (sinkpad0);
798 gst_element_release_request_pad (interleave, sinkpad1);
799 gst_object_unref (sinkpad1);
800 gst_object_unref (interleave);
801 gst_object_unref (pipeline);
802 }
803
804 GST_END_TEST;
805
806 static Suite *
interleave_suite(void)807 interleave_suite (void)
808 {
809 Suite *s = suite_create ("interleave");
810 TCase *tc_chain = tcase_create ("general");
811
812 suite_add_tcase (s, tc_chain);
813 tcase_set_timeout (tc_chain, 180);
814 tcase_add_test (tc_chain, test_create_and_unref);
815 tcase_add_test (tc_chain, test_request_pads);
816 tcase_add_test (tc_chain, test_interleave_2ch);
817 tcase_add_test (tc_chain, test_interleave_2ch_1eos);
818 tcase_add_test (tc_chain, test_interleave_2ch_pipeline_interleaved);
819 tcase_add_test (tc_chain, test_interleave_2ch_pipeline_non_interleaved);
820 tcase_add_test (tc_chain, test_interleave_2ch_pipeline_input_chanpos);
821 tcase_add_test (tc_chain, test_interleave_2ch_pipeline_custom_chanpos);
822
823 return s;
824 }
825
826 GST_CHECK_MAIN (interleave);
827