2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstbufferpool.c: Buffer-pool operations
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.
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.
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.
24 #include "gst_private.h"
26 #include "gstbuffer.h"
28 static GMutex *_default_pool_lock;
29 static GHashTable *_default_pools;
31 static GstBuffer* gst_buffer_pool_default_buffer_new (GstBufferPool *pool, gint64 location, gint size, gpointer user_data);
32 static void gst_buffer_pool_default_buffer_free (GstBuffer *buffer);
33 static void gst_buffer_pool_default_destroy_hook (GstBufferPool *pool, gpointer user_data);
35 typedef struct _GstBufferPoolDefault GstBufferPoolDefault;
37 struct _GstBufferPoolDefault {
43 _gst_buffer_pool_initialize (void)
45 _default_pools = g_hash_table_new(NULL,NULL);
46 _default_pool_lock = g_mutex_new ();
50 * gst_buffer_pool_new:
52 * Create a new buffer pool.
54 * Returns: new buffer pool
57 gst_buffer_pool_new (void)
61 pool = g_new0 (GstBufferPool, 1);
62 GST_DEBUG (GST_CAT_BUFFER,"allocating new buffer pool %p\n", pool);
64 /* all hooks and user data set to NULL or 0 by g_new0 */
66 pool->lock = g_mutex_new ();
68 atomic_set (&pool->refcount, 1);
77 * gst_buffer_pool_ref:
78 * @pool: the GstBufferPool to reference
80 * Increment the refcount of this buffer pool.
83 gst_buffer_pool_ref (GstBufferPool *pool)
85 g_return_if_fail (pool != NULL);
87 GST_DEBUG(GST_CAT_BUFFER,"referencing buffer pool %p from %d\n", pool, GST_BUFFER_POOL_REFCOUNT(pool));
90 atomic_inc (&(pool->refcount));
92 g_return_if_fail (pool->refcount > 0);
93 GST_BUFFER_POOL_LOCK (pool);
95 GST_BUFFER_POOL_UNLOCK (pool);
100 * gst_buffer_pool_ref_by_count:
101 * @pool: the GstBufferPool to reference
104 * Increment the refcount of this buffer pool by the given number.
107 gst_buffer_pool_ref_by_count (GstBufferPool *pool, int count)
109 g_return_if_fail (pool != NULL);
110 g_return_if_fail (count >= 0);
113 g_return_if_fail (atomic_read (&(pool->refcount)) > 0);
114 atomic_add (count, &(pool->refcount));
116 g_return_if_fail (pool->refcount > 0);
117 GST_BUFFER_POOL_LOCK (pool);
118 pool->refcount += count;
119 GST_BUFFER_POOL_UNLOCK (pool);
124 * gst_buffer_pool_unref:
125 * @pool: the GstBufferPool to unref
127 * Decrement the refcount of this buffer pool. If the refcount is
128 * zero and the pool is a default implementation,
129 * the buffer pool will be destroyed.
132 gst_buffer_pool_unref (GstBufferPool *pool)
136 g_return_if_fail (pool != NULL);
138 GST_DEBUG(GST_CAT_BUFFER, "unreferencing buffer pool %p from %d\n", pool, GST_BUFFER_POOL_REFCOUNT(pool));
141 g_return_if_fail (atomic_read (&(pool->refcount)) > 0);
142 zero = atomic_dec_and_test (&(pool->refcount));
144 g_return_if_fail (pool->refcount > 0);
145 GST_BUFFER_POOL_LOCK (pool);
147 zero = (pool->refcount == 0);
148 GST_BUFFER_POOL_UNLOCK (pool);
151 /* if we ended up with the refcount at zero, destroy the buffer pool*/
153 gst_buffer_pool_destroy (pool);
158 * gst_buffer_pool_set_buffer_new_function:
159 * @pool: the pool to set the buffer create function for
160 * @create: the create function
162 * Sets the function that will be called when a buffer is created
166 gst_buffer_pool_set_buffer_new_function (GstBufferPool *pool,
167 GstBufferPoolBufferNewFunction create)
169 g_return_if_fail (pool != NULL);
171 pool->buffer_new = create;
175 * gst_buffer_pool_set_buffer_free_function:
176 * @pool: the pool to set the buffer free function for
177 * @destroy: the free function
179 * Sets the function that will be called when a buffer is freed
183 gst_buffer_pool_set_buffer_free_function (GstBufferPool *pool,
184 GstBufferFreeFunc destroy)
186 g_return_if_fail (pool != NULL);
188 pool->buffer_free = destroy;
192 * gst_buffer_pool_set_buffer_copy_function:
193 * @pool: the pool to set the buffer copy function for
194 * @copy: the copy function
196 * Sets the function that will be called when a buffer is copied.
198 * You may use the default GstBuffer implementation (gst_buffer_copy).
201 gst_buffer_pool_set_buffer_copy_function (GstBufferPool *pool,
202 GstBufferCopyFunc copy)
204 g_return_if_fail (pool != NULL);
206 pool->buffer_copy = copy;
210 * gst_buffer_pool_set_destroy_hook:
211 * @pool: the pool to set the destroy hook for
212 * @destroy: the destroy function
214 * Sets the function that will be called before a bufferpool is destroyed.
215 * You can take care of you private_data here.
218 gst_buffer_pool_set_destroy_hook (GstBufferPool *pool,
219 GstBufferPoolDestroyHook destroy)
221 g_return_if_fail (pool != NULL);
223 pool->destroy_hook = destroy;
227 * gst_buffer_pool_set_user_data:
228 * @pool: the pool to set the user data for
229 * @user_data: any user data to be passed to the create/destroy buffer functions
230 * and the destroy hook
232 * You can put your private data here.
235 gst_buffer_pool_set_user_data (GstBufferPool *pool,
238 g_return_if_fail (pool != NULL);
240 pool->user_data = user_data;
244 * gst_buffer_pool_get_user_data:
245 * @pool: the pool to get the user data from
249 * Returns: The user data of this bufferpool
252 gst_buffer_pool_get_user_data (GstBufferPool *pool)
254 g_return_val_if_fail (pool != NULL, NULL);
256 return pool->user_data;
260 * gst_buffer_pool_destroy:
261 * @pool: the pool to destroy
263 * Frees the memory for this bufferpool, calls the destroy hook.
266 gst_buffer_pool_destroy (GstBufferPool *pool)
268 g_return_if_fail (pool != NULL);
270 if (pool->destroy_hook)
271 pool->destroy_hook (pool, pool->user_data);
277 * This is so we don't get messed up by GST_BUFFER_WHERE.
280 _pool_gst_buffer_copy (GstBuffer *buffer)
281 { return gst_buffer_copy (buffer); }
284 * gst_buffer_pool_get_default:
285 * @buffer_size: the number of bytes this buffer will store
286 * @pool_size: the default number of buffers to be preallocated
288 * Returns an instance of a buffer pool using the default
289 * implementation. If a buffer pool instance with the same buffer_size
290 * already exists this will be returned, otherwise a new instance will
293 * Returns: an instance of GstBufferPool
296 gst_buffer_pool_get_default (guint buffer_size, guint pool_size)
299 GMemChunk *data_chunk;
300 guint real_buffer_size;
301 GstBufferPoolDefault *def;
303 /* round up to the nearest 32 bytes for cache-line and other efficiencies */
304 real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
306 /* check for an existing GstBufferPool with the same real_buffer_size */
307 /* (we won't worry about the pool_size) */
308 g_mutex_lock (_default_pool_lock);
309 pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
310 g_mutex_unlock (_default_pool_lock);
313 gst_buffer_pool_ref(pool);
317 data_chunk = g_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size,
318 real_buffer_size * pool_size, G_ALLOC_AND_FREE);
320 pool = gst_buffer_pool_new();
321 gst_buffer_pool_set_buffer_new_function (pool, gst_buffer_pool_default_buffer_new);
322 gst_buffer_pool_set_buffer_free_function (pool, gst_buffer_pool_default_buffer_free);
323 gst_buffer_pool_set_buffer_copy_function (pool, _pool_gst_buffer_copy);
324 gst_buffer_pool_set_destroy_hook (pool, gst_buffer_pool_default_destroy_hook);
326 def = g_new0 (GstBufferPoolDefault, 1);
327 def->size = buffer_size;
328 def->mem_chunk = data_chunk;
329 pool->user_data = def;
331 g_mutex_lock (_default_pool_lock);
332 g_hash_table_insert(_default_pools,GINT_TO_POINTER(real_buffer_size),pool);
333 g_mutex_unlock (_default_pool_lock);
335 GST_DEBUG(GST_CAT_BUFFER,"new buffer pool %p bytes:%d size:%d\n", pool, real_buffer_size, pool_size);
341 gst_buffer_pool_default_buffer_new (GstBufferPool *pool, gint64 location /*unused*/,
342 gint size /*unused*/, gpointer user_data)
345 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
346 GMemChunk *data_chunk = def->mem_chunk;
348 gst_buffer_pool_ref(pool);
349 buffer = gst_buffer_new();
350 GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p",buffer,pool);
352 g_mutex_lock (pool->lock);
353 GST_BUFFER_DATA(buffer) = g_mem_chunk_alloc(data_chunk);
354 g_mutex_unlock (pool->lock);
356 GST_BUFFER_SIZE(buffer) = def->size;
357 GST_BUFFER_MAXSIZE(buffer) = def->size;
363 gst_buffer_pool_default_buffer_free (GstBuffer *buffer)
365 GstBufferPool *pool = buffer->pool;
366 GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->user_data;
367 GMemChunk *data_chunk = def->mem_chunk;
368 gpointer data = GST_BUFFER_DATA(buffer);
370 g_mutex_lock (pool->lock);
371 g_mem_chunk_free (data_chunk,data);
372 g_mutex_unlock (pool->lock);
375 gst_buffer_pool_unref(pool);
379 gst_buffer_pool_default_destroy_hook (GstBufferPool *pool, gpointer user_data)
381 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
382 GMemChunk *data_chunk = def->mem_chunk;
384 GST_DEBUG(GST_CAT_BUFFER,"destroying default buffer pool %p\n", pool);
386 g_mutex_free (pool->lock);
387 g_mem_chunk_reset(data_chunk);