1 /* GStreamer unit tests for the audiointerleave 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 #include <gst/check/gstharness.h>
38 
39 static void
gst_check_setup_events_audiointerleave(GstPad * srcpad,GstElement * element,GstCaps * caps,GstFormat format,const gchar * stream_id)40 gst_check_setup_events_audiointerleave (GstPad * srcpad, GstElement * element,
41     GstCaps * caps, GstFormat format, const gchar * stream_id)
42 {
43   GstSegment segment;
44 
45   gst_segment_init (&segment, format);
46 
47   fail_unless (gst_pad_push_event (srcpad,
48           gst_event_new_stream_start (stream_id)));
49   if (caps)
50     fail_unless (gst_pad_push_event (srcpad, gst_event_new_caps (caps)));
51   fail_unless (gst_pad_push_event (srcpad, gst_event_new_segment (&segment)));
52 }
53 
GST_START_TEST(test_create_and_unref)54 GST_START_TEST (test_create_and_unref)
55 {
56   GstElement *interleave;
57 
58   interleave = gst_element_factory_make ("audiointerleave", NULL);
59   fail_unless (interleave != NULL);
60 
61   gst_element_set_state (interleave, GST_STATE_NULL);
62   gst_object_unref (interleave);
63 }
64 
65 GST_END_TEST;
66 
GST_START_TEST(test_request_pads)67 GST_START_TEST (test_request_pads)
68 {
69   GstElement *interleave;
70   GstPad *pad1, *pad2;
71 
72   interleave = gst_element_factory_make ("audiointerleave", NULL);
73   fail_unless (interleave != NULL);
74 
75   pad1 = gst_element_get_request_pad (interleave, "sink_%u");
76   fail_unless (pad1 != NULL);
77   fail_unless_equals_string (GST_OBJECT_NAME (pad1), "sink_0");
78 
79   pad2 = gst_element_get_request_pad (interleave, "sink_%u");
80   fail_unless (pad2 != NULL);
81   fail_unless_equals_string (GST_OBJECT_NAME (pad2), "sink_1");
82 
83   gst_element_release_request_pad (interleave, pad2);
84   gst_object_unref (pad2);
85   gst_element_release_request_pad (interleave, pad1);
86   gst_object_unref (pad1);
87 
88   gst_element_set_state (interleave, GST_STATE_NULL);
89   gst_object_unref (interleave);
90 }
91 
92 GST_END_TEST;
93 
94 static GstPad **mysrcpads, *mysinkpad;
95 static GstBus *bus;
96 static GstElement *interleave;
97 static GMutex data_mutex;
98 static GCond data_cond;
99 static gint have_data;
100 static gfloat input[2];
101 
102 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
103     GST_PAD_SINK,
104     GST_PAD_ALWAYS,
105     GST_STATIC_CAPS ("audio/x-raw, "
106         "format = (string) " GST_AUDIO_NE (F32) ", "
107         "channels = (int) 2, layout = (string) {interleaved, non-interleaved}, rate = (int) 48000"));
108 
109 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
110     GST_PAD_SRC,
111     GST_PAD_ALWAYS,
112     GST_STATIC_CAPS ("audio/x-raw, "
113         "format = (string) " GST_AUDIO_NE (F32) ", "
114         "channels = (int) 1, layout = (string) interleaved, rate = (int) 48000"));
115 
116 #define CAPS_48khz \
117         "audio/x-raw, " \
118         "format = (string) " GST_AUDIO_NE (F32) ", " \
119         "channels = (int) 1, layout = (string) non-interleaved," \
120         "rate = (int) 48000"
121 
122 static GstFlowReturn
interleave_chain_func(GstPad * pad,GstObject * parent,GstBuffer * buffer)123 interleave_chain_func (GstPad * pad, GstObject * parent, GstBuffer * buffer)
124 {
125   GstMapInfo map;
126   gfloat *outdata;
127   gint i;
128 
129   fail_unless (GST_IS_BUFFER (buffer));
130   fail_unless (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_GAP));
131   gst_buffer_map (buffer, &map, GST_MAP_READ);
132   outdata = (gfloat *) map.data;
133   fail_unless (outdata != NULL);
134 
135 #ifdef HAVE_VALGRIND
136   if (!(RUNNING_ON_VALGRIND))
137 #endif
138     for (i = 0; i < map.size / sizeof (float); i += 2) {
139       fail_unless_equals_float (outdata[i], input[0]);
140       fail_unless_equals_float (outdata[i + 1], input[1]);
141     }
142 
143   g_mutex_lock (&data_mutex);
144   have_data += map.size;
145   g_cond_signal (&data_cond);
146   g_mutex_unlock (&data_mutex);
147 
148   gst_buffer_unmap (buffer, &map);
149   gst_buffer_unref (buffer);
150 
151 
152   return GST_FLOW_OK;
153 }
154 
GST_START_TEST(test_audiointerleave_2ch)155 GST_START_TEST (test_audiointerleave_2ch)
156 {
157   GstElement *queue;
158   GstPad *sink0, *sink1, *src, *tmp;
159   GstCaps *caps;
160   gint i;
161   GstBuffer *inbuf;
162   gfloat *indata;
163   GstMapInfo map;
164 
165   mysrcpads = g_new0 (GstPad *, 2);
166 
167   have_data = 0;
168 
169   interleave = gst_element_factory_make ("audiointerleave", NULL);
170   fail_unless (interleave != NULL);
171 
172   g_object_set (interleave, "latency", GST_SECOND / 4, NULL);
173 
174   queue = gst_element_factory_make ("queue", "queue");
175   fail_unless (queue != NULL);
176 
177   sink0 = gst_element_get_request_pad (interleave, "sink_%u");
178   fail_unless (sink0 != NULL);
179   fail_unless_equals_string (GST_OBJECT_NAME (sink0), "sink_0");
180 
181   sink1 = gst_element_get_request_pad (interleave, "sink_%u");
182   fail_unless (sink1 != NULL);
183   fail_unless_equals_string (GST_OBJECT_NAME (sink1), "sink_1");
184 
185   mysrcpads[0] = gst_pad_new_from_static_template (&srctemplate, "src0");
186   fail_unless (mysrcpads[0] != NULL);
187 
188   caps = gst_caps_from_string (CAPS_48khz);
189   gst_pad_set_active (mysrcpads[0], TRUE);
190   gst_check_setup_events_audiointerleave (mysrcpads[0], interleave, caps,
191       GST_FORMAT_TIME, "0");
192   gst_pad_use_fixed_caps (mysrcpads[0]);
193 
194   mysrcpads[1] = gst_pad_new_from_static_template (&srctemplate, "src1");
195   fail_unless (mysrcpads[1] != NULL);
196 
197   gst_pad_set_active (mysrcpads[1], TRUE);
198   gst_check_setup_events_audiointerleave (mysrcpads[1], interleave, caps,
199       GST_FORMAT_TIME, "1");
200   gst_pad_use_fixed_caps (mysrcpads[1]);
201 
202   tmp = gst_element_get_static_pad (queue, "sink");
203   fail_unless (gst_pad_link (mysrcpads[0], tmp) == GST_PAD_LINK_OK);
204   gst_object_unref (tmp);
205   tmp = gst_element_get_static_pad (queue, "src");
206   fail_unless (gst_pad_link (tmp, sink0) == GST_PAD_LINK_OK);
207   gst_object_unref (tmp);
208 
209   fail_unless (gst_pad_link (mysrcpads[1], sink1) == GST_PAD_LINK_OK);
210 
211   mysinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
212   fail_unless (mysinkpad != NULL);
213   gst_pad_set_chain_function (mysinkpad, interleave_chain_func);
214   gst_pad_set_active (mysinkpad, TRUE);
215 
216   src = gst_element_get_static_pad (interleave, "src");
217   fail_unless (src != NULL);
218   fail_unless (gst_pad_link (src, mysinkpad) == GST_PAD_LINK_OK);
219   gst_object_unref (src);
220 
221   bus = gst_bus_new ();
222   gst_element_set_bus (interleave, bus);
223 
224   fail_unless (gst_element_set_state (interleave,
225           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
226   fail_unless (gst_element_set_state (queue,
227           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
228 
229   input[0] = -1.0;
230   inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
231   //GST_BUFFER_PTS (inbuf) = 0;
232   gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
233   indata = (gfloat *) map.data;
234   for (i = 0; i < 48000; i++)
235     indata[i] = -1.0;
236   gst_buffer_unmap (inbuf, &map);
237   fail_unless (gst_pad_push (mysrcpads[0], inbuf) == GST_FLOW_OK);
238 
239   input[1] = 1.0;
240   inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
241   //GST_BUFFER_PTS (inbuf) = 0;
242   gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
243   indata = (gfloat *) map.data;
244   for (i = 0; i < 48000; i++)
245     indata[i] = 1.0;
246   gst_buffer_unmap (inbuf, &map);
247   fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
248 
249   inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
250   //GST_BUFFER_PTS (inbuf) = GST_SECOND;
251   gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
252   indata = (gfloat *) map.data;
253   for (i = 0; i < 48000; i++)
254     indata[i] = -1.0;
255   gst_buffer_unmap (inbuf, &map);
256   fail_unless (gst_pad_push (mysrcpads[0], inbuf) == GST_FLOW_OK);
257 
258   inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
259   //GST_BUFFER_PTS (inbuf) = GST_SECOND;
260   gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
261   indata = (gfloat *) map.data;
262   for (i = 0; i < 48000; i++)
263     indata[i] = 1.0;
264   gst_buffer_unmap (inbuf, &map);
265   fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
266 
267   g_mutex_lock (&data_mutex);
268   while (have_data < 48000 * 2 * 2 * sizeof (float))
269     g_cond_wait (&data_cond, &data_mutex);
270   g_mutex_unlock (&data_mutex);
271 
272   gst_bus_set_flushing (bus, TRUE);
273   gst_element_set_state (interleave, GST_STATE_NULL);
274   gst_element_set_state (queue, GST_STATE_NULL);
275 
276   gst_object_unref (mysrcpads[0]);
277   gst_object_unref (mysrcpads[1]);
278   gst_object_unref (mysinkpad);
279 
280   gst_element_release_request_pad (interleave, sink0);
281   gst_object_unref (sink0);
282   gst_element_release_request_pad (interleave, sink1);
283   gst_object_unref (sink1);
284 
285   gst_object_unref (interleave);
286   gst_object_unref (queue);
287   gst_object_unref (bus);
288   gst_caps_unref (caps);
289 
290   g_free (mysrcpads);
291 }
292 
293 GST_END_TEST;
294 
GST_START_TEST(test_audiointerleave_2ch_1eos)295 GST_START_TEST (test_audiointerleave_2ch_1eos)
296 {
297   GstElement *queue;
298   GstPad *sink0, *sink1, *src, *tmp;
299   GstCaps *caps;
300   gint i;
301   GstBuffer *inbuf;
302   gfloat *indata;
303   GstMapInfo map;
304 
305   mysrcpads = g_new0 (GstPad *, 2);
306 
307   have_data = 0;
308 
309   interleave = gst_element_factory_make ("audiointerleave", NULL);
310   fail_unless (interleave != NULL);
311 
312   g_object_set (interleave, "latency", GST_SECOND / 4, NULL);
313 
314   queue = gst_element_factory_make ("queue", "queue");
315   fail_unless (queue != NULL);
316 
317   sink0 = gst_element_get_request_pad (interleave, "sink_%u");
318   fail_unless (sink0 != NULL);
319   fail_unless_equals_string (GST_OBJECT_NAME (sink0), "sink_0");
320 
321   sink1 = gst_element_get_request_pad (interleave, "sink_%u");
322   fail_unless (sink1 != NULL);
323   fail_unless_equals_string (GST_OBJECT_NAME (sink1), "sink_1");
324 
325   mysrcpads[0] = gst_pad_new_from_static_template (&srctemplate, "src0");
326   fail_unless (mysrcpads[0] != NULL);
327 
328   caps = gst_caps_from_string (CAPS_48khz);
329   gst_pad_set_active (mysrcpads[0], TRUE);
330   gst_check_setup_events_audiointerleave (mysrcpads[0], interleave, caps,
331       GST_FORMAT_TIME, "0");
332   gst_pad_use_fixed_caps (mysrcpads[0]);
333 
334   mysrcpads[1] = gst_pad_new_from_static_template (&srctemplate, "src1");
335   fail_unless (mysrcpads[1] != NULL);
336 
337   gst_pad_set_active (mysrcpads[1], TRUE);
338   gst_check_setup_events_audiointerleave (mysrcpads[1], interleave, caps,
339       GST_FORMAT_TIME, "1");
340   gst_pad_use_fixed_caps (mysrcpads[1]);
341 
342   tmp = gst_element_get_static_pad (queue, "sink");
343   fail_unless (gst_pad_link (mysrcpads[0], tmp) == GST_PAD_LINK_OK);
344   gst_object_unref (tmp);
345   tmp = gst_element_get_static_pad (queue, "src");
346   fail_unless (gst_pad_link (tmp, sink0) == GST_PAD_LINK_OK);
347   gst_object_unref (tmp);
348 
349   fail_unless (gst_pad_link (mysrcpads[1], sink1) == GST_PAD_LINK_OK);
350 
351   mysinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
352   fail_unless (mysinkpad != NULL);
353   gst_pad_set_chain_function (mysinkpad, interleave_chain_func);
354   gst_pad_set_active (mysinkpad, TRUE);
355 
356   src = gst_element_get_static_pad (interleave, "src");
357   fail_unless (src != NULL);
358   fail_unless (gst_pad_link (src, mysinkpad) == GST_PAD_LINK_OK);
359   gst_object_unref (src);
360 
361   bus = gst_bus_new ();
362   gst_element_set_bus (interleave, bus);
363 
364   fail_unless (gst_element_set_state (interleave,
365           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
366   fail_unless (gst_element_set_state (queue,
367           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
368 
369   input[0] = -1.0;
370   inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
371   GST_BUFFER_PTS (inbuf) = 0;
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[0], inbuf) == GST_FLOW_OK);
378 
379   input[1] = 1.0;
380   inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
381   GST_BUFFER_PTS (inbuf) = 0;
382   gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
383   indata = (gfloat *) map.data;
384   for (i = 0; i < 48000; i++)
385     indata[i] = 1.0;
386   gst_buffer_unmap (inbuf, &map);
387   fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
388 
389   g_mutex_lock (&data_mutex);
390   /* 48000 samples per buffer * 2 sources * 2 buffers */
391   while (have_data != 48000 * 2 * sizeof (float))
392     g_cond_wait (&data_cond, &data_mutex);
393   g_mutex_unlock (&data_mutex);
394 
395   input[0] = 0.0;
396   gst_pad_push_event (mysrcpads[0], gst_event_new_eos ());
397 
398   input[1] = 1.0;
399   inbuf = gst_buffer_new_and_alloc (48000 * sizeof (gfloat));
400   GST_BUFFER_PTS (inbuf) = GST_SECOND;
401   gst_buffer_map (inbuf, &map, GST_MAP_WRITE);
402   indata = (gfloat *) map.data;
403   for (i = 0; i < 48000; i++)
404     indata[i] = 1.0;
405   gst_buffer_unmap (inbuf, &map);
406   fail_unless (gst_pad_push (mysrcpads[1], inbuf) == GST_FLOW_OK);
407 
408   g_mutex_lock (&data_mutex);
409   /* 48000 samples per buffer * 2 sources * 2 buffers */
410   while (have_data != 48000 * 2 * 2 * sizeof (float))
411     g_cond_wait (&data_cond, &data_mutex);
412   g_mutex_unlock (&data_mutex);
413 
414   gst_bus_set_flushing (bus, TRUE);
415   gst_element_set_state (interleave, GST_STATE_NULL);
416   gst_element_set_state (queue, GST_STATE_NULL);
417 
418   gst_object_unref (mysrcpads[0]);
419   gst_object_unref (mysrcpads[1]);
420   gst_object_unref (mysinkpad);
421 
422   gst_element_release_request_pad (interleave, sink0);
423   gst_object_unref (sink0);
424   gst_element_release_request_pad (interleave, sink1);
425   gst_object_unref (sink1);
426 
427   gst_object_unref (interleave);
428   gst_object_unref (queue);
429   gst_object_unref (bus);
430   gst_caps_unref (caps);
431 
432   g_free (mysrcpads);
433 }
434 
435 GST_END_TEST;
436 
437 static void
src_handoff_float32(GstElement * element,GstBuffer * buffer,GstPad * pad,gboolean interleaved,gpointer user_data)438 src_handoff_float32 (GstElement * element, GstBuffer * buffer, GstPad * pad,
439     gboolean interleaved, gpointer user_data)
440 {
441   gint n = GPOINTER_TO_INT (user_data);
442   gfloat *data;
443   gint i, num_samples;
444   GstCaps *caps;
445   guint64 mask;
446   GstAudioChannelPosition pos;
447   GstMapInfo map;
448 
449   fail_unless (gst_buffer_is_writable (buffer));
450 
451   switch (n) {
452     case 0:
453     case 1:
454     case 2:
455       pos = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
456       break;
457     case 3:
458       pos = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
459       break;
460     default:
461       pos = GST_AUDIO_CHANNEL_POSITION_INVALID;
462       break;
463   }
464 
465   mask = G_GUINT64_CONSTANT (1) << pos;
466 
467   caps = gst_caps_new_simple ("audio/x-raw",
468       "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
469       "channels", G_TYPE_INT, 1,
470       "layout", G_TYPE_STRING, interleaved ? "interleaved" : "non-interleaved",
471       "channel-mask", GST_TYPE_BITMASK, mask, "rate", G_TYPE_INT, 48000, NULL);
472 
473   gst_pad_set_caps (pad, caps);
474   gst_caps_unref (caps);
475 
476   fail_unless (gst_buffer_map (buffer, &map, GST_MAP_WRITE));
477   fail_unless (map.size % sizeof (gfloat) == 0);
478 
479   fail_unless (map.size > 480);
480 
481   num_samples = map.size / sizeof (gfloat);
482   data = (gfloat *) map.data;
483 
484   for (i = 0; i < num_samples; i++)
485     data[i] = (n % 2 == 0) ? -1.0 : 1.0;
486 
487   gst_buffer_unmap (buffer, &map);
488 }
489 
490 static void
src_handoff_float32_audiointerleaved(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)491 src_handoff_float32_audiointerleaved (GstElement * element, GstBuffer * buffer,
492     GstPad * pad, gpointer user_data)
493 {
494   src_handoff_float32 (element, buffer, pad, TRUE, user_data);
495 }
496 
497 static void
src_handoff_float32_non_audiointerleaved(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)498 src_handoff_float32_non_audiointerleaved (GstElement * element,
499     GstBuffer * buffer, GstPad * pad, gpointer user_data)
500 {
501   src_handoff_float32 (element, buffer, pad, FALSE, user_data);
502 }
503 
504 static void
sink_handoff_float32(GstElement * element,GstBuffer * buffer,GstPad * pad,gpointer user_data)505 sink_handoff_float32 (GstElement * element, GstBuffer * buffer, GstPad * pad,
506     gpointer user_data)
507 {
508   gint i;
509   GstMapInfo map;
510   gfloat *data;
511   GstCaps *caps, *ccaps;
512   gint n = GPOINTER_TO_INT (user_data);
513   guint64 mask;
514 
515   fail_unless (GST_IS_BUFFER (buffer));
516   gst_buffer_map (buffer, &map, GST_MAP_READ);
517   data = (gfloat *) map.data;
518 
519   /* Give a little leeway for rounding errors */
520   fail_unless (gst_util_uint64_scale (map.size, GST_SECOND,
521           48000 * 2 * sizeof (gfloat)) <= GST_BUFFER_DURATION (buffer) + 1 ||
522       gst_util_uint64_scale (map.size, GST_SECOND,
523           48000 * 2 * sizeof (gfloat)) >= GST_BUFFER_DURATION (buffer) - 1);
524 
525   if (n == 0 || n == 3) {
526     GstAudioChannelPosition pos[2] =
527         { GST_AUDIO_CHANNEL_POSITION_NONE, GST_AUDIO_CHANNEL_POSITION_NONE };
528     gst_audio_channel_positions_to_mask (pos, 2, FALSE, &mask);
529   } else if (n == 1) {
530     GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
531       GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
532     };
533     gst_audio_channel_positions_to_mask (pos, 2, FALSE, &mask);
534   } else if (n == 2) {
535     GstAudioChannelPosition pos[2] = { GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
536       GST_AUDIO_CHANNEL_POSITION_REAR_CENTER
537     };
538     gst_audio_channel_positions_to_mask (pos, 2, FALSE, &mask);
539   } else {
540     g_assert_not_reached ();
541   }
542 
543   if (pad) {
544     caps = gst_caps_new_simple ("audio/x-raw",
545         "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
546         "channels", G_TYPE_INT, 2, "rate", G_TYPE_INT, 48000,
547         "layout", G_TYPE_STRING, "interleaved",
548         "channel-mask", GST_TYPE_BITMASK, mask, NULL);
549 
550     ccaps = gst_pad_get_current_caps (pad);
551     fail_unless (gst_caps_is_equal (caps, ccaps));
552     gst_caps_unref (ccaps);
553     gst_caps_unref (caps);
554   }
555 #ifdef HAVE_VALGRIND
556   if (!(RUNNING_ON_VALGRIND))
557 #endif
558     for (i = 0; i < map.size / sizeof (float); i += 2) {
559       fail_unless_equals_float (data[i], -1.0);
560       if (n != 3)
561         fail_unless_equals_float (data[i + 1], 1.0);
562     }
563   have_data += map.size;
564 
565   gst_buffer_unmap (buffer, &map);
566 
567 }
568 
569 static void
test_audiointerleave_2ch_pipeline(gboolean interleaved)570 test_audiointerleave_2ch_pipeline (gboolean interleaved)
571 {
572   GstElement *pipeline, *queue, *src1, *src2, *interleave, *sink;
573   GstPad *sinkpad0, *sinkpad1, *tmp, *tmp2;
574   GstMessage *msg;
575   void *src_handoff_float32 =
576       interleaved ? &src_handoff_float32_audiointerleaved :
577       &src_handoff_float32_non_audiointerleaved;
578 
579   have_data = 0;
580 
581   pipeline = (GstElement *) gst_pipeline_new ("pipeline");
582   fail_unless (pipeline != NULL);
583 
584   src1 = gst_element_factory_make ("fakesrc", "src1");
585   fail_unless (src1 != NULL);
586   g_object_set (src1, "num-buffers", 4, NULL);
587   g_object_set (src1, "sizetype", 2,
588       "sizemax", (int) 48000 * sizeof (gfloat),
589       "datarate", (int) 48000 * sizeof (gfloat), NULL);
590   g_object_set (src1, "signal-handoffs", TRUE, NULL);
591   g_object_set (src1, "format", GST_FORMAT_TIME, NULL);
592   g_signal_connect (src1, "handoff", G_CALLBACK (src_handoff_float32),
593       GINT_TO_POINTER (0));
594   gst_bin_add (GST_BIN (pipeline), src1);
595 
596   src2 = gst_element_factory_make ("fakesrc", "src2");
597   fail_unless (src2 != NULL);
598   g_object_set (src2, "num-buffers", 4, NULL);
599   g_object_set (src2, "sizetype", 2,
600       "sizemax", (int) 48000 * sizeof (gfloat),
601       "datarate", (int) 48000 * sizeof (gfloat), NULL);
602   g_object_set (src2, "signal-handoffs", TRUE, NULL);
603   g_object_set (src2, "format", GST_FORMAT_TIME, NULL);
604   g_signal_connect (src2, "handoff", G_CALLBACK (src_handoff_float32),
605       GINT_TO_POINTER (1));
606   gst_bin_add (GST_BIN (pipeline), src2);
607 
608   queue = gst_element_factory_make ("queue", "queue");
609   fail_unless (queue != NULL);
610   gst_bin_add (GST_BIN (pipeline), queue);
611 
612   interleave = gst_element_factory_make ("audiointerleave", "audiointerleave");
613   fail_unless (interleave != NULL);
614   gst_bin_add (GST_BIN (pipeline), gst_object_ref (interleave));
615 
616   sinkpad0 = gst_element_get_request_pad (interleave, "sink_%u");
617   fail_unless (sinkpad0 != NULL);
618   tmp = gst_element_get_static_pad (src1, "src");
619   fail_unless (gst_pad_link (tmp, sinkpad0) == GST_PAD_LINK_OK);
620   gst_object_unref (tmp);
621 
622   sinkpad1 = gst_element_get_request_pad (interleave, "sink_%u");
623   fail_unless (sinkpad1 != NULL);
624   tmp = gst_element_get_static_pad (src2, "src");
625   tmp2 = gst_element_get_static_pad (queue, "sink");
626   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
627   gst_object_unref (tmp);
628   gst_object_unref (tmp2);
629   tmp = gst_element_get_static_pad (queue, "src");
630   fail_unless (gst_pad_link (tmp, sinkpad1) == GST_PAD_LINK_OK);
631   gst_object_unref (tmp);
632 
633   sink = gst_element_factory_make ("fakesink", "sink");
634   fail_unless (sink != NULL);
635   g_object_set (sink, "signal-handoffs", TRUE, NULL);
636   g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff_float32),
637       GINT_TO_POINTER (0));
638   gst_bin_add (GST_BIN (pipeline), sink);
639   tmp = gst_element_get_static_pad (interleave, "src");
640   tmp2 = gst_element_get_static_pad (sink, "sink");
641   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
642   gst_object_unref (tmp);
643   gst_object_unref (tmp2);
644 
645   gst_element_set_state (pipeline, GST_STATE_PLAYING);
646 
647   msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
648   gst_message_unref (msg);
649 
650   /* 48000 samples per buffer * 2 sources * 4 buffers */
651   fail_unless (have_data == 48000 * 2 * 4 * sizeof (gfloat));
652 
653   gst_element_set_state (pipeline, GST_STATE_NULL);
654   gst_element_release_request_pad (interleave, sinkpad0);
655   gst_object_unref (sinkpad0);
656   gst_element_release_request_pad (interleave, sinkpad1);
657   gst_object_unref (sinkpad1);
658   gst_object_unref (interleave);
659   gst_object_unref (pipeline);
660 }
661 
GST_START_TEST(test_audiointerleave_2ch_pipeline_audiointerleaved)662 GST_START_TEST (test_audiointerleave_2ch_pipeline_audiointerleaved)
663 {
664   test_audiointerleave_2ch_pipeline (TRUE);
665 }
666 
667 GST_END_TEST;
668 
GST_START_TEST(test_audiointerleave_2ch_pipeline_non_audiointerleaved)669 GST_START_TEST (test_audiointerleave_2ch_pipeline_non_audiointerleaved)
670 {
671   test_audiointerleave_2ch_pipeline (FALSE);
672 }
673 
674 GST_END_TEST;
675 
GST_START_TEST(test_audiointerleave_2ch_pipeline_input_chanpos)676 GST_START_TEST (test_audiointerleave_2ch_pipeline_input_chanpos)
677 {
678   GstElement *pipeline, *queue, *src1, *src2, *interleave, *sink;
679   GstPad *sinkpad0, *sinkpad1, *tmp, *tmp2;
680   GstMessage *msg;
681 
682   have_data = 0;
683 
684   pipeline = (GstElement *) gst_pipeline_new ("pipeline");
685   fail_unless (pipeline != NULL);
686 
687   src1 = gst_element_factory_make ("fakesrc", "src1");
688   fail_unless (src1 != NULL);
689   g_object_set (src1, "num-buffers", 4, NULL);
690   g_object_set (src1, "sizetype", 2,
691       "sizemax", (int) 48000 * sizeof (gfloat),
692       "datarate", (int) 48000 * sizeof (gfloat), NULL);
693   g_object_set (src1, "signal-handoffs", TRUE, NULL);
694   g_object_set (src1, "format", GST_FORMAT_TIME, NULL);
695   g_signal_connect (src1, "handoff",
696       G_CALLBACK (src_handoff_float32_audiointerleaved), GINT_TO_POINTER (2));
697   gst_bin_add (GST_BIN (pipeline), src1);
698 
699   src2 = gst_element_factory_make ("fakesrc", "src2");
700   fail_unless (src2 != NULL);
701   g_object_set (src2, "num-buffers", 4, NULL);
702   g_object_set (src2, "sizetype", 2,
703       "sizemax", (int) 48000 * sizeof (gfloat),
704       "datarate", (int) 48000 * sizeof (gfloat), NULL);
705   g_object_set (src2, "signal-handoffs", TRUE, NULL);
706   g_object_set (src2, "format", GST_FORMAT_TIME, NULL);
707   g_signal_connect (src2, "handoff",
708       G_CALLBACK (src_handoff_float32_audiointerleaved), GINT_TO_POINTER (3));
709   gst_bin_add (GST_BIN (pipeline), src2);
710 
711   queue = gst_element_factory_make ("queue", "queue");
712   fail_unless (queue != NULL);
713   gst_bin_add (GST_BIN (pipeline), queue);
714 
715   interleave = gst_element_factory_make ("audiointerleave", "audiointerleave");
716   fail_unless (interleave != NULL);
717   g_object_set (interleave, "channel-positions-from-input", TRUE, NULL);
718   gst_bin_add (GST_BIN (pipeline), gst_object_ref (interleave));
719 
720   sinkpad0 = gst_element_get_request_pad (interleave, "sink_%u");
721   fail_unless (sinkpad0 != NULL);
722   tmp = gst_element_get_static_pad (src1, "src");
723   fail_unless (gst_pad_link (tmp, sinkpad0) == GST_PAD_LINK_OK);
724   gst_object_unref (tmp);
725 
726   sinkpad1 = gst_element_get_request_pad (interleave, "sink_%u");
727   fail_unless (sinkpad1 != NULL);
728   tmp = gst_element_get_static_pad (src2, "src");
729   tmp2 = gst_element_get_static_pad (queue, "sink");
730   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
731   gst_object_unref (tmp);
732   gst_object_unref (tmp2);
733   tmp = gst_element_get_static_pad (queue, "src");
734   fail_unless (gst_pad_link (tmp, sinkpad1) == GST_PAD_LINK_OK);
735   gst_object_unref (tmp);
736 
737   sink = gst_element_factory_make ("fakesink", "sink");
738   fail_unless (sink != NULL);
739   g_object_set (sink, "signal-handoffs", TRUE, NULL);
740   g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff_float32),
741       GINT_TO_POINTER (1));
742   gst_bin_add (GST_BIN (pipeline), sink);
743   tmp = gst_element_get_static_pad (interleave, "src");
744   tmp2 = gst_element_get_static_pad (sink, "sink");
745   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
746   gst_object_unref (tmp);
747   gst_object_unref (tmp2);
748 
749   gst_element_set_state (pipeline, GST_STATE_PLAYING);
750 
751   msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
752   gst_message_unref (msg);
753 
754   /* 48000 samples per buffer * 2 sources * 4 buffers */
755   fail_unless (have_data == 48000 * 2 * 4 * sizeof (gfloat));
756 
757   gst_element_set_state (pipeline, GST_STATE_NULL);
758   gst_element_release_request_pad (interleave, sinkpad0);
759   gst_object_unref (sinkpad0);
760   gst_element_release_request_pad (interleave, sinkpad1);
761   gst_object_unref (sinkpad1);
762   gst_object_unref (interleave);
763   gst_object_unref (pipeline);
764 }
765 
766 GST_END_TEST;
767 
GST_START_TEST(test_audiointerleave_2ch_pipeline_custom_chanpos)768 GST_START_TEST (test_audiointerleave_2ch_pipeline_custom_chanpos)
769 {
770   GstElement *pipeline, *queue, *src1, *src2, *interleave, *sink;
771   GstPad *sinkpad0, *sinkpad1, *tmp, *tmp2;
772   GstMessage *msg;
773   GValueArray *arr;
774   GValue val = { 0, };
775 
776   have_data = 0;
777 
778   pipeline = (GstElement *) gst_pipeline_new ("pipeline");
779   fail_unless (pipeline != NULL);
780 
781   src1 = gst_element_factory_make ("fakesrc", "src1");
782   fail_unless (src1 != NULL);
783   g_object_set (src1, "num-buffers", 4, NULL);
784   g_object_set (src1, "signal-handoffs", TRUE, NULL);
785   g_object_set (src1, "sizetype", 2,
786       "sizemax", (int) 48000 * sizeof (gfloat),
787       "datarate", (int) 48000 * sizeof (gfloat), NULL);
788   g_object_set (src1, "format", GST_FORMAT_TIME, NULL);
789   g_signal_connect (src1, "handoff",
790       G_CALLBACK (src_handoff_float32_audiointerleaved), GINT_TO_POINTER (0));
791   gst_bin_add (GST_BIN (pipeline), src1);
792 
793   src2 = gst_element_factory_make ("fakesrc", "src2");
794   fail_unless (src2 != NULL);
795   g_object_set (src2, "num-buffers", 4, NULL);
796   g_object_set (src2, "signal-handoffs", TRUE, NULL);
797   g_object_set (src2, "sizetype", 2,
798       "sizemax", (int) 48000 * sizeof (gfloat),
799       "datarate", (int) 48000 * sizeof (gfloat), NULL);
800   g_object_set (src2, "format", GST_FORMAT_TIME, NULL);
801   g_signal_connect (src2, "handoff",
802       G_CALLBACK (src_handoff_float32_audiointerleaved), GINT_TO_POINTER (1));
803   gst_bin_add (GST_BIN (pipeline), src2);
804 
805   queue = gst_element_factory_make ("queue", "queue");
806   fail_unless (queue != NULL);
807   gst_bin_add (GST_BIN (pipeline), queue);
808 
809   interleave = gst_element_factory_make ("audiointerleave", "audiointerleave");
810   fail_unless (interleave != NULL);
811   g_object_set (interleave, "channel-positions-from-input", FALSE, NULL);
812   arr = g_value_array_new (2);
813 
814   g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION);
815   g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER);
816   g_value_array_append (arr, &val);
817   g_value_reset (&val);
818   g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_REAR_CENTER);
819   g_value_array_append (arr, &val);
820   g_value_unset (&val);
821 
822   g_object_set (interleave, "channel-positions", arr, NULL);
823   g_value_array_free (arr);
824   gst_bin_add (GST_BIN (pipeline), gst_object_ref (interleave));
825 
826   sinkpad0 = gst_element_get_request_pad (interleave, "sink_%u");
827   fail_unless (sinkpad0 != NULL);
828   tmp = gst_element_get_static_pad (src1, "src");
829   fail_unless (gst_pad_link (tmp, sinkpad0) == GST_PAD_LINK_OK);
830   gst_object_unref (tmp);
831 
832   sinkpad1 = gst_element_get_request_pad (interleave, "sink_%u");
833   fail_unless (sinkpad1 != NULL);
834   tmp = gst_element_get_static_pad (src2, "src");
835   tmp2 = gst_element_get_static_pad (queue, "sink");
836   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
837   gst_object_unref (tmp);
838   gst_object_unref (tmp2);
839   tmp = gst_element_get_static_pad (queue, "src");
840   fail_unless (gst_pad_link (tmp, sinkpad1) == GST_PAD_LINK_OK);
841   gst_object_unref (tmp);
842 
843   sink = gst_element_factory_make ("fakesink", "sink");
844   fail_unless (sink != NULL);
845   g_object_set (sink, "signal-handoffs", TRUE, NULL);
846   g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff_float32),
847       GINT_TO_POINTER (2));
848   gst_bin_add (GST_BIN (pipeline), sink);
849   tmp = gst_element_get_static_pad (interleave, "src");
850   tmp2 = gst_element_get_static_pad (sink, "sink");
851   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
852   gst_object_unref (tmp);
853   gst_object_unref (tmp2);
854 
855   gst_element_set_state (pipeline, GST_STATE_PLAYING);
856 
857   msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
858   gst_message_unref (msg);
859 
860   /* 48000 samples per buffer * 2 sources * 4 buffers */
861   fail_unless (have_data == 48000 * 2 * 4 * sizeof (gfloat));
862 
863   gst_element_set_state (pipeline, GST_STATE_NULL);
864   gst_element_release_request_pad (interleave, sinkpad0);
865   gst_object_unref (sinkpad0);
866   gst_element_release_request_pad (interleave, sinkpad1);
867   gst_object_unref (sinkpad1);
868   gst_object_unref (interleave);
869   gst_object_unref (pipeline);
870 }
871 
872 GST_END_TEST;
873 
GST_START_TEST(test_audiointerleave_2ch_pipeline_no_chanpos)874 GST_START_TEST (test_audiointerleave_2ch_pipeline_no_chanpos)
875 {
876   GstElement *pipeline, *queue, *src1, *src2, *interleave, *sink;
877   GstPad *sinkpad0, *sinkpad1, *tmp, *tmp2;
878   GstMessage *msg;
879 
880   have_data = 0;
881 
882   pipeline = (GstElement *) gst_pipeline_new ("pipeline");
883   fail_unless (pipeline != NULL);
884 
885   src1 = gst_element_factory_make ("fakesrc", "src1");
886   fail_unless (src1 != NULL);
887   g_object_set (src1, "num-buffers", 4, NULL);
888   g_object_set (src1, "signal-handoffs", TRUE, NULL);
889   g_object_set (src1, "sizetype", 2,
890       "sizemax", (int) 48000 * sizeof (gfloat),
891       "datarate", (int) 48000 * sizeof (gfloat), NULL);
892   g_object_set (src1, "format", GST_FORMAT_TIME, NULL);
893   g_signal_connect (src1, "handoff",
894       G_CALLBACK (src_handoff_float32_audiointerleaved), GINT_TO_POINTER (0));
895   gst_bin_add (GST_BIN (pipeline), src1);
896 
897   src2 = gst_element_factory_make ("fakesrc", "src2");
898   fail_unless (src2 != NULL);
899   g_object_set (src2, "num-buffers", 4, NULL);
900   g_object_set (src2, "signal-handoffs", TRUE, NULL);
901   g_object_set (src2, "sizetype", 2,
902       "sizemax", (int) 48000 * sizeof (gfloat),
903       "datarate", (int) 48000 * sizeof (gfloat), NULL);
904   g_object_set (src2, "format", GST_FORMAT_TIME, NULL);
905   g_signal_connect (src2, "handoff",
906       G_CALLBACK (src_handoff_float32_audiointerleaved), GINT_TO_POINTER (1));
907   gst_bin_add (GST_BIN (pipeline), src2);
908 
909   queue = gst_element_factory_make ("queue", "queue");
910   fail_unless (queue != NULL);
911   gst_bin_add (GST_BIN (pipeline), queue);
912 
913   interleave = gst_element_factory_make ("audiointerleave", "audiointerleave");
914   fail_unless (interleave != NULL);
915   g_object_set (interleave, "channel-positions-from-input", FALSE, NULL);
916   gst_bin_add (GST_BIN (pipeline), gst_object_ref (interleave));
917 
918   sinkpad0 = gst_element_get_request_pad (interleave, "sink_%u");
919   fail_unless (sinkpad0 != NULL);
920   tmp = gst_element_get_static_pad (src1, "src");
921   fail_unless (gst_pad_link (tmp, sinkpad0) == GST_PAD_LINK_OK);
922   gst_object_unref (tmp);
923 
924   sinkpad1 = gst_element_get_request_pad (interleave, "sink_%u");
925   fail_unless (sinkpad1 != NULL);
926   tmp = gst_element_get_static_pad (src2, "src");
927   tmp2 = gst_element_get_static_pad (queue, "sink");
928   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
929   gst_object_unref (tmp);
930   gst_object_unref (tmp2);
931   tmp = gst_element_get_static_pad (queue, "src");
932   fail_unless (gst_pad_link (tmp, sinkpad1) == GST_PAD_LINK_OK);
933   gst_object_unref (tmp);
934 
935   sink = gst_element_factory_make ("fakesink", "sink");
936   fail_unless (sink != NULL);
937   g_object_set (sink, "signal-handoffs", TRUE, NULL);
938   g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff_float32),
939       GINT_TO_POINTER (0));
940   gst_bin_add (GST_BIN (pipeline), sink);
941   tmp = gst_element_get_static_pad (interleave, "src");
942   tmp2 = gst_element_get_static_pad (sink, "sink");
943   fail_unless (gst_pad_link (tmp, tmp2) == GST_PAD_LINK_OK);
944   gst_object_unref (tmp);
945   gst_object_unref (tmp2);
946 
947   gst_element_set_state (pipeline, GST_STATE_PLAYING);
948 
949   msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
950   gst_message_unref (msg);
951 
952   /* 48000 samples per buffer * 2 sources * 4 buffers */
953   fail_unless (have_data == 48000 * 2 * 4 * sizeof (gfloat));
954 
955   gst_element_set_state (pipeline, GST_STATE_NULL);
956   gst_element_release_request_pad (interleave, sinkpad0);
957   gst_object_unref (sinkpad0);
958   gst_element_release_request_pad (interleave, sinkpad1);
959   gst_object_unref (sinkpad1);
960   gst_object_unref (interleave);
961   gst_object_unref (pipeline);
962 }
963 
964 GST_END_TEST;
965 
966 static void
forward_check_event(GstHarness * h,GstHarness * hsrc,GstEventType type)967 forward_check_event (GstHarness * h, GstHarness * hsrc, GstEventType type)
968 {
969   GstEvent *e;
970 
971   e = gst_harness_pull_event (hsrc);
972   fail_unless (GST_EVENT_TYPE (e) == type);
973   gst_harness_push_event (h, e);
974 }
975 
GST_START_TEST(test_audiointerleave_2ch_smallbuf)976 GST_START_TEST (test_audiointerleave_2ch_smallbuf)
977 {
978   GstElement *audiointerleave;
979   GstHarness *hsrc;
980   GstHarness *h;
981   GstHarness *h2;
982   GstBuffer *buffer;
983   gint i;
984   GstEvent *ev;
985   GstCaps *ecaps, *caps;
986 
987   audiointerleave = gst_element_factory_make ("audiointerleave", NULL);
988 
989   g_object_set (audiointerleave, "latency", GST_SECOND / 2,
990       "output-buffer-duration", GST_SECOND / 4, NULL);
991 
992   h = gst_harness_new_with_element (audiointerleave, "sink_0", "src");
993   gst_harness_use_testclock (h);
994 
995   h2 = gst_harness_new_with_element (audiointerleave, "sink_1", NULL);
996   gst_harness_set_src_caps_str (h2, "audio/x-raw, "
997       "format=" GST_AUDIO_NE (F32) ", channels=(int)1,"
998       " layout=interleaved, rate=48000, channel-mask=(bitmask)8");
999 
1000   hsrc = gst_harness_new ("fakesrc");
1001   gst_harness_use_testclock (hsrc);
1002   g_object_set (hsrc->element,
1003       "is-live", TRUE,
1004       "sync", TRUE,
1005       "signal-handoffs", TRUE,
1006       "format", GST_FORMAT_TIME,
1007       "sizetype", 2,
1008       "sizemax", (int) 480 * sizeof (gfloat),
1009       "datarate", (int) 48000 * sizeof (gfloat), NULL);
1010   g_signal_connect (hsrc->element, "handoff",
1011       G_CALLBACK (src_handoff_float32_audiointerleaved), GINT_TO_POINTER (2));
1012   gst_harness_play (hsrc);
1013 
1014   gst_harness_crank_single_clock_wait (hsrc);
1015   forward_check_event (h, hsrc, GST_EVENT_STREAM_START);
1016   forward_check_event (h, hsrc, GST_EVENT_CAPS);
1017   forward_check_event (h, hsrc, GST_EVENT_SEGMENT);
1018   gst_harness_push (h, gst_harness_pull (hsrc));        /* buffer */
1019 
1020   for (i = 0; i < 24; i++) {
1021     gst_harness_crank_single_clock_wait (hsrc);
1022     forward_check_event (h, hsrc, GST_EVENT_CAPS);
1023     gst_harness_push (h, gst_harness_pull (hsrc));      /* buffer */
1024   }
1025 
1026   gst_harness_crank_single_clock_wait (h);
1027 
1028 
1029   gst_event_unref (gst_harness_pull_event (h)); /* stream-start */
1030   ev = gst_harness_pull_event (h);      /* caps */
1031   fail_unless_equals_int (GST_EVENT_CAPS, GST_EVENT_TYPE (ev));
1032 
1033   caps = gst_caps_new_simple ("audio/x-raw",
1034       "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
1035       "channels", G_TYPE_INT, 2,
1036       "layout", G_TYPE_STRING, "interleaved",
1037       "rate", G_TYPE_INT, 48000, "channel-mask", GST_TYPE_BITMASK,
1038       (guint64) 0x9, NULL);
1039 
1040   gst_event_parse_caps (ev, &ecaps);
1041   gst_check_caps_equal (ecaps, caps);
1042   gst_caps_unref (caps);
1043   gst_event_unref (ev);
1044 
1045   /* eat the caps processing */
1046   gst_harness_crank_single_clock_wait (h);
1047   for (i = 0; i < 23; i++)
1048     gst_harness_crank_single_clock_wait (h);
1049   fail_unless_equals_uint64 (gst_clock_get_time (GST_ELEMENT_CLOCK
1050           (h->element)), 750 * GST_MSECOND);
1051 
1052   buffer = gst_harness_pull (h);
1053   sink_handoff_float32 (NULL, buffer, NULL, GUINT_TO_POINTER (3));
1054   gst_buffer_unref (buffer);
1055   fail_unless_equals_int (gst_harness_buffers_received (h), 1);
1056 
1057   for (i = 0; i < 50; i++) {
1058     gst_harness_crank_single_clock_wait (hsrc);
1059     forward_check_event (h, hsrc, GST_EVENT_CAPS);
1060     gst_harness_push (h, gst_harness_pull (hsrc));      /* buffer */
1061   }
1062   for (i = 0; i < 25; i++)
1063     gst_harness_crank_single_clock_wait (h);
1064   fail_unless_equals_uint64 (gst_clock_get_time (GST_ELEMENT_CLOCK
1065           (h->element)), 1000 * GST_MSECOND);
1066   buffer = gst_harness_pull (h);
1067   sink_handoff_float32 (NULL, buffer, NULL, GUINT_TO_POINTER (3));
1068   gst_buffer_unref (buffer);
1069   fail_unless_equals_int (gst_harness_buffers_received (h), 2);
1070 
1071   for (i = 0; i < 25; i++) {
1072     gst_harness_crank_single_clock_wait (hsrc);
1073     forward_check_event (h, hsrc, GST_EVENT_CAPS);
1074     gst_harness_push (h, gst_harness_pull (hsrc));      /* buffer */
1075   }
1076   for (i = 0; i < 25; i++)
1077     gst_harness_crank_single_clock_wait (h);
1078   fail_unless_equals_uint64 (gst_clock_get_time (GST_ELEMENT_CLOCK
1079           (h->element)), 1250 * GST_MSECOND);
1080   buffer = gst_harness_pull (h);
1081   sink_handoff_float32 (NULL, buffer, NULL, GUINT_TO_POINTER (3));
1082   gst_buffer_unref (buffer);
1083   fail_unless_equals_int (gst_harness_buffers_received (h), 3);
1084 
1085   gst_harness_push_event (h, gst_event_new_eos ());
1086 
1087   for (i = 0; i < 25; i++)
1088     gst_harness_crank_single_clock_wait (h);
1089   fail_unless_equals_uint64 (gst_clock_get_time (GST_ELEMENT_CLOCK
1090           (h->element)), 1500 * GST_MSECOND);
1091   buffer = gst_harness_pull (h);
1092   sink_handoff_float32 (NULL, buffer, NULL, GUINT_TO_POINTER (3));
1093   gst_buffer_unref (buffer);
1094 
1095   fail_unless_equals_int (gst_harness_buffers_received (h), 4);
1096 
1097   gst_harness_teardown (h2);
1098   gst_harness_teardown (h);
1099   gst_harness_teardown (hsrc);
1100   gst_object_unref (audiointerleave);
1101 }
1102 
1103 GST_END_TEST;
1104 
1105 static Suite *
audiointerleave_suite(void)1106 audiointerleave_suite (void)
1107 {
1108   Suite *s = suite_create ("audiointerleave");
1109   TCase *tc_chain = tcase_create ("general");
1110 
1111   suite_add_tcase (s, tc_chain);
1112   tcase_set_timeout (tc_chain, 180);
1113   tcase_add_test (tc_chain, test_create_and_unref);
1114   tcase_add_test (tc_chain, test_request_pads);
1115   tcase_add_test (tc_chain, test_audiointerleave_2ch);
1116   tcase_add_test (tc_chain, test_audiointerleave_2ch_1eos);
1117   tcase_add_test (tc_chain, test_audiointerleave_2ch_pipeline_audiointerleaved);
1118   tcase_add_test (tc_chain,
1119       test_audiointerleave_2ch_pipeline_non_audiointerleaved);
1120   tcase_add_test (tc_chain, test_audiointerleave_2ch_pipeline_input_chanpos);
1121   tcase_add_test (tc_chain, test_audiointerleave_2ch_pipeline_custom_chanpos);
1122   tcase_add_test (tc_chain, test_audiointerleave_2ch_pipeline_no_chanpos);
1123   tcase_add_test (tc_chain, test_audiointerleave_2ch_smallbuf);
1124 
1125   return s;
1126 }
1127 
1128 GST_CHECK_MAIN (audiointerleave);
1129