1 /* GStreamer unit tests for the interleave element
2 * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
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 <stdio.h>
25 #include <gst/audio/audio.h>
26 #include <gst/check/gstcheck.h>
27 #include <gst/audio/audio.h>
28
GST_START_TEST(test_create_and_unref)29 GST_START_TEST (test_create_and_unref)
30 {
31 GstElement *deinterleave;
32
33 deinterleave = gst_element_factory_make ("deinterleave", NULL);
34 fail_unless (deinterleave != NULL);
35
36 gst_element_set_state (deinterleave, GST_STATE_NULL);
37 gst_object_unref (deinterleave);
38 }
39
40 GST_END_TEST;
41
42 static GstPad *mysrcpad, **mysinkpads;
43 static gint nsinkpads;
44 static GstBus *bus;
45 static GstElement *deinterleave;
46
47 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
48 GST_PAD_SINK,
49 GST_PAD_ALWAYS,
50 GST_STATIC_CAPS ("audio/x-raw, "
51 "format = (string) " GST_AUDIO_NE (F32) ", "
52 "channels = (int) 1, layout = (string) {interleaved, non-interleaved}, rate = (int) {32000, 48000}"));
53
54 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
55 GST_PAD_SRC,
56 GST_PAD_ALWAYS,
57 GST_STATIC_CAPS ("audio/x-raw, "
58 "format = (string) " GST_AUDIO_NE (F32) ", "
59 "channels = (int) { 2, 3 }, layout = (string) interleaved, rate = (int) {32000, 48000}"));
60
61 #define CAPS_32khz \
62 "audio/x-raw, " \
63 "format = (string) "GST_AUDIO_NE (F32) ", " \
64 "channels = (int) 2, layout = (string) interleaved, " \
65 "rate = (int) 32000"
66
67 #define CAPS_48khz \
68 "audio/x-raw, " \
69 "format = (string) "GST_AUDIO_NE (F32) ", " \
70 "channels = (int) 2, layout = (string) interleaved, " \
71 "rate = (int) 48000"
72
73 #define CAPS_48khz_3CH \
74 "audio/x-raw, " \
75 "format = (string) "GST_AUDIO_NE (F32) ", " \
76 "channels = (int) 3, layout = (string) interleaved, " \
77 "rate = (int) 48000"
78
79 static GstFlowReturn
deinterleave_chain_func(GstPad * pad,GstObject * parent,GstBuffer * buffer)80 deinterleave_chain_func (GstPad * pad, GstObject * parent, GstBuffer * buffer)
81 {
82 gint i;
83 GstMapInfo map;
84 gfloat *indata;
85
86 fail_unless (GST_IS_BUFFER (buffer));
87 gst_buffer_map (buffer, &map, GST_MAP_READ);
88 indata = (gfloat *) map.data;
89 fail_unless_equals_int (map.size, 48000 * sizeof (gfloat));
90 fail_unless (indata != NULL);
91
92 if (strcmp (GST_PAD_NAME (pad), "sink0") == 0) {
93 for (i = 0; i < 48000; i++)
94 fail_unless_equals_float (indata[i], -1.0);
95 } else if (strcmp (GST_PAD_NAME (pad), "sink1") == 0) {
96 for (i = 0; i < 48000; i++)
97 fail_unless_equals_float (indata[i], 1.0);
98 } else {
99 g_assert_not_reached ();
100 }
101 gst_buffer_unmap (buffer, &map);
102 gst_buffer_unref (buffer);
103
104 return GST_FLOW_OK;
105 }
106
107 static void
deinterleave_pad_added(GstElement * src,GstPad * pad,gpointer data)108 deinterleave_pad_added (GstElement * src, GstPad * pad, gpointer data)
109 {
110 gchar *name;
111 gint link = GPOINTER_TO_INT (data);
112
113 if (nsinkpads >= link)
114 return;
115
116 name = g_strdup_printf ("sink%d", nsinkpads);
117
118 mysinkpads[nsinkpads] =
119 gst_pad_new_from_static_template (&sinktemplate, name);
120 g_free (name);
121 fail_if (mysinkpads[nsinkpads] == NULL);
122
123 gst_pad_set_chain_function (mysinkpads[nsinkpads], deinterleave_chain_func);
124 fail_unless (gst_pad_link (pad, mysinkpads[nsinkpads]) == GST_PAD_LINK_OK);
125 gst_pad_set_active (mysinkpads[nsinkpads], TRUE);
126 nsinkpads++;
127 }
128
GST_START_TEST(test_2_channels)129 GST_START_TEST (test_2_channels)
130 {
131 GstPad *sinkpad;
132 gint i;
133 GstBuffer *inbuf;
134 GstCaps *caps;
135 gfloat *indata;
136 GstMapInfo map;
137 guint64 channel_mask = 0;
138
139 mysinkpads = g_new0 (GstPad *, 2);
140 nsinkpads = 0;
141
142 deinterleave = gst_element_factory_make ("deinterleave", NULL);
143 fail_unless (deinterleave != NULL);
144
145 mysrcpad = gst_pad_new_from_static_template (&srctemplate, "src");
146 fail_unless (mysrcpad != NULL);
147 gst_pad_set_active (mysrcpad, TRUE);
148
149 caps = gst_caps_from_string (CAPS_48khz);
150 channel_mask |=
151 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
152 channel_mask |=
153 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
154 gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
155 NULL);
156
157 gst_check_setup_events (mysrcpad, deinterleave, caps, GST_FORMAT_TIME);
158
159 sinkpad = gst_element_get_static_pad (deinterleave, "sink");
160 fail_unless (sinkpad != NULL);
161 fail_unless (gst_pad_link (mysrcpad, sinkpad) == GST_PAD_LINK_OK);
162 g_object_unref (sinkpad);
163
164 g_signal_connect (deinterleave, "pad-added",
165 G_CALLBACK (deinterleave_pad_added), GINT_TO_POINTER (2));
166
167 bus = gst_bus_new ();
168 gst_element_set_bus (deinterleave, bus);
169
170 fail_unless (gst_element_set_state (deinterleave,
171 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
172
173 inbuf = gst_buffer_new_and_alloc (2 * 48000 * sizeof (gfloat));
174 inbuf = gst_buffer_make_writable (inbuf);
175 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
176 indata = (gfloat *) map.data;
177 for (i = 0; i < 2 * 48000; i += 2) {
178 indata[i] = -1.0;
179 indata[i + 1] = 1.0;
180 }
181 gst_buffer_unmap (inbuf, &map);
182
183 fail_unless (gst_pad_push (mysrcpad, inbuf) == GST_FLOW_OK);
184
185 fail_unless (gst_element_set_state (deinterleave,
186 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
187
188 for (i = 0; i < nsinkpads; i++)
189 g_object_unref (mysinkpads[i]);
190 g_free (mysinkpads);
191 mysinkpads = NULL;
192
193 g_object_unref (deinterleave);
194 gst_bus_set_flushing (bus, TRUE);
195 g_object_unref (bus);
196 gst_caps_unref (caps);
197 gst_object_unref (mysrcpad);
198 }
199
200 GST_END_TEST;
201
GST_START_TEST(test_2_channels_1_linked)202 GST_START_TEST (test_2_channels_1_linked)
203 {
204 GstPad *sinkpad;
205 gint i;
206 GstBuffer *inbuf;
207 GstCaps *caps;
208 gfloat *indata;
209 GstMapInfo map;
210 guint64 channel_mask = 0;
211
212 nsinkpads = 0;
213 mysinkpads = g_new0 (GstPad *, 2);
214
215 deinterleave = gst_element_factory_make ("deinterleave", NULL);
216 fail_unless (deinterleave != NULL);
217
218 mysrcpad = gst_pad_new_from_static_template (&srctemplate, "src");
219 fail_unless (mysrcpad != NULL);
220 gst_pad_set_active (mysrcpad, TRUE);
221
222 caps = gst_caps_from_string (CAPS_48khz);
223 channel_mask |=
224 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
225 channel_mask |=
226 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
227 gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
228 NULL);
229
230 gst_check_setup_events (mysrcpad, deinterleave, caps, GST_FORMAT_TIME);
231
232 sinkpad = gst_element_get_static_pad (deinterleave, "sink");
233 fail_unless (sinkpad != NULL);
234 fail_unless (gst_pad_link (mysrcpad, sinkpad) == GST_PAD_LINK_OK);
235 g_object_unref (sinkpad);
236
237 g_signal_connect (deinterleave, "pad-added",
238 G_CALLBACK (deinterleave_pad_added), GINT_TO_POINTER (1));
239
240 bus = gst_bus_new ();
241 gst_element_set_bus (deinterleave, bus);
242
243 fail_unless (gst_element_set_state (deinterleave,
244 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
245
246 inbuf = gst_buffer_new_and_alloc (2 * 48000 * sizeof (gfloat));
247 inbuf = gst_buffer_make_writable (inbuf);
248 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
249 indata = (gfloat *) map.data;
250 for (i = 0; i < 2 * 48000; i += 2) {
251 indata[i] = -1.0;
252 indata[i + 1] = 1.0;
253 }
254 gst_buffer_unmap (inbuf, &map);
255
256 fail_unless (gst_pad_push (mysrcpad, inbuf) == GST_FLOW_OK);
257
258 fail_unless (gst_element_set_state (deinterleave,
259 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
260
261 for (i = 0; i < nsinkpads; i++)
262 g_object_unref (mysinkpads[i]);
263 g_free (mysinkpads);
264 mysinkpads = NULL;
265
266 g_object_unref (deinterleave);
267 gst_bus_set_flushing (bus, TRUE);
268 g_object_unref (bus);
269 gst_caps_unref (caps);
270 gst_object_unref (mysrcpad);
271 }
272
273 GST_END_TEST;
274
GST_START_TEST(test_2_channels_caps_change)275 GST_START_TEST (test_2_channels_caps_change)
276 {
277 GstPad *sinkpad;
278 GstCaps *caps, *caps2;
279 GstCaps *ret_caps;
280 gint i;
281 GstBuffer *inbuf;
282 gfloat *indata;
283 GstMapInfo map;
284 guint64 channel_mask;
285
286 nsinkpads = 0;
287 mysinkpads = g_new0 (GstPad *, 2);
288
289 deinterleave = gst_element_factory_make ("deinterleave", NULL);
290 fail_unless (deinterleave != NULL);
291
292 mysrcpad = gst_pad_new_from_static_template (&srctemplate, "src");
293 fail_unless (mysrcpad != NULL);
294
295 gst_pad_set_active (mysrcpad, TRUE);
296
297 caps = gst_caps_from_string (CAPS_48khz);
298 channel_mask = 0;
299 channel_mask |=
300 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
301 channel_mask |=
302 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
303 gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
304 NULL);
305
306 sinkpad = gst_element_get_static_pad (deinterleave, "sink");
307 fail_unless (sinkpad != NULL);
308 fail_unless (gst_pad_link (mysrcpad, sinkpad) == GST_PAD_LINK_OK);
309 g_object_unref (sinkpad);
310
311 ret_caps = gst_pad_peer_query_caps (mysrcpad, caps);
312 fail_if (gst_caps_is_empty (ret_caps));
313 fail_unless (gst_pad_peer_query_accept_caps (mysrcpad, caps));
314 gst_caps_unref (ret_caps);
315 gst_check_setup_events (mysrcpad, deinterleave, caps, GST_FORMAT_TIME);
316
317 g_signal_connect (deinterleave, "pad-added",
318 G_CALLBACK (deinterleave_pad_added), GINT_TO_POINTER (2));
319
320 bus = gst_bus_new ();
321 gst_element_set_bus (deinterleave, bus);
322
323 fail_unless (gst_element_set_state (deinterleave,
324 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
325
326 inbuf = gst_buffer_new_and_alloc (2 * 48000 * sizeof (gfloat));
327 inbuf = gst_buffer_make_writable (inbuf);
328 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
329 indata = (gfloat *) map.data;
330 for (i = 0; i < 2 * 48000; i += 2) {
331 indata[i] = -1.0;
332 indata[i + 1] = 1.0;
333 }
334 gst_buffer_unmap (inbuf, &map);
335
336 fail_unless (gst_pad_push (mysrcpad, inbuf) == GST_FLOW_OK);
337
338 caps2 = gst_caps_from_string (CAPS_32khz);
339 channel_mask = 0;
340 channel_mask |=
341 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
342 channel_mask |=
343 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
344 gst_caps_set_simple (caps2, "channel-mask", GST_TYPE_BITMASK, channel_mask,
345 NULL);
346 ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2);
347 fail_if (gst_caps_is_empty (ret_caps));
348 fail_unless (gst_pad_peer_query_accept_caps (mysrcpad, caps2));
349 gst_caps_unref (ret_caps);
350 gst_pad_set_caps (mysrcpad, caps2);
351
352 inbuf = gst_buffer_new_and_alloc (2 * 48000 * sizeof (gfloat));
353 inbuf = gst_buffer_make_writable (inbuf);
354 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
355 indata = (gfloat *) map.data;
356 for (i = 0; i < 2 * 48000; i += 2) {
357 indata[i] = -1.0;
358 indata[i + 1] = 1.0;
359 }
360 gst_buffer_unmap (inbuf, &map);
361
362 /* Should work fine because the caps changed in a compatible way */
363 fail_unless (gst_pad_push (mysrcpad, inbuf) == GST_FLOW_OK);
364
365 gst_caps_unref (caps2);
366
367 caps2 = gst_caps_from_string (CAPS_48khz_3CH);
368 channel_mask = 0;
369 channel_mask |=
370 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
371 channel_mask |=
372 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
373 channel_mask |=
374 G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
375 gst_caps_set_simple (caps2, "channel-mask", GST_TYPE_BITMASK, channel_mask,
376 NULL);
377 ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2);
378 fail_unless (gst_caps_is_empty (ret_caps));
379 gst_caps_unref (ret_caps);
380 fail_if (gst_pad_peer_query_accept_caps (mysrcpad, caps2));
381 gst_pad_set_caps (mysrcpad, caps2);
382
383 inbuf = gst_buffer_new_and_alloc (3 * 48000 * sizeof (gfloat));
384 inbuf = gst_buffer_make_writable (inbuf);
385 gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
386 indata = (gfloat *) map.data;
387 for (i = 0; i < 3 * 48000; i += 3) {
388 indata[i] = -1.0;
389 indata[i + 1] = 1.0;
390 indata[i + 2] = 0.0;
391 }
392 gst_buffer_unmap (inbuf, &map);
393
394 /* Should break because the caps changed in an incompatible way */
395 fail_if (gst_pad_push (mysrcpad, inbuf) == GST_FLOW_OK);
396
397 fail_unless (gst_element_set_state (deinterleave,
398 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
399
400 for (i = 0; i < nsinkpads; i++)
401 g_object_unref (mysinkpads[i]);
402 g_free (mysinkpads);
403 mysinkpads = NULL;
404
405 g_object_unref (deinterleave);
406 gst_bus_set_flushing (bus, TRUE);
407 g_object_unref (bus);
408 gst_caps_unref (caps);
409 gst_caps_unref (caps2);
410 gst_object_unref (mysrcpad);
411 }
412
413 GST_END_TEST;
414
415
416 #define SAMPLES_PER_BUFFER 10
417 #define NUM_CHANNELS 8
418 #define SAMPLE_RATE 44100
419
420 static guint pads_created;
421
422 static void
set_channel_positions(GstCaps * caps,int channels,GstAudioChannelPosition * channelpositions)423 set_channel_positions (GstCaps * caps, int channels,
424 GstAudioChannelPosition * channelpositions)
425 {
426 int c;
427 guint64 channel_mask = 0;
428
429 for (c = 0; c < channels; c++)
430 channel_mask |= G_GUINT64_CONSTANT (1) << channelpositions[c];
431
432 gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
433 NULL);
434 }
435
436 static void
src_handoff_float32_8ch(GstElement * src,GstBuffer * buf,GstPad * pad,gpointer user_data)437 src_handoff_float32_8ch (GstElement * src, GstBuffer * buf, GstPad * pad,
438 gpointer user_data)
439 {
440 gfloat *data, *p;
441 guint size, i, c;
442
443 size = sizeof (gfloat) * SAMPLES_PER_BUFFER * NUM_CHANNELS;
444 data = p = (gfloat *) g_malloc (size);
445
446 for (i = 0; i < SAMPLES_PER_BUFFER; ++i) {
447 for (c = 0; c < NUM_CHANNELS; ++c) {
448 *p = (gfloat) ((i * NUM_CHANNELS) + c);
449 ++p;
450 }
451 }
452
453 if (gst_buffer_n_memory (buf)) {
454 gst_buffer_replace_memory_range (buf, 0, -1,
455 gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
456 } else {
457 gst_buffer_insert_memory (buf, 0,
458 gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
459 }
460 GST_BUFFER_OFFSET (buf) = 0;
461 GST_BUFFER_TIMESTAMP (buf) = 0;
462 }
463
464 static GstPadProbeReturn
src_event_probe(GstPad * pad,GstPadProbeInfo * info,gpointer userdata)465 src_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
466 {
467 GstAudioChannelPosition layout[NUM_CHANNELS];
468 GstCaps *caps;
469 guint i;
470
471 if ((info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM)
472 && GST_EVENT_TYPE (info->data) == GST_EVENT_STREAM_START) {
473 gst_pad_remove_probe (pad, info->id);
474
475 caps = gst_caps_new_simple ("audio/x-raw",
476 "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
477 "channels", G_TYPE_INT, NUM_CHANNELS,
478 "layout", G_TYPE_STRING, "interleaved",
479 "rate", G_TYPE_INT, SAMPLE_RATE, NULL);
480
481 for (i = 0; i < NUM_CHANNELS; ++i)
482 layout[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT + i;
483
484 set_channel_positions (caps, NUM_CHANNELS, layout);
485 gst_pad_set_caps (pad, caps);
486 gst_caps_unref (caps);
487 }
488
489 return GST_PAD_PROBE_OK;
490 }
491
492 static GstPadProbeReturn
float_buffer_check_probe(GstPad * pad,GstPadProbeInfo * info,gpointer userdata)493 float_buffer_check_probe (GstPad * pad, GstPadProbeInfo * info,
494 gpointer userdata)
495 {
496 GstMapInfo map;
497 gfloat *data;
498 guint padnum, numpads;
499 guint num, i;
500 GstCaps *caps;
501 GstStructure *s;
502 GstAudioChannelPosition *pos;
503 gint channels;
504 GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
505 GstAudioInfo audio_info;
506 guint pad_id = GPOINTER_TO_UINT (userdata);
507
508 fail_unless_equals_int (sscanf (GST_PAD_NAME (pad), "src_%u", &padnum), 1);
509
510 numpads = pads_created;
511
512 /* Check caps */
513 caps = gst_pad_get_current_caps (pad);
514 fail_unless (caps != NULL);
515 s = gst_caps_get_structure (caps, 0);
516 fail_unless (gst_structure_get_int (s, "channels", &channels));
517 fail_unless_equals_int (channels, 1);
518
519 gst_audio_info_init (&audio_info);
520 fail_unless (gst_audio_info_from_caps (&audio_info, caps));
521
522 pos = audio_info.position;
523 fail_unless (pos != NULL
524 && pos[0] == GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT + pad_id);
525 gst_caps_unref (caps);
526
527 gst_buffer_map (buffer, &map, GST_MAP_READ);
528 data = (gfloat *) map.data;
529 num = map.size / sizeof (gfloat);
530
531 /* Check buffer content */
532 for (i = 0; i < num; ++i) {
533 guint val, rest;
534
535 val = (guint) data[i];
536 GST_LOG ("%s[%u]: %8f", GST_PAD_NAME (pad), i, data[i]);
537 /* can't use the modulo operator in the assertion statement, since due to
538 * the way it gets expanded it would be interpreted as a printf operator
539 * in the failure case, which will result in segfaults */
540 rest = val % numpads;
541 /* check that the first channel is on pad src0, the second on src1 etc. */
542 fail_unless_equals_int (rest, padnum);
543 }
544 gst_buffer_unmap (buffer, &map);
545
546 return GST_PAD_PROBE_OK; /* don't drop data */
547 }
548
549 static void
pad_added_setup_data_check_float32_8ch_cb(GstElement * deinterleave,GstPad * pad,GstElement * pipeline)550 pad_added_setup_data_check_float32_8ch_cb (GstElement * deinterleave,
551 GstPad * pad, GstElement * pipeline)
552 {
553 GstElement *queue, *sink;
554 GstPad *sinkpad;
555
556 queue = gst_element_factory_make ("queue", NULL);
557 fail_unless (queue != NULL);
558
559 sink = gst_element_factory_make ("fakesink", NULL);
560 fail_unless (sink != NULL);
561
562 gst_bin_add_many (GST_BIN (pipeline), queue, sink, NULL);
563 gst_element_link_pads_full (queue, "src", sink, "sink",
564 GST_PAD_LINK_CHECK_NOTHING);
565
566 sinkpad = gst_element_get_static_pad (queue, "sink");
567
568 fail_unless_equals_int (gst_pad_link (pad, sinkpad), GST_PAD_LINK_OK);
569 gst_object_unref (sinkpad);
570
571 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, float_buffer_check_probe,
572 GUINT_TO_POINTER (pads_created), NULL);
573
574 gst_element_set_state (sink, GST_STATE_PLAYING);
575 gst_element_set_state (queue, GST_STATE_PLAYING);
576
577 GST_LOG ("new pad: %s", GST_PAD_NAME (pad));
578 ++pads_created;
579 }
580
581 static GstElement *
make_fake_src_8chans_float32(void)582 make_fake_src_8chans_float32 (void)
583 {
584 GstElement *src;
585 GstPad *pad;
586
587 src = gst_element_factory_make ("fakesrc", "src");
588 fail_unless (src != NULL, "failed to create fakesrc element");
589
590 g_object_set (src, "num-buffers", 1, NULL);
591 g_object_set (src, "signal-handoffs", TRUE, NULL);
592
593 g_signal_connect (src, "handoff", G_CALLBACK (src_handoff_float32_8ch), NULL);
594
595 pad = gst_element_get_static_pad (src, "src");
596 gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, src_event_probe,
597 NULL, NULL);
598 gst_object_unref (pad);
599
600 return src;
601 }
602
GST_START_TEST(test_8_channels_float32)603 GST_START_TEST (test_8_channels_float32)
604 {
605 GstElement *pipeline, *src, *deinterleave;
606 GstMessage *msg;
607
608 pipeline = (GstElement *) gst_pipeline_new ("pipeline");
609 fail_unless (pipeline != NULL, "failed to create pipeline");
610
611 src = make_fake_src_8chans_float32 ();
612
613 deinterleave = gst_element_factory_make ("deinterleave", "deinterleave");
614 fail_unless (deinterleave != NULL, "failed to create deinterleave element");
615 g_object_set (deinterleave, "keep-positions", TRUE, NULL);
616
617 gst_bin_add_many (GST_BIN (pipeline), src, deinterleave, NULL);
618
619 fail_unless (gst_element_link (src, deinterleave),
620 "failed to link src <=> deinterleave");
621
622 g_signal_connect (deinterleave, "pad-added",
623 G_CALLBACK (pad_added_setup_data_check_float32_8ch_cb), pipeline);
624
625 pads_created = 0;
626
627 gst_element_set_state (pipeline, GST_STATE_PLAYING);
628
629 msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
630 gst_message_unref (msg);
631
632 fail_unless_equals_int (pads_created, NUM_CHANNELS);
633
634 gst_element_set_state (pipeline, GST_STATE_NULL);
635 gst_object_unref (pipeline);
636 }
637
638 GST_END_TEST;
639
640 static Suite *
deinterleave_suite(void)641 deinterleave_suite (void)
642 {
643 Suite *s = suite_create ("deinterleave");
644 TCase *tc_chain = tcase_create ("general");
645
646 suite_add_tcase (s, tc_chain);
647 tcase_set_timeout (tc_chain, 180);
648 tcase_add_test (tc_chain, test_create_and_unref);
649 tcase_add_test (tc_chain, test_2_channels);
650 tcase_add_test (tc_chain, test_2_channels_1_linked);
651 tcase_add_test (tc_chain, test_2_channels_caps_change);
652 tcase_add_test (tc_chain, test_8_channels_float32);
653
654 return s;
655 }
656
657 GST_CHECK_MAIN (deinterleave);
658