Coverage Report

Created: 2026-05-28 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gstreamer/subprojects/gstreamer/gst/gstbufferlist.c
Line
Count
Source
1
/* GStreamer
2
 * Copyright (C) 2009 Axis Communications <dev-gstreamer at axis dot com>
3
 * @author Jonas Holmberg <jonas dot holmberg at axis dot com>
4
 * Copyright (C) 2014 Tim-Philipp Müller <tim at centricular dot com>
5
 *
6
 * gstbufferlist.c: Buffer list
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Library General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Library General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Library General Public
19
 * License along with this library; if not, write to the
20
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21
 * Boston, MA 02110-1301, USA.
22
 */
23
24
/**
25
 * SECTION:gstbufferlist
26
 * @title: GstBufferList
27
 * @short_description: Lists of buffers for data-passing
28
 * @see_also: #GstPad, #GstMiniObject
29
 *
30
 * Buffer lists are an object containing a list of buffers.
31
 *
32
 * Buffer lists are created with gst_buffer_list_new() and filled with data
33
 * using gst_buffer_list_insert().
34
 *
35
 * Buffer lists can be pushed on a srcpad with gst_pad_push_list(). This is
36
 * interesting when multiple buffers need to be pushed in one go because it
37
 * can reduce the amount of overhead for pushing each buffer individually.
38
 */
39
#define GST_DISABLE_MINIOBJECT_INLINE_FUNCTIONS
40
#include "gst_private.h"
41
42
#include "gstbuffer.h"
43
#include "gstbufferlist.h"
44
#include "gstutils.h"
45
46
#define GST_CAT_DEFAULT GST_CAT_BUFFER_LIST
47
48
#define GST_BUFFER_LIST_IS_USING_DYNAMIC_ARRAY(list) \
49
0
    ((list)->buffers != &(list)->arr[0])
50
51
/**
52
 * GstBufferList:
53
 *
54
 * Opaque list of grouped buffers.
55
 */
56
struct _GstBufferList
57
{
58
  GstMiniObject mini_object;
59
60
  GstBuffer **buffers;
61
  guint n_buffers;
62
  guint n_allocated;
63
64
  /* one-item array, in reality more items are pre-allocated
65
   * as part of the GstBufferList structure, and that
66
   * pre-allocated array extends beyond the declared struct */
67
  GstBuffer *arr[1];
68
};
69
70
GType _gst_buffer_list_type = 0;
71
72
5
GST_DEFINE_MINI_OBJECT_TYPE (GstBufferList, gst_buffer_list);
73
5
74
5
void
75
5
_priv_gst_buffer_list_initialize (void)
76
5
{
77
5
  _gst_buffer_list_type = gst_buffer_list_get_type ();
78
5
}
79
80
static GstBufferList *
81
_gst_buffer_list_copy (GstBufferList * list)
82
0
{
83
0
  GstBufferList *copy;
84
0
  guint i, len;
85
86
0
  len = list->n_buffers;
87
0
  copy = gst_buffer_list_new_sized (list->n_allocated);
88
89
  /* add and ref all buffers in the array */
90
0
  for (i = 0; i < len; i++) {
91
0
    copy->buffers[i] = gst_buffer_ref (list->buffers[i]);
92
0
    gst_mini_object_add_parent (GST_MINI_OBJECT_CAST (copy->buffers[i]),
93
0
        GST_MINI_OBJECT_CAST (copy));
94
0
  }
95
96
0
  copy->n_buffers = len;
97
98
0
  return copy;
99
0
}
100
101
static void
102
_gst_buffer_list_free (GstBufferList * list)
103
0
{
104
0
  guint i, len;
105
106
0
  GST_LOG ("free %p", list);
107
108
  /* unrefs all buffers too */
109
0
  len = list->n_buffers;
110
0
  for (i = 0; i < len; i++) {
111
0
    gst_mini_object_remove_parent (GST_MINI_OBJECT_CAST (list->buffers[i]),
112
0
        GST_MINI_OBJECT_CAST (list));
113
0
    gst_buffer_unref (list->buffers[i]);
114
0
  }
115
116
0
  if (GST_BUFFER_LIST_IS_USING_DYNAMIC_ARRAY (list))
117
0
    g_free (list->buffers);
118
119
#ifdef USE_POISONING
120
  memset (list, 0xff, sizeof (GstBufferList));
121
#endif
122
123
0
  g_free (list);
124
0
}
125
126
static void
127
gst_buffer_list_init (GstBufferList * list, guint n_allocated)
128
0
{
129
0
  gst_mini_object_init (GST_MINI_OBJECT_CAST (list), 0, _gst_buffer_list_type,
130
0
      (GstMiniObjectCopyFunction) _gst_buffer_list_copy, NULL,
131
0
      (GstMiniObjectFreeFunction) _gst_buffer_list_free);
132
133
0
  list->buffers = &list->arr[0];
134
0
  list->n_buffers = 0;
135
0
  list->n_allocated = n_allocated;
136
137
0
  GST_LOG ("init %p", list);
138
0
}
139
140
/**
141
 * gst_buffer_list_new_sized:
142
 * @size: an initial reserved size
143
 *
144
 * Creates a new, empty #GstBufferList. The list will have @size space
145
 * preallocated so that memory reallocations can be avoided.
146
 *
147
 * Returns: (transfer full): the new #GstBufferList.
148
 */
149
GstBufferList *
150
gst_buffer_list_new_sized (guint size)
151
0
{
152
0
  GstBufferList *list;
153
0
  gsize slice_size;
154
0
  guint n_allocated;
155
156
0
  if (size == 0)
157
0
    size = 1;
158
159
0
  n_allocated = GST_ROUND_UP_16 (size);
160
161
0
  slice_size = sizeof (GstBufferList) + (n_allocated - 1) * sizeof (gpointer);
162
163
0
  list = g_malloc0 (slice_size);
164
165
0
  GST_LOG ("new %p", list);
166
167
0
  gst_buffer_list_init (list, n_allocated);
168
169
0
  return list;
170
0
}
171
172
/**
173
 * gst_buffer_list_new:
174
 *
175
 * Creates a new, empty #GstBufferList.
176
 *
177
 * Returns: (transfer full): the new #GstBufferList.
178
 */
179
GstBufferList *
180
gst_buffer_list_new (void)
181
0
{
182
0
  return gst_buffer_list_new_sized (8);
183
0
}
184
185
/**
186
 * gst_buffer_list_length:
187
 * @list: a #GstBufferList
188
 *
189
 * Returns the number of buffers in @list.
190
 *
191
 * Returns: the number of buffers in the buffer list
192
 */
193
guint
194
gst_buffer_list_length (GstBufferList * list)
195
0
{
196
0
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), 0);
197
198
0
  return list->n_buffers;
199
0
}
200
201
static inline void
202
gst_buffer_list_remove_range_internal (GstBufferList * list, guint idx,
203
    guint length, gboolean unref_old)
204
0
{
205
0
  guint i;
206
207
0
  if (unref_old) {
208
0
    for (i = idx; i < idx + length; ++i) {
209
0
      gst_mini_object_remove_parent (GST_MINI_OBJECT_CAST (list->buffers[i]),
210
0
          GST_MINI_OBJECT_CAST (list));
211
0
      gst_buffer_unref (list->buffers[i]);
212
0
    }
213
0
  }
214
215
0
  if (idx + length != list->n_buffers) {
216
0
    memmove (&list->buffers[idx], &list->buffers[idx + length],
217
0
        (list->n_buffers - (idx + length)) * sizeof (void *));
218
0
  }
219
220
0
  list->n_buffers -= length;
221
0
}
222
223
/**
224
 * gst_buffer_list_foreach:
225
 * @list: a #GstBufferList
226
 * @func: (scope call) (closure user_data): a #GstBufferListFunc to call
227
 * @user_data: user data passed to @func
228
 *
229
 * Calls @func with @data for each buffer in @list.
230
 *
231
 * @func can modify the passed buffer pointer or its contents. The return value
232
 * of @func defines if this function returns or if the remaining buffers in
233
 * the list should be skipped.
234
 *
235
 * Returns: %TRUE when @func returned %TRUE for each buffer in @list or when
236
 * @list is empty.
237
 */
238
gboolean
239
gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
240
    gpointer user_data)
241
0
{
242
0
  guint i, len;
243
0
  gboolean ret = TRUE;
244
0
  gboolean list_was_writable, first_warning = TRUE;
245
246
0
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
247
0
  g_return_val_if_fail (func != NULL, FALSE);
248
249
0
  list_was_writable = gst_buffer_list_is_writable (list);
250
251
0
  len = list->n_buffers;
252
0
  for (i = 0; i < len;) {
253
0
    GstBuffer *buf, *buf_ret;
254
0
    gboolean was_writable;
255
256
0
    buf = buf_ret = list->buffers[i];
257
258
    /* If the buffer is writable, we remove us as parent for now to
259
     * allow the callback to destroy the buffer. If we get the buffer
260
     * back, we add ourselves as parent again.
261
     *
262
     * Non-writable buffers just get another reference as they were not
263
     * writable to begin with, and they would possibly become writable
264
     * by removing ourselves as parent
265
     */
266
0
    was_writable = list_was_writable && gst_buffer_is_writable (buf);
267
268
0
    if (was_writable)
269
0
      gst_mini_object_remove_parent (GST_MINI_OBJECT_CAST (buf),
270
0
          GST_MINI_OBJECT_CAST (list));
271
0
    else
272
0
      gst_buffer_ref (buf);
273
274
0
    ret = func (&buf_ret, i, user_data);
275
276
    /* Check if the function changed the buffer */
277
0
    if (buf != buf_ret) {
278
      /* If the list was not writable but the callback was actually changing
279
       * our buffer, then it wouldn't have been allowed to do so.
280
       *
281
       * Fortunately we still have a reference to the old buffer in that case
282
       * and just not modify the list, unref the new buffer (if any) and warn
283
       * about this */
284
0
      if (!list_was_writable) {
285
0
        if (first_warning) {
286
0
          g_critical
287
0
              ("gst_buffer_list_foreach: non-writable list %p was changed from callback",
288
0
              list);
289
0
          first_warning = FALSE;
290
0
        }
291
0
        if (buf_ret)
292
0
          gst_buffer_unref (buf_ret);
293
0
      } else if (buf_ret == NULL) {
294
0
        gst_buffer_list_remove_range_internal (list, i, 1, !was_writable);
295
0
        --len;
296
0
      } else {
297
0
        if (!was_writable) {
298
0
          gst_mini_object_remove_parent (GST_MINI_OBJECT_CAST (buf),
299
0
              GST_MINI_OBJECT_CAST (list));
300
0
          gst_buffer_unref (buf);
301
0
        }
302
303
0
        list->buffers[i] = buf_ret;
304
0
        gst_mini_object_add_parent (GST_MINI_OBJECT_CAST (buf_ret),
305
0
            GST_MINI_OBJECT_CAST (list));
306
0
      }
307
0
    } else {
308
0
      if (was_writable)
309
0
        gst_mini_object_add_parent (GST_MINI_OBJECT_CAST (buf),
310
0
            GST_MINI_OBJECT_CAST (list));
311
0
      else
312
0
        gst_buffer_unref (buf);
313
0
    }
314
315
0
    if (!ret)
316
0
      break;
317
318
    /* If the buffer was not removed by func go to the next buffer */
319
0
    if (buf_ret != NULL)
320
0
      i++;
321
0
  }
322
0
  return ret;
323
0
}
324
325
/**
326
 * gst_buffer_list_get:
327
 * @list: a #GstBufferList
328
 * @idx: the index
329
 *
330
 * Gets the buffer at @idx.
331
 *
332
 * You must make sure that @idx does not exceed the number of
333
 * buffers available.
334
 *
335
 * Returns: (transfer none): the buffer at @idx in @group.
336
 *     The returned buffer remains valid as long as @list is valid and
337
 *     buffer is not removed from the list.
338
 */
339
GstBuffer *
340
gst_buffer_list_get (GstBufferList * list, guint idx)
341
0
{
342
0
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL);
343
0
  g_return_val_if_fail (idx < list->n_buffers, NULL);
344
345
0
  return list->buffers[idx];
346
0
}
347
348
/**
349
 * gst_buffer_list_get_writable:
350
 * @list: a (writable) #GstBufferList
351
 * @idx: the index
352
 *
353
 * Gets the buffer at @idx, ensuring it is a writable buffer.
354
 *
355
 * You must make sure that @idx does not exceed the number of
356
 * buffers available.
357
 *
358
 * Returns: (transfer none): the buffer at @idx in @group.
359
 *     The returned buffer remains valid as long as @list is valid and
360
 *     the buffer is not removed from the list.
361
 *
362
 * Since: 1.14
363
 */
364
GstBuffer *
365
gst_buffer_list_get_writable (GstBufferList * list, guint idx)
366
0
{
367
0
  GstBuffer *new_buf;
368
369
0
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL);
370
0
  g_return_val_if_fail (gst_buffer_list_is_writable (list), NULL);
371
0
  g_return_val_if_fail (idx < list->n_buffers, NULL);
372
373
  /* We have to implement this manually here to correctly add/remove the
374
   * parent */
375
0
  if (gst_buffer_is_writable (list->buffers[idx]))
376
0
    return list->buffers[idx];
377
378
0
  gst_mini_object_remove_parent (GST_MINI_OBJECT_CAST (list->buffers[idx]),
379
0
      GST_MINI_OBJECT_CAST (list));
380
0
  new_buf = gst_buffer_copy (list->buffers[idx]);
381
0
  gst_mini_object_add_parent (GST_MINI_OBJECT_CAST (new_buf),
382
0
      GST_MINI_OBJECT_CAST (list));
383
0
  gst_buffer_unref (list->buffers[idx]);
384
0
  list->buffers[idx] = new_buf;
385
386
0
  return new_buf;
387
0
}
388
389
/**
390
 * gst_buffer_list_add:
391
 * @l: a #GstBufferList
392
 * @b: a #GstBuffer
393
 *
394
 * Append @b at the end of @l.
395
 */
396
/**
397
 * gst_buffer_list_insert:
398
 * @list: a #GstBufferList
399
 * @idx: the index
400
 * @buffer: (transfer full): a #GstBuffer
401
 *
402
 * Inserts @buffer at @idx in @list. Other buffers are moved to make room for
403
 * this new buffer.
404
 *
405
 * A -1 value for @idx will append the buffer at the end.
406
 */
407
void
408
gst_buffer_list_insert (GstBufferList * list, gint idx, GstBuffer * buffer)
409
0
{
410
0
  guint want_alloc;
411
412
0
  g_return_if_fail (GST_IS_BUFFER_LIST (list));
413
0
  g_return_if_fail (buffer != NULL);
414
0
  g_return_if_fail (gst_buffer_list_is_writable (list));
415
416
0
  if (idx == -1 && list->n_buffers < list->n_allocated) {
417
0
    gst_mini_object_add_parent (GST_MINI_OBJECT_CAST (buffer),
418
0
        GST_MINI_OBJECT_CAST (list));
419
0
    list->buffers[list->n_buffers++] = buffer;
420
0
    return;
421
0
  }
422
423
0
  if (idx == -1 || idx > list->n_buffers)
424
0
    idx = list->n_buffers;
425
426
0
  want_alloc = list->n_buffers + 1;
427
428
0
  if (want_alloc > list->n_allocated) {
429
0
    if (G_UNLIKELY (list->n_allocated > (G_MAXUINT / 2)))
430
0
      g_error ("Growing GstBufferList would result in overflow");
431
432
0
    want_alloc = MAX (GST_ROUND_UP_16 (want_alloc), list->n_allocated * 2);
433
434
0
    if (GST_BUFFER_LIST_IS_USING_DYNAMIC_ARRAY (list)) {
435
0
      list->buffers = g_renew (GstBuffer *, list->buffers, want_alloc);
436
0
    } else {
437
0
      list->buffers = g_new0 (GstBuffer *, want_alloc);
438
0
      memcpy (list->buffers, &list->arr[0], list->n_buffers * sizeof (void *));
439
0
      GST_CAT_LOG (GST_CAT_PERFORMANCE, "exceeding pre-alloced array");
440
0
    }
441
442
0
    list->n_allocated = want_alloc;
443
0
  }
444
445
0
  if (idx < list->n_buffers) {
446
0
    memmove (&list->buffers[idx + 1], &list->buffers[idx],
447
0
        (list->n_buffers - idx) * sizeof (void *));
448
0
  }
449
450
0
  ++list->n_buffers;
451
0
  list->buffers[idx] = buffer;
452
0
  gst_mini_object_add_parent (GST_MINI_OBJECT_CAST (buffer),
453
0
      GST_MINI_OBJECT_CAST (list));
454
0
}
455
456
/**
457
 * gst_buffer_list_remove:
458
 * @list: a #GstBufferList
459
 * @idx: the index
460
 * @length: the amount to remove
461
 *
462
 * Removes @length buffers starting from @idx in @list. The following buffers
463
 * are moved to close the gap.
464
 */
465
void
466
gst_buffer_list_remove (GstBufferList * list, guint idx, guint length)
467
0
{
468
0
  g_return_if_fail (GST_IS_BUFFER_LIST (list));
469
0
  g_return_if_fail (idx < list->n_buffers);
470
0
  g_return_if_fail (idx + length <= list->n_buffers);
471
0
  g_return_if_fail (gst_buffer_list_is_writable (list));
472
473
0
  gst_buffer_list_remove_range_internal (list, idx, length, TRUE);
474
0
}
475
476
/**
477
 * gst_buffer_list_copy_deep:
478
 * @list: a #GstBufferList
479
 *
480
 * Creates a copy of the given buffer list. This will make a newly allocated
481
 * copy of the buffers that the source buffer list contains.
482
 *
483
 * Returns: (transfer full): a new copy of @list.
484
 *
485
 * Since: 1.6
486
 */
487
GstBufferList *
488
gst_buffer_list_copy_deep (const GstBufferList * list)
489
0
{
490
0
  guint i, len;
491
0
  GstBufferList *result = NULL;
492
493
0
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL);
494
495
0
  result = gst_buffer_list_new ();
496
497
0
  len = list->n_buffers;
498
0
  for (i = 0; i < len; i++) {
499
0
    GstBuffer *old = list->buffers[i];
500
0
    GstBuffer *new = gst_buffer_copy_deep (old);
501
502
0
    if (G_LIKELY (new)) {
503
0
      gst_buffer_list_insert (result, i, new);
504
0
    } else {
505
0
      g_warning
506
0
          ("Failed to deep copy buffer %p while deep "
507
0
          "copying buffer list %p. Buffer list copy "
508
0
          "will be incomplete", old, list);
509
0
    }
510
0
  }
511
512
0
  return result;
513
0
}
514
515
/**
516
 * gst_buffer_list_calculate_size:
517
 * @list: a #GstBufferList
518
 *
519
 * Calculates the size of the data contained in @list by adding the
520
 * size of all buffers.
521
 *
522
 * Returns: the size of the data contained in @list in bytes.
523
 *
524
 * Since: 1.14
525
 */
526
gsize
527
gst_buffer_list_calculate_size (GstBufferList * list)
528
0
{
529
0
  GstBuffer **buffers;
530
0
  gsize size = 0;
531
0
  guint i, n;
532
533
0
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), 0);
534
535
0
  n = list->n_buffers;
536
0
  buffers = list->buffers;
537
538
0
  for (i = 0; i < n; ++i)
539
0
    size += gst_buffer_get_size (buffers[i]);
540
541
0
  return size;
542
0
}
543
544
/**
545
 * gst_buffer_list_ref: (skip)
546
 * @list: a #GstBufferList
547
 *
548
 * Increases the refcount of the given buffer list by one.
549
 *
550
 * Note that the refcount affects the writability of @list and its data, see
551
 * gst_buffer_list_make_writable(). It is important to note that keeping
552
 * additional references to GstBufferList instances can potentially increase
553
 * the number of memcpy operations in a pipeline.
554
 *
555
 * Returns: (transfer full): @list
556
 */
557
GstBufferList *
558
gst_buffer_list_ref (GstBufferList * list)
559
0
{
560
0
  return
561
0
      GST_BUFFER_LIST_CAST (gst_mini_object_ref (GST_MINI_OBJECT_CAST (list)));
562
0
}
563
564
/**
565
 * gst_buffer_list_unref: (skip)
566
 * @list: (transfer full): a #GstBufferList
567
 *
568
 * Decreases the refcount of the buffer list. If the refcount reaches 0, the
569
 * buffer list will be freed.
570
 */
571
void
572
gst_buffer_list_unref (GstBufferList * list)
573
0
{
574
0
  gst_mini_object_unref (GST_MINI_OBJECT_CAST (list));
575
0
}
576
577
/**
578
 * gst_clear_buffer_list: (skip)
579
 * @list_ptr: a pointer to a #GstBufferList reference
580
 *
581
 * Clears a reference to a #GstBufferList.
582
 *
583
 * @list_ptr must not be %NULL.
584
 *
585
 * If the reference is %NULL then this function does nothing. Otherwise, the
586
 * reference count of the list is decreased and the pointer is set to %NULL.
587
 *
588
 * Since: 1.16
589
 */
590
void
591
gst_clear_buffer_list (GstBufferList ** list_ptr)
592
0
{
593
0
  gst_clear_mini_object ((GstMiniObject **) list_ptr);
594
0
}
595
596
/**
597
 * gst_buffer_list_copy: (skip)
598
 * @list: a #GstBufferList
599
 *
600
 * Creates a shallow copy of the given buffer list. This will make a newly
601
 * allocated copy of the source list with copies of buffer pointers. The
602
 * refcount of buffers pointed to will be increased by one.
603
 *
604
 * Returns: (transfer full): a new copy of @list.
605
 */
606
GstBufferList *
607
gst_buffer_list_copy (const GstBufferList * list)
608
0
{
609
0
  return
610
0
      GST_BUFFER_LIST_CAST (gst_mini_object_copy (GST_MINI_OBJECT_CONST_CAST
611
0
          (list)));
612
0
}
613
614
/**
615
 * gst_buffer_list_replace:
616
 * @old_list: (inout) (transfer full) (nullable): pointer to a pointer to a
617
 *     #GstBufferList to be replaced.
618
 * @new_list: (transfer none) (allow-none): pointer to a #GstBufferList that
619
 *     will replace the buffer list pointed to by @old_list.
620
 *
621
 * Modifies a pointer to a #GstBufferList to point to a different
622
 * #GstBufferList. The modification is done atomically (so this is useful for
623
 * ensuring thread safety in some cases), and the reference counts are updated
624
 * appropriately (the old buffer list is unreffed, the new is reffed).
625
 *
626
 * Either @new_list or the #GstBufferList pointed to by @old_list may be %NULL.
627
 *
628
 * Returns: %TRUE if @new_list was different from @old_list
629
 *
630
 * Since: 1.16
631
 */
632
gboolean
633
gst_buffer_list_replace (GstBufferList ** old_list, GstBufferList * new_list)
634
0
{
635
0
  return gst_mini_object_replace ((GstMiniObject **) old_list,
636
0
      (GstMiniObject *) new_list);
637
0
}
638
639
/**
640
 * gst_buffer_list_take:
641
 * @old_list: (inout) (transfer full): pointer to a pointer to a #GstBufferList
642
 *     to be replaced.
643
 * @new_list: (transfer full) (allow-none): pointer to a #GstBufferList
644
 *     that will replace the bufferlist pointed to by @old_list.
645
 *
646
 * Modifies a pointer to a #GstBufferList to point to a different
647
 * #GstBufferList. This function is similar to gst_buffer_list_replace() except
648
 * that it takes ownership of @new_list.
649
 *
650
 * Returns: %TRUE if @new_list was different from @old_list
651
 *
652
 * Since: 1.16
653
 */
654
gboolean
655
gst_buffer_list_take (GstBufferList ** old_list, GstBufferList * new_list)
656
0
{
657
0
  return gst_mini_object_take ((GstMiniObject **) old_list,
658
0
      (GstMiniObject *) new_list);
659
0
}
660
661
/**
662
 * gst_buffer_list_steal: (skip)
663
 * @old_list: (inout) (transfer full) (nullable): pointer to a
664
 *     pointer to a #GstBufferList to be stolen.
665
 *
666
 * Atomically replace the #GstBufferList pointed to by @old_list with %NULL and
667
 * return the original buffer list.
668
 * Since: 1.28
669
 */
670
GstBufferList *
671
gst_buffer_list_steal (GstBufferList ** old_list)
672
0
{
673
0
  return GST_BUFFER_LIST_CAST (gst_mini_object_steal ((GstMiniObject **)
674
0
          old_list));
675
0
}
676
677
/**
678
 * gst_buffer_list_is_writable:
679
 * @list: a #GstEvent
680
 *
681
 * Tests if you can safely modify @list. It is only safe to modify buffer list when
682
 * there is only one owner of the buffer list - ie, the object is writable.
683
 */
684
gboolean
685
gst_buffer_list_is_writable (const GstBufferList * list)
686
0
{
687
0
  return gst_mini_object_is_writable (GST_MINI_OBJECT_CONST_CAST (list));
688
0
}
689
690
/**
691
 * gst_buffer_list_make_writable:
692
 * @list: (transfer full): a #GstBufferList
693
 *
694
 * Returns a writable copy of @list.
695
 *
696
 * If there is only one reference count on @list, the caller must be the owner,
697
 * and so this function will return the buffer list object unchanged. If on the other
698
 * hand there is more than one reference on the object, a new buffer list object will
699
 * be returned. The caller's reference on @list will be removed, and instead the
700
 * caller will own a reference to the returned object.
701
 *
702
 * In short, this function unrefs the buffer_list in the argument and refs the buffer list
703
 * that it returns. Don't access the argument after calling this function. See
704
 * also: gst_buffer_list_ref().
705
 *
706
 * Returns: (transfer full): a writable buffer list which may or may not be the
707
 *     same as @buffer list
708
 */
709
GstBufferList *
710
gst_buffer_list_make_writable (GstBufferList * list)
711
0
{
712
0
  return
713
0
      GST_BUFFER_LIST_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST
714
0
          (list)));
715
0
}