1 /* GStreamer
2  *
3  * unit tests for audio support library
4  *
5  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
6  * Copyright (C) 2011 Sebastian Dröge <sebastian.droege@collabora.co.uk>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include <gst/check/gstcheck.h>
29 
30 #include <gst/audio/audio.h>
31 #include <string.h>
32 
33 static GstBuffer *
make_buffer(guint8 ** _data)34 make_buffer (guint8 ** _data)
35 {
36   GstBuffer *buf = gst_buffer_new ();
37   guint8 *data = (guint8 *) g_malloc (1000);
38 
39   gst_buffer_append_memory (buf,
40       gst_memory_new_wrapped (0, data, 1000, 0, 1000, data, g_free));
41   if (_data)
42     *_data = data;
43   return buf;
44 }
45 
46 static void
setup_segment(GstSegment * s,GstFormat fmt,guint64 start,guint64 stop,guint64 stream_time)47 setup_segment (GstSegment * s, GstFormat fmt, guint64 start, guint64 stop,
48     guint64 stream_time)
49 {
50   gst_segment_init (s, fmt);
51   s->start = start;
52   s->stop = stop;
53   s->time = stream_time;
54 }
55 
GST_START_TEST(test_buffer_clip_unsupported_format)56 GST_START_TEST (test_buffer_clip_unsupported_format)
57 {
58   GstSegment s;
59   GstBuffer *buf;
60   guint8 *data;
61 
62   /* If the format is not TIME or DEFAULT it should assert()
63    * FIXME: check if return value is the same as the input buffer.
64    *        probably can't be done because the assert() does a SIGABRT.
65    */
66   buf = make_buffer (&data);
67   setup_segment (&s, GST_FORMAT_PERCENT, 0, 10, 0);
68 
69   GST_BUFFER_TIMESTAMP (buf) = 0 * GST_SECOND;
70   GST_BUFFER_DURATION (buf) = 0;
71   GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
72   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
73 
74   ASSERT_CRITICAL (gst_audio_buffer_clip (buf, &s, 100, 1));
75 
76   gst_buffer_unref (buf);
77 }
78 
79 GST_END_TEST;
80 
GST_START_TEST(test_buffer_clip_time_start_and_stop)81 GST_START_TEST (test_buffer_clip_time_start_and_stop)
82 {
83   GstSegment s;
84   GstBuffer *buf;
85   GstBuffer *ret;
86   GstMapInfo map;
87   guint8 *data;
88 
89   /* Clip start and end */
90   buf = make_buffer (&data);
91   setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 8 * GST_SECOND,
92       4 * GST_SECOND);
93 
94   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
95   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
96   GST_BUFFER_OFFSET (buf) = 200;
97   GST_BUFFER_OFFSET_END (buf) = 1200;
98 
99   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
100   fail_unless (ret != NULL);
101 
102   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
103   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
104   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
105   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
106   gst_buffer_map (ret, &map, GST_MAP_READ);
107   fail_unless (map.data == data + 200);
108   fail_unless (map.size == 400);
109   gst_buffer_unmap (ret, &map);
110 
111   gst_buffer_unref (ret);
112 }
113 
114 GST_END_TEST;
115 
GST_START_TEST(test_buffer_clip_time_start_and_stop_planar)116 GST_START_TEST (test_buffer_clip_time_start_and_stop_planar)
117 {
118   GstSegment s;
119   GstBuffer *buf;
120   GstBuffer *ret;
121   GstAudioInfo info;
122   GstAudioBuffer abuf;
123   guint8 *data;
124 
125   /* Clip start and end */
126   buf = make_buffer (&data);
127 
128   gst_audio_info_init (&info);
129   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 1, NULL);
130   info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
131   gst_buffer_add_audio_meta (buf, &info, 1000, NULL);
132 
133   setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 8 * GST_SECOND,
134       4 * GST_SECOND);
135 
136   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
137   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
138   GST_BUFFER_OFFSET (buf) = 200;
139   GST_BUFFER_OFFSET_END (buf) = 1200;
140 
141   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
142   fail_unless (ret != NULL);
143 
144   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
145   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
146   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
147   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
148   gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
149   fail_unless_equals_int (abuf.n_planes, 1);
150   fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 400);
151   fail_unless_equals_pointer (abuf.planes[0], data + 200);
152   gst_audio_buffer_unmap (&abuf);
153 
154   gst_buffer_unref (ret);
155 }
156 
157 GST_END_TEST;
158 
GST_START_TEST(test_buffer_clip_time_start)159 GST_START_TEST (test_buffer_clip_time_start)
160 {
161   GstSegment s;
162   GstBuffer *buf;
163   GstBuffer *ret;
164   GstMapInfo map;
165   guint8 *data;
166 
167   /* Clip only start */
168   buf = make_buffer (&data);
169   setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 12 * GST_SECOND,
170       4 * GST_SECOND);
171 
172   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
173   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
174   GST_BUFFER_OFFSET (buf) = 200;
175   GST_BUFFER_OFFSET_END (buf) = 1200;
176 
177   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
178   fail_unless (ret != NULL);
179 
180   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
181   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
182   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
183   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1200);
184   gst_buffer_map (ret, &map, GST_MAP_READ);
185   fail_unless (map.data == data + 200);
186   fail_unless (map.size == 800);
187   gst_buffer_unmap (ret, &map);
188 
189   gst_buffer_unref (ret);
190 }
191 
192 GST_END_TEST;
193 
GST_START_TEST(test_buffer_clip_time_start_planar)194 GST_START_TEST (test_buffer_clip_time_start_planar)
195 {
196   GstSegment s;
197   GstBuffer *buf;
198   GstBuffer *ret;
199   GstAudioInfo info;
200   GstAudioMeta *meta;
201   GstAudioBuffer abuf;
202   guint8 *data;
203 
204   /* Clip only start */
205   buf = make_buffer (&data);
206 
207   gst_audio_info_init (&info);
208   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 2, NULL);
209   info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
210   gst_buffer_add_audio_meta (buf, &info, 500, NULL);
211 
212   setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 12 * GST_SECOND,
213       4 * GST_SECOND);
214 
215   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
216   GST_BUFFER_DURATION (buf) = 5 * GST_SECOND;
217   GST_BUFFER_OFFSET (buf) = 200;
218   GST_BUFFER_OFFSET_END (buf) = 700;
219 
220   ret = gst_audio_buffer_clip (buf, &s, 100, 2);
221   fail_unless (ret != NULL);
222 
223   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
224   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 3 * GST_SECOND);
225   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
226   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 700);
227 
228   meta = gst_buffer_get_audio_meta (ret);
229   fail_unless (meta);
230   fail_unless_equals_int (meta->info.channels, 2);
231   fail_unless_equals_int (meta->samples, 300);
232 
233   gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
234   fail_unless_equals_int (abuf.n_planes, 2);
235   fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 300);
236   fail_unless_equals_pointer (abuf.planes[0], data + 200);
237   fail_unless_equals_pointer (abuf.planes[1], data + 700);
238   gst_audio_buffer_unmap (&abuf);
239 
240   gst_buffer_unref (ret);
241 }
242 
243 GST_END_TEST;
244 
GST_START_TEST(test_buffer_clip_time_stop)245 GST_START_TEST (test_buffer_clip_time_stop)
246 {
247   GstSegment s;
248   GstBuffer *buf;
249   GstBuffer *ret;
250   GstMapInfo map;
251   guint8 *data;
252 
253   /* Clip only stop */
254   buf = make_buffer (&data);
255   setup_segment (&s, GST_FORMAT_TIME, 2 * GST_SECOND, 10 * GST_SECOND,
256       2 * GST_SECOND);
257 
258   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
259   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
260   GST_BUFFER_OFFSET (buf) = 200;
261   GST_BUFFER_OFFSET_END (buf) = 1200;
262 
263   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
264   fail_unless (ret != NULL);
265 
266   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
267   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
268   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
269   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1000);
270   gst_buffer_map (ret, &map, GST_MAP_READ);
271   fail_unless (map.data == data);
272   fail_unless (map.size == 800);
273   gst_buffer_unmap (ret, &map);
274 
275   gst_buffer_unref (ret);
276 }
277 
278 GST_END_TEST;
279 
GST_START_TEST(test_buffer_clip_time_stop_planar)280 GST_START_TEST (test_buffer_clip_time_stop_planar)
281 {
282   GstSegment s;
283   GstBuffer *buf;
284   GstBuffer *ret;
285   GstAudioInfo info;
286   GstAudioMeta *meta;
287   GstAudioBuffer abuf;
288   guint8 *data;
289 
290   /* Clip only stop */
291   buf = make_buffer (&data);
292 
293   gst_audio_info_init (&info);
294   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 2, NULL);
295   info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
296   gst_buffer_add_audio_meta (buf, &info, 500, NULL);
297 
298   setup_segment (&s, GST_FORMAT_TIME, 2 * GST_SECOND, 6 * GST_SECOND,
299       2 * GST_SECOND);
300 
301   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
302   GST_BUFFER_DURATION (buf) = 5 * GST_SECOND;
303   GST_BUFFER_OFFSET (buf) = 200;
304   GST_BUFFER_OFFSET_END (buf) = 700;
305 
306   ret = gst_audio_buffer_clip (buf, &s, 100, 2);
307   fail_unless (ret != NULL);
308 
309   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
310   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
311   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
312   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 600);
313 
314   meta = gst_buffer_get_audio_meta (ret);
315   fail_unless (meta);
316   fail_unless_equals_int (meta->info.channels, 2);
317   fail_unless_equals_int (meta->samples, 400);
318 
319   gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
320   fail_unless_equals_int (abuf.n_planes, 2);
321   fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 400);
322   fail_unless_equals_pointer (abuf.planes[0], data);
323   fail_unless_equals_pointer (abuf.planes[1], data + 500);
324   gst_audio_buffer_unmap (&abuf);
325 
326   gst_buffer_unref (ret);
327 }
328 
329 GST_END_TEST;
330 
GST_START_TEST(test_buffer_clip_time_outside)331 GST_START_TEST (test_buffer_clip_time_outside)
332 {
333   GstSegment s;
334   GstBuffer *buf;
335   GstBuffer *ret;
336 
337   /* Buffer outside segment */
338   buf = make_buffer (NULL);
339   setup_segment (&s, GST_FORMAT_TIME, 12 * GST_SECOND, 20 * GST_SECOND,
340       12 * GST_SECOND);
341 
342   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
343   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
344   GST_BUFFER_OFFSET (buf) = 200;
345   GST_BUFFER_OFFSET_END (buf) = 1200;
346 
347   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
348   fail_unless (ret == NULL);
349 }
350 
351 GST_END_TEST;
352 
GST_START_TEST(test_buffer_clip_time_start_and_stop_no_meta)353 GST_START_TEST (test_buffer_clip_time_start_and_stop_no_meta)
354 {
355   GstSegment s;
356   GstBuffer *buf;
357   GstBuffer *ret;
358   GstMapInfo map;
359   guint8 *data;
360 
361   /* Clip start and end but don't touch duration, offset and offset_end */
362   buf = make_buffer (&data);
363   setup_segment (&s, GST_FORMAT_TIME, 4 * GST_SECOND, 8 * GST_SECOND,
364       4 * GST_SECOND);
365 
366   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
367   GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
368   GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
369   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
370 
371   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
372   fail_unless (ret != NULL);
373 
374   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
375   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
376   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), GST_BUFFER_OFFSET_NONE);
377   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret),
378       GST_BUFFER_OFFSET_NONE);
379   gst_buffer_map (ret, &map, GST_MAP_READ);
380   fail_unless (map.data == data + 200);
381   fail_unless (map.size == 400);
382   gst_buffer_unmap (ret, &map);
383 
384   gst_buffer_unref (ret);
385 }
386 
387 GST_END_TEST;
388 
GST_START_TEST(test_buffer_clip_time_no_timestamp)389 GST_START_TEST (test_buffer_clip_time_no_timestamp)
390 {
391   GstSegment s;
392   GstBuffer *buf;
393   GstBuffer *ret;
394 
395   /* If the buffer has no timestamp it should assert()
396    * FIXME: check if return value is the same as the input buffer.
397    *        probably can't be done because the assert() does a SIGABRT.
398    */
399   buf = make_buffer (NULL);
400   setup_segment (&s, GST_FORMAT_TIME, 0 * GST_SECOND, 10 * GST_SECOND,
401       0 * GST_SECOND);
402 
403   GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
404   GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
405   GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
406   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
407 
408   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
409   fail_unless (ret == buf);
410 
411   gst_buffer_unref (buf);
412 }
413 
414 GST_END_TEST;
415 
GST_START_TEST(test_buffer_clip_time_handles_rounding)416 GST_START_TEST (test_buffer_clip_time_handles_rounding)
417 {
418   GstSegment s;
419   GstBuffer *buf;
420   GstBuffer *ret;
421   GstMapInfo map;
422   guint8 *data;
423   GstClockTime time_per_sample = GST_SECOND / 100;
424 
425   /* Clip only stop */
426   buf = make_buffer (&data);
427   setup_segment (&s, GST_FORMAT_TIME, 2 * GST_SECOND, 10 * GST_SECOND,
428       2 * GST_SECOND);
429 
430   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
431   /* the max duration that still converts back to the same size of samples */
432   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND + (time_per_sample - 1);
433   GST_BUFFER_OFFSET (buf) = 200;
434   GST_BUFFER_OFFSET_END (buf) = 1200;
435 
436   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
437   fail_unless (ret != NULL);
438 
439   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
440   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
441   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
442   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1000);
443   gst_buffer_map (ret, &map, GST_MAP_READ);
444   fail_unless (map.data == data);
445   fail_unless (map.size == 800);
446   gst_buffer_unmap (ret, &map);
447 
448   gst_buffer_unref (ret);
449 }
450 
451 GST_END_TEST;
452 
GST_START_TEST(test_buffer_clip_samples_start_and_stop)453 GST_START_TEST (test_buffer_clip_samples_start_and_stop)
454 {
455   GstSegment s;
456   GstBuffer *buf;
457   GstBuffer *ret;
458   GstMapInfo map;
459   guint8 *data;
460 
461   /* Clip start and end */
462   buf = make_buffer (&data);
463   setup_segment (&s, GST_FORMAT_DEFAULT, 400, 800, 400);
464 
465   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
466   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
467   GST_BUFFER_OFFSET (buf) = 200;
468   GST_BUFFER_OFFSET_END (buf) = 1200;
469 
470   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
471   fail_unless (ret != NULL);
472 
473   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
474   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 4 * GST_SECOND);
475   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
476   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 800);
477   gst_buffer_map (ret, &map, GST_MAP_READ);
478   fail_unless (map.data == data + 200);
479   fail_unless (map.size == 400);
480   gst_buffer_unmap (ret, &map);
481 
482   gst_buffer_unref (ret);
483 }
484 
485 GST_END_TEST;
486 
GST_START_TEST(test_buffer_clip_samples_start_and_stop_planar)487 GST_START_TEST (test_buffer_clip_samples_start_and_stop_planar)
488 {
489   GstSegment s;
490   GstBuffer *buf;
491   GstBuffer *ret;
492   GstAudioInfo info;
493   GstAudioMeta *meta;
494   GstAudioBuffer abuf;
495   guint8 *data;
496 
497   /* Clip start and end */
498   buf = make_buffer (&data);
499 
500   gst_audio_info_init (&info);
501   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S8, 44100, 2, NULL);
502   info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
503   gst_buffer_add_audio_meta (buf, &info, 500, NULL);
504 
505 
506   setup_segment (&s, GST_FORMAT_DEFAULT, 400, 600, 400);
507 
508   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
509   GST_BUFFER_DURATION (buf) = 5 * GST_SECOND;
510   GST_BUFFER_OFFSET (buf) = 200;
511   GST_BUFFER_OFFSET_END (buf) = 700;
512 
513   ret = gst_audio_buffer_clip (buf, &s, 100, 2);
514   fail_unless (ret != NULL);
515 
516   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
517   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 2 * GST_SECOND);
518   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
519   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 600);
520 
521   meta = gst_buffer_get_audio_meta (ret);
522   fail_unless (meta);
523   fail_unless_equals_int (meta->info.channels, 2);
524   fail_unless_equals_int (meta->samples, 200);
525 
526   gst_audio_buffer_map (&abuf, &info, ret, GST_MAP_READ);
527   fail_unless_equals_int (abuf.n_planes, 2);
528   fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf), 200);
529   fail_unless_equals_pointer (abuf.planes[0], data + 200);
530   fail_unless_equals_pointer (abuf.planes[1], data + 700);
531   gst_audio_buffer_unmap (&abuf);
532 
533   gst_buffer_unref (ret);
534 }
535 
536 GST_END_TEST;
537 
GST_START_TEST(test_buffer_clip_samples_start)538 GST_START_TEST (test_buffer_clip_samples_start)
539 {
540   GstSegment s;
541   GstBuffer *buf;
542   GstBuffer *ret;
543   GstMapInfo map;
544   guint8 *data;
545 
546   /* Clip only start */
547   buf = make_buffer (&data);
548   setup_segment (&s, GST_FORMAT_DEFAULT, 400, 1200, 400);
549 
550   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
551   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
552   GST_BUFFER_OFFSET (buf) = 200;
553   GST_BUFFER_OFFSET_END (buf) = 1200;
554 
555   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
556   fail_unless (ret != NULL);
557 
558   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
559   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
560   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
561   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1200);
562   gst_buffer_map (ret, &map, GST_MAP_READ);
563   fail_unless (map.data == data + 200);
564   fail_unless (map.size == 800);
565   gst_buffer_unmap (ret, &map);
566 
567   gst_buffer_unref (ret);
568 }
569 
570 GST_END_TEST;
571 
GST_START_TEST(test_buffer_clip_samples_stop)572 GST_START_TEST (test_buffer_clip_samples_stop)
573 {
574   GstSegment s;
575   GstBuffer *buf;
576   GstBuffer *ret;
577   GstMapInfo map;
578   guint8 *data;
579 
580   /* Clip only stop */
581   buf = make_buffer (&data);
582   setup_segment (&s, GST_FORMAT_DEFAULT, 200, 1000, 200);
583 
584   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
585   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
586   GST_BUFFER_OFFSET (buf) = 200;
587   GST_BUFFER_OFFSET_END (buf) = 1200;
588 
589   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
590   fail_unless (ret != NULL);
591 
592   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 2 * GST_SECOND);
593   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), 8 * GST_SECOND);
594   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 200);
595   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret), 1000);
596   gst_buffer_map (ret, &map, GST_MAP_READ);
597   fail_unless (map.data == data);
598   fail_unless (map.size == 800);
599   gst_buffer_unmap (ret, &map);
600 
601   gst_buffer_unref (ret);
602 }
603 
604 GST_END_TEST;
605 
GST_START_TEST(test_buffer_clip_samples_outside)606 GST_START_TEST (test_buffer_clip_samples_outside)
607 {
608   GstSegment s;
609   GstBuffer *buf;
610   GstBuffer *ret;
611 
612   /* Buffer outside segment */
613   buf = make_buffer (NULL);
614   setup_segment (&s, GST_FORMAT_DEFAULT, 1200, 2000, 1200);
615 
616   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
617   GST_BUFFER_DURATION (buf) = 10 * GST_SECOND;
618   GST_BUFFER_OFFSET (buf) = 200;
619   GST_BUFFER_OFFSET_END (buf) = 1200;
620 
621   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
622   fail_unless (ret == NULL);
623 }
624 
625 GST_END_TEST;
626 
GST_START_TEST(test_buffer_clip_samples_start_and_stop_no_meta)627 GST_START_TEST (test_buffer_clip_samples_start_and_stop_no_meta)
628 {
629   GstSegment s;
630   GstBuffer *buf;
631   GstBuffer *ret;
632   GstMapInfo map;
633   guint8 *data;
634 
635   /* Clip start and end but don't touch duration and offset_end */
636   buf = make_buffer (&data);
637   setup_segment (&s, GST_FORMAT_DEFAULT, 400, 800, 400);
638 
639   GST_BUFFER_TIMESTAMP (buf) = 2 * GST_SECOND;
640   GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
641   GST_BUFFER_OFFSET (buf) = 200;
642   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
643 
644   ret = gst_audio_buffer_clip (buf, &s, 100, 1);
645   fail_unless (ret != NULL);
646 
647   fail_unless_equals_int64 (GST_BUFFER_TIMESTAMP (ret), 4 * GST_SECOND);
648   fail_unless_equals_int64 (GST_BUFFER_DURATION (ret), GST_CLOCK_TIME_NONE);
649   fail_unless_equals_int64 (GST_BUFFER_OFFSET (ret), 400);
650   fail_unless_equals_int64 (GST_BUFFER_OFFSET_END (ret),
651       GST_BUFFER_OFFSET_NONE);
652   gst_buffer_map (ret, &map, GST_MAP_READ);
653   fail_unless (map.data == data + 200);
654   fail_unless (map.size == 400);
655   gst_buffer_unmap (ret, &map);
656 
657   gst_buffer_unref (ret);
658 }
659 
660 GST_END_TEST;
661 
GST_START_TEST(test_buffer_clip_samples_no_timestamp)662 GST_START_TEST (test_buffer_clip_samples_no_timestamp)
663 {
664   GstSegment s;
665   GstBuffer *buf;
666 
667   /* If the buffer has no offset it should assert()
668    * FIXME: check if return value is the same as the input buffer.
669    *        probably can't be done because the assert() does a SIGABRT.
670    */
671   buf = make_buffer (NULL);
672   setup_segment (&s, GST_FORMAT_DEFAULT, 0, 10, 0);
673 
674   GST_BUFFER_TIMESTAMP (buf) = 0 * GST_SECOND;
675   GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
676   GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
677   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
678 
679   ASSERT_CRITICAL (gst_audio_buffer_clip (buf, &s, 100, 1));
680 
681   gst_buffer_unref (buf);
682 }
683 
684 GST_END_TEST;
685 
GST_START_TEST(test_multichannel_checks)686 GST_START_TEST (test_multichannel_checks)
687 {
688   GstAudioChannelPosition pos_2_mixed[2] = {
689     GST_AUDIO_CHANNEL_POSITION_MONO,
690     GST_AUDIO_CHANNEL_POSITION_NONE
691   };
692   GstAudioChannelPosition pos_2_none[2] = {
693     GST_AUDIO_CHANNEL_POSITION_NONE,
694     GST_AUDIO_CHANNEL_POSITION_NONE
695   };
696   GstAudioChannelPosition pos_2_flr[2] = {
697     GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
698     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
699   };
700   GstAudioChannelPosition pos_2_frl[2] = {
701     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
702     GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
703   };
704   GstAudioChannelPosition pos_2_frr[2] = {
705     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
706     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
707   };
708   GstAudioChannelPosition pos_3_flrc[3] = {
709     GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
710     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
711     GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER
712   };
713   GstAudioChannelPosition pos_3_frcl[3] = {
714     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
715     GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
716     GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT
717   };
718   GstAudioInfo info, info2;
719   GstCaps *caps;
720 
721   gst_audio_info_init (&info);
722   gst_audio_info_init (&info2);
723 
724   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 2, NULL);
725   fail_unless (memcmp (&info.position, pos_2_flr, sizeof (pos_2_flr)) == 0);
726 
727   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 2, pos_2_flr);
728   fail_unless (memcmp (&info.position, pos_2_flr, sizeof (pos_2_flr)) == 0);
729   caps = gst_audio_info_to_caps (&info);
730   fail_unless (gst_audio_info_from_caps (&info2, caps));
731   fail_unless (memcmp (&info, &info2, sizeof (info)) == 0);
732   gst_caps_unref (caps);
733 
734   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 2, pos_2_none);
735   fail_unless (memcmp (&info.position, pos_2_none, sizeof (pos_2_none)) == 0);
736   caps = gst_audio_info_to_caps (&info);
737   fail_unless (gst_audio_info_from_caps (&info2, caps));
738   fail_unless (memcmp (&info, &info2, sizeof (info)) == 0);
739   gst_caps_unref (caps);
740 
741   gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000, 3, pos_3_flrc);
742   fail_unless (memcmp (&info.position, pos_3_flrc, sizeof (pos_3_flrc)) == 0);
743   caps = gst_audio_info_to_caps (&info);
744   fail_unless (gst_audio_info_from_caps (&info2, caps));
745   fail_unless (memcmp (&info, &info2, sizeof (info)) == 0);
746   gst_caps_unref (caps);
747 
748   ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
749           2, pos_2_frl));
750   ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
751           2, pos_2_mixed));
752   ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
753           2, pos_2_frr));
754   ASSERT_WARNING (gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_F32, 48000,
755           3, pos_3_frcl));
756 }
757 
758 GST_END_TEST;
759 
760 typedef struct
761 {
762   gint channels;
763   GstAudioChannelPosition from[32], to[32];
764   gint32 in[32], out[32];
765   gint32 plane_offsets[32];
766   gboolean fail;
767 } MultichannelReorderData;
768 
GST_START_TEST(test_multichannel_reorder)769 GST_START_TEST (test_multichannel_reorder)
770 {
771   MultichannelReorderData tests[] = {
772     {1,
773           {GST_AUDIO_CHANNEL_POSITION_MONO},
774           {GST_AUDIO_CHANNEL_POSITION_MONO},
775           {0, 1, 2, 3},
776           {0, 1, 2, 3},
777           {0},
778         FALSE},
779     {1,
780           {GST_AUDIO_CHANNEL_POSITION_MONO},
781           {GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
782           {0, 1, 2, 3},
783           {0, 1, 2, 3},
784           {0},
785         TRUE},
786     {2,
787           {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
788               GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
789           {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
790               GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
791           {0, 1, 2, 3},
792           {0, 1, 2, 3},
793           {0, 1},
794         FALSE},
795     {2,
796           {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
797               GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
798           {GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
799               GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT},
800           {0, 1, 2, 3},
801           {1, 0, 3, 2},
802           {1, 0},
803         FALSE},
804     {4,
805           {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
806                 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
807                 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
808               GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
809           {GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
810                 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
811                 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
812               GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
813           {0, 1, 2, 3},
814           {1, 2, 0, 3},
815           {1, 2, 0, 3},
816         FALSE},
817     {4,
818           {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
819                 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
820                 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
821               GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
822           {GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
823                 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
824                 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
825               GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER},
826           {0, 1, 2, 3},
827           {3, 0, 1, 2},
828           {3, 0, 1, 2},
829         FALSE},
830     {4,
831           {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
832                 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
833                 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
834               GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
835           {GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
836                 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
837                 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
838               GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT},
839           {0, 1, 2, 3},
840           {3, 2, 1, 0},
841           {3, 2, 1, 0},
842         FALSE},
843   };
844   gint i, j;
845   GstBuffer *buf;
846   GstMapInfo map;
847   GstAudioInfo info;
848   GstAudioBuffer abuf;
849 
850   for (i = 0; i < G_N_ELEMENTS (tests); i++) {
851     buf =
852         gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, tests[i].in,
853         sizeof (tests[i].in), 0, sizeof (tests[i].in), NULL, NULL);
854 
855     if (tests[i].fail) {
856       fail_if (gst_audio_buffer_reorder_channels (buf, GST_AUDIO_FORMAT_S32,
857               tests[i].channels, tests[i].from, tests[i].to));
858     } else {
859       /* first interpret as interleaved */
860 
861       fail_unless (gst_audio_buffer_reorder_channels (buf, GST_AUDIO_FORMAT_S32,
862               tests[i].channels, tests[i].from, tests[i].to));
863 
864       gst_buffer_map (buf, &map, GST_MAP_READ);
865       fail_unless_equals_int (map.size, sizeof (tests[i].in));
866       fail_unless (memcmp (tests[i].out, map.data, map.size) == 0);
867       gst_buffer_unmap (buf, &map);
868 
869       /* now interpret as planar */
870 
871       gst_audio_info_init (&info);
872       gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S32, 44100,
873           tests[i].channels, NULL);
874       info.layout = GST_AUDIO_LAYOUT_NON_INTERLEAVED;
875 
876       gst_buffer_add_audio_meta (buf, &info,
877           sizeof (tests[i].in) / (tests[i].channels * sizeof (gint32)), NULL);
878 
879       fail_unless (gst_audio_buffer_reorder_channels (buf, GST_AUDIO_FORMAT_S32,
880               tests[i].channels, tests[i].from, tests[i].to));
881 
882       fail_unless (gst_audio_buffer_map (&abuf, &info, buf, GST_MAP_READ));
883       fail_unless_equals_int (abuf.n_planes, tests[i].channels);
884       fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&abuf),
885           sizeof (tests[i].in) / tests[i].channels);
886       for (j = 0; j < abuf.n_planes; j++) {
887         fail_unless_equals_pointer (abuf.planes[j],
888             abuf.map_infos[0].data +
889             tests[i].plane_offsets[j] * GST_AUDIO_BUFFER_PLANE_SIZE (&abuf));
890       }
891       gst_audio_buffer_unmap (&abuf);
892     }
893     gst_buffer_unref (buf);
894   }
895 }
896 
897 GST_END_TEST;
898 
GST_START_TEST(test_audio_format_s8)899 GST_START_TEST (test_audio_format_s8)
900 {
901   GstAudioFormat fmt;
902 
903   fmt = gst_audio_format_build_integer (TRUE, G_BYTE_ORDER, 8, 8);
904   fail_unless (fmt == GST_AUDIO_FORMAT_S8);
905 
906 }
907 
908 GST_END_TEST;
909 
GST_START_TEST(test_audio_format_u8)910 GST_START_TEST (test_audio_format_u8)
911 {
912   GstAudioFormat fmt;
913   fmt = gst_audio_format_build_integer (FALSE, G_BYTE_ORDER, 8, 8);
914   fail_unless (fmt == GST_AUDIO_FORMAT_U8);
915 }
916 
917 GST_END_TEST;
918 
GST_START_TEST(test_fill_silence)919 GST_START_TEST (test_fill_silence)
920 {
921   GstAudioInfo info;
922   GstAudioFormat f;
923   gint i;
924   guint8 test_silence[32];
925 
926   for (f = GST_AUDIO_FORMAT_S8; f < GST_AUDIO_FORMAT_F64; f++) {
927     gst_audio_info_set_format (&info, f, 48000, 1, NULL);
928 
929     gst_audio_format_fill_silence (info.finfo, test_silence,
930         GST_AUDIO_INFO_BPF (&info) * 4);
931 
932     for (i = 0; i < 4; i++)
933       fail_unless (memcmp (test_silence + i * GST_AUDIO_INFO_BPF (&info),
934               info.finfo->silence, GST_AUDIO_INFO_BPF (&info)) == 0);
935   }
936 }
937 
938 GST_END_TEST;
939 
GST_START_TEST(test_stream_align)940 GST_START_TEST (test_stream_align)
941 {
942   GstAudioStreamAlign *align;
943   guint i;
944   GstClockTime timestamp;
945   GstClockTime out_timestamp, out_duration;
946   gboolean discont;
947 
948   align = gst_audio_stream_align_new (1000, 40 * GST_MSECOND, 1 * GST_SECOND);
949 
950   for (i = 0; i < 500; i++) {
951     timestamp = 10 * GST_MSECOND * i;
952     discont = i == 0;
953 
954     discont =
955         gst_audio_stream_align_process (align, discont, timestamp, 10,
956         &out_timestamp, &out_duration, NULL);
957 
958     fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
959     fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
960     if (i == 0)
961       fail_unless (discont);
962     else
963       fail_unless (!discont);
964   }
965 
966   /* Drift forwards by 1ms per 10ms buffer for the first 40 buffers.
967    * - after 40 buffers we're above alignment threshold
968    * - after 40 + 100 buffers we're at discont wait
969    */
970   for (i = 0; i < 500; i++) {
971     timestamp = 10 * GST_MSECOND * i;
972     discont = i == 0;
973     if (i > 0)
974       timestamp += 1 * GST_MSECOND * MIN (i, 40);
975 
976     discont =
977         gst_audio_stream_align_process (align, discont, timestamp, 10,
978         &out_timestamp, &out_duration, NULL);
979 
980     if (i < 140) {
981       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
982       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
983       if (i == 0)
984         fail_unless (discont);
985       else
986         fail_unless (!discont);
987     } else {
988       if (i == 140)
989         fail_unless (discont);
990       else
991         fail_unless (!discont);
992       fail_unless_equals_uint64 (out_timestamp,
993           10 * GST_MSECOND * i + 40 * GST_MSECOND);
994       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
995     }
996   }
997 
998   /* Drift backwards by 1ms per 10ms buffer for the first 40 buffers.
999    * - after 40 buffers we're above alignment threshold
1000    * - after 40 + 100 buffers we're at discont wait
1001    */
1002   for (i = 0; i < 500; i++) {
1003     timestamp = 10 * GST_MSECOND * i;
1004     discont = i == 0;
1005     if (i > 0)
1006       timestamp -= 1 * GST_MSECOND * MIN (i, 40);
1007 
1008     discont =
1009         gst_audio_stream_align_process (align, discont, timestamp, 10,
1010         &out_timestamp, &out_duration, NULL);
1011 
1012     if (i < 140) {
1013       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1014       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1015       if (i == 0)
1016         fail_unless (discont);
1017       else
1018         fail_unless (!discont);
1019     } else {
1020       if (i == 140)
1021         fail_unless (discont);
1022       else
1023         fail_unless (!discont);
1024 
1025       fail_unless_equals_uint64 (out_timestamp,
1026           10 * GST_MSECOND * i - 40 * GST_MSECOND);
1027       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1028     }
1029   }
1030 
1031   /* Shift all buffers but the first by 40ms
1032    * - after 1 buffers we're above alignment threshold
1033    * - after 101 buffers we're at discont wait
1034    */
1035   for (i = 0; i < 500; i++) {
1036     timestamp = 10 * GST_MSECOND * i;
1037     discont = i == 0;
1038     if (i > 0)
1039       timestamp += 40 * GST_MSECOND;
1040 
1041     discont =
1042         gst_audio_stream_align_process (align, discont, timestamp, 10,
1043         &out_timestamp, &out_duration, NULL);
1044 
1045     if (i < 101) {
1046       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1047       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1048       if (i == 0)
1049         fail_unless (discont);
1050       else
1051         fail_unless (!discont);
1052     } else {
1053       if (i == 101)
1054         fail_unless (discont);
1055       else
1056         fail_unless (!discont);
1057       fail_unless_equals_uint64 (out_timestamp,
1058           10 * GST_MSECOND * i + 40 * GST_MSECOND);
1059       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1060     }
1061   }
1062 
1063   /* Shift every second buffer by 40ms:
1064    * - never discont!
1065    */
1066   for (i = 0; i < 500; i++) {
1067     timestamp = 10 * GST_MSECOND * i;
1068     discont = i == 0;
1069 
1070     if (i % 2 == 0 && i > 0)
1071       timestamp += 40 * GST_MSECOND;
1072 
1073     discont =
1074         gst_audio_stream_align_process (align, discont, timestamp, 10,
1075         &out_timestamp, &out_duration, NULL);
1076 
1077     fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1078     fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1079     if (i == 0)
1080       fail_unless (discont);
1081     else
1082       fail_unless (!discont);
1083   }
1084 
1085   /* Shift every buffer 100 by 2: discont at buffer 200
1086    */
1087   for (i = 0; i < 500; i++) {
1088     timestamp = 10 * GST_MSECOND * i;
1089     discont = i == 0;
1090     if (i >= 100)
1091       timestamp += 2 * GST_SECOND;
1092 
1093     discont =
1094         gst_audio_stream_align_process (align, discont, timestamp, 10,
1095         &out_timestamp, &out_duration, NULL);
1096 
1097     if (i < 200) {
1098       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1099       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1100       if (i == 0)
1101         fail_unless (discont);
1102       else
1103         fail_unless (!discont);
1104     } else {
1105       fail_unless_equals_uint64 (out_timestamp,
1106           10 * GST_MSECOND * i + 2 * GST_SECOND);
1107       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1108       if (i == 200)
1109         fail_unless (discont);
1110       else
1111         fail_unless (!discont);
1112     }
1113   }
1114 
1115   gst_audio_stream_align_free (align);
1116 }
1117 
1118 GST_END_TEST;
1119 
GST_START_TEST(test_stream_align_reverse)1120 GST_START_TEST (test_stream_align_reverse)
1121 {
1122   GstAudioStreamAlign *align;
1123   gint i;
1124   GstClockTime timestamp;
1125   GstClockTime out_timestamp, out_duration;
1126   gboolean discont;
1127 
1128   align = gst_audio_stream_align_new (-1000, 40 * GST_MSECOND, 1 * GST_SECOND);
1129 
1130   for (i = 499; i >= 0; i--) {
1131     timestamp = 10 * GST_MSECOND * i;
1132     discont = i == 499;
1133 
1134     discont =
1135         gst_audio_stream_align_process (align, discont, timestamp, 10,
1136         &out_timestamp, &out_duration, NULL);
1137 
1138     fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1139     fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1140     if (i == 499)
1141       fail_unless (discont);
1142     else
1143       fail_unless (!discont);
1144   }
1145 
1146   /* Drift forwards by 1ms per 10ms buffer for the first 40 buffers.
1147    * - after 40 buffers we're above alignment threshold
1148    * - after 40 + 100 buffers we're at discont wait
1149    */
1150   for (i = 499; i >= 0; i--) {
1151     timestamp = 10 * GST_MSECOND * i;
1152     discont = i == 499;
1153     if (i < 499)
1154       timestamp += 1 * GST_MSECOND * MIN (499 - i, 40);
1155 
1156     discont =
1157         gst_audio_stream_align_process (align, discont, timestamp, 10,
1158         &out_timestamp, &out_duration, NULL);
1159 
1160     if (i >= 500 - 140) {
1161       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1162       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1163       if (i == 499)
1164         fail_unless (discont);
1165       else
1166         fail_unless (!discont);
1167     } else {
1168       if (i == 499 - 140)
1169         fail_unless (discont);
1170       else
1171         fail_unless (!discont);
1172       fail_unless_equals_uint64 (out_timestamp,
1173           10 * GST_MSECOND * i + 40 * GST_MSECOND);
1174       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1175     }
1176   }
1177 
1178   /* Drift backwards by 1ms per 10ms buffer for the first 40 buffers.
1179    * - after 40 buffers we're above alignment threshold
1180    * - after 40 + 100 buffers we're at discont wait
1181    */
1182   for (i = 499; i >= 4; i--) {
1183     timestamp = 10 * GST_MSECOND * i;
1184     discont = i == 499;
1185     if (i < 499)
1186       timestamp -= 1 * GST_MSECOND * MIN (499 - i, 40);
1187 
1188     discont =
1189         gst_audio_stream_align_process (align, discont, timestamp, 10,
1190         &out_timestamp, &out_duration, NULL);
1191 
1192     if (i >= 500 - 140) {
1193       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1194       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1195       if (i == 499)
1196         fail_unless (discont);
1197       else
1198         fail_unless (!discont);
1199     } else {
1200       if (i == 499 - 140)
1201         fail_unless (discont);
1202       else
1203         fail_unless (!discont);
1204 
1205       fail_unless_equals_uint64 (out_timestamp,
1206           10 * GST_MSECOND * i - 40 * GST_MSECOND);
1207       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1208     }
1209   }
1210 
1211   /* Shift all buffers but the first by 40ms
1212    * - after 1 buffers we're above alignment threshold
1213    * - after 101 buffers we're at discont wait
1214    */
1215   for (i = 499; i >= 0; i--) {
1216     timestamp = 10 * GST_MSECOND * i;
1217     discont = i == 499;
1218     if (i < 499)
1219       timestamp += 40 * GST_MSECOND;
1220 
1221     discont =
1222         gst_audio_stream_align_process (align, discont, timestamp, 10,
1223         &out_timestamp, &out_duration, NULL);
1224 
1225     if (i >= 500 - 101) {
1226       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1227       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1228       if (i == 499)
1229         fail_unless (discont);
1230       else
1231         fail_unless (!discont);
1232     } else {
1233       if (i == 499 - 101)
1234         fail_unless (discont);
1235       else
1236         fail_unless (!discont);
1237       fail_unless_equals_uint64 (out_timestamp,
1238           10 * GST_MSECOND * i + 40 * GST_MSECOND);
1239       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1240     }
1241   }
1242 
1243   /* Shift every second buffer by 40ms:
1244    * - never discont!
1245    */
1246   for (i = 499; i >= 0; i--) {
1247     timestamp = 10 * GST_MSECOND * i;
1248     discont = i == 499;
1249 
1250     if (i % 2 == 0 && i < 499)
1251       timestamp += 40 * GST_MSECOND;
1252 
1253     discont =
1254         gst_audio_stream_align_process (align, discont, timestamp, 10,
1255         &out_timestamp, &out_duration, NULL);
1256 
1257     fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1258     fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1259     if (i == 499)
1260       fail_unless (discont);
1261     else
1262       fail_unless (!discont);
1263   }
1264 
1265   /* Shift buffer 100 by 2: discont at buffer 200
1266    */
1267   for (i = 499; i >= 0; i--) {
1268     timestamp = 10 * GST_MSECOND * i;
1269     discont = i == 499;
1270     if (i < 500 - 100)
1271       timestamp += 2 * GST_SECOND;
1272 
1273     discont =
1274         gst_audio_stream_align_process (align, discont, timestamp, 10,
1275         &out_timestamp, &out_duration, NULL);
1276 
1277     if (i >= 500 - 200) {
1278       fail_unless_equals_uint64 (out_timestamp, 10 * GST_MSECOND * i);
1279       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1280       if (i == 499)
1281         fail_unless (discont);
1282       else
1283         fail_unless (!discont);
1284     } else {
1285       fail_unless_equals_uint64 (out_timestamp,
1286           10 * GST_MSECOND * i + 2 * GST_SECOND);
1287       fail_unless_equals_uint64 (out_duration, 10 * GST_MSECOND);
1288       if (i == 499 - 200)
1289         fail_unless (discont);
1290       else
1291         fail_unless (!discont);
1292     }
1293   }
1294 
1295   gst_audio_stream_align_free (align);
1296 }
1297 
1298 GST_END_TEST;
1299 
1300 typedef struct
1301 {
1302   GstAudioFormat format;
1303   GstAudioLayout layout;
1304   gint channels;
1305   gsize samples;
1306   gsize plane_size;
1307   gsize offsets[10];
1308   gboolean add_meta;
1309   gboolean use_offsets;
1310 } AudioBufferTestData;
1311 
GST_START_TEST(test_audio_buffer_and_audio_meta)1312 GST_START_TEST (test_audio_buffer_and_audio_meta)
1313 {
1314   AudioBufferTestData td[] = {
1315     {GST_AUDIO_FORMAT_S24_32, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
1316         4, 60, 240, {10, 760, 510, 260}, TRUE, TRUE},
1317     {GST_AUDIO_FORMAT_F32, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
1318         4, 60, 240, {0, 240, 480, 720}, TRUE, FALSE},
1319     {GST_AUDIO_FORMAT_S16, GST_AUDIO_LAYOUT_INTERLEAVED,
1320         4, 125, 1000, {0}, TRUE, FALSE},
1321     {GST_AUDIO_FORMAT_S16, GST_AUDIO_LAYOUT_INTERLEAVED,
1322         4, 125, 1000, {0}, FALSE, FALSE},
1323     {GST_AUDIO_FORMAT_S8, GST_AUDIO_LAYOUT_INTERLEAVED,
1324         8, 125, 1000, {0}, FALSE, FALSE},
1325     {GST_AUDIO_FORMAT_U8, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
1326         8, 125, 125, {0, 125, 250, 375, 500, 625, 750, 875}, TRUE, FALSE},
1327     {GST_AUDIO_FORMAT_U32, GST_AUDIO_LAYOUT_NON_INTERLEAVED,
1328           10, 25, 100, {0, 100, 200, 300, 400, 500, 600, 700, 800, 900}, TRUE,
1329         FALSE},
1330     {GST_AUDIO_FORMAT_U32, GST_AUDIO_LAYOUT_INTERLEAVED,
1331         10, 25, 1000, {0}, FALSE, FALSE},
1332   };
1333   gint i;
1334 
1335   for (i = 0; i < G_N_ELEMENTS (td); i++) {
1336     GstBuffer *buf;
1337     guint8 *data;
1338     GstAudioInfo info;
1339     GstAudioMeta *meta;
1340     GstAudioBuffer buffer;
1341     gint j;
1342 
1343     gst_audio_info_init (&info);
1344     gst_audio_info_set_format (&info, td[i].format, 44100, td[i].channels,
1345         NULL);
1346     info.layout = td[i].layout;
1347 
1348     buf = make_buffer (&data);
1349     if (td[i].add_meta) {
1350       meta = gst_buffer_add_audio_meta (buf, &info, td[i].samples,
1351           td[i].use_offsets ? td[i].offsets : NULL);
1352 
1353       fail_unless (meta);
1354       fail_unless (GST_AUDIO_INFO_IS_VALID (&meta->info));
1355       fail_unless (gst_audio_info_is_equal (&meta->info, &info));
1356       fail_unless_equals_int (meta->info.finfo->format, td[i].format);
1357       fail_unless_equals_int (meta->info.layout, td[i].layout);
1358       fail_unless_equals_int (meta->info.channels, td[i].channels);
1359       fail_unless_equals_int (meta->samples, td[i].samples);
1360 
1361       if (td[i].layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
1362         fail_unless (meta->offsets);
1363         for (j = 0; j < td[i].channels; j++) {
1364           fail_unless_equals_int (meta->offsets[j], td[i].offsets[j]);
1365         }
1366       } else {
1367         fail_if (meta->offsets);
1368       }
1369     }
1370 
1371     fail_unless (gst_audio_buffer_map (&buffer, &info, buf, GST_MAP_READ));
1372     fail_unless_equals_pointer (buffer.buffer, buf);
1373     fail_unless (GST_AUDIO_INFO_IS_VALID (&buffer.info));
1374     fail_unless (gst_audio_info_is_equal (&buffer.info, &info));
1375     fail_unless_equals_int (buffer.n_samples, td[i].samples);
1376 
1377     if (td[i].layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
1378       fail_unless_equals_int (buffer.n_planes, td[i].channels);
1379       for (j = 0; j < td[i].channels; j++) {
1380         fail_unless_equals_pointer (buffer.planes[j], data + td[i].offsets[j]);
1381       }
1382     } else {
1383       fail_unless_equals_int (buffer.n_planes, 1);
1384       fail_unless_equals_pointer (buffer.planes[0], data);
1385     }
1386 
1387     fail_unless_equals_int (GST_AUDIO_BUFFER_PLANE_SIZE (&buffer),
1388         td[i].plane_size);
1389 
1390     if (buffer.n_planes <= 8) {
1391       fail_unless_equals_pointer (buffer.map_infos, buffer.priv_map_infos_arr);
1392       fail_unless_equals_pointer (buffer.planes, buffer.priv_planes_arr);
1393     } else {
1394       fail_if (buffer.map_infos == buffer.priv_map_infos_arr);
1395       fail_if (buffer.planes == buffer.priv_planes_arr);
1396     }
1397 
1398     gst_audio_buffer_unmap (&buffer);
1399     gst_buffer_unref (buf);
1400   }
1401 }
1402 
1403 GST_END_TEST;
1404 
1405 static Suite *
audio_suite(void)1406 audio_suite (void)
1407 {
1408   Suite *s = suite_create ("audio support library");
1409 
1410   TCase *tc_chain = tcase_create ("general");
1411 
1412   suite_add_tcase (s, tc_chain);
1413   tcase_add_test (tc_chain, test_buffer_clip_unsupported_format);
1414   tcase_add_test (tc_chain, test_buffer_clip_time_start_and_stop);
1415   tcase_add_test (tc_chain, test_buffer_clip_time_start_and_stop_planar);
1416   tcase_add_test (tc_chain, test_buffer_clip_time_start);
1417   tcase_add_test (tc_chain, test_buffer_clip_time_start_planar);
1418   tcase_add_test (tc_chain, test_buffer_clip_time_stop);
1419   tcase_add_test (tc_chain, test_buffer_clip_time_stop_planar);
1420   tcase_add_test (tc_chain, test_buffer_clip_time_outside);
1421   tcase_add_test (tc_chain, test_buffer_clip_time_start_and_stop_no_meta);
1422   tcase_add_test (tc_chain, test_buffer_clip_time_no_timestamp);
1423   tcase_add_test (tc_chain, test_buffer_clip_time_handles_rounding);
1424   tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop);
1425   tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop_planar);
1426   tcase_add_test (tc_chain, test_buffer_clip_samples_start);
1427   tcase_add_test (tc_chain, test_buffer_clip_samples_stop);
1428   tcase_add_test (tc_chain, test_buffer_clip_samples_outside);
1429   tcase_add_test (tc_chain, test_buffer_clip_samples_start_and_stop_no_meta);
1430   tcase_add_test (tc_chain, test_buffer_clip_samples_no_timestamp);
1431   tcase_add_test (tc_chain, test_multichannel_checks);
1432   tcase_add_test (tc_chain, test_multichannel_reorder);
1433   tcase_add_test (tc_chain, test_audio_format_s8);
1434   tcase_add_test (tc_chain, test_audio_format_u8);
1435   tcase_add_test (tc_chain, test_fill_silence);
1436   tcase_add_test (tc_chain, test_stream_align);
1437   tcase_add_test (tc_chain, test_stream_align_reverse);
1438   tcase_add_test (tc_chain, test_audio_buffer_and_audio_meta);
1439 
1440   return s;
1441 }
1442 
1443 GST_CHECK_MAIN (audio);
1444