Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / gstbufferpool.c
1 /* GStreamer
2  * Copyright (C) 2010 Wim Taymans <wim.taymans@gmail.com>
3  *
4  * gstbufferpool.c: GstBufferPool baseclass
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:gstbufferpool
24  * @short_description: Pool for buffers
25  * @see_also: #GstBuffer
26  *
27  */
28
29 #include "gst_private.h"
30
31 #include <errno.h>
32 #ifdef HAVE_UNISTD_H
33 #  include <unistd.h>
34 #endif
35 #include <sys/types.h>
36
37 #include "gstinfo.h"
38 #include "gstquark.h"
39
40 #include "gstbufferpool.h"
41
42 GST_DEBUG_CATEGORY_STATIC (gst_buffer_pool_debug);
43 #define GST_CAT_DEFAULT gst_buffer_pool_debug
44
45 #define GST_BUFFER_POOL_GET_PRIVATE(obj)  \
46    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BUFFER_POOL, GstBufferPoolPrivate))
47
48 #define GST_BUFFER_POOL_LOCK(pool)   (g_static_rec_mutex_lock(&pool->priv->rec_lock))
49 #define GST_BUFFER_POOL_UNLOCK(pool) (g_static_rec_mutex_unlock(&pool->priv->rec_lock))
50
51 struct _GstBufferPoolPrivate
52 {
53   GStaticRecMutex rec_lock;
54   guint size;
55   guint min_buffers;
56   guint max_buffers;
57   guint prefix;
58   guint postfix;
59   guint align;
60 };
61
62 enum
63 {
64   /* add more above */
65   LAST_SIGNAL
66 };
67
68 static void gst_buffer_pool_finalize (GObject * object);
69
70 G_DEFINE_TYPE (GstBufferPool, gst_buffer_pool, GST_TYPE_OBJECT);
71
72 static gboolean default_start (GstBufferPool * pool);
73 static gboolean default_stop (GstBufferPool * pool);
74 static gboolean default_set_config (GstBufferPool * pool,
75     GstStructure * config);
76 static GstFlowReturn default_alloc_buffer (GstBufferPool * pool,
77     GstBuffer ** buffer, GstBufferPoolParams * params);
78 static GstFlowReturn default_acquire_buffer (GstBufferPool * pool,
79     GstBuffer ** buffer, GstBufferPoolParams * params);
80 static void default_free_buffer (GstBufferPool * pool, GstBuffer * buffer);
81 static void default_release_buffer (GstBufferPool * pool, GstBuffer * buffer);
82
83 static void
84 gst_buffer_pool_class_init (GstBufferPoolClass * klass)
85 {
86   GObjectClass *gobject_class = (GObjectClass *) klass;
87
88   g_type_class_add_private (klass, sizeof (GstBufferPoolPrivate));
89
90   gobject_class->finalize = gst_buffer_pool_finalize;
91
92   klass->start = default_start;
93   klass->stop = default_stop;
94   klass->set_config = default_set_config;
95   klass->acquire_buffer = default_acquire_buffer;
96   klass->alloc_buffer = default_alloc_buffer;
97   klass->release_buffer = default_release_buffer;
98   klass->free_buffer = default_free_buffer;
99
100   GST_DEBUG_CATEGORY_INIT (gst_buffer_pool_debug, "bufferpool", 0,
101       "bufferpool debug");
102 }
103
104 static void
105 gst_buffer_pool_init (GstBufferPool * pool)
106 {
107   pool->priv = GST_BUFFER_POOL_GET_PRIVATE (pool);
108
109   g_static_rec_mutex_init (&pool->priv->rec_lock);
110
111   pool->poll = gst_poll_new_timer ();
112   pool->queue = gst_atomic_queue_new (10);
113   pool->flushing = TRUE;
114   pool->active = FALSE;
115   pool->configured = FALSE;
116   pool->started = FALSE;
117   pool->config = gst_structure_id_empty_new (GST_QUARK (BUFFER_POOL_CONFIG));
118   gst_buffer_pool_config_set (pool->config, NULL, 0, 0, 0, 0, 0, 1);
119
120   GST_DEBUG_OBJECT (pool, "created");
121 }
122
123 static void
124 gst_buffer_pool_finalize (GObject * object)
125 {
126   GstBufferPool *pool;
127
128   pool = GST_BUFFER_POOL_CAST (object);
129
130   GST_DEBUG_OBJECT (pool, "finalize");
131
132   gst_buffer_pool_set_active (pool, FALSE);
133   gst_atomic_queue_unref (pool->queue);
134   gst_poll_free (pool->poll);
135   gst_structure_free (pool->config);
136   g_static_rec_mutex_free (&pool->priv->rec_lock);
137
138   G_OBJECT_CLASS (gst_buffer_pool_parent_class)->finalize (object);
139 }
140
141 /**
142  * gst_buffer_pool_new:
143  *
144  * Creates a new #GstBufferPool instance.
145  *
146  * Returns: a new #GstBufferPool instance
147  */
148 GstBufferPool *
149 gst_buffer_pool_new (void)
150 {
151   GstBufferPool *result;
152
153   result = g_object_newv (GST_TYPE_BUFFER_POOL, 0, NULL);
154   GST_DEBUG_OBJECT (result, "created new buffer pool");
155
156   return result;
157 }
158
159 static GstFlowReturn
160 default_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
161     GstBufferPoolParams * params)
162 {
163   guint size, align;
164   GstBufferPoolPrivate *priv = pool->priv;
165
166   *buffer = gst_buffer_new ();
167
168   align = priv->align - 1;
169   size = priv->prefix + priv->postfix + priv->size + align;
170   if (size > 0) {
171     guint8 *memptr;
172
173     memptr = g_malloc (size);
174     GST_BUFFER_MALLOCDATA (*buffer) = memptr;
175     memptr = (guint8 *) ((guintptr) (memptr + align) & ~align);
176     GST_BUFFER_DATA (*buffer) = memptr + priv->prefix;
177     GST_BUFFER_SIZE (*buffer) = priv->size;
178   }
179
180   return GST_FLOW_OK;
181 }
182
183 /* the default implementation for preallocating the buffers
184  * in the pool */
185 static gboolean
186 default_start (GstBufferPool * pool)
187 {
188   guint i;
189   GstBufferPoolPrivate *priv = pool->priv;
190   GstBufferPoolClass *pclass;
191
192   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
193
194   /* no alloc function, error */
195   if (G_UNLIKELY (pclass->alloc_buffer == NULL))
196     goto no_alloc;
197
198   /* we need to prealloc buffers */
199   for (i = 0; i < priv->min_buffers; i++) {
200     GstBuffer *buffer;
201
202     if (pclass->alloc_buffer (pool, &buffer, NULL) != GST_FLOW_OK)
203       goto alloc_failed;
204
205     GST_LOG_OBJECT (pool, "prealloced buffer %d: %p", i, buffer);
206     /* store in the queue */
207     gst_atomic_queue_push (pool->queue, buffer);
208     gst_poll_write_control (pool->poll);
209   }
210   return TRUE;
211
212   /* ERRORS */
213 no_alloc:
214   {
215     GST_WARNING_OBJECT (pool, "no alloc function");
216     return FALSE;
217   }
218 alloc_failed:
219   {
220     GST_WARNING_OBJECT (pool, "alloc function failed");
221     return FALSE;
222   }
223 }
224
225 /* must be called with the lock */
226 static gboolean
227 do_start (GstBufferPool * pool)
228 {
229   if (!pool->started) {
230     GstBufferPoolClass *pclass;
231
232     pclass = GST_BUFFER_POOL_GET_CLASS (pool);
233
234     GST_LOG_OBJECT (pool, "starting");
235     /* start the pool, subclasses should allocate buffers and put them
236      * in the queue */
237     if (G_LIKELY (pclass->start)) {
238       if (!pclass->start (pool))
239         return FALSE;
240     }
241     pool->started = TRUE;
242   }
243   return TRUE;
244 }
245
246
247 static void
248 default_free_buffer (GstBufferPool * pool, GstBuffer * buffer)
249 {
250   gst_buffer_unref (buffer);
251 }
252
253 /* must be called with the lock */
254 static gboolean
255 default_stop (GstBufferPool * pool)
256 {
257   GstBuffer *buffer;
258   GstBufferPoolClass *pclass;
259
260   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
261
262   /* clear the pool */
263   while ((buffer = gst_atomic_queue_pop (pool->queue))) {
264     gst_poll_read_control (pool->poll);
265
266     if (G_LIKELY (pclass->free_buffer))
267       pclass->free_buffer (pool, buffer);
268   }
269   return TRUE;
270 }
271
272 /* must be called with the lock */
273 static gboolean
274 do_stop (GstBufferPool * pool)
275 {
276   if (pool->started) {
277     GstBufferPoolClass *pclass;
278
279     pclass = GST_BUFFER_POOL_GET_CLASS (pool);
280
281     GST_LOG_OBJECT (pool, "stopping");
282     if (G_LIKELY (pclass->stop)) {
283       if (!pclass->stop (pool))
284         return FALSE;
285     }
286     pool->started = FALSE;
287   }
288   return TRUE;
289 }
290
291 /**
292  * gst_buffer_pool_set_active:
293  * @pool: a #GstBufferPool
294  * @active: the new active state
295  *
296  * Control the active state of @pool. When the pool is active, new calls to
297  * gst_buffer_pool_acquire_buffer() will return with GST_FLOW_WRONG_STATE.
298  *
299  * Returns: %FALSE when the pool was not configured or when preallocation of the
300  * buffers failed.
301  */
302 gboolean
303 gst_buffer_pool_set_active (GstBufferPool * pool, gboolean active)
304 {
305   GstBufferPoolClass *pclass;
306   gboolean res = TRUE;
307
308   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE);
309
310   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
311
312   GST_LOG_OBJECT (pool, "active %d", active);
313
314   GST_BUFFER_POOL_LOCK (pool);
315   /* just return if we are already in the right state */
316   if (pool->active == active)
317     goto was_ok;
318
319   /* we need to be configured */
320   if (!pool->configured)
321     goto not_configured;
322
323   if (active) {
324     if (!do_start (pool))
325       goto start_failed;
326
327     /* unset the flushing state now */
328     gst_poll_read_control (pool->poll);
329     g_atomic_int_set (&pool->flushing, FALSE);
330   } else {
331     /* set to flushing first */
332     g_atomic_int_set (&pool->flushing, TRUE);
333     gst_poll_write_control (pool->poll);
334
335     /* when all buffers are in the pool, free them. Else they will be
336      * freed when they are released */
337     if (g_atomic_int_get (&pool->outstanding) == 0) {
338       if (!do_stop (pool))
339         goto stop_failed;
340     }
341   }
342   pool->active = active;
343   GST_BUFFER_POOL_UNLOCK (pool);
344
345   return res;
346
347 was_ok:
348   {
349     GST_DEBUG_OBJECT (pool, "pool was in the right state");
350     GST_BUFFER_POOL_UNLOCK (pool);
351     return TRUE;
352   }
353 not_configured:
354   {
355     GST_ERROR_OBJECT (pool, "pool was not configured");
356     GST_BUFFER_POOL_UNLOCK (pool);
357     return FALSE;
358   }
359 start_failed:
360   {
361     GST_ERROR_OBJECT (pool, "start failed");
362     GST_BUFFER_POOL_UNLOCK (pool);
363     return FALSE;
364   }
365 stop_failed:
366   {
367     GST_WARNING_OBJECT (pool, "stop failed");
368     GST_BUFFER_POOL_UNLOCK (pool);
369     return FALSE;
370   }
371 }
372
373 static gboolean
374 default_set_config (GstBufferPool * pool, GstStructure * config)
375 {
376   GstBufferPoolPrivate *priv = pool->priv;
377   const GstCaps *caps;
378   guint size, min_buffers, max_buffers;
379   guint prefix, postfix, align;
380
381   /* parse the config and keep around */
382   if (!gst_buffer_pool_config_get (config, &caps, &size, &min_buffers,
383           &max_buffers, &prefix, &postfix, &align))
384     goto wrong_config;
385
386   priv->size = size;
387   priv->min_buffers = min_buffers;
388   priv->max_buffers = max_buffers;
389   priv->prefix = prefix;
390   priv->postfix = postfix;
391   priv->align = align;
392
393   return TRUE;
394
395 wrong_config:
396   {
397     GST_WARNING_OBJECT (pool, "invalid config");
398     return FALSE;
399   }
400 }
401
402 /**
403  * gst_buffer_pool_set_config:
404  * @pool: a #GstBufferPool
405  * @config: a #GstStructure
406  *
407  * Set the configuration of the pool. The pool must be inactive and all buffers
408  * allocated form this pool must be returned or else this function will do
409  * nothing and return FALSE.
410  *
411  * @condfig is a #GstStructure that contains the configuration parameters for
412  * the pool. A default and mandatory set of parameters can be configured with
413  * gst_buffer_pool_config_set(). This function takes ownership of @config.
414  *
415  * Returns: TRUE when the configuration could be set.
416  */
417 gboolean
418 gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
419 {
420   gboolean result;
421   GstBufferPoolClass *pclass;
422
423   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE);
424   g_return_val_if_fail (config != NULL, FALSE);
425
426   GST_BUFFER_POOL_LOCK (pool);
427   /* can't change the settings when active */
428   if (pool->active)
429     goto was_active;
430
431   /* we can't change when outstanding buffers */
432   if (g_atomic_int_get (&pool->outstanding) != 0)
433     goto have_outstanding;
434
435   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
436
437   /* set the new config */
438   if (G_LIKELY (pclass->set_config))
439     result = pclass->set_config (pool, config);
440   else
441     result = FALSE;
442
443   if (result) {
444     if (pool->config)
445       gst_structure_free (pool->config);
446     pool->config = config;
447
448     /* now we are configured */
449     pool->configured = TRUE;
450   }
451   GST_BUFFER_POOL_UNLOCK (pool);
452
453   return result;
454
455   /* ERRORS */
456 was_active:
457   {
458     GST_WARNING_OBJECT (pool, "can't change config, we are active");
459     GST_BUFFER_POOL_UNLOCK (pool);
460     return FALSE;
461   }
462 have_outstanding:
463   {
464     GST_WARNING_OBJECT (pool, "can't change config, have outstanding buffers");
465     GST_BUFFER_POOL_UNLOCK (pool);
466     return FALSE;
467   }
468 }
469
470 /**
471  * gst_buffer_pool_get_config:
472  * @pool: a #GstBufferPool
473  *
474  * Get a copy of the current configuration of the pool. This configuration
475  * can either be modified and used for the gst_buffer_pool_set_config() call
476  * or it must be freed after usage.
477  *
478  * Returns: a copy of the current configuration of @pool. use
479  * gst_structure_free() after usage or gst_buffer_pool_set_config().
480  */
481 GstStructure *
482 gst_buffer_pool_get_config (GstBufferPool * pool)
483 {
484   GstStructure *result;
485
486   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), NULL);
487
488   GST_BUFFER_POOL_UNLOCK (pool);
489   result = gst_structure_copy (pool->config);
490   GST_BUFFER_POOL_UNLOCK (pool);
491
492   return result;
493 }
494
495 /**
496  * gst_buffer_pool_config_set:
497  * @pool: a #GstBufferPool
498  * @size: the size of each buffer, not including pre and post fix
499  * @min_buffers: the minimum amount of buffers to allocate.
500  * @max_buffers: the maximum amount of buffers to allocate or 0 for unlimited.
501  * @prefix: prefix each buffer with this many bytes
502  * @postfix: postfix each buffer with this many bytes
503  * @align: alignment of the buffer data.
504  *
505  * Configure @config with the given parameters.
506  */
507 void
508 gst_buffer_pool_config_set (GstStructure * config, const GstCaps * caps,
509     guint size, guint min_buffers, guint max_buffers, guint prefix,
510     guint postfix, guint align)
511 {
512   g_return_if_fail (config != NULL);
513
514   gst_structure_id_set (config,
515       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
516       GST_QUARK (SIZE), G_TYPE_UINT, size,
517       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
518       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
519       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
520       GST_QUARK (POSTFIX), G_TYPE_UINT, postfix,
521       GST_QUARK (ALIGN), G_TYPE_UINT, align, NULL);
522 }
523
524 /**
525  * gst_buffer_pool_config_get:
526  * @pool: a #GstBufferPool
527  * @size: the size of each buffer, not including pre and post fix
528  * @min_buffers: the minimum amount of buffers to allocate.
529  * @max_buffers: the maximum amount of buffers to allocate or 0 for unlimited.
530  * @prefix: prefix each buffer with this many bytes
531  * @postfix: postfix each buffer with this many bytes
532  * @align: alignment of the buffer data.
533  *
534  * Get the configuration values from @config.
535  */
536 gboolean
537 gst_buffer_pool_config_get (GstStructure * config, const GstCaps ** caps,
538     guint * size, guint * min_buffers, guint * max_buffers, guint * prefix,
539     guint * postfix, guint * align)
540 {
541   g_return_val_if_fail (config != NULL, FALSE);
542
543   return gst_structure_id_get (config,
544       GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
545       GST_QUARK (SIZE), G_TYPE_UINT, size,
546       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
547       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
548       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
549       GST_QUARK (POSTFIX), G_TYPE_UINT, postfix,
550       GST_QUARK (ALIGN), G_TYPE_UINT, align, NULL);
551 }
552
553 static GstFlowReturn
554 default_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
555     GstBufferPoolParams * params)
556 {
557   GstFlowReturn result;
558   GstBufferPoolClass *pclass;
559   GstBufferPoolPrivate *priv = pool->priv;
560
561   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
562
563   while (TRUE) {
564     if (G_UNLIKELY (g_atomic_int_get (&pool->flushing)))
565       goto flushing;
566
567     /* try to get a buffer from the queue */
568     *buffer = gst_atomic_queue_pop (pool->queue);
569     if (G_LIKELY (*buffer)) {
570       gst_poll_read_control (pool->poll);
571       result = GST_FLOW_OK;
572       GST_LOG_OBJECT (pool, "acquired buffer %p", *buffer);
573       break;
574     }
575
576     /* no buffer */
577     if (priv->max_buffers == 0) {
578       /* no max_buffers, we allocate some more */
579       if (G_LIKELY (pclass->alloc_buffer)) {
580         result = pclass->alloc_buffer (pool, buffer, params);
581       } else
582         result = GST_FLOW_NOT_SUPPORTED;
583       GST_LOG_OBJECT (pool, "alloc buffer %p", *buffer);
584       break;
585     }
586
587     /* check if we need to wait */
588     if (params && !(params->flags & GST_BUFFER_POOL_FLAG_WAIT)) {
589       GST_LOG_OBJECT (pool, "no more buffers");
590       result = GST_FLOW_UNEXPECTED;
591       break;
592     }
593
594     /* now wait */
595     GST_LOG_OBJECT (pool, "waiting for free buffers");
596     gst_poll_wait (pool->poll, GST_CLOCK_TIME_NONE);
597   }
598
599   return result;
600
601   /* ERRORS */
602 flushing:
603   {
604     GST_DEBUG_OBJECT (pool, "we are flushing");
605     return GST_FLOW_WRONG_STATE;
606   }
607 }
608
609 static inline void
610 dec_outstanding (GstBufferPool * pool)
611 {
612   if (g_atomic_int_dec_and_test (&pool->outstanding)) {
613     /* all buffers are returned to the pool, see if we need to free them */
614     if (g_atomic_int_get (&pool->flushing)) {
615       /* take the lock so that set_active is not run concurrently */
616       GST_BUFFER_POOL_LOCK (pool);
617       /* recheck the flushing state in the lock, the pool could have been
618        * set to active again */
619       if (g_atomic_int_get (&pool->flushing))
620         do_stop (pool);
621
622       GST_BUFFER_POOL_UNLOCK (pool);
623     }
624   }
625 }
626
627 /**
628  * gst_buffer_pool_acquire_buffer:
629  * @pool: a #GstBufferPool
630  * @buffer: a location for a #GstBuffer
631  * @params: parameters.
632  *
633  * Acquire a buffer from @pool. @buffer should point to a memory location that
634  * can hold a pointer to the new buffer.
635  *
636  * @params can be NULL or contain optional parameters to influence the allocation.
637  *
638  * Returns: a #GstFlowReturn such as GST_FLOW_WRONG_STATE when the pool is
639  * inactive.
640  */
641 GstFlowReturn
642 gst_buffer_pool_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
643     GstBufferPoolParams * params)
644 {
645   GstBufferPoolClass *pclass;
646   GstFlowReturn result;
647
648   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), GST_FLOW_ERROR);
649   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
650
651   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
652
653   /* assume we'll have one more outstanding buffer we need to do that so
654    * that concurrent set_active doesn't clear the buffers */
655   g_atomic_int_inc (&pool->outstanding);
656
657   if (G_LIKELY (pclass->acquire_buffer))
658     result = pclass->acquire_buffer (pool, buffer, params);
659   else
660     result = GST_FLOW_NOT_SUPPORTED;
661
662   if (G_LIKELY (result == GST_FLOW_OK)) {
663     /* all buffers from the pool point to the pool and have the refcount of the
664      * pool incremented */
665     (*buffer)->pool = gst_object_ref (pool);
666   } else {
667     dec_outstanding (pool);
668   }
669
670   return result;
671 }
672
673 static void
674 default_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
675 {
676   /* keep it around in our queue */
677   GST_LOG_OBJECT (pool, "released buffer %p", buffer);
678   gst_atomic_queue_push (pool->queue, buffer);
679   gst_poll_write_control (pool->poll);
680 }
681
682 /**
683  * gst_buffer_pool_release_buffer:
684  * @pool: a #GstBufferPool
685  * @buffer: a #GstBuffer
686  *
687  * Release @buffer to @pool. @buffer should have previously been allocated from
688  * @pool with gst_buffer_pool_acquire_buffer().
689  *
690  * This function is usually called automatically when the last ref on @buffer
691  * disappears.
692  */
693 void
694 gst_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
695 {
696   GstBufferPoolClass *pclass;
697
698   g_return_if_fail (GST_IS_BUFFER_POOL (pool));
699   g_return_if_fail (buffer != NULL);
700
701   /* check that the buffer is ours, all buffers returned to the pool have the
702    * pool member set to NULL and the pool refcount decreased */
703   if (!g_atomic_pointer_compare_and_exchange ((gpointer *) & buffer->pool,
704           pool, NULL))
705     return;
706
707   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
708
709   if (G_LIKELY (pclass->release_buffer))
710     pclass->release_buffer (pool, buffer);
711
712   dec_outstanding (pool);
713
714   /* decrease the refcount that the buffer had to us */
715   gst_object_unref (pool);
716 }