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