bufferpool: also allow NULL params in _acquire
[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 struct _GstBufferPoolPrivate
47 {
48   guint min_buffers;
49   guint max_buffers;
50   guint size;
51   guint prefix;
52   guint postfix;
53   guint align;
54 };
55
56 enum
57 {
58   /* add more above */
59   LAST_SIGNAL
60 };
61
62 static void gst_buffer_pool_finalize (GObject * object);
63
64 G_DEFINE_TYPE (GstBufferPool, gst_buffer_pool, GST_TYPE_OBJECT);
65
66 static gboolean default_set_active (GstBufferPool * pool, gboolean active);
67 static gboolean default_set_config (GstBufferPool * pool,
68     GstStructure * config);
69 static GstFlowReturn default_alloc_buffer (GstBufferPool * pool,
70     GstBuffer ** buffer, GstBufferPoolParams * params);
71 static GstFlowReturn default_acquire_buffer (GstBufferPool * pool,
72     GstBuffer ** buffer, GstBufferPoolParams * params);
73 static void default_free_buffer (GstBufferPool * pool, GstBuffer * buffer);
74 static void default_release_buffer (GstBufferPool * pool, GstBuffer * buffer);
75
76 static void
77 gst_buffer_pool_class_init (GstBufferPoolClass * klass)
78 {
79   GObjectClass *gobject_class = (GObjectClass *) klass;
80
81   gobject_class->finalize = gst_buffer_pool_finalize;
82
83   klass->set_active = default_set_active;
84   klass->set_config = default_set_config;
85   klass->acquire_buffer = default_acquire_buffer;
86   klass->alloc_buffer = default_alloc_buffer;
87   klass->release_buffer = default_release_buffer;
88   klass->free_buffer = default_free_buffer;
89 }
90
91 static void
92 gst_buffer_pool_init (GstBufferPool * pool)
93 {
94   pool->priv = GST_BUFFER_POOL_GET_PRIVATE (pool);
95
96   pool->config = gst_structure_id_new (GST_QUARK (BUFFER_POOL_CONFIG),
97       GST_QUARK (SIZE), G_TYPE_UINT, 0,
98       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, 0,
99       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, 0,
100       GST_QUARK (PREFIX), G_TYPE_UINT, 0,
101       GST_QUARK (POSTFIX), G_TYPE_UINT, 0,
102       GST_QUARK (ALIGN), G_TYPE_UINT, 1, NULL);
103   pool->poll = gst_poll_new_timer ();
104   pool->queue = gst_atomic_queue_new (10);
105   default_set_active (pool, FALSE);
106
107   GST_DEBUG_OBJECT (pool, "created");
108 }
109
110 static void
111 gst_buffer_pool_finalize (GObject * object)
112 {
113   GstBufferPool *pool;
114
115   pool = GST_BUFFER_POOL_CAST (object);
116
117   GST_DEBUG_OBJECT (pool, "finalize");
118
119   gst_buffer_pool_set_active (pool, FALSE);
120   gst_atomic_queue_unref (pool->queue);
121   gst_poll_free (pool->poll);
122   gst_structure_free (pool->config);
123
124   G_OBJECT_CLASS (gst_buffer_pool_parent_class)->finalize (object);
125 }
126
127 /**
128  * gst_buffer_pool_new:
129  *
130  * Creates a new #GstBufferPool instance.
131  *
132  * Returns: a new #GstBufferPool instance
133  */
134 GstBufferPool *
135 gst_buffer_pool_new (void)
136 {
137   GstBufferPool *result;
138
139   result = g_object_newv (GST_TYPE_BUFFER_POOL, 0, NULL);
140   GST_DEBUG_OBJECT (result, "created new buffer pool");
141
142   return result;
143 }
144
145 static void
146 default_free_buffer (GstBufferPool * pool, GstBuffer * buffer)
147 {
148   gst_buffer_unref (buffer);
149 }
150
151 static void
152 free_buffer (GstBufferPool * pool, GstBuffer * buffer)
153 {
154   GstBufferPoolClass *pclass;
155
156   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
157
158   if (G_LIKELY (pclass->free_buffer))
159     pclass->free_buffer (pool, buffer);
160 }
161
162 /* the default implementation for allocating and freeing the
163  * buffers when changing the active state */
164 static gboolean
165 default_set_active (GstBufferPool * pool, gboolean active)
166 {
167   guint i;
168   GstBufferPoolPrivate *priv = pool->priv;
169
170   if (active) {
171     GstBufferPoolClass *pclass;
172
173     pclass = GST_BUFFER_POOL_GET_CLASS (pool);
174
175     if (G_UNLIKELY (pclass->alloc_buffer == NULL))
176       return TRUE;
177
178     /* we need to prealloc buffers */
179     for (i = priv->min_buffers; i > 0; i--) {
180       GstBuffer *buffer;
181
182       if (pclass->alloc_buffer (pool, &buffer, NULL) != GST_FLOW_OK)
183         return FALSE;
184
185       /* store in the queue */
186       gst_atomic_queue_push (pool->queue, buffer);
187       gst_poll_write_control (pool->poll);
188     }
189   } else {
190     GstBuffer *buffer;
191
192     /* clear the pool */
193     while ((buffer = gst_atomic_queue_pop (pool->queue))) {
194       gst_poll_read_control (pool->poll);
195       free_buffer (pool, buffer);
196     }
197   }
198   return TRUE;
199 }
200
201 /**
202  * gst_buffer_pool_set_active:
203  * @pool: a #GstBufferPool
204  * @active: the new active state
205  *
206  * Control the active state of @pool. When the pool is active, new calls to
207  * gst_buffer_pool_acquire_buffer() will return with GST_FLOW_WRONG_STATE.
208  *
209  * Returns: %FALSE when the pool was not configured or when preallocation of the
210  * buffers failed.
211  */
212 gboolean
213 gst_buffer_pool_set_active (GstBufferPool * pool, gboolean active)
214 {
215   GstBufferPoolClass *pclass;
216   gboolean res;
217
218   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE);
219
220   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
221
222   /* just return if we are already in the right state */
223   if (!g_atomic_int_compare_and_exchange (&pool->active, !active, active))
224     return TRUE;
225
226   /* we need to be configured */
227   if (!g_atomic_int_get (&pool->configured))
228     return FALSE;
229
230   if (!active)
231     gst_poll_write_control (pool->poll);
232
233   if (G_LIKELY (pclass->set_active))
234     res = pclass->set_active (pool, active);
235   else
236     res = TRUE;
237
238   if (active)
239     gst_poll_read_control (pool->poll);
240
241   return res;
242 }
243
244 static gboolean
245 default_set_config (GstBufferPool * pool, GstStructure * config)
246 {
247   GstBufferPoolPrivate *priv = pool->priv;
248
249   /* parse the config and keep around */
250   gst_buffer_pool_config_get (config, &priv->size, &priv->min_buffers,
251       &priv->max_buffers, &priv->prefix, &priv->postfix, &priv->align);
252
253   return TRUE;
254 }
255
256 /**
257  * gst_buffer_pool_set_config:
258  * @pool: a #GstBufferPool
259  * @config: a #GstStructure
260  *
261  * Set the configuration of the pool. The pool must be inactive and all buffers
262  * allocated form this pool must be returned or else this function will do
263  * nothing and return FALSE.
264  *
265  * @condfig is a #GstStructure that contains the configuration parameters for
266  * the pool. A default and mandatory set of parameters can be configured with
267  * gst_buffer_pool_config_set(). This function takes ownership of @config.
268  *
269  * Returns: TRUE when the configuration could be set.
270  */
271 gboolean
272 gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
273 {
274   gboolean result;
275   GstBufferPoolClass *pclass;
276
277   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE);
278   g_return_val_if_fail (config != NULL, FALSE);
279
280   /* can't change the settings when active */
281   if (g_atomic_int_get (&pool->active))
282     return FALSE;
283
284   /* we can't change when outstanding buffers */
285   if (g_atomic_int_get (&pool->outstanding) != 0)
286     return FALSE;
287
288   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
289
290   /* free the buffer when we are inactive */
291   if (G_LIKELY (pclass->set_config))
292     result = pclass->set_config (pool, config);
293   else
294     result = FALSE;
295
296   if (result) {
297     if (pool->config)
298       gst_structure_free (pool->config);
299     pool->config = config;
300
301     /* now we are configured */
302     g_atomic_int_set (&pool->configured, 1);
303   }
304
305   return result;
306 }
307
308 /**
309  * gst_buffer_pool_get_config:
310  * @pool: a #GstBufferPool
311  *
312  * Get the current configuration of the pool. This configuration is read-only,
313  * use gst_structure_copy() to make a writable copy.
314  */
315 const GstStructure *
316 gst_buffer_pool_get_config (GstBufferPool * pool)
317 {
318   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), NULL);
319
320   return pool->config;
321 }
322
323 /**
324  * gst_buffer_pool_config_set:
325  * @pool: a #GstBufferPool
326  * @size: the size of each buffer, not including pre and post fix
327  * @min_buffers: the minimum amount of buffers to allocate.
328  * @max_buffers: the maximum amount of buffers to allocate or 0 for unlimited.
329  * @prefix: prefix each buffer with this many bytes
330  * @postfix: postfix each buffer with this many bytes
331  * @align: alignment of the buffer data.
332  *
333  * Configure @config with the given parameters.
334  */
335 void
336 gst_buffer_pool_config_set (GstStructure * config, guint size,
337     guint min_buffers, guint max_buffers, guint prefix, guint postfix,
338     guint align)
339 {
340   g_return_if_fail (config != NULL);
341
342   gst_structure_id_set (config,
343       GST_QUARK (SIZE), G_TYPE_UINT, size,
344       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
345       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
346       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
347       GST_QUARK (POSTFIX), G_TYPE_UINT, postfix,
348       GST_QUARK (ALIGN), G_TYPE_UINT, align, NULL);
349 }
350
351 /**
352  * gst_buffer_pool_config_get:
353  * @pool: a #GstBufferPool
354  * @size: the size of each buffer, not including pre and post fix
355  * @min_buffers: the minimum amount of buffers to allocate.
356  * @max_buffers: the maximum amount of buffers to allocate or 0 for unlimited.
357  * @prefix: prefix each buffer with this many bytes
358  * @postfix: postfix each buffer with this many bytes
359  * @align: alignment of the buffer data.
360  *
361  * Get the configuration values from @config.
362  */
363 gboolean
364 gst_buffer_pool_config_get (GstStructure * config, guint * size,
365     guint * min_buffers, guint * max_buffers, guint * prefix, guint * postfix,
366     guint * align)
367 {
368   g_return_val_if_fail (config != NULL, FALSE);
369
370   return gst_structure_id_get (config,
371       GST_QUARK (SIZE), G_TYPE_UINT, size,
372       GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
373       GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
374       GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
375       GST_QUARK (POSTFIX), G_TYPE_UINT, postfix,
376       GST_QUARK (ALIGN), G_TYPE_UINT, align, NULL);
377 }
378
379 static GstFlowReturn
380 default_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
381     GstBufferPoolParams * params)
382 {
383   guint size, align;
384   GstBufferPoolPrivate *priv = pool->priv;
385
386   *buffer = gst_buffer_new ();
387
388   align = priv->align - 1;
389   size = priv->prefix + priv->postfix + priv->size + align;
390   if (size > 0) {
391     guint8 *memptr;
392
393     memptr = g_malloc (size);
394     GST_BUFFER_MALLOCDATA (*buffer) = memptr;
395     memptr = (guint8 *) ((guintptr) (memptr + align) & ~align);
396     GST_BUFFER_DATA (*buffer) = memptr + priv->prefix;
397     GST_BUFFER_SIZE (*buffer) = priv->size;
398   }
399
400   return GST_FLOW_OK;
401 }
402
403 static GstFlowReturn
404 default_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
405     GstBufferPoolParams * params)
406 {
407   GstFlowReturn result;
408   GstBufferPoolClass *pclass;
409   GstBufferPoolPrivate *priv = pool->priv;
410
411   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
412
413   while (TRUE) {
414     if (!g_atomic_int_get (&pool->active))
415       return GST_FLOW_WRONG_STATE;
416
417     /* try to get a buffer from the queue */
418     *buffer = gst_atomic_queue_pop (pool->queue);
419     if (*buffer) {
420       gst_poll_read_control (pool->poll);
421       result = GST_FLOW_OK;
422       break;
423     }
424
425     /* no buffer */
426     if (priv->max_buffers == 0) {
427       /* no max_buffers, we allocate some more */
428       if (G_LIKELY (pclass->alloc_buffer)) {
429         result = pclass->alloc_buffer (pool, buffer, params);
430       } else
431         result = GST_FLOW_NOT_SUPPORTED;
432       break;
433     }
434
435     /* check if we need to wait */
436     if (params && !(params->flags & GST_BUFFER_POOL_FLAG_WAIT)) {
437       result = GST_FLOW_UNEXPECTED;
438       break;
439     }
440
441     /* now wait */
442     gst_poll_wait (pool->poll, GST_CLOCK_TIME_NONE);
443   }
444
445   return result;
446 }
447
448 /**
449  * gst_buffer_pool_acquire_buffer:
450  * @pool: a #GstBufferPool
451  * @buffer: a location for a #GstBuffer
452  * @params: parameters.
453  *
454  * Acquire a buffer from @pool. @buffer should point to a memory location that
455  * can hold a pointer to the new buffer.
456  *
457  * @params can be NULL or contain optional parameters to influence the allocation.
458  *
459  * Returns: a #GstFlowReturn such as GST_FLOW_WRONG_STATE when the pool is
460  * inactive.
461  */
462 GstFlowReturn
463 gst_buffer_pool_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
464     GstBufferPoolParams * params)
465 {
466   GstBufferPoolClass *pclass;
467   GstFlowReturn result;
468
469   g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), GST_FLOW_ERROR);
470   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
471
472   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
473
474   if (G_LIKELY (pclass->acquire_buffer))
475     result = pclass->acquire_buffer (pool, buffer, params);
476   else
477     result = GST_FLOW_NOT_SUPPORTED;
478
479   if (G_LIKELY (result == GST_FLOW_OK && *buffer))
480     g_atomic_int_inc (&pool->outstanding);
481
482   return result;
483 }
484
485 static void
486 default_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
487 {
488   if (G_UNLIKELY (!g_atomic_int_get (&pool->active))) {
489     /* we are inactive, remove the buffer again */
490     free_buffer (pool, buffer);
491   } else {
492     /* keep it around in our queue */
493     gst_atomic_queue_push (pool->queue, buffer);
494     gst_poll_write_control (pool->poll);
495   }
496 }
497
498 /**
499  * gst_buffer_pool_release_buffer:
500  * @pool: a #GstBufferPool
501  * @buffer: a #GstBuffer
502  *
503  * Release @buffer to @pool. @buffer should have previously been allocated from
504  * @pool with gst_buffer_pool_acquire_buffer().
505  *
506  * This function is usually called automatically when the last ref on @buffer
507  * disappears.
508  */
509 void
510 gst_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
511 {
512   GstBufferPoolClass *pclass;
513
514   g_return_if_fail (GST_IS_BUFFER_POOL (pool));
515   g_return_if_fail (buffer != NULL);
516
517   pclass = GST_BUFFER_POOL_GET_CLASS (pool);
518
519   if (G_LIKELY (pclass->release_buffer))
520     pclass->release_buffer (pool, buffer);
521
522   g_atomic_int_exchange_and_add (&pool->outstanding, -1);
523 }