Add metadata copy functions. Fixes #393099.
[platform/upstream/gstreamer.git] / gst / gstbuffer.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstbuffer.c: Buffer operations
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /**
24  * SECTION:gstbuffer
25  * @short_description: Data-passing buffer type, supporting sub-buffers.
26  * @see_also: #GstPad, #GstMiniObject
27  *
28  * Buffers are the basic unit of data transfer in GStreamer.  The #GstBuffer
29  * type provides all the state necessary to define a region of memory as part
30  * of a stream.  Sub-buffers are also supported, allowing a smaller region of a
31  * buffer to become its own buffer, with mechanisms in place to ensure that
32  * neither memory space goes away prematurely.
33  *
34  * Buffers are usually created with gst_buffer_new(). After a buffer has been
35  * created one will typically allocate memory for it and set the size of the
36  * buffer data.  The following example creates a buffer that can hold a given
37  * video frame with a given width, height and bits per plane.
38  * <example>
39  * <title>Creating a buffer for a video frame</title>
40  *   <programlisting>
41  *   GstBuffer *buffer;
42  *   gint size, width, height, bpp;
43  *   ...
44  *   size = width * height * bpp;
45  *   buffer = gst_buffer_new ();
46  *   GST_BUFFER_SIZE (buffer) = size;
47  *   GST_BUFFER_MALLOCDATA (buffer) = g_malloc (size);
48  *   GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
49  *   ...
50  *   </programlisting>
51  * </example>
52  *
53  * Alternatively, use gst_buffer_new_and_alloc()
54  * to create a buffer with preallocated data of a given size.
55  *
56  * The data pointed to by the buffer can be retrieved with the GST_BUFFER_DATA()
57  * macro. The size of the data can be found with GST_BUFFER_SIZE(). For buffers
58  * of size 0, the data pointer is undefined (usually NULL) and should never be used.
59  *
60  * If an element knows what pad you will push the buffer out on, it should use
61  * gst_pad_alloc_buffer() instead to create a buffer.  This allows downstream
62  * elements to provide special buffers to write in, like hardware buffers.
63  *
64  * A buffer has a pointer to a #GstCaps describing the media type of the data
65  * in the buffer. Attach caps to the buffer with gst_buffer_set_caps(); this
66  * is typically done before pushing out a buffer using gst_pad_push() so that
67  * the downstream element knows the type of the buffer.
68  *
69  * A buffer will usually have a timestamp, and a duration, but neither of these
70  * are guaranteed (they may be set to #GST_CLOCK_TIME_NONE). Whenever a
71  * meaningful value can be given for these, they should be set. The timestamp
72  * and duration are measured in nanoseconds (they are #GstClockTime values).
73  *
74  * A buffer can also have one or both of a start and an end offset. These are
75  * media-type specific. For video buffers, the start offset will generally be
76  * the frame number. For audio buffers, it will be the number of samples
77  * produced so far. For compressed data, it could be the byte offset in a
78  * source or destination file. Likewise, the end offset will be the offset of
79  * the end of the buffer. These can only be meaningfully interpreted if you
80  * know the media type of the buffer (the #GstCaps set on it). Either or both
81  * can be set to #GST_BUFFER_OFFSET_NONE.
82  *
83  * gst_buffer_ref() is used to increase the refcount of a buffer. This must be
84  * done when you want to keep a handle to the buffer after pushing it to the
85  * next element.
86  *
87  * To efficiently create a smaller buffer out of an existing one, you can
88  * use gst_buffer_create_sub().
89  *
90  * If a plug-in wants to modify the buffer data in-place, it should first obtain
91  * a buffer that is safe to modify by using gst_buffer_make_writable().  This
92  * function is optimized so that a copy will only be made when it is necessary.
93  *
94  * A plugin that only wishes to modify the metadata of a buffer, such as the
95  * offset, timestamp or caps, should use gst_buffer_make_metadata_writable(),
96  * which will create a subbuffer of the original buffer to ensure the caller
97  * has sole ownership, and not copy the buffer data.
98  *
99  * Several flags of the buffer can be set and unset with the
100  * GST_BUFFER_FLAG_SET() and GST_BUFFER_FLAG_UNSET() macros. Use
101  * GST_BUFFER_FLAG_IS_SET() to test if a certain #GstBufferFlag is set.
102  *
103  * Buffers can be efficiently merged into a larger buffer with
104  * gst_buffer_merge() and gst_buffer_span() if the gst_buffer_is_span_fast()
105  * function returns TRUE.
106  *
107  * An element should either unref the buffer or push it out on a src pad
108  * using gst_pad_push() (see #GstPad).
109  *
110  * Buffers are usually freed by unreffing them with gst_buffer_unref(). When
111  * the refcount drops to 0, any data pointed to by GST_BUFFER_MALLOCDATA() will
112  * also be freed.
113  *
114  * Last reviewed on August 11th, 2006 (0.10.10)
115  */
116 #include "gst_private.h"
117
118 #include "gstbuffer.h"
119 #include "gstinfo.h"
120 #include "gstutils.h"
121 #include "gstminiobject.h"
122
123 static void gst_buffer_init (GTypeInstance * instance, gpointer g_class);
124 static void gst_buffer_class_init (gpointer g_class, gpointer class_data);
125 static void gst_buffer_finalize (GstBuffer * buffer);
126 static GstBuffer *_gst_buffer_copy (GstBuffer * buffer);
127 static GType gst_subbuffer_get_type (void);
128
129 static GType _gst_subbuffer_type = 0;
130 static GType _gst_buffer_type = 0;
131
132 void
133 _gst_buffer_initialize (void)
134 {
135   gpointer ptr;
136
137   gst_buffer_get_type ();
138   gst_subbuffer_get_type ();
139
140   /* the GstMiniObject types need to be class_ref'd once before it can be
141    * done from multiple threads;
142    * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
143   ptr = g_type_class_ref (GST_TYPE_BUFFER);
144   g_type_class_unref (ptr);
145 }
146
147 GType
148 gst_buffer_get_type (void)
149 {
150   if (G_UNLIKELY (_gst_buffer_type == 0)) {
151     static const GTypeInfo buffer_info = {
152       sizeof (GstBufferClass),
153       NULL,
154       NULL,
155       gst_buffer_class_init,
156       NULL,
157       NULL,
158       sizeof (GstBuffer),
159       0,
160       gst_buffer_init,
161       NULL
162     };
163
164     _gst_buffer_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
165         "GstBuffer", &buffer_info, 0);
166   }
167   return _gst_buffer_type;
168 }
169
170 static void
171 gst_buffer_class_init (gpointer g_class, gpointer class_data)
172 {
173   GstBufferClass *buffer_class = GST_BUFFER_CLASS (g_class);
174
175   buffer_class->mini_object_class.copy =
176       (GstMiniObjectCopyFunction) _gst_buffer_copy;
177   buffer_class->mini_object_class.finalize =
178       (GstMiniObjectFinalizeFunction) gst_buffer_finalize;
179
180 }
181
182 static void
183 gst_buffer_finalize (GstBuffer * buffer)
184 {
185   g_return_if_fail (buffer != NULL);
186
187   GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
188
189   /* free our data */
190   g_free (buffer->malloc_data);
191
192   gst_caps_replace (&GST_BUFFER_CAPS (buffer), NULL);
193 }
194
195 /**
196  * gst_buffer_copy_metadata:
197  * @dest: a destination #GstBuffer
198  * @src: a source #GstBuffer
199  * @flags: flags indicating what metadata fields should be copied.
200  *
201  * Copies the metadata from @src into @dest. The data, size and mallocdata
202  * fields are not copied.
203  *
204  * @flags indicate which fields will be copied. Use #GST_BUFFER_COPY_ALL to copy
205  * all the metadata fields.
206  *
207  * This function is typically called from a custom buffer copy function after
208  * creating @dest and setting the data, size, mallocdata.
209  *
210  * Since: 0.10.13
211  */
212 void
213 gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
214     GstBufferCopyFlags flags)
215 {
216   g_return_if_fail (dest != NULL);
217   g_return_if_fail (src != NULL);
218
219   GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p", src, dest);
220
221   if (flags & GST_BUFFER_COPY_FLAGS) {
222     guint mask;
223
224     /* copy relevant flags */
225     mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
226         GST_BUFFER_FLAG_DELTA_UNIT | GST_BUFFER_FLAG_DISCONT |
227         GST_BUFFER_FLAG_GAP;
228     GST_MINI_OBJECT_FLAGS (dest) |= GST_MINI_OBJECT_FLAGS (src) & mask;
229   }
230
231   if (flags & GST_BUFFER_COPY_TIMESTAMPS) {
232     GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
233     GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
234     GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
235     GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
236   }
237
238   if (flags & GST_BUFFER_COPY_CAPS) {
239     if (GST_BUFFER_CAPS (src))
240       GST_BUFFER_CAPS (dest) = gst_caps_ref (GST_BUFFER_CAPS (src));
241     else
242       GST_BUFFER_CAPS (dest) = NULL;
243   }
244 }
245
246 static GstBuffer *
247 _gst_buffer_copy (GstBuffer * buffer)
248 {
249   GstBuffer *copy;
250
251   g_return_val_if_fail (buffer != NULL, NULL);
252
253   /* create a fresh new buffer */
254   copy = gst_buffer_new ();
255
256   /* we simply copy everything from our parent */
257   copy->data = g_memdup (buffer->data, buffer->size);
258   /* make sure it gets freed (even if the parent is subclassed, we return a
259      normal buffer) */
260   copy->malloc_data = copy->data;
261   copy->size = buffer->size;
262
263   gst_buffer_copy_metadata (copy, buffer, GST_BUFFER_COPY_ALL);
264
265   return copy;
266 }
267
268 static void
269 gst_buffer_init (GTypeInstance * instance, gpointer g_class)
270 {
271   GstBuffer *buffer;
272
273   buffer = (GstBuffer *) instance;
274
275   GST_CAT_LOG (GST_CAT_BUFFER, "init %p", buffer);
276
277   GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
278   GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
279   GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
280   GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
281 }
282
283 /**
284  * gst_buffer_new:
285  *
286  * Creates a newly allocated buffer without any data.
287  *
288  * MT safe.
289  * Returns: the new #GstBuffer.
290  */
291 GstBuffer *
292 gst_buffer_new (void)
293 {
294   GstBuffer *newbuf;
295
296   newbuf = (GstBuffer *) gst_mini_object_new (_gst_buffer_type);
297
298   GST_CAT_LOG (GST_CAT_BUFFER, "new %p", newbuf);
299
300   return newbuf;
301 }
302
303 /**
304  * gst_buffer_new_and_alloc:
305  * @size: the size of the new buffer's data.
306  *
307  * Creates a newly allocated buffer with data of the given size.
308  * The buffer memory is not cleared.
309  *
310  * Note that when @size == 0, the buffer data pointer will be NULL.
311  *
312  * MT safe.
313  * Returns: the new #GstBuffer.
314  */
315 GstBuffer *
316 gst_buffer_new_and_alloc (guint size)
317 {
318   GstBuffer *newbuf;
319
320   newbuf = gst_buffer_new ();
321
322   newbuf->malloc_data = g_malloc (size);
323   GST_BUFFER_DATA (newbuf) = newbuf->malloc_data;
324   GST_BUFFER_SIZE (newbuf) = size;
325
326   GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size);
327
328   return newbuf;
329 }
330
331 /**
332  * gst_buffer_get_caps:
333  * @buffer: a #GstBuffer.
334  *
335  * Gets the media type of the buffer. This can be NULL if there
336  * is no media type attached to this buffer.
337  *
338  * Returns: a reference to the #GstCaps. unref after usage.
339  * Returns NULL if there were no caps on this buffer.
340  */
341 /* FIXME can we make this threadsafe without a lock on the buffer?
342  * We can use compare and swap and atomic reads. */
343 GstCaps *
344 gst_buffer_get_caps (GstBuffer * buffer)
345 {
346   GstCaps *ret;
347
348   g_return_val_if_fail (buffer != NULL, NULL);
349
350   ret = GST_BUFFER_CAPS (buffer);
351
352   if (ret)
353     gst_caps_ref (ret);
354
355   return ret;
356 }
357
358 /**
359  * gst_buffer_set_caps:
360  * @buffer: a #GstBuffer.
361  * @caps: a #GstCaps.
362  *
363  * Sets the media type on the buffer. The refcount of the caps will
364  * be increased and any previous caps on the buffer will be
365  * unreffed.
366  */
367 /* FIXME can we make this threadsafe without a lock on the buffer?
368  * We can use compare and swap and atomic reads. Another idea is to
369  * not attach the caps to the buffer but use an event to signal a caps
370  * change. */
371 void
372 gst_buffer_set_caps (GstBuffer * buffer, GstCaps * caps)
373 {
374   g_return_if_fail (buffer != NULL);
375
376   gst_caps_replace (&GST_BUFFER_CAPS (buffer), caps);
377 }
378
379 /**
380  * gst_buffer_is_metadata_writable:
381  * @buf: a #GstBuffer
382  *
383  * Similar to gst_buffer_is_writable, but this only ensures that the
384  * refcount of the buffer is 1, indicating that the caller is the sole
385  * owner and can change the buffer metadata, such as caps and timestamps.
386  *
387  * Returns: TRUE if the metadata is writable.
388  */
389 gboolean
390 gst_buffer_is_metadata_writable (GstBuffer * buf)
391 {
392   return (GST_MINI_OBJECT_REFCOUNT_VALUE (GST_MINI_OBJECT_CAST (buf)) == 1);
393 }
394
395 /**
396  * gst_buffer_make_metadata_writable:
397  * @buf: a #GstBuffer
398  *
399  * Similar to gst_buffer_make_writable, but does not ensure that the buffer
400  * data array is writable. Instead, this just ensures that the returned buffer
401  * is solely owned by the caller, by creating a subbuffer of the original
402  * buffer if necessary.
403  * 
404  * After calling this function, @buf should not be referenced anymore. The
405  * result of this function has guaranteed writable metadata.
406  *
407  * Returns: A new #GstBuffer with writable metadata.
408  */
409 GstBuffer *
410 gst_buffer_make_metadata_writable (GstBuffer * buf)
411 {
412   GstBuffer *ret;
413
414   if (gst_buffer_is_metadata_writable (buf)) {
415     ret = buf;
416   } else {
417     ret = gst_buffer_create_sub (buf, 0, GST_BUFFER_SIZE (buf));
418
419     /* copy all the flags except IN_CAPS */
420     GST_BUFFER_FLAGS (ret) = GST_BUFFER_FLAGS (buf);
421     GST_BUFFER_FLAG_UNSET (ret, GST_BUFFER_FLAG_IN_CAPS);
422     /* data should always be set to READONLY */
423     GST_BUFFER_FLAG_SET (ret, GST_BUFFER_FLAG_READONLY);
424
425     gst_buffer_unref (buf);
426   }
427
428   return ret;
429 }
430
431 typedef struct _GstSubBuffer GstSubBuffer;
432 typedef struct _GstSubBufferClass GstSubBufferClass;
433
434 #define GST_IS_SUBBUFFER(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), _gst_subbuffer_type))
435 #define GST_SUBBUFFER_CAST(obj) ((GstSubBuffer *)(obj))
436
437 struct _GstSubBuffer
438 {
439   GstBuffer buffer;
440
441   GstBuffer *parent;
442 };
443
444 struct _GstSubBufferClass
445 {
446   GstBufferClass buffer_class;
447 };
448
449 static GstBufferClass *sub_parent_class;
450
451 static void gst_subbuffer_init (GTypeInstance * instance, gpointer g_class);
452 static void gst_subbuffer_class_init (gpointer g_class, gpointer class_data);
453 static void gst_subbuffer_finalize (GstSubBuffer * buffer);
454
455 static GType
456 gst_subbuffer_get_type (void)
457 {
458   if (G_UNLIKELY (_gst_subbuffer_type == 0)) {
459     static const GTypeInfo subbuffer_info = {
460       sizeof (GstSubBufferClass),
461       NULL,
462       NULL,
463       gst_subbuffer_class_init,
464       NULL,
465       NULL,
466       sizeof (GstSubBuffer),
467       0,
468       gst_subbuffer_init,
469       NULL
470     };
471
472     _gst_subbuffer_type = g_type_register_static (GST_TYPE_BUFFER,
473         "GstSubBuffer", &subbuffer_info, 0);
474   }
475   return _gst_subbuffer_type;
476 }
477
478 static void
479 gst_subbuffer_class_init (gpointer g_class, gpointer class_data)
480 {
481   GstBufferClass *buffer_class = GST_BUFFER_CLASS (g_class);
482
483   sub_parent_class = g_type_class_peek_parent (g_class);
484
485   buffer_class->mini_object_class.finalize =
486       (GstMiniObjectFinalizeFunction) gst_subbuffer_finalize;
487 }
488
489 static void
490 gst_subbuffer_finalize (GstSubBuffer * buffer)
491 {
492   gst_buffer_unref (buffer->parent);
493
494   GST_MINI_OBJECT_CLASS (sub_parent_class)->
495       finalize (GST_MINI_OBJECT_CAST (buffer));
496 }
497
498 static void
499 gst_subbuffer_init (GTypeInstance * instance, gpointer g_class)
500 {
501   GST_BUFFER_FLAG_SET (GST_BUFFER_CAST (instance), GST_BUFFER_FLAG_READONLY);
502 }
503
504 /**
505  * gst_buffer_create_sub:
506  * @parent: a #GstBuffer.
507  * @offset: the offset into parent #GstBuffer at which the new sub-buffer 
508  *          begins.
509  * @size: the size of the new #GstBuffer sub-buffer, in bytes.
510  *
511  * Creates a sub-buffer from @parent at @offset and @size.
512  * This sub-buffer uses the actual memory space of the parent buffer.
513  * This function will copy the offset and timestamp fields when the
514  * offset is 0. If not, they will be set to #GST_CLOCK_TIME_NONE and 
515  * #GST_BUFFER_OFFSET_NONE.
516  * If @offset equals 0 and @size equals the total size of @buffer, the
517  * duration and offset end fields are also copied. If not they will be set
518  * to #GST_CLOCK_TIME_NONE and #GST_BUFFER_OFFSET_NONE.
519  *
520  * MT safe.
521  * Returns: the new #GstBuffer.
522  * Returns NULL if the arguments were invalid.
523  */
524 GstBuffer *
525 gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
526 {
527   GstSubBuffer *subbuffer;
528   GstBuffer *parent;
529   gboolean complete;
530
531   g_return_val_if_fail (buffer != NULL, NULL);
532   g_return_val_if_fail (buffer->mini_object.refcount > 0, NULL);
533   g_return_val_if_fail (buffer->size >= offset + size, NULL);
534
535   /* find real parent */
536   if (GST_IS_SUBBUFFER (buffer)) {
537     parent = GST_SUBBUFFER_CAST (buffer)->parent;
538   } else {
539     parent = buffer;
540   }
541   gst_buffer_ref (parent);
542
543   /* create the new buffer */
544   subbuffer = (GstSubBuffer *) gst_mini_object_new (_gst_subbuffer_type);
545   subbuffer->parent = parent;
546
547   GST_CAT_LOG (GST_CAT_BUFFER, "new subbuffer %p (parent %p)", subbuffer,
548       parent);
549
550   /* set the right values in the child */
551   GST_BUFFER_DATA (GST_BUFFER_CAST (subbuffer)) = buffer->data + offset;
552   GST_BUFFER_SIZE (GST_BUFFER_CAST (subbuffer)) = size;
553
554   /* we can copy the timestamp and offset if the new buffer starts at
555    * offset 0 */
556   if (offset == 0) {
557     GST_BUFFER_TIMESTAMP (subbuffer) = GST_BUFFER_TIMESTAMP (buffer);
558     GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET (buffer);
559     complete = (buffer->size == size);
560   } else {
561     GST_BUFFER_TIMESTAMP (subbuffer) = GST_CLOCK_TIME_NONE;
562     GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET_NONE;
563     complete = FALSE;
564   }
565
566   if (complete) {
567     GstCaps *caps;
568
569     /* if we copied the complete buffer we can copy the duration,
570      * offset_end and caps as well */
571     GST_BUFFER_DURATION (subbuffer) = GST_BUFFER_DURATION (buffer);
572     GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_END (buffer);
573     if ((caps = GST_BUFFER_CAPS (buffer)))
574       gst_caps_ref (caps);
575     GST_BUFFER_CAPS (subbuffer) = caps;
576   } else {
577     GST_BUFFER_DURATION (subbuffer) = GST_CLOCK_TIME_NONE;
578     GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_NONE;
579     GST_BUFFER_CAPS (subbuffer) = NULL;
580   }
581   return GST_BUFFER_CAST (subbuffer);
582 }
583
584 /**
585  * gst_buffer_is_span_fast:
586  * @buf1: the first #GstBuffer.
587  * @buf2: the second #GstBuffer.
588  *
589  * Determines whether a gst_buffer_span() can be done without copying
590  * the contents, that is, whether the data areas are contiguous sub-buffers of 
591  * the same buffer.
592  *
593  * MT safe.
594  * Returns: TRUE if the buffers are contiguous,
595  * FALSE if a copy would be required.
596  */
597 gboolean
598 gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
599 {
600   g_return_val_if_fail (buf1 != NULL && buf2 != NULL, FALSE);
601   g_return_val_if_fail (buf1->mini_object.refcount > 0, FALSE);
602   g_return_val_if_fail (buf2->mini_object.refcount > 0, FALSE);
603
604   /* it's only fast if we have subbuffers of the same parent */
605   return (GST_IS_SUBBUFFER (buf1) &&
606       GST_IS_SUBBUFFER (buf2) &&
607       (GST_SUBBUFFER_CAST (buf1)->parent == GST_SUBBUFFER_CAST (buf2)->parent)
608       && ((buf1->data + buf1->size) == buf2->data));
609 }
610
611 /**
612  * gst_buffer_span:
613  * @buf1: the first source #GstBuffer to merge.
614  * @offset: the offset in the first buffer from where the new
615  * buffer should start.
616  * @buf2: the second source #GstBuffer to merge.
617  * @len: the total length of the new buffer.
618  *
619  * Creates a new buffer that consists of part of buf1 and buf2.
620  * Logically, buf1 and buf2 are concatenated into a single larger
621  * buffer, and a new buffer is created at the given offset inside
622  * this space, with a given length.
623  *
624  * If the two source buffers are children of the same larger buffer,
625  * and are contiguous, the new buffer will be a child of the shared
626  * parent, and thus no copying is necessary. you can use
627  * gst_buffer_is_span_fast() to determine if a memcpy will be needed.
628  *
629  * MT safe.
630  * Returns: the new #GstBuffer that spans the two source buffers.
631  * Returns NULL if the arguments are invalid.
632  */
633 GstBuffer *
634 gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
635     guint32 len)
636 {
637   GstBuffer *newbuf;
638
639   g_return_val_if_fail (buf1 != NULL && buf2 != NULL, NULL);
640   g_return_val_if_fail (buf1->mini_object.refcount > 0, NULL);
641   g_return_val_if_fail (buf2->mini_object.refcount > 0, NULL);
642   g_return_val_if_fail (len > 0, NULL);
643   g_return_val_if_fail (len <= buf1->size + buf2->size - offset, NULL);
644
645   /* if the two buffers have the same parent and are adjacent */
646   if (gst_buffer_is_span_fast (buf1, buf2)) {
647     GstBuffer *parent = GST_SUBBUFFER_CAST (buf1)->parent;
648
649     /* we simply create a subbuffer of the common parent */
650     newbuf = gst_buffer_create_sub (parent,
651         buf1->data - parent->data + offset, len);
652   } else {
653     GST_CAT_DEBUG (GST_CAT_BUFFER,
654         "slow path taken while spanning buffers %p and %p", buf1, buf2);
655     /* otherwise we simply have to brute-force copy the buffers */
656     newbuf = gst_buffer_new_and_alloc (len);
657
658     /* copy the first buffer's data across */
659     memcpy (newbuf->data, buf1->data + offset, buf1->size - offset);
660     /* copy the second buffer's data across */
661     memcpy (newbuf->data + (buf1->size - offset), buf2->data,
662         len - (buf1->size - offset));
663   }
664   /* if the offset is 0, the new buffer has the same timestamp as buf1 */
665   if (offset == 0) {
666     GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET (buf1);
667     GST_BUFFER_TIMESTAMP (newbuf) = GST_BUFFER_TIMESTAMP (buf1);
668
669     /* if we completely merged the two buffers (appended), we can
670      * calculate the duration too. Also make sure we's not messing with
671      * invalid DURATIONS */
672     if (buf1->size + buf2->size == len) {
673       if (GST_BUFFER_DURATION_IS_VALID (buf1) &&
674           GST_BUFFER_DURATION_IS_VALID (buf2)) {
675         /* add duration */
676         GST_BUFFER_DURATION (newbuf) = GST_BUFFER_DURATION (buf1) +
677             GST_BUFFER_DURATION (buf2);
678       }
679       if (GST_BUFFER_OFFSET_END_IS_VALID (buf2)) {
680         /* add offset_end */
681         GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_END (buf2);
682       }
683     }
684   }
685
686   return newbuf;
687 }