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