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