153a08b512b90a5b855e577b22c49b36b9618b95
[platform/upstream/gstreamer.git] / tests / check / libs / adapter.c
1 /* GStreamer
2  *
3  * unit test for adapter
4  *
5  * Copyright (C) <2005> Wim Taymans <wim at fluendo dot com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 #include <gst/base/gstadapter.h>
26
27 /* does some implementation dependent checking that should 
28  * also be optimal 
29  */
30
31 /*
32  * Start peeking on an adapter with 1 buffer pushed. 
33  */
34 GST_START_TEST (test_peek1)
35 {
36   GstAdapter *adapter;
37   GstBuffer *buffer;
38   guint avail;
39   GstMapInfo info;
40   const guint8 *data1, *data2, *idata;
41
42   adapter = gst_adapter_new ();
43   fail_if (adapter == NULL);
44
45   /* push single buffer in adapter */
46   buffer = gst_buffer_new_and_alloc (512);
47
48   fail_unless (gst_buffer_map (buffer, &info, GST_MAP_READ));
49   idata = info.data;
50   gst_buffer_unmap (buffer, &info);
51
52   fail_if (buffer == NULL);
53   gst_adapter_push (adapter, buffer);
54
55   /* available and available_fast should return the size of the 
56    * buffer */
57   avail = gst_adapter_available (adapter);
58   fail_if (avail != 512);
59   avail = gst_adapter_available_fast (adapter);
60   fail_if (avail != 512);
61
62   /* should g_critical with NULL as result */
63   ASSERT_CRITICAL (data1 = gst_adapter_map (adapter, 0));
64   fail_if (data1 != NULL);
65
66   /* should return NULL as result */
67   data1 = gst_adapter_map (adapter, 513);
68   fail_if (data1 != NULL);
69
70   /* this should work */
71   data1 = gst_adapter_map (adapter, 512);
72   fail_if (data1 == NULL);
73   /* it should point to the buffer data as well */
74   fail_if (data1 != idata);
75   gst_adapter_unmap (adapter);
76
77   data2 = gst_adapter_map (adapter, 512);
78   fail_if (data2 == NULL);
79   /* second peek should return the same pointer */
80   fail_if (data2 != data1);
81   gst_adapter_unmap (adapter);
82
83   /* this should fail since we don't have that many bytes */
84   ASSERT_CRITICAL (gst_adapter_flush (adapter, 513));
85
86   /* this should work fine */
87   gst_adapter_flush (adapter, 10);
88
89   /* see if we have 10 bytes less available */
90   avail = gst_adapter_available (adapter);
91   fail_if (avail != 502);
92   avail = gst_adapter_available_fast (adapter);
93   fail_if (avail != 502);
94
95   /* should return NULL as result */
96   data2 = gst_adapter_map (adapter, 503);
97   fail_if (data2 != NULL);
98
99   /* should work fine */
100   data2 = gst_adapter_map (adapter, 502);
101   fail_if (data2 == NULL);
102   /* peek should return the same old pointer + 10 */
103   fail_if (data2 != data1 + 10);
104   fail_if (data2 != (guint8 *) idata + 10);
105   gst_adapter_unmap (adapter);
106
107   /* flush some more */
108   gst_adapter_flush (adapter, 500);
109
110   /* see if we have 2 bytes available */
111   avail = gst_adapter_available (adapter);
112   fail_if (avail != 2);
113   avail = gst_adapter_available_fast (adapter);
114   fail_if (avail != 2);
115
116   data2 = gst_adapter_map (adapter, 2);
117   fail_if (data2 == NULL);
118   fail_if (data2 != data1 + 510);
119   fail_if (data2 != (guint8 *) idata + 510);
120   gst_adapter_unmap (adapter);
121
122   /* flush some more */
123   gst_adapter_flush (adapter, 2);
124
125   /* see if we have 0 bytes available */
126   avail = gst_adapter_available (adapter);
127   fail_if (avail != 0);
128   avail = gst_adapter_available_fast (adapter);
129   fail_if (avail != 0);
130
131   /* silly clear just for fun */
132   gst_adapter_clear (adapter);
133
134   g_object_unref (adapter);
135 }
136
137 GST_END_TEST;
138
139 /* Start peeking on an adapter with 2 non-mergeable buffers 
140  * pushed. 
141  */
142 GST_START_TEST (test_peek2)
143 {
144 }
145
146 GST_END_TEST;
147
148 /* Start peeking on an adapter with 2 mergeable buffers 
149  * pushed. 
150  */
151 GST_START_TEST (test_peek3)
152 {
153 }
154
155 GST_END_TEST;
156
157 /* take data from an adapter with 1 buffer pushed.
158  */
159 GST_START_TEST (test_take1)
160 {
161   GstAdapter *adapter;
162   GstBuffer *buffer, *buffer2;
163   guint avail;
164   GstMapInfo info, info2;
165
166   adapter = gst_adapter_new ();
167   fail_unless (adapter != NULL);
168
169   buffer = gst_buffer_new_and_alloc (100);
170   fail_unless (buffer != NULL);
171   fail_unless (gst_buffer_map (buffer, &info, GST_MAP_READ));
172   fail_unless (info.data != NULL);
173   fail_unless (info.size == 100);
174
175   /* push in the adapter */
176   gst_adapter_push (adapter, buffer);
177
178   avail = gst_adapter_available (adapter);
179   fail_unless (avail == 100);
180
181   /* take out buffer */
182   buffer2 = gst_adapter_take_buffer (adapter, 100);
183   fail_unless (buffer2 != NULL);
184
185   fail_unless (gst_buffer_map (buffer2, &info2, GST_MAP_READ));
186   fail_unless (info2.data != NULL);
187   fail_unless (info2.size == 100);
188
189   avail = gst_adapter_available (adapter);
190   fail_unless (avail == 0);
191
192   /* the buffer should be the same */
193   fail_unless (buffer == buffer2);
194   fail_unless (info.data == info2.data);
195
196   gst_buffer_unmap (buffer, &info);
197   gst_buffer_unmap (buffer2, &info2);
198
199   gst_buffer_unref (buffer2);
200
201   g_object_unref (adapter);
202 }
203
204 GST_END_TEST;
205
206 /* take data from an adapter with 2 non-mergeable buffers 
207  * pushed.
208  */
209 GST_START_TEST (test_take2)
210 {
211 }
212
213 GST_END_TEST;
214
215 /* take data from an adapter with 2 mergeable buffers 
216  * pushed.
217  */
218 GST_START_TEST (test_take3)
219 {
220   GstAdapter *adapter;
221   GstBuffer *buffer, *buffer2;
222   guint avail;
223   GstMapInfo info, info2;
224
225   adapter = gst_adapter_new ();
226   fail_unless (adapter != NULL);
227
228   buffer = gst_buffer_new_and_alloc (100);
229   fail_unless (buffer != NULL);
230   fail_unless (gst_buffer_map (buffer, &info, GST_MAP_READ));
231   fail_unless (info.data != NULL);
232   fail_unless (info.size == 100);
233   gst_buffer_unmap (buffer, &info);
234
235   /* set up and push subbuffers */
236   buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 25);
237   gst_adapter_push (adapter, buffer2);
238   buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 25, 25);
239   gst_adapter_push (adapter, buffer2);
240   buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 50, 25);
241   gst_adapter_push (adapter, buffer2);
242   buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 75, 25);
243   gst_adapter_push (adapter, buffer2);
244
245   gst_buffer_unref (buffer);
246
247   avail = gst_adapter_available (adapter);
248   fail_unless (avail == 100);
249
250   /* take out buffer */
251   buffer2 = gst_adapter_take_buffer (adapter, 100);
252   fail_unless (buffer2 != NULL);
253   fail_unless (gst_buffer_map (buffer2, &info2, GST_MAP_READ));
254   fail_unless (info2.data != NULL);
255   fail_unless (info2.size == 100);
256
257   avail = gst_adapter_available (adapter);
258   fail_unless (avail == 0);
259
260 #if 0
261   /* the data should be the same FIXME, implement span in adapter again. */
262   fail_unless (info.data == info2.data);
263 #endif
264
265   gst_buffer_unmap (buffer2, &info2);
266   gst_buffer_unref (buffer2);
267
268   g_object_unref (adapter);
269 }
270
271 GST_END_TEST;
272
273 static GstAdapter *
274 create_and_fill_adapter (void)
275 {
276   GstAdapter *adapter;
277   gint i, j;
278
279   adapter = gst_adapter_new ();
280   fail_unless (adapter != NULL);
281
282   for (i = 0; i < 10000; i += 4) {
283     GstBuffer *buf;
284     GstMapInfo info;
285     guint8 *ptr;
286
287     buf = gst_buffer_new_and_alloc (sizeof (guint32) * 4);
288     fail_unless (buf != NULL);
289
290     fail_unless (gst_buffer_map (buf, &info, GST_MAP_WRITE));
291     ptr = info.data;
292
293     for (j = 0; j < 4; j++) {
294       GST_WRITE_UINT32_LE (ptr, i + j);
295       ptr += sizeof (guint32);
296     }
297     gst_buffer_unmap (buf, &info);
298
299     gst_adapter_push (adapter, buf);
300   }
301
302   return adapter;
303 }
304
305 /* Fill a buffer with a sequence of 32 bit ints and read them back out,
306  * checking that they're still in the right order */
307 GST_START_TEST (test_take_order)
308 {
309   GstAdapter *adapter;
310   int i = 0;
311
312   adapter = create_and_fill_adapter ();
313   while (gst_adapter_available (adapter) >= sizeof (guint32)) {
314     guint8 *data = gst_adapter_take (adapter, sizeof (guint32));
315     guint32 val = GST_READ_UINT32_LE (data);
316
317     GST_DEBUG ("val %8u", val);
318     fail_unless (val == i);
319     i++;
320     g_free (data);
321   }
322   fail_unless (gst_adapter_available (adapter) == 0,
323       "Data was left in the adapter");
324
325   g_object_unref (adapter);
326 }
327
328 GST_END_TEST;
329
330 /* Fill a buffer with a sequence of 32 bit ints and read them back out
331  * using take_buffer, checking that they're still in the right order */
332 GST_START_TEST (test_take_buf_order)
333 {
334   GstAdapter *adapter;
335   int i = 0;
336
337   adapter = create_and_fill_adapter ();
338   while (gst_adapter_available (adapter) >= sizeof (guint32)) {
339     GstBuffer *buf = gst_adapter_take_buffer (adapter, sizeof (guint32));
340     GstMapInfo info;
341
342     fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
343     fail_unless (GST_READ_UINT32_LE (info.data) == i);
344     gst_buffer_unmap (buf, &info);
345
346     i++;
347
348     gst_buffer_unref (buf);
349   }
350   fail_unless (gst_adapter_available (adapter) == 0,
351       "Data was left in the adapter");
352
353   g_object_unref (adapter);
354 }
355
356 GST_END_TEST;
357
358 GST_START_TEST (test_timestamp)
359 {
360   GstAdapter *adapter;
361   GstBuffer *buffer;
362   guint avail;
363   GstClockTime timestamp;
364   guint64 dist;
365   guint8 *data;
366   const guint8 *cdata;
367
368   adapter = gst_adapter_new ();
369   fail_unless (adapter != NULL);
370
371   buffer = gst_buffer_new_and_alloc (100);
372
373   /* push in the adapter */
374   gst_adapter_push (adapter, buffer);
375   avail = gst_adapter_available (adapter);
376   fail_unless (avail == 100);
377
378   /* timestamp is now undefined */
379   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
380   fail_unless (timestamp == GST_CLOCK_TIME_NONE);
381   fail_unless (dist == 0);
382
383   gst_adapter_flush (adapter, 50);
384   avail = gst_adapter_available (adapter);
385   fail_unless (avail == 50);
386
387   /* still undefined, dist changed, though */
388   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
389   fail_unless (timestamp == GST_CLOCK_TIME_NONE);
390   fail_unless (dist == 50);
391
392   buffer = gst_buffer_new_and_alloc (100);
393   GST_BUFFER_TIMESTAMP (buffer) = 1 * GST_SECOND;
394
395   /* push in the adapter */
396   gst_adapter_push (adapter, buffer);
397   avail = gst_adapter_available (adapter);
398   fail_unless (avail == 150);
399
400   /* timestamp is still undefined */
401   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
402   fail_unless (timestamp == GST_CLOCK_TIME_NONE);
403   fail_unless (dist == 50);
404
405   /* flush out first buffer we are now at the second buffer timestamp */
406   gst_adapter_flush (adapter, 50);
407   avail = gst_adapter_available (adapter);
408   fail_unless (avail == 100);
409
410   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
411   fail_unless (timestamp == 1 * GST_SECOND);
412   fail_unless (dist == 0);
413
414   /* move some more, still the same timestamp but further away */
415   gst_adapter_flush (adapter, 50);
416   avail = gst_adapter_available (adapter);
417   fail_unless (avail == 50);
418
419   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
420   fail_unless (timestamp == 1 * GST_SECOND);
421   fail_unless (dist == 50);
422
423   /* push a buffer without timestamp in the adapter */
424   buffer = gst_buffer_new_and_alloc (100);
425   gst_adapter_push (adapter, buffer);
426   avail = gst_adapter_available (adapter);
427   fail_unless (avail == 150);
428   /* push a buffer with timestamp in the adapter */
429   buffer = gst_buffer_new_and_alloc (100);
430   GST_BUFFER_TIMESTAMP (buffer) = 2 * GST_SECOND;
431   gst_adapter_push (adapter, buffer);
432   avail = gst_adapter_available (adapter);
433   fail_unless (avail == 250);
434
435   /* timestamp still as it was before the push */
436   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
437   fail_unless (timestamp == 1 * GST_SECOND);
438   fail_unless (dist == 50);
439
440   /* flush away buffer with the timestamp */
441   gst_adapter_flush (adapter, 50);
442   avail = gst_adapter_available (adapter);
443   fail_unless (avail == 200);
444   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
445   fail_unless (timestamp == 1 * GST_SECOND);
446   fail_unless (dist == 100);
447
448   /* move into the second buffer */
449   gst_adapter_flush (adapter, 50);
450   avail = gst_adapter_available (adapter);
451   fail_unless (avail == 150);
452   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
453   fail_unless (timestamp == 1 * GST_SECOND);
454   fail_unless (dist == 150);
455
456   /* move to third buffer we move to the new timestamp */
457   gst_adapter_flush (adapter, 50);
458   avail = gst_adapter_available (adapter);
459   fail_unless (avail == 100);
460   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
461   fail_unless (timestamp == 2 * GST_SECOND);
462   fail_unless (dist == 0);
463
464   /* move everything out */
465   gst_adapter_flush (adapter, 100);
466   avail = gst_adapter_available (adapter);
467   fail_unless (avail == 0);
468   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
469   fail_unless (timestamp == 2 * GST_SECOND);
470   fail_unless (dist == 100);
471
472   /* clear everything */
473   gst_adapter_clear (adapter);
474   avail = gst_adapter_available (adapter);
475   fail_unless (avail == 0);
476   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
477   fail_unless (timestamp == GST_CLOCK_TIME_NONE);
478   fail_unless (dist == 0);
479
480   /* push an empty buffer with timestamp in the adapter */
481   buffer = gst_buffer_new ();
482   GST_BUFFER_TIMESTAMP (buffer) = 2 * GST_SECOND;
483   gst_adapter_push (adapter, buffer);
484   avail = gst_adapter_available (adapter);
485   fail_unless (avail == 0);
486   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
487   fail_unless (timestamp == 2 * GST_SECOND);
488   fail_unless (dist == 0);
489
490   /* push another empty buffer */
491   buffer = gst_buffer_new ();
492   GST_BUFFER_TIMESTAMP (buffer) = 3 * GST_SECOND;
493   gst_adapter_push (adapter, buffer);
494   avail = gst_adapter_available (adapter);
495   fail_unless (avail == 0);
496   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
497   fail_unless (timestamp == 2 * GST_SECOND);
498   fail_unless (dist == 0);
499
500   /* push a buffer with timestamp in the adapter */
501   buffer = gst_buffer_new_and_alloc (100);
502   GST_BUFFER_TIMESTAMP (buffer) = 4 * GST_SECOND;
503   gst_adapter_push (adapter, buffer);
504   avail = gst_adapter_available (adapter);
505   fail_unless (avail == 100);
506   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
507   fail_unless (timestamp == 2 * GST_SECOND);
508   fail_unless (dist == 0);
509
510   gst_adapter_flush (adapter, 1);
511   avail = gst_adapter_available (adapter);
512   fail_unless (avail == 99);
513   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
514   fail_unless (timestamp == 4 * GST_SECOND);
515   fail_unless (dist == 1);
516
517   /* push an empty buffer with timestamp in the adapter */
518   buffer = gst_buffer_new ();
519   GST_BUFFER_TIMESTAMP (buffer) = 5 * GST_SECOND;
520   gst_adapter_push (adapter, buffer);
521   avail = gst_adapter_available (adapter);
522   fail_unless (avail == 99);
523   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
524   fail_unless (timestamp == 4 * GST_SECOND);
525   fail_unless (dist == 1);
526
527   /* push buffer without timestamp */
528   buffer = gst_buffer_new_and_alloc (100);
529   gst_adapter_push (adapter, buffer);
530   avail = gst_adapter_available (adapter);
531   fail_unless (avail == 199);
532   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
533   fail_unless (timestamp == 4 * GST_SECOND);
534   fail_unless (dist == 1);
535
536   /* remove first buffer, timestamp of empty buffer is visible */
537   buffer = gst_adapter_take_buffer (adapter, 99);
538   fail_unless (buffer != NULL);
539   fail_unless (gst_buffer_get_size (buffer) == 99);
540   gst_buffer_unref (buffer);
541   avail = gst_adapter_available (adapter);
542   fail_unless (avail == 100);
543   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
544   fail_unless (timestamp == 5 * GST_SECOND);
545   fail_unless (dist == 0);
546
547   /* remove empty buffer, timestamp still visible */
548   cdata = gst_adapter_map (adapter, 50);
549   fail_unless (cdata != NULL);
550   gst_adapter_unmap (adapter);
551
552   data = gst_adapter_take (adapter, 50);
553   fail_unless (data != NULL);
554   g_free (data);
555   avail = gst_adapter_available (adapter);
556   fail_unless (avail == 50);
557   timestamp = gst_adapter_prev_timestamp (adapter, &dist);
558   fail_unless (timestamp == 5 * GST_SECOND);
559   fail_unless (dist == 50);
560
561   g_object_unref (adapter);
562 }
563
564 GST_END_TEST;
565
566 GST_START_TEST (test_scan)
567 {
568   GstAdapter *adapter;
569   GstBuffer *buffer;
570   GstMapInfo info;
571   guint offset;
572   guint i;
573
574   adapter = gst_adapter_new ();
575   fail_unless (adapter != NULL);
576
577   buffer = gst_buffer_new_and_alloc (100);
578
579   fail_unless (gst_buffer_map (buffer, &info, GST_MAP_WRITE));
580   /* fill with pattern */
581   for (i = 0; i < 100; i++)
582     ((guint8 *) info.data)[i] = i;
583   gst_buffer_unmap (buffer, &info);
584
585   gst_adapter_push (adapter, buffer);
586
587   /* find first bytes */
588   offset =
589       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x00010203, 0, 100);
590   fail_unless (offset == 0);
591   offset =
592       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x01020304, 0, 100);
593   fail_unless (offset == 1);
594   offset =
595       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x01020304, 1, 99);
596   fail_unless (offset == 1);
597   /* offset is past the pattern start */
598   offset =
599       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x01020304, 2, 98);
600   fail_unless (offset == -1);
601   /* not enough bytes to find the pattern */
602   offset =
603       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x02030405, 2, 3);
604   fail_unless (offset == -1);
605   offset =
606       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x02030405, 2, 4);
607   fail_unless (offset == 2);
608   /* size does not include the last scanned byte */
609   offset =
610       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x40414243, 0, 0x41);
611   fail_unless (offset == -1);
612   offset =
613       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x40414243, 0, 0x43);
614   fail_unless (offset == -1);
615   offset =
616       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x40414243, 0, 0x44);
617   fail_unless (offset == 0x40);
618   /* past the start */
619   offset =
620       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x40414243, 65, 10);
621   fail_unless (offset == -1);
622   offset =
623       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x40414243, 64, 5);
624   fail_unless (offset == 64);
625   offset =
626       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x60616263, 65, 35);
627   fail_unless (offset == 0x60);
628   offset =
629       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x60616263, 0x60, 4);
630   fail_unless (offset == 0x60);
631   /* past the start */
632   offset =
633       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x60616263, 0x61, 3);
634   fail_unless (offset == -1);
635
636   offset =
637       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x60616263, 99, 1);
638   fail_unless (offset == -1);
639
640   /* add another buffer */
641   buffer = gst_buffer_new_and_alloc (100);
642
643   fail_unless (gst_buffer_map (buffer, &info, GST_MAP_WRITE));
644   /* fill with pattern */
645   for (i = 0; i < 100; i++)
646     ((guint8 *) info.data)[i] = i + 100;
647   gst_buffer_unmap (buffer, &info);
648
649   gst_adapter_push (adapter, buffer);
650
651   /* past the start */
652   offset =
653       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x60616263, 0x61, 6);
654   fail_unless (offset == -1);
655   /* this should work */
656   offset =
657       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x61626364, 0x61, 4);
658   fail_unless (offset == 0x61);
659   /* not enough data */
660   offset =
661       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x62636465, 0x61, 4);
662   fail_unless (offset == -1);
663   offset =
664       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x62636465, 0x61, 5);
665   fail_unless (offset == 0x62);
666   offset =
667       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x62636465, 0, 120);
668   fail_unless (offset == 0x62);
669
670   /* border conditions */
671   offset =
672       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x62636465, 0, 200);
673   fail_unless (offset == 0x62);
674   offset =
675       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x63646566, 0, 200);
676   fail_unless (offset == 0x63);
677   /* we completely searched the first list */
678   offset =
679       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x64656667, 0, 200);
680   fail_unless (offset == 0x64);
681   /* skip first buffer */
682   offset =
683       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x64656667, 0x64,
684       100);
685   fail_unless (offset == 0x64);
686   /* past the start */
687   offset =
688       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x64656667, 0x65,
689       10);
690   fail_unless (offset == -1);
691   /* not enough data to scan */
692   offset =
693       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x64656667, 0x63, 4);
694   fail_unless (offset == -1);
695   offset =
696       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x64656667, 0x63, 5);
697   fail_unless (offset == 0x64);
698   offset =
699       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0xc4c5c6c7, 0, 199);
700   fail_unless (offset == -1);
701   offset =
702       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0xc4c5c6c7, 0x62,
703       102);
704   fail_unless (offset == 0xc4);
705   /* different masks */
706   offset =
707       gst_adapter_masked_scan_uint32 (adapter, 0x00ffffff, 0x00656667, 0x64,
708       100);
709   fail_unless (offset == 0x64);
710   offset =
711       gst_adapter_masked_scan_uint32 (adapter, 0x000000ff, 0x00000000, 0, 100);
712   fail_unless (offset == -1);
713   offset =
714       gst_adapter_masked_scan_uint32 (adapter, 0x000000ff, 0x00000003, 0, 100);
715   fail_unless (offset == 0);
716   offset =
717       gst_adapter_masked_scan_uint32 (adapter, 0x000000ff, 0x00000061, 0x61,
718       100);
719   fail_unless (offset == -1);
720   offset =
721       gst_adapter_masked_scan_uint32 (adapter, 0xff000000, 0x61000000, 0, 0x62);
722   fail_unless (offset == -1);
723   /* does not even exist */
724   ASSERT_CRITICAL (offset =
725       gst_adapter_masked_scan_uint32 (adapter, 0x00ffffff, 0xffffffff, 0x65,
726           99));
727   fail_unless (offset == -1);
728
729   /* flush some bytes */
730   gst_adapter_flush (adapter, 0x20);
731
732   offset =
733       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x20212223, 0, 100);
734   fail_unless (offset == 0);
735   offset =
736       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x20212223, 0, 4);
737   fail_unless (offset == 0);
738   offset =
739       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0xc4c5c6c7, 0x62,
740       70);
741   fail_unless (offset == 0xa4);
742   offset =
743       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0xc4c5c6c7, 0, 168);
744   fail_unless (offset == 0xa4);
745
746   offset =
747       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0xc4c5c6c7, 164, 4);
748   fail_unless (offset == 0xa4);
749   offset =
750       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0xc4c5c6c7, 0x44,
751       100);
752   fail_unless (offset == 0xa4);
753   /* not enough bytes */
754   offset =
755       gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0xc4c5c6c7, 0x44,
756       99);
757   fail_unless (offset == -1);
758
759   g_object_unref (adapter);
760 }
761
762 GST_END_TEST;
763
764 /* Fill a buffer with a sequence of 32 bit ints and read them back out
765  * using take_buffer, checking that they're still in the right order */
766 GST_START_TEST (test_take_list)
767 {
768   GstAdapter *adapter;
769   int i = 0;
770
771   adapter = create_and_fill_adapter ();
772   while (gst_adapter_available (adapter) >= sizeof (guint32)) {
773     GList *list, *walk;
774     GstBuffer *buf;
775     gsize left;
776     GstMapInfo info;
777     guint8 *ptr;
778
779     list = gst_adapter_take_list (adapter, sizeof (guint32) * 5);
780     fail_unless (list != NULL);
781
782     for (walk = list; walk; walk = g_list_next (walk)) {
783       buf = walk->data;
784
785       fail_unless (gst_buffer_map (buf, &info, GST_MAP_READ));
786
787       ptr = info.data;
788       left = info.size;
789
790       while (left > 0) {
791         fail_unless (GST_READ_UINT32_LE (ptr) == i);
792         i++;
793         ptr += sizeof (guint32);
794         left -= sizeof (guint32);
795       }
796       gst_buffer_unmap (buf, &info);
797
798       gst_buffer_unref (buf);
799     }
800     g_list_free (list);
801   }
802   fail_unless (gst_adapter_available (adapter) == 0,
803       "Data was left in the adapter");
804
805   g_object_unref (adapter);
806 }
807
808 GST_END_TEST;
809
810 GST_START_TEST (test_merge)
811 {
812   GstAdapter *adapter;
813   GstBuffer *buffer;
814   gint i;
815
816   adapter = gst_adapter_new ();
817   fail_if (adapter == NULL);
818
819   buffer = gst_buffer_new_and_alloc (10);
820   fail_if (buffer == NULL);
821   gst_adapter_push (adapter, buffer);
822
823   for (i = 0; i < 1000; i++) {
824     buffer = gst_buffer_new_and_alloc (10);
825     gst_adapter_push (adapter, buffer);
826
827     fail_unless (gst_adapter_map (adapter, 20) != NULL);
828     gst_adapter_unmap (adapter);
829
830     gst_adapter_flush (adapter, 10);
831   }
832   g_object_unref (adapter);
833 }
834
835 GST_END_TEST;
836
837 static Suite *
838 gst_adapter_suite (void)
839 {
840   Suite *s = suite_create ("adapter");
841   TCase *tc_chain = tcase_create ("general");
842
843   suite_add_tcase (s, tc_chain);
844   tcase_add_test (tc_chain, test_peek1);
845   tcase_add_test (tc_chain, test_peek2);
846   tcase_add_test (tc_chain, test_peek3);
847   tcase_add_test (tc_chain, test_take1);
848   tcase_add_test (tc_chain, test_take2);
849   tcase_add_test (tc_chain, test_take3);
850   tcase_add_test (tc_chain, test_take_order);
851   tcase_add_test (tc_chain, test_take_buf_order);
852   tcase_add_test (tc_chain, test_timestamp);
853   tcase_add_test (tc_chain, test_scan);
854   tcase_add_test (tc_chain, test_take_list);
855   tcase_add_test (tc_chain, test_merge);
856
857   return s;
858 }
859
860 GST_CHECK_MAIN (gst_adapter);