adapter: Add methods to query current offset
[platform/upstream/gstreamer.git] / libs / gst / base / gstadapter.c
1 /* GStreamer
2  * Copyright (C) 2004 Benjamin Otte <otte@gnome.org>
3  *               2005 Wim Taymans <wim@fluendo.com>
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 /**
22  * SECTION:gstadapter
23  * @short_description: adapts incoming data on a sink pad into chunks of N bytes
24  *
25  * This class is for elements that receive buffers in an undesired size.
26  * While for example raw video contains one image per buffer, the same is not
27  * true for a lot of other formats, especially those that come directly from
28  * a file. So if you have undefined buffer sizes and require a specific size,
29  * this object is for you.
30  *
31  * An adapter is created with gst_adapter_new(). It can be freed again with
32  * g_object_unref().
33  *
34  * The theory of operation is like this: All buffers received are put
35  * into the adapter using gst_adapter_push() and the data is then read back
36  * in chunks of the desired size using gst_adapter_map()/gst_adapter_unmap()
37  * and/or gst_adapter_copy(). After the data has been processed, it is freed
38  * using gst_adapter_unmap().
39  *
40  * Other methods such as gst_adapter_take() and gst_adapter_take_buffer()
41  * combine gst_adapter_map() and gst_adapter_unmap() in one method and are
42  * potentially more convenient for some use cases.
43  *
44  * For example, a sink pad's chain function that needs to pass data to a library
45  * in 512-byte chunks could be implemented like this:
46  * |[<!-- language="C" -->
47  * static GstFlowReturn
48  * sink_pad_chain (GstPad *pad, GstObject *parent, GstBuffer *buffer)
49  * {
50  *   MyElement *this;
51  *   GstAdapter *adapter;
52  *   GstFlowReturn ret = GST_FLOW_OK;
53  *
54  *   this = MY_ELEMENT (parent);
55  *
56  *   adapter = this->adapter;
57  *
58  *   // put buffer into adapter
59  *   gst_adapter_push (adapter, buffer);
60  *
61  *   // while we can read out 512 bytes, process them
62  *   while (gst_adapter_available (adapter) >= 512 && ret == GST_FLOW_OK) {
63  *     const guint8 *data = gst_adapter_map (adapter, 512);
64  *     // use flowreturn as an error value
65  *     ret = my_library_foo (data);
66  *     gst_adapter_unmap (adapter);
67  *     gst_adapter_flush (adapter, 512);
68  *   }
69  *   return ret;
70  * }
71  * ]|
72  *
73  * For another example, a simple element inside GStreamer that uses #GstAdapter
74  * is the libvisual element.
75  *
76  * An element using #GstAdapter in its sink pad chain function should ensure that
77  * when the FLUSH_STOP event is received, that any queued data is cleared using
78  * gst_adapter_clear(). Data should also be cleared or processed on EOS and
79  * when changing state from %GST_STATE_PAUSED to %GST_STATE_READY.
80  *
81  * Also check the GST_BUFFER_FLAG_DISCONT flag on the buffer. Some elements might
82  * need to clear the adapter after a discontinuity.
83  *
84  * The adapter will keep track of the timestamps of the buffers
85  * that were pushed. The last seen timestamp before the current position
86  * can be queried with gst_adapter_prev_pts(). This function can
87  * optionally return the number of bytes between the start of the buffer that
88  * carried the timestamp and the current adapter position. The distance is
89  * useful when dealing with, for example, raw audio samples because it allows
90  * you to calculate the timestamp of the current adapter position by using the
91  * last seen timestamp and the amount of bytes since.  Additionally, the
92  * gst_adapter_prev_pts_at_offset() can be used to determine the last
93  * seen timestamp at a particular offset in the adapter.
94  *
95  * The adapter will also keep track of the offset of the buffers
96  * (#GST_BUFFER_OFFSET) that were pushed. The last seen offset before the
97  * current position can be queried with gst_adapter_prev_offset(). This function
98  * can optionally return the number of bytes between the start of the buffer
99  * that carried the offset and the current adapter position. If the meaning of
100  * #GST_BUFFER_OFFSET for the stream being handled corresponds to bytes, then
101  * the accumulated offset since the last #GST_BUFFER_FLAG_DISCONT buffer can be
102  * queried with gst_adapter_get_offset_from_discont(). This is useful for
103  * elements that want to track the position of data in the stream based on the
104  * offset of the incoming buffers.
105  *
106  * A last thing to note is that while #GstAdapter is pretty optimized,
107  * merging buffers still might be an operation that requires a malloc() and
108  * memcpy() operation, and these operations are not the fastest. Because of
109  * this, some functions like gst_adapter_available_fast() are provided to help
110  * speed up such cases should you want to. To avoid repeated memory allocations,
111  * gst_adapter_copy() can be used to copy data into a (statically allocated)
112  * user provided buffer.
113  *
114  * #GstAdapter is not MT safe. All operations on an adapter must be serialized by
115  * the caller. This is not normally a problem, however, as the normal use case
116  * of #GstAdapter is inside one pad's chain function, in which case access is
117  * serialized via the pad's STREAM_LOCK.
118  *
119  * Note that gst_adapter_push() takes ownership of the buffer passed. Use
120  * gst_buffer_ref() before pushing it into the adapter if you still want to
121  * access the buffer later. The adapter will never modify the data in the
122  * buffer pushed in it.
123  */
124
125 #include <gst/gst_private.h>
126 #include "gstadapter.h"
127 #include <string.h>
128
129 /* default size for the assembled data buffer */
130 #define DEFAULT_SIZE 4096
131
132 #define INCREASE_OFFSET(a, offs) if ((a)->offset_discont != GST_BUFFER_OFFSET_NONE) { (a)->offset_discont += (offs); }
133
134 static void gst_adapter_flush_unchecked (GstAdapter * adapter, gsize flush);
135
136 GST_DEBUG_CATEGORY_STATIC (gst_adapter_debug);
137 #define GST_CAT_DEFAULT gst_adapter_debug
138
139 struct _GstAdapter
140 {
141   GObject object;
142
143   /*< private > */
144   GSList *buflist;
145   GSList *buflist_end;
146   gsize size;
147   gsize skip;
148   guint count;
149
150   /* we keep state of assembled pieces */
151   gpointer assembled_data;
152   gsize assembled_size;
153   gsize assembled_len;
154
155   GstClockTime pts;
156   guint64 pts_distance;
157   GstClockTime dts;
158   guint64 dts_distance;
159   guint64 offset;
160   guint64 offset_distance;
161
162   gsize scan_offset;
163   GSList *scan_entry;
164
165   guint64 offset_discont;
166
167   GstMapInfo info;
168 };
169
170 struct _GstAdapterClass
171 {
172   GObjectClass parent_class;
173 };
174
175 #define _do_init \
176   GST_DEBUG_CATEGORY_INIT (gst_adapter_debug, "adapter", 0, "object to splice and merge buffers to desired size")
177 #define gst_adapter_parent_class parent_class
178 G_DEFINE_TYPE_WITH_CODE (GstAdapter, gst_adapter, G_TYPE_OBJECT, _do_init);
179
180 static void gst_adapter_dispose (GObject * object);
181 static void gst_adapter_finalize (GObject * object);
182
183 static void
184 gst_adapter_class_init (GstAdapterClass * klass)
185 {
186   GObjectClass *object = G_OBJECT_CLASS (klass);
187
188   object->dispose = gst_adapter_dispose;
189   object->finalize = gst_adapter_finalize;
190 }
191
192 static void
193 gst_adapter_init (GstAdapter * adapter)
194 {
195   adapter->assembled_data = g_malloc (DEFAULT_SIZE);
196   adapter->assembled_size = DEFAULT_SIZE;
197   adapter->pts = GST_CLOCK_TIME_NONE;
198   adapter->pts_distance = 0;
199   adapter->dts = GST_CLOCK_TIME_NONE;
200   adapter->dts_distance = 0;
201   adapter->offset = GST_BUFFER_OFFSET_NONE;
202   adapter->offset_distance = 0;
203   adapter->offset_discont = GST_BUFFER_OFFSET_NONE;
204 }
205
206 static void
207 gst_adapter_dispose (GObject * object)
208 {
209   GstAdapter *adapter = GST_ADAPTER (object);
210
211   gst_adapter_clear (adapter);
212
213   GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
214 }
215
216 static void
217 gst_adapter_finalize (GObject * object)
218 {
219   GstAdapter *adapter = GST_ADAPTER (object);
220
221   g_free (adapter->assembled_data);
222
223   GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
224 }
225
226 /**
227  * gst_adapter_new:
228  *
229  * Creates a new #GstAdapter. Free with g_object_unref().
230  *
231  * Returns: (transfer full): a new #GstAdapter
232  */
233 GstAdapter *
234 gst_adapter_new (void)
235 {
236   return g_object_newv (GST_TYPE_ADAPTER, 0, NULL);
237 }
238
239 /**
240  * gst_adapter_clear:
241  * @adapter: a #GstAdapter
242  *
243  * Removes all buffers from @adapter.
244  */
245 void
246 gst_adapter_clear (GstAdapter * adapter)
247 {
248   g_return_if_fail (GST_IS_ADAPTER (adapter));
249
250   if (adapter->info.memory)
251     gst_adapter_unmap (adapter);
252
253   g_slist_foreach (adapter->buflist, (GFunc) gst_mini_object_unref, NULL);
254   g_slist_free (adapter->buflist);
255   adapter->buflist = NULL;
256   adapter->buflist_end = NULL;
257   adapter->count = 0;
258   adapter->size = 0;
259   adapter->skip = 0;
260   adapter->assembled_len = 0;
261   adapter->pts = GST_CLOCK_TIME_NONE;
262   adapter->pts_distance = 0;
263   adapter->dts = GST_CLOCK_TIME_NONE;
264   adapter->dts_distance = 0;
265   adapter->offset = GST_BUFFER_OFFSET_NONE;
266   adapter->offset_distance = 0;
267   adapter->scan_offset = 0;
268   adapter->scan_entry = NULL;
269   adapter->offset_discont = GST_BUFFER_OFFSET_NONE;
270 }
271
272 static inline void
273 update_timestamps_and_offset (GstAdapter * adapter, GstBuffer * buf)
274 {
275   GstClockTime pts, dts;
276   guint64 offset;
277
278   pts = GST_BUFFER_PTS (buf);
279   if (GST_CLOCK_TIME_IS_VALID (pts)) {
280     GST_LOG_OBJECT (adapter, "new pts %" GST_TIME_FORMAT, GST_TIME_ARGS (pts));
281     adapter->pts = pts;
282     adapter->pts_distance = 0;
283   }
284   dts = GST_BUFFER_DTS (buf);
285   if (GST_CLOCK_TIME_IS_VALID (dts)) {
286     GST_LOG_OBJECT (adapter, "new dts %" GST_TIME_FORMAT, GST_TIME_ARGS (dts));
287     adapter->dts = dts;
288     adapter->dts_distance = 0;
289   }
290   offset = GST_BUFFER_OFFSET (buf);
291   if (GST_BUFFER_IS_DISCONT (buf)) {
292     /* Take offset as-is (might be NONE) */
293     adapter->offset_discont = offset;
294     GST_LOG_OBJECT (adapter, "offset discont now %" G_GUINT64_FORMAT,
295         adapter->offset_discont);
296   }
297   if (offset != GST_BUFFER_OFFSET_NONE) {
298     GST_LOG_OBJECT (adapter, "new offset %" G_GUINT64_FORMAT, offset);
299     adapter->offset = offset;
300     adapter->offset_distance = 0;
301   }
302 }
303
304 /* copy data into @dest, skipping @skip bytes from the head buffers */
305 static void
306 copy_into_unchecked (GstAdapter * adapter, guint8 * dest, gsize skip,
307     gsize size)
308 {
309   GSList *g;
310   GstBuffer *buf;
311   gsize bsize, csize;
312
313   /* first step, do skipping */
314   /* we might well be copying where we were scanning */
315   if (adapter->scan_entry && (adapter->scan_offset <= skip)) {
316     g = adapter->scan_entry;
317     skip -= adapter->scan_offset;
318   } else {
319     g = adapter->buflist;
320   }
321   buf = g->data;
322   bsize = gst_buffer_get_size (buf);
323   while (G_UNLIKELY (skip >= bsize)) {
324     skip -= bsize;
325     g = g_slist_next (g);
326     buf = g->data;
327     bsize = gst_buffer_get_size (buf);
328   }
329   /* copy partial buffer */
330   csize = MIN (bsize - skip, size);
331   GST_DEBUG ("bsize %" G_GSIZE_FORMAT ", skip %" G_GSIZE_FORMAT ", csize %"
332       G_GSIZE_FORMAT, bsize, skip, csize);
333   GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, adapter, "extract %" G_GSIZE_FORMAT
334       " bytes", csize);
335   gst_buffer_extract (buf, skip, dest, csize);
336   size -= csize;
337   dest += csize;
338
339   /* second step, copy remainder */
340   while (size > 0) {
341     g = g_slist_next (g);
342     buf = g->data;
343     bsize = gst_buffer_get_size (buf);
344     if (G_LIKELY (bsize > 0)) {
345       csize = MIN (bsize, size);
346       GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, adapter,
347           "extract %" G_GSIZE_FORMAT " bytes", csize);
348       gst_buffer_extract (buf, 0, dest, csize);
349       size -= csize;
350       dest += csize;
351     }
352   }
353 }
354
355 /**
356  * gst_adapter_push:
357  * @adapter: a #GstAdapter
358  * @buf: (transfer full): a #GstBuffer to add to queue in the adapter
359  *
360  * Adds the data from @buf to the data stored inside @adapter and takes
361  * ownership of the buffer.
362  */
363 void
364 gst_adapter_push (GstAdapter * adapter, GstBuffer * buf)
365 {
366   gsize size;
367
368   g_return_if_fail (GST_IS_ADAPTER (adapter));
369   g_return_if_fail (GST_IS_BUFFER (buf));
370
371   size = gst_buffer_get_size (buf);
372   adapter->size += size;
373
374   /* Note: merging buffers at this point is premature. */
375   if (G_UNLIKELY (adapter->buflist == NULL)) {
376     GST_LOG_OBJECT (adapter, "pushing %p first %" G_GSIZE_FORMAT " bytes",
377         buf, size);
378     adapter->buflist = adapter->buflist_end = g_slist_append (NULL, buf);
379     update_timestamps_and_offset (adapter, buf);
380   } else {
381     /* Otherwise append to the end, and advance our end pointer */
382     GST_LOG_OBJECT (adapter, "pushing %p %" G_GSIZE_FORMAT " bytes at end, "
383         "size now %" G_GSIZE_FORMAT, buf, size, adapter->size);
384     adapter->buflist_end = g_slist_append (adapter->buflist_end, buf);
385     adapter->buflist_end = g_slist_next (adapter->buflist_end);
386   }
387   ++adapter->count;
388 }
389
390 #if 0
391 /* Internal method only. Tries to merge buffers at the head of the queue
392  * to form a single larger buffer of size 'size'.
393  *
394  * Returns %TRUE if it managed to merge anything.
395  */
396 static gboolean
397 gst_adapter_try_to_merge_up (GstAdapter * adapter, gsize size)
398 {
399   GstBuffer *cur, *head;
400   GSList *g;
401   gboolean ret = FALSE;
402   gsize hsize;
403
404   g = adapter->buflist;
405   if (g == NULL)
406     return FALSE;
407
408   head = g->data;
409
410   hsize = gst_buffer_get_size (head);
411
412   /* Remove skipped part from the buffer (otherwise the buffer might grow indefinitely) */
413   head = gst_buffer_make_writable (head);
414   gst_buffer_resize (head, adapter->skip, hsize - adapter->skip);
415   hsize -= adapter->skip;
416   adapter->skip = 0;
417   g->data = head;
418
419   g = g_slist_next (g);
420
421   while (g != NULL && hsize < size) {
422     cur = g->data;
423     /* Merge the head buffer and the next in line */
424     GST_LOG_OBJECT (adapter, "Merging buffers of size %" G_GSIZE_FORMAT " & %"
425         G_GSIZE_FORMAT " in search of target %" G_GSIZE_FORMAT,
426         hsize, gst_buffer_get_size (cur), size);
427
428     head = gst_buffer_append (head, cur);
429     hsize = gst_buffer_get_size (head);
430     ret = TRUE;
431
432     /* Delete the front list item, and store our new buffer in the 2nd list
433      * item */
434     adapter->buflist = g_slist_delete_link (adapter->buflist, adapter->buflist);
435     g->data = head;
436
437     /* invalidate scan position */
438     adapter->scan_offset = 0;
439     adapter->scan_entry = NULL;
440
441     g = g_slist_next (g);
442   }
443
444   return ret;
445 }
446 #endif
447
448 /**
449  * gst_adapter_map:
450  * @adapter: a #GstAdapter
451  * @size: the number of bytes to map/peek
452  *
453  * Gets the first @size bytes stored in the @adapter. The returned pointer is
454  * valid until the next function is called on the adapter.
455  *
456  * Note that setting the returned pointer as the data of a #GstBuffer is
457  * incorrect for general-purpose plugins. The reason is that if a downstream
458  * element stores the buffer so that it has access to it outside of the bounds
459  * of its chain function, the buffer will have an invalid data pointer after
460  * your element flushes the bytes. In that case you should use
461  * gst_adapter_take(), which returns a freshly-allocated buffer that you can set
462  * as #GstBuffer memory or the potentially more performant
463  * gst_adapter_take_buffer().
464  *
465  * Returns %NULL if @size bytes are not available.
466  *
467  * Returns: (transfer none) (array length=size) (element-type guint8) (nullable):
468  *     a pointer to the first @size bytes of data, or %NULL
469  */
470 gconstpointer
471 gst_adapter_map (GstAdapter * adapter, gsize size)
472 {
473   GstBuffer *cur;
474   gsize skip, csize;
475   gsize toreuse, tocopy;
476   guint8 *data;
477
478   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
479   g_return_val_if_fail (size > 0, NULL);
480
481   if (adapter->info.memory)
482     gst_adapter_unmap (adapter);
483
484   /* we don't have enough data, return NULL. This is unlikely
485    * as one usually does an _available() first instead of peeking a
486    * random size. */
487   if (G_UNLIKELY (size > adapter->size))
488     return NULL;
489
490   /* we have enough assembled data, return it */
491   if (adapter->assembled_len >= size)
492     return adapter->assembled_data;
493
494 #if 0
495   do {
496 #endif
497     cur = adapter->buflist->data;
498     skip = adapter->skip;
499
500     csize = gst_buffer_get_size (cur);
501     if (csize >= size + skip) {
502       if (!gst_buffer_map (cur, &adapter->info, GST_MAP_READ))
503         return FALSE;
504
505       return (guint8 *) adapter->info.data + skip;
506     }
507     /* We may be able to efficiently merge buffers in our pool to
508      * gather a big enough chunk to return it from the head buffer directly */
509 #if 0
510   } while (gst_adapter_try_to_merge_up (adapter, size));
511 #endif
512
513   /* see how much data we can reuse from the assembled memory and how much
514    * we need to copy */
515   toreuse = adapter->assembled_len;
516   tocopy = size - toreuse;
517
518   /* Gonna need to copy stuff out */
519   if (G_UNLIKELY (adapter->assembled_size < size)) {
520     adapter->assembled_size = (size / DEFAULT_SIZE + 1) * DEFAULT_SIZE;
521     GST_DEBUG_OBJECT (adapter, "resizing internal buffer to %" G_GSIZE_FORMAT,
522         adapter->assembled_size);
523     if (toreuse == 0) {
524       GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "alloc new buffer");
525       /* no g_realloc to avoid a memcpy that is not desired here since we are
526        * not going to reuse any data here */
527       g_free (adapter->assembled_data);
528       adapter->assembled_data = g_malloc (adapter->assembled_size);
529     } else {
530       /* we are going to reuse all data, realloc then */
531       GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "reusing %" G_GSIZE_FORMAT " bytes",
532           toreuse);
533       adapter->assembled_data =
534           g_realloc (adapter->assembled_data, adapter->assembled_size);
535     }
536   }
537   GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy remaining %" G_GSIZE_FORMAT
538       " bytes from adapter", tocopy);
539   data = adapter->assembled_data;
540   copy_into_unchecked (adapter, data + toreuse, skip + toreuse, tocopy);
541   adapter->assembled_len = size;
542
543   return adapter->assembled_data;
544 }
545
546 /**
547  * gst_adapter_unmap:
548  * @adapter: a #GstAdapter
549  *
550  * Releases the memory obtained with the last gst_adapter_map().
551  */
552 void
553 gst_adapter_unmap (GstAdapter * adapter)
554 {
555   g_return_if_fail (GST_IS_ADAPTER (adapter));
556
557   if (adapter->info.memory) {
558     GstBuffer *cur = adapter->buflist->data;
559     GST_LOG_OBJECT (adapter, "unmap memory buffer %p", cur);
560     gst_buffer_unmap (cur, &adapter->info);
561     adapter->info.memory = NULL;
562   }
563 }
564
565 /**
566  * gst_adapter_copy: (skip)
567  * @adapter: a #GstAdapter
568  * @dest: (out caller-allocates) (array length=size) (element-type guint8):
569  *     the memory to copy into
570  * @offset: the bytes offset in the adapter to start from
571  * @size: the number of bytes to copy
572  *
573  * Copies @size bytes of data starting at @offset out of the buffers
574  * contained in #GstAdapter into an array @dest provided by the caller.
575  *
576  * The array @dest should be large enough to contain @size bytes.
577  * The user should check that the adapter has (@offset + @size) bytes
578  * available before calling this function.
579  */
580 void
581 gst_adapter_copy (GstAdapter * adapter, gpointer dest, gsize offset, gsize size)
582 {
583   g_return_if_fail (GST_IS_ADAPTER (adapter));
584   g_return_if_fail (size > 0);
585   g_return_if_fail (offset + size <= adapter->size);
586
587   copy_into_unchecked (adapter, dest, offset + adapter->skip, size);
588 }
589
590 /**
591  * gst_adapter_copy_bytes: (rename-to gst_adapter_copy)
592  * @adapter: a #GstAdapter
593  * @offset: the bytes offset in the adapter to start from
594  * @size: the number of bytes to copy
595  *
596  * Similar to gst_adapter_copy, but more suitable for language bindings. @size
597  * bytes of data starting at @offset will be copied out of the buffers contained
598  * in @adapter and into a new #GBytes structure which is returned. Depending on
599  * the value of the @size argument an empty #GBytes structure may be returned.
600  *
601  * Returns: (transfer full): A new #GBytes structure containing the copied data.
602  *
603  * Since: 1.4
604  */
605 GBytes *
606 gst_adapter_copy_bytes (GstAdapter * adapter, gsize offset, gsize size)
607 {
608   gpointer data;
609   data = g_malloc (size);
610   gst_adapter_copy (adapter, data, offset, size);
611   return g_bytes_new_take (data, size);
612 }
613
614 /*Flushes the first @flush bytes in the @adapter*/
615 static void
616 gst_adapter_flush_unchecked (GstAdapter * adapter, gsize flush)
617 {
618   GstBuffer *cur;
619   gsize size;
620   GSList *g;
621
622   GST_LOG_OBJECT (adapter, "flushing %" G_GSIZE_FORMAT " bytes", flush);
623
624   if (adapter->info.memory)
625     gst_adapter_unmap (adapter);
626
627   /* clear state */
628   adapter->size -= flush;
629   adapter->assembled_len = 0;
630
631   /* take skip into account */
632   flush += adapter->skip;
633   /* distance is always at least the amount of skipped bytes */
634   adapter->pts_distance -= adapter->skip;
635   adapter->dts_distance -= adapter->skip;
636   adapter->offset_distance -= adapter->skip;
637   INCREASE_OFFSET (adapter, -adapter->skip);
638
639   g = adapter->buflist;
640   cur = g->data;
641   size = gst_buffer_get_size (cur);
642   while (flush >= size) {
643     /* can skip whole buffer */
644     GST_LOG_OBJECT (adapter, "flushing out head buffer");
645     adapter->pts_distance += size;
646     adapter->dts_distance += size;
647     adapter->offset_distance += size;
648     flush -= size;
649     INCREASE_OFFSET (adapter, size);
650
651     gst_buffer_unref (cur);
652     g = g_slist_delete_link (g, g);
653     --adapter->count;
654
655     if (G_UNLIKELY (g == NULL)) {
656       GST_LOG_OBJECT (adapter, "adapter empty now");
657       adapter->buflist_end = NULL;
658       break;
659     }
660     /* there is a new head buffer, update the timestamps */
661     cur = g->data;
662     update_timestamps_and_offset (adapter, cur);
663     size = gst_buffer_get_size (cur);
664   }
665   adapter->buflist = g;
666   /* account for the remaining bytes */
667   adapter->skip = flush;
668   adapter->pts_distance += flush;
669   adapter->dts_distance += flush;
670   adapter->offset_distance += flush;
671   INCREASE_OFFSET (adapter, flush);
672   /* invalidate scan position */
673   adapter->scan_offset = 0;
674   adapter->scan_entry = NULL;
675 }
676
677 /**
678  * gst_adapter_flush:
679  * @adapter: a #GstAdapter
680  * @flush: the number of bytes to flush
681  *
682  * Flushes the first @flush bytes in the @adapter. The caller must ensure that
683  * at least this many bytes are available.
684  *
685  * See also: gst_adapter_map(), gst_adapter_unmap()
686  */
687 void
688 gst_adapter_flush (GstAdapter * adapter, gsize flush)
689 {
690   g_return_if_fail (GST_IS_ADAPTER (adapter));
691   g_return_if_fail (flush <= adapter->size);
692
693   /* flushing out 0 bytes will do nothing */
694   if (G_UNLIKELY (flush == 0))
695     return;
696
697   gst_adapter_flush_unchecked (adapter, flush);
698 }
699
700 /* internal function, nbytes should be flushed if needed after calling this function */
701 static guint8 *
702 gst_adapter_get_internal (GstAdapter * adapter, gsize nbytes)
703 {
704   guint8 *data;
705   gsize toreuse, tocopy;
706
707   /* see how much data we can reuse from the assembled memory and how much
708    * we need to copy */
709   toreuse = MIN (nbytes, adapter->assembled_len);
710   tocopy = nbytes - toreuse;
711
712   /* find memory to return */
713   if (adapter->assembled_size >= nbytes && toreuse > 0) {
714     /* we reuse already allocated memory but only when we're going to reuse
715      * something from it because else we are worse than the malloc and copy
716      * case below */
717     GST_LOG_OBJECT (adapter, "reusing %" G_GSIZE_FORMAT " bytes of assembled"
718         " data", toreuse);
719     /* we have enough free space in the assembled array */
720     data = adapter->assembled_data;
721     /* flush after this function should set the assembled_size to 0 */
722     adapter->assembled_data = g_malloc (adapter->assembled_size);
723   } else {
724     GST_LOG_OBJECT (adapter, "allocating %" G_GSIZE_FORMAT " bytes", nbytes);
725     /* not enough bytes in the assembled array, just allocate new space */
726     data = g_malloc (nbytes);
727     /* reuse what we can from the already assembled data */
728     if (toreuse) {
729       GST_LOG_OBJECT (adapter, "reusing %" G_GSIZE_FORMAT " bytes", toreuse);
730       GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, adapter,
731           "memcpy %" G_GSIZE_FORMAT " bytes", toreuse);
732       memcpy (data, adapter->assembled_data, toreuse);
733     }
734   }
735   if (tocopy) {
736     /* copy the remaining data */
737     copy_into_unchecked (adapter, toreuse + data, toreuse + adapter->skip,
738         tocopy);
739   }
740   return data;
741 }
742
743 /**
744  * gst_adapter_take:
745  * @adapter: a #GstAdapter
746  * @nbytes: the number of bytes to take
747  *
748  * Returns a freshly allocated buffer containing the first @nbytes bytes of the
749  * @adapter. The returned bytes will be flushed from the adapter.
750  *
751  * Caller owns returned value. g_free after usage.
752  *
753  * Free-function: g_free
754  *
755  * Returns: (transfer full) (array length=nbytes) (element-type guint8) (nullable):
756  *     oven-fresh hot data, or %NULL if @nbytes bytes are not available
757  */
758 gpointer
759 gst_adapter_take (GstAdapter * adapter, gsize nbytes)
760 {
761   gpointer data;
762
763   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
764   g_return_val_if_fail (nbytes > 0, NULL);
765
766   /* we don't have enough data, return NULL. This is unlikely
767    * as one usually does an _available() first instead of peeking a
768    * random size. */
769   if (G_UNLIKELY (nbytes > adapter->size))
770     return NULL;
771
772   data = gst_adapter_get_internal (adapter, nbytes);
773
774   gst_adapter_flush_unchecked (adapter, nbytes);
775
776   return data;
777 }
778
779 /**
780  * gst_adapter_get_buffer_fast:
781  * @adapter:  a #GstAdapter
782  * @nbytes: the number of bytes to get
783  *
784  * Returns a #GstBuffer containing the first @nbytes of the @adapter, but
785  * does not flush them from the adapter. See gst_adapter_take_buffer_fast()
786  * for details.
787  *
788  * Caller owns a reference to the returned buffer. gst_buffer_unref() after
789  * usage.
790  *
791  * Free-function: gst_buffer_unref
792  *
793  * Returns: (transfer full) (nullable): a #GstBuffer containing the first
794  *     @nbytes of the adapter, or %NULL if @nbytes bytes are not available.
795  *     gst_buffer_unref() when no longer needed.
796  *
797  * Since: 1.6
798  */
799 GstBuffer *
800 gst_adapter_get_buffer_fast (GstAdapter * adapter, gsize nbytes)
801 {
802   GstBuffer *buffer = NULL;
803   GstBuffer *cur;
804   GSList *item;
805   gsize skip;
806   gsize left = nbytes;
807
808   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
809   g_return_val_if_fail (nbytes > 0, NULL);
810
811   GST_LOG_OBJECT (adapter, "getting buffer of %" G_GSIZE_FORMAT " bytes",
812       nbytes);
813
814   /* we don't have enough data, return NULL. This is unlikely
815    * as one usually does an _available() first instead of grabbing a
816    * random size. */
817   if (G_UNLIKELY (nbytes > adapter->size))
818     return NULL;
819
820   skip = adapter->skip;
821   cur = adapter->buflist->data;
822
823   if (skip == 0 && gst_buffer_get_size (cur) == nbytes) {
824     GST_LOG_OBJECT (adapter, "providing buffer of %" G_GSIZE_FORMAT " bytes"
825         " as head buffer", nbytes);
826     buffer = gst_buffer_ref (cur);
827     goto done;
828   }
829
830   for (item = adapter->buflist; item && left > 0; item = item->next) {
831     gsize size, cur_size;
832
833     cur = item->data;
834     cur_size = gst_buffer_get_size (cur);
835     size = MIN (cur_size - skip, left);
836
837     GST_LOG_OBJECT (adapter, "appending %" G_GSIZE_FORMAT " bytes"
838         " via region copy", size);
839     if (buffer)
840       gst_buffer_copy_into (buffer, cur,
841           GST_BUFFER_COPY_MEMORY | GST_BUFFER_COPY_META, skip, size);
842     else
843       buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, size);
844     skip = 0;
845     left -= size;
846   }
847
848 done:
849
850   return buffer;
851 }
852
853 /**
854  * gst_adapter_take_buffer_fast:
855  * @adapter:  a #GstAdapter
856  * @nbytes: the number of bytes to take
857  *
858  * Returns a #GstBuffer containing the first @nbytes of the @adapter.
859  * The returned bytes will be flushed from the adapter.  This function
860  * is potentially more performant than gst_adapter_take_buffer() since
861  * it can reuse the memory in pushed buffers by subbuffering or
862  * merging. Unlike gst_adapter_take_buffer(), the returned buffer may
863  * be composed of multiple non-contiguous #GstMemory objects, no
864  * copies are made.
865  *
866  * Note that no assumptions should be made as to whether certain buffer
867  * flags such as the DISCONT flag are set on the returned buffer, or not.
868  * The caller needs to explicitly set or unset flags that should be set or
869  * unset.
870  *
871  * This will also copy over all GstMeta of the input buffers except
872  * for meta with the %GST_META_FLAG_POOLED flag or with the "memory" tag.
873  *
874  * This function can return buffer up to the return value of
875  * gst_adapter_available() without making copies if possible.
876  *
877  * Caller owns a reference to the returned buffer. gst_buffer_unref() after
878  * usage.
879  *
880  * Free-function: gst_buffer_unref
881  *
882  * Returns: (transfer full) (nullable): a #GstBuffer containing the first
883  *     @nbytes of the adapter, or %NULL if @nbytes bytes are not available.
884  *     gst_buffer_unref() when no longer needed.
885  *
886  * Since: 1.2
887  */
888 GstBuffer *
889 gst_adapter_take_buffer_fast (GstAdapter * adapter, gsize nbytes)
890 {
891   GstBuffer *buffer;
892
893   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
894   g_return_val_if_fail (nbytes > 0, NULL);
895
896   buffer = gst_adapter_get_buffer_fast (adapter, nbytes);
897   if (buffer)
898     gst_adapter_flush_unchecked (adapter, nbytes);
899
900   return buffer;
901 }
902
903 static gboolean
904 foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
905 {
906   GstBuffer *outbuf = user_data;
907   const GstMetaInfo *info = (*meta)->info;
908   gboolean do_copy = FALSE;
909
910   if (gst_meta_api_type_has_tag (info->api, _gst_meta_tag_memory)) {
911     /* never call the transform_meta with memory specific metadata */
912     GST_DEBUG ("not copying memory specific metadata %s",
913         g_type_name (info->api));
914     do_copy = FALSE;
915   } else {
916     do_copy = TRUE;
917     GST_DEBUG ("copying metadata %s", g_type_name (info->api));
918   }
919
920   if (do_copy) {
921     GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
922     GST_DEBUG ("copy metadata %s", g_type_name (info->api));
923     /* simply copy then */
924     info->transform_func (outbuf, *meta, inbuf,
925         _gst_meta_transform_copy, &copy_data);
926   }
927   return TRUE;
928 }
929
930 /**
931  * gst_adapter_get_buffer:
932  * @adapter: a #GstAdapter
933  * @nbytes: the number of bytes to get
934  *
935  * Returns a #GstBuffer containing the first @nbytes of the @adapter, but
936  * does not flush them from the adapter. See gst_adapter_take_buffer()
937  * for details.
938  *
939  * Caller owns a reference to the returned buffer. gst_buffer_unref() after
940  * usage.
941  *
942  * Free-function: gst_buffer_unref
943  *
944  * Returns: (transfer full) (nullable): a #GstBuffer containing the first
945  *     @nbytes of the adapter, or %NULL if @nbytes bytes are not available.
946  *     gst_buffer_unref() when no longer needed.
947  *
948  * Since: 1.6
949  */
950 GstBuffer *
951 gst_adapter_get_buffer (GstAdapter * adapter, gsize nbytes)
952 {
953   GstBuffer *buffer;
954   GstBuffer *cur;
955   gsize hsize, skip;
956   guint8 *data;
957
958   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
959   g_return_val_if_fail (nbytes > 0, NULL);
960
961   GST_LOG_OBJECT (adapter, "getting buffer of %" G_GSIZE_FORMAT " bytes",
962       nbytes);
963
964   /* we don't have enough data, return NULL. This is unlikely
965    * as one usually does an _available() first instead of grabbing a
966    * random size. */
967   if (G_UNLIKELY (nbytes > adapter->size))
968     return NULL;
969
970   cur = adapter->buflist->data;
971   skip = adapter->skip;
972   hsize = gst_buffer_get_size (cur);
973
974   /* our head buffer has enough data left, return it */
975   if (skip == 0 && hsize == nbytes) {
976     GST_LOG_OBJECT (adapter, "providing buffer of %" G_GSIZE_FORMAT " bytes"
977         " as head buffer", nbytes);
978     buffer = gst_buffer_ref (cur);
979     goto done;
980   } else if (hsize >= nbytes + skip) {
981     GST_LOG_OBJECT (adapter, "providing buffer of %" G_GSIZE_FORMAT " bytes"
982         " via region copy", nbytes);
983     buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, nbytes);
984     goto done;
985   }
986 #if 0
987   if (gst_adapter_try_to_merge_up (adapter, nbytes)) {
988     /* Merged something, let's try again for sub-buffering */
989     cur = adapter->buflist->data;
990     skip = adapter->skip;
991     if (gst_buffer_get_size (cur) >= nbytes + skip) {
992       GST_LOG_OBJECT (adapter, "providing buffer of %" G_GSIZE_FORMAT " bytes"
993           " via sub-buffer", nbytes);
994       buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, nbytes);
995       goto done;
996     }
997   }
998 #endif
999
1000   data = gst_adapter_get_internal (adapter, nbytes);
1001
1002   buffer = gst_buffer_new_wrapped (data, nbytes);
1003
1004   {
1005     GSList *g;
1006     GstBuffer *cur;
1007     gsize read_offset = 0;
1008
1009     g = adapter->buflist;
1010     while (g && read_offset < nbytes + adapter->skip) {
1011       cur = g->data;
1012
1013       gst_buffer_foreach_meta (cur, foreach_metadata, buffer);
1014       read_offset += gst_buffer_get_size (cur);
1015
1016       g = g_slist_next (g);
1017     }
1018   }
1019
1020 done:
1021
1022   return buffer;
1023 }
1024
1025 /**
1026  * gst_adapter_take_buffer:
1027  * @adapter: a #GstAdapter
1028  * @nbytes: the number of bytes to take
1029  *
1030  * Returns a #GstBuffer containing the first @nbytes bytes of the
1031  * @adapter. The returned bytes will be flushed from the adapter.
1032  * This function is potentially more performant than
1033  * gst_adapter_take() since it can reuse the memory in pushed buffers
1034  * by subbuffering or merging. This function will always return a
1035  * buffer with a single memory region.
1036  *
1037  * Note that no assumptions should be made as to whether certain buffer
1038  * flags such as the DISCONT flag are set on the returned buffer, or not.
1039  * The caller needs to explicitly set or unset flags that should be set or
1040  * unset.
1041  *
1042  * Since 1.6 this will also copy over all GstMeta of the input buffers except
1043  * for meta with the %GST_META_FLAG_POOLED flag or with the "memory" tag.
1044  *
1045  * Caller owns a reference to the returned buffer. gst_buffer_unref() after
1046  * usage.
1047  *
1048  * Free-function: gst_buffer_unref
1049  *
1050  * Returns: (transfer full) (nullable): a #GstBuffer containing the first
1051  *     @nbytes of the adapter, or %NULL if @nbytes bytes are not available.
1052  *     gst_buffer_unref() when no longer needed.
1053  */
1054 GstBuffer *
1055 gst_adapter_take_buffer (GstAdapter * adapter, gsize nbytes)
1056 {
1057   GstBuffer *buffer;
1058
1059   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
1060   g_return_val_if_fail (nbytes > 0, NULL);
1061
1062   buffer = gst_adapter_get_buffer (adapter, nbytes);
1063   if (buffer)
1064     gst_adapter_flush_unchecked (adapter, nbytes);
1065
1066   return buffer;
1067 }
1068
1069 /**
1070  * gst_adapter_take_list:
1071  * @adapter: a #GstAdapter
1072  * @nbytes: the number of bytes to take
1073  *
1074  * Returns a #GList of buffers containing the first @nbytes bytes of the
1075  * @adapter. The returned bytes will be flushed from the adapter.
1076  * When the caller can deal with individual buffers, this function is more
1077  * performant because no memory should be copied.
1078  *
1079  * Caller owns returned list and contained buffers. gst_buffer_unref() each
1080  * buffer in the list before freeing the list after usage.
1081  *
1082  * Returns: (element-type Gst.Buffer) (transfer full) (nullable): a #GList of
1083  *     buffers containing the first @nbytes of the adapter, or %NULL if @nbytes
1084  *     bytes are not available
1085  */
1086 GList *
1087 gst_adapter_take_list (GstAdapter * adapter, gsize nbytes)
1088 {
1089   GQueue queue = G_QUEUE_INIT;
1090   GstBuffer *cur;
1091   gsize hsize, skip, cur_size;
1092
1093   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
1094   g_return_val_if_fail (nbytes <= adapter->size, NULL);
1095
1096   GST_LOG_OBJECT (adapter, "taking %" G_GSIZE_FORMAT " bytes", nbytes);
1097
1098   while (nbytes > 0) {
1099     cur = adapter->buflist->data;
1100     skip = adapter->skip;
1101     cur_size = gst_buffer_get_size (cur);
1102     hsize = MIN (nbytes, cur_size - skip);
1103
1104     cur = gst_adapter_take_buffer (adapter, hsize);
1105
1106     g_queue_push_tail (&queue, cur);
1107
1108     nbytes -= hsize;
1109   }
1110   return queue.head;
1111 }
1112
1113 /**
1114  * gst_adapter_get_list:
1115  * @adapter: a #GstAdapter
1116  * @nbytes: the number of bytes to get
1117  *
1118  * Returns a #GList of buffers containing the first @nbytes bytes of the
1119  * @adapter, but does not flush them from the adapter. See
1120  * gst_adapter_take_list() for details.
1121  *
1122  * Caller owns returned list and contained buffers. gst_buffer_unref() each
1123  * buffer in the list before freeing the list after usage.
1124  *
1125  * Returns: (element-type Gst.Buffer) (transfer full) (nullable): a #GList of
1126  *     buffers containing the first @nbytes of the adapter, or %NULL if @nbytes
1127  *     bytes are not available
1128  *
1129  * Since: 1.6
1130  */
1131 GList *
1132 gst_adapter_get_list (GstAdapter * adapter, gsize nbytes)
1133 {
1134   GQueue queue = G_QUEUE_INIT;
1135   GstBuffer *cur, *buffer;
1136   gsize hsize, skip, cur_size;
1137   GSList *g = NULL;
1138
1139   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
1140   g_return_val_if_fail (nbytes <= adapter->size, NULL);
1141
1142   GST_LOG_OBJECT (adapter, "getting %" G_GSIZE_FORMAT " bytes", nbytes);
1143
1144   g = adapter->buflist;
1145   skip = adapter->skip;
1146
1147   while (nbytes > 0) {
1148     cur = g->data;
1149     cur_size = gst_buffer_get_size (cur);
1150     hsize = MIN (nbytes, cur_size - skip);
1151
1152     if (skip == 0 && cur_size == hsize) {
1153       GST_LOG_OBJECT (adapter,
1154           "inserting a buffer of %" G_GSIZE_FORMAT " bytes", hsize);
1155       buffer = gst_buffer_ref (cur);
1156     } else {
1157       GST_LOG_OBJECT (adapter, "inserting a buffer of %" G_GSIZE_FORMAT " bytes"
1158           " via region copy", hsize);
1159       buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, hsize);
1160     }
1161
1162     g_queue_push_tail (&queue, buffer);
1163
1164     nbytes -= hsize;
1165     skip = 0;
1166     g = g_slist_next (g);
1167   }
1168
1169   return queue.head;
1170 }
1171
1172 /**
1173  * gst_adapter_take_buffer_list:
1174  * @adapter: a #GstAdapter
1175  * @nbytes: the number of bytes to take
1176  *
1177  * Returns a #GstBufferList of buffers containing the first @nbytes bytes of
1178  * the @adapter. The returned bytes will be flushed from the adapter.
1179  * When the caller can deal with individual buffers, this function is more
1180  * performant because no memory should be copied.
1181  *
1182  * Caller owns the returned list. Call gst_buffer_list_unref() to free
1183  * the list after usage.
1184  *
1185  * Returns: (transfer full) (nullable): a #GstBufferList of buffers containing
1186  *     the first @nbytes of the adapter, or %NULL if @nbytes bytes are not
1187  *     available
1188  *
1189  * Since: 1.6
1190  */
1191 GstBufferList *
1192 gst_adapter_take_buffer_list (GstAdapter * adapter, gsize nbytes)
1193 {
1194   GstBufferList *buffer_list;
1195   GstBuffer *cur;
1196   gsize hsize, skip, cur_size;
1197   guint n_bufs;
1198
1199   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
1200
1201   if (nbytes > adapter->size)
1202     return NULL;
1203
1204   GST_LOG_OBJECT (adapter, "taking %" G_GSIZE_FORMAT " bytes", nbytes);
1205
1206   /* try to create buffer list with sufficient size, so no resize is done later */
1207   if (adapter->count < 64)
1208     n_bufs = adapter->count;
1209   else
1210     n_bufs = (adapter->count * nbytes * 1.2 / adapter->size) + 1;
1211
1212   buffer_list = gst_buffer_list_new_sized (n_bufs);
1213
1214   while (nbytes > 0) {
1215     cur = adapter->buflist->data;
1216     skip = adapter->skip;
1217     cur_size = gst_buffer_get_size (cur);
1218     hsize = MIN (nbytes, cur_size - skip);
1219
1220     gst_buffer_list_add (buffer_list, gst_adapter_take_buffer (adapter, hsize));
1221     nbytes -= hsize;
1222   }
1223   return buffer_list;
1224 }
1225
1226 /**
1227  * gst_adapter_get_buffer_list:
1228  * @adapter: a #GstAdapter
1229  * @nbytes: the number of bytes to get
1230  *
1231  * Returns a #GstBufferList of buffers containing the first @nbytes bytes of
1232  * the @adapter but does not flush them from the adapter. See
1233  * gst_adapter_take_buffer_list() for details.
1234  *
1235  * Caller owns the returned list. Call gst_buffer_list_unref() to free
1236  * the list after usage.
1237  *
1238  * Returns: (transfer full) (nullable): a #GstBufferList of buffers containing
1239  *     the first @nbytes of the adapter, or %NULL if @nbytes bytes are not
1240  *     available
1241  *
1242  * Since: 1.6
1243  */
1244 GstBufferList *
1245 gst_adapter_get_buffer_list (GstAdapter * adapter, gsize nbytes)
1246 {
1247   GstBufferList *buffer_list;
1248   GstBuffer *cur, *buffer;
1249   gsize hsize, skip, cur_size;
1250   guint n_bufs;
1251   GSList *g = NULL;
1252
1253   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
1254
1255   if (nbytes > adapter->size)
1256     return NULL;
1257
1258   GST_LOG_OBJECT (adapter, "getting %" G_GSIZE_FORMAT " bytes", nbytes);
1259
1260   /* try to create buffer list with sufficient size, so no resize is done later */
1261   if (adapter->count < 64)
1262     n_bufs = adapter->count;
1263   else
1264     n_bufs = (adapter->count * nbytes * 1.2 / adapter->size) + 1;
1265
1266   buffer_list = gst_buffer_list_new_sized (n_bufs);
1267
1268   g = adapter->buflist;
1269   skip = adapter->skip;
1270
1271   while (nbytes > 0) {
1272     cur = g->data;
1273     cur_size = gst_buffer_get_size (cur);
1274     hsize = MIN (nbytes, cur_size - skip);
1275
1276     if (skip == 0 && cur_size == hsize) {
1277       GST_LOG_OBJECT (adapter,
1278           "inserting a buffer of %" G_GSIZE_FORMAT " bytes", hsize);
1279       buffer = gst_buffer_ref (cur);
1280     } else {
1281       GST_LOG_OBJECT (adapter, "inserting a buffer of %" G_GSIZE_FORMAT " bytes"
1282           " via region copy", hsize);
1283       buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, hsize);
1284     }
1285
1286     gst_buffer_list_add (buffer_list, buffer);
1287
1288     nbytes -= hsize;
1289     skip = 0;
1290     g = g_slist_next (g);
1291   }
1292
1293   return buffer_list;
1294 }
1295
1296 /**
1297  * gst_adapter_available:
1298  * @adapter: a #GstAdapter
1299  *
1300  * Gets the maximum amount of bytes available, that is it returns the maximum
1301  * value that can be supplied to gst_adapter_map() without that function
1302  * returning %NULL.
1303  *
1304  * Returns: number of bytes available in @adapter
1305  */
1306 gsize
1307 gst_adapter_available (GstAdapter * adapter)
1308 {
1309   g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
1310
1311   return adapter->size;
1312 }
1313
1314 /**
1315  * gst_adapter_available_fast:
1316  * @adapter: a #GstAdapter
1317  *
1318  * Gets the maximum number of bytes that are immediately available without
1319  * requiring any expensive operations (like copying the data into a
1320  * temporary buffer).
1321  *
1322  * Returns: number of bytes that are available in @adapter without expensive
1323  * operations
1324  */
1325 gsize
1326 gst_adapter_available_fast (GstAdapter * adapter)
1327 {
1328   GstBuffer *cur;
1329   gsize size;
1330   GSList *g;
1331
1332   g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
1333
1334   /* no data */
1335   if (adapter->size == 0)
1336     return 0;
1337
1338   /* some stuff we already assembled */
1339   if (adapter->assembled_len)
1340     return adapter->assembled_len;
1341
1342   /* take the first non-zero buffer */
1343   g = adapter->buflist;
1344   while (TRUE) {
1345     cur = g->data;
1346     size = gst_buffer_get_size (cur);
1347     if (size != 0)
1348       break;
1349     g = g_slist_next (g);
1350   }
1351
1352   /* we can quickly get the (remaining) data of the first buffer */
1353   return size - adapter->skip;
1354 }
1355
1356 /**
1357  * gst_adapter_get_offset_from_discont:
1358  * @adapter: a #GstAdapter
1359  *
1360  * Get the offset of the adapter based on the incoming buffer offset.  Will only
1361  * return valid values if the incoming buffers have valid offsets set on them.
1362  *
1363  * The offset will be initially recorded for all buffers with
1364  * %GST_BUFFER_FLAG_DISCONT on them, and then calculated for all other following
1365  * buffers based on their size.
1366  *
1367  * Since: 1.10
1368  *
1369  * Returns: The offset. Can be %GST_BUFFER_OFFSET_NONE.
1370  */
1371 guint64
1372 gst_adapter_get_offset_from_discont (GstAdapter * adapter)
1373 {
1374   return adapter->offset_discont;
1375 }
1376
1377 /**
1378  * gst_adapter_prev_offset:
1379  * @adapter: a #GstAdapter
1380  * @distance: (out) (allow-none): pointer to a location for distance, or %NULL
1381  *
1382  * Get the offset that was before the current byte in the adapter. When
1383  * @distance is given, the amount of bytes between the offset and the current
1384  * position is returned.
1385  *
1386  * The offset is reset to GST_BUFFER_OFFSET_NONE and the distance is set to 0
1387  * when the adapter is first created or when it is cleared. This also means that
1388  * before the first byte with an offset is removed from the adapter, the offset
1389  * and distance returned are GST_BUFFER_OFFSET_NONE and 0 respectively.
1390  *
1391  * Since: 1.10
1392  *
1393  * Returns: The previous seen offset.
1394  */
1395 guint64
1396 gst_adapter_prev_offset (GstAdapter * adapter, guint64 * distance)
1397 {
1398   g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_BUFFER_OFFSET_NONE);
1399
1400   if (distance)
1401     *distance = adapter->offset_distance;
1402
1403   return adapter->offset;
1404
1405 }
1406
1407 /**
1408  * gst_adapter_prev_pts:
1409  * @adapter: a #GstAdapter
1410  * @distance: (out) (allow-none): pointer to location for distance, or %NULL
1411  *
1412  * Get the pts that was before the current byte in the adapter. When
1413  * @distance is given, the amount of bytes between the pts and the current
1414  * position is returned.
1415  *
1416  * The pts is reset to GST_CLOCK_TIME_NONE and the distance is set to 0 when
1417  * the adapter is first created or when it is cleared. This also means that before
1418  * the first byte with a pts is removed from the adapter, the pts
1419  * and distance returned are GST_CLOCK_TIME_NONE and 0 respectively.
1420  *
1421  * Returns: The previously seen pts.
1422  */
1423 GstClockTime
1424 gst_adapter_prev_pts (GstAdapter * adapter, guint64 * distance)
1425 {
1426   g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
1427
1428   if (distance)
1429     *distance = adapter->pts_distance;
1430
1431   return adapter->pts;
1432 }
1433
1434 /**
1435  * gst_adapter_prev_dts:
1436  * @adapter: a #GstAdapter
1437  * @distance: (out) (allow-none): pointer to location for distance, or %NULL
1438  *
1439  * Get the dts that was before the current byte in the adapter. When
1440  * @distance is given, the amount of bytes between the dts and the current
1441  * position is returned.
1442  *
1443  * The dts is reset to GST_CLOCK_TIME_NONE and the distance is set to 0 when
1444  * the adapter is first created or when it is cleared. This also means that before
1445  * the first byte with a dts is removed from the adapter, the dts
1446  * and distance returned are GST_CLOCK_TIME_NONE and 0 respectively.
1447  *
1448  * Returns: The previously seen dts.
1449  */
1450 GstClockTime
1451 gst_adapter_prev_dts (GstAdapter * adapter, guint64 * distance)
1452 {
1453   g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
1454
1455   if (distance)
1456     *distance = adapter->dts_distance;
1457
1458   return adapter->dts;
1459 }
1460
1461 /**
1462  * gst_adapter_prev_pts_at_offset:
1463  * @adapter: a #GstAdapter
1464  * @offset: the offset in the adapter at which to get timestamp
1465  * @distance: (out) (allow-none): pointer to location for distance, or %NULL
1466  *
1467  * Get the pts that was before the byte at offset @offset in the adapter. When
1468  * @distance is given, the amount of bytes between the pts and the current
1469  * position is returned.
1470  *
1471  * The pts is reset to GST_CLOCK_TIME_NONE and the distance is set to 0 when
1472  * the adapter is first created or when it is cleared. This also means that before
1473  * the first byte with a pts is removed from the adapter, the pts
1474  * and distance returned are GST_CLOCK_TIME_NONE and 0 respectively.
1475  *
1476  * Since: 1.2
1477  * Returns: The previously seen pts at given offset.
1478  */
1479 GstClockTime
1480 gst_adapter_prev_pts_at_offset (GstAdapter * adapter, gsize offset,
1481     guint64 * distance)
1482 {
1483   GstBuffer *cur;
1484   GSList *g;
1485   gsize read_offset = 0;
1486   GstClockTime pts = adapter->pts;
1487
1488   g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
1489
1490   g = adapter->buflist;
1491
1492   while (g && read_offset < offset + adapter->skip) {
1493     cur = g->data;
1494
1495     read_offset += gst_buffer_get_size (cur);
1496     if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_PTS (cur))) {
1497       pts = GST_BUFFER_PTS (cur);
1498     }
1499
1500     g = g_slist_next (g);
1501   }
1502
1503   if (distance)
1504     *distance = adapter->dts_distance + offset;
1505
1506   return pts;
1507 }
1508
1509 /**
1510  * gst_adapter_prev_dts_at_offset:
1511  * @adapter: a #GstAdapter
1512  * @offset: the offset in the adapter at which to get timestamp
1513  * @distance: (out) (allow-none): pointer to location for distance, or %NULL
1514  *
1515  * Get the dts that was before the byte at offset @offset in the adapter. When
1516  * @distance is given, the amount of bytes between the dts and the current
1517  * position is returned.
1518  *
1519  * The dts is reset to GST_CLOCK_TIME_NONE and the distance is set to 0 when
1520  * the adapter is first created or when it is cleared. This also means that before
1521  * the first byte with a dts is removed from the adapter, the dts
1522  * and distance returned are GST_CLOCK_TIME_NONE and 0 respectively.
1523  *
1524  * Since: 1.2
1525  * Returns: The previously seen dts at given offset.
1526  */
1527 GstClockTime
1528 gst_adapter_prev_dts_at_offset (GstAdapter * adapter, gsize offset,
1529     guint64 * distance)
1530 {
1531   GstBuffer *cur;
1532   GSList *g;
1533   gsize read_offset = 0;
1534   GstClockTime dts = adapter->dts;
1535
1536   g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
1537
1538   g = adapter->buflist;
1539
1540   while (g && read_offset < offset + adapter->skip) {
1541     cur = g->data;
1542
1543     read_offset += gst_buffer_get_size (cur);
1544     if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DTS (cur))) {
1545       dts = GST_BUFFER_DTS (cur);
1546     }
1547
1548     g = g_slist_next (g);
1549   }
1550
1551   if (distance)
1552     *distance = adapter->dts_distance + offset;
1553
1554   return dts;
1555 }
1556
1557 /**
1558  * gst_adapter_masked_scan_uint32_peek:
1559  * @adapter: a #GstAdapter
1560  * @mask: mask to apply to data before matching against @pattern
1561  * @pattern: pattern to match (after mask is applied)
1562  * @offset: offset into the adapter data from which to start scanning, returns
1563  *          the last scanned position.
1564  * @size: number of bytes to scan from offset
1565  * @value: (out) (allow-none): pointer to uint32 to return matching data
1566  *
1567  * Scan for pattern @pattern with applied mask @mask in the adapter data,
1568  * starting from offset @offset.  If a match is found, the value that matched
1569  * is returned through @value, otherwise @value is left untouched.
1570  *
1571  * The bytes in @pattern and @mask are interpreted left-to-right, regardless
1572  * of endianness.  All four bytes of the pattern must be present in the
1573  * adapter for it to match, even if the first or last bytes are masked out.
1574  *
1575  * It is an error to call this function without making sure that there is
1576  * enough data (offset+size bytes) in the adapter.
1577  *
1578  * Returns: offset of the first match, or -1 if no match was found.
1579  */
1580 gssize
1581 gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
1582     guint32 pattern, gsize offset, gsize size, guint32 * value)
1583 {
1584   GSList *g;
1585   gsize skip, bsize, i;
1586   guint32 state;
1587   GstMapInfo info;
1588   guint8 *bdata;
1589   GstBuffer *buf;
1590
1591   g_return_val_if_fail (size > 0, -1);
1592   g_return_val_if_fail (offset + size <= adapter->size, -1);
1593   g_return_val_if_fail (((~mask) & pattern) == 0, -1);
1594
1595   /* we can't find the pattern with less than 4 bytes */
1596   if (G_UNLIKELY (size < 4))
1597     return -1;
1598
1599   skip = offset + adapter->skip;
1600
1601   /* first step, do skipping and position on the first buffer */
1602   /* optimistically assume scanning continues sequentially */
1603   if (adapter->scan_entry && (adapter->scan_offset <= skip)) {
1604     g = adapter->scan_entry;
1605     skip -= adapter->scan_offset;
1606   } else {
1607     g = adapter->buflist;
1608     adapter->scan_offset = 0;
1609     adapter->scan_entry = NULL;
1610   }
1611   buf = g->data;
1612   bsize = gst_buffer_get_size (buf);
1613   while (G_UNLIKELY (skip >= bsize)) {
1614     skip -= bsize;
1615     g = g_slist_next (g);
1616     adapter->scan_offset += bsize;
1617     adapter->scan_entry = g;
1618     buf = g->data;
1619     bsize = gst_buffer_get_size (buf);
1620   }
1621   /* get the data now */
1622   if (!gst_buffer_map (buf, &info, GST_MAP_READ))
1623     return -1;
1624
1625   bdata = (guint8 *) info.data + skip;
1626   bsize = info.size - skip;
1627   skip = 0;
1628
1629   /* set the state to something that does not match */
1630   state = ~pattern;
1631
1632   /* now find data */
1633   do {
1634     bsize = MIN (bsize, size);
1635     for (i = 0; i < bsize; i++) {
1636       state = ((state << 8) | bdata[i]);
1637       if (G_UNLIKELY ((state & mask) == pattern)) {
1638         /* we have a match but we need to have skipped at
1639          * least 4 bytes to fill the state. */
1640         if (G_LIKELY (skip + i >= 3)) {
1641           if (G_LIKELY (value))
1642             *value = state;
1643           gst_buffer_unmap (buf, &info);
1644           return offset + skip + i - 3;
1645         }
1646       }
1647     }
1648     size -= bsize;
1649     if (size == 0)
1650       break;
1651
1652     /* nothing found yet, go to next buffer */
1653     skip += bsize;
1654     g = g_slist_next (g);
1655     adapter->scan_offset += info.size;
1656     adapter->scan_entry = g;
1657     gst_buffer_unmap (buf, &info);
1658     buf = g->data;
1659
1660     if (!gst_buffer_map (buf, &info, GST_MAP_READ))
1661       return -1;
1662
1663     bsize = info.size;
1664     bdata = info.data;
1665   } while (TRUE);
1666
1667   gst_buffer_unmap (buf, &info);
1668
1669   /* nothing found */
1670   return -1;
1671 }
1672
1673 /**
1674  * gst_adapter_masked_scan_uint32:
1675  * @adapter: a #GstAdapter
1676  * @mask: mask to apply to data before matching against @pattern
1677  * @pattern: pattern to match (after mask is applied)
1678  * @offset: offset into the adapter data from which to start scanning, returns
1679  *          the last scanned position.
1680  * @size: number of bytes to scan from offset
1681  *
1682  * Scan for pattern @pattern with applied mask @mask in the adapter data,
1683  * starting from offset @offset.
1684  *
1685  * The bytes in @pattern and @mask are interpreted left-to-right, regardless
1686  * of endianness.  All four bytes of the pattern must be present in the
1687  * adapter for it to match, even if the first or last bytes are masked out.
1688  *
1689  * It is an error to call this function without making sure that there is
1690  * enough data (offset+size bytes) in the adapter.
1691  *
1692  * This function calls gst_adapter_masked_scan_uint32_peek() passing %NULL
1693  * for value.
1694  *
1695  * Returns: offset of the first match, or -1 if no match was found.
1696  *
1697  * Example:
1698  * <programlisting>
1699  * // Assume the adapter contains 0x00 0x01 0x02 ... 0xfe 0xff
1700  *
1701  * gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x00010203, 0, 256);
1702  * // -> returns 0
1703  * gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x00010203, 1, 255);
1704  * // -> returns -1
1705  * gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x01020304, 1, 255);
1706  * // -> returns 1
1707  * gst_adapter_masked_scan_uint32 (adapter, 0xffff, 0x0001, 0, 256);
1708  * // -> returns -1
1709  * gst_adapter_masked_scan_uint32 (adapter, 0xffff, 0x0203, 0, 256);
1710  * // -> returns 0
1711  * gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0x02030000, 0, 256);
1712  * // -> returns 2
1713  * gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0x02030000, 0, 4);
1714  * // -> returns -1
1715  * </programlisting>
1716  */
1717 gssize
1718 gst_adapter_masked_scan_uint32 (GstAdapter * adapter, guint32 mask,
1719     guint32 pattern, gsize offset, gsize size)
1720 {
1721   return gst_adapter_masked_scan_uint32_peek (adapter, mask, pattern, offset,
1722       size, NULL);
1723 }