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 * @destroy: 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_pool_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
246 * @user_data: any user data to be passed to the create/destroy buffer functions
247 * and the destroy hook
252 gst_buffer_pool_get_user_data (GstBufferPool *pool,
255 g_return_val_if_fail (pool != NULL, NULL);
257 return pool->user_data;
261 * gst_buffer_pool_destroy:
262 * @pool: the pool to destroy
264 * Frees the memory for this bufferpool, calls the destroy hook.
267 gst_buffer_pool_destroy (GstBufferPool *pool)
269 g_return_if_fail (pool != NULL);
271 if (pool->destroy_hook)
272 pool->destroy_hook (pool, pool->user_data);
278 * gst_buffer_pool_get_default:
279 * @buffer_size: the number of bytes this buffer will store
280 * @pool_size: the default number of buffers to be preallocated
282 * Returns an instance of a buffer pool using the default
283 * implementation. If a buffer pool instance with the same buffer_size
284 * already exists this will be returned, otherwise a new instance will
287 * Returns: an instance of GstBufferPool
290 gst_buffer_pool_get_default (guint buffer_size, guint pool_size)
293 GMemChunk *data_chunk;
294 guint real_buffer_size;
295 GstBufferPoolDefault *def;
297 // round up to the nearest 32 bytes for cache-line and other efficiencies
298 real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
300 // check for an existing GstBufferPool with the same real_buffer_size
301 // (we won't worry about the pool_size)
302 g_mutex_lock (_default_pool_lock);
303 pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
304 g_mutex_unlock (_default_pool_lock);
307 gst_buffer_pool_ref(pool);
311 data_chunk = g_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size,
312 real_buffer_size * pool_size, G_ALLOC_AND_FREE);
314 pool = gst_buffer_pool_new();
315 gst_buffer_pool_set_buffer_new_function (pool, gst_buffer_pool_default_buffer_new);
316 gst_buffer_pool_set_buffer_free_function (pool, gst_buffer_pool_default_buffer_free);
317 gst_buffer_pool_set_buffer_copy_function (pool, gst_buffer_copy);
318 gst_buffer_pool_set_destroy_hook (pool, gst_buffer_pool_default_destroy_hook);
320 def = g_new0 (GstBufferPoolDefault, 1);
321 def->size = buffer_size;
322 def->mem_chunk = data_chunk;
323 pool->user_data = def;
325 g_mutex_lock (_default_pool_lock);
326 g_hash_table_insert(_default_pools,GINT_TO_POINTER(real_buffer_size),pool);
327 g_mutex_unlock (_default_pool_lock);
329 GST_DEBUG(GST_CAT_BUFFER,"new buffer pool %p bytes:%d size:%d\n", pool, real_buffer_size, pool_size);
335 gst_buffer_pool_default_buffer_new (GstBufferPool *pool, gint64 location /*unused*/,
336 gint size /*unused*/, gpointer user_data)
339 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
340 GMemChunk *data_chunk = def->mem_chunk;
342 gst_buffer_pool_ref(pool);
343 buffer = gst_buffer_new();
344 GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p",buffer,pool);
346 g_mutex_lock (pool->lock);
347 GST_BUFFER_DATA(buffer) = g_mem_chunk_alloc(data_chunk);
348 g_mutex_unlock (pool->lock);
350 GST_BUFFER_SIZE(buffer) = def->size;
351 GST_BUFFER_MAXSIZE(buffer) = def->size;
357 gst_buffer_pool_default_buffer_free (GstBuffer *buffer)
359 GstBufferPool *pool = buffer->pool;
360 GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->user_data;
361 GMemChunk *data_chunk = def->mem_chunk;
362 gpointer data = GST_BUFFER_DATA(buffer);
364 g_mutex_lock (pool->lock);
365 g_mem_chunk_free (data_chunk,data);
366 g_mutex_unlock (pool->lock);
369 gst_buffer_pool_unref(pool);
373 gst_buffer_pool_default_destroy_hook (GstBufferPool *pool, gpointer user_data)
375 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
376 GMemChunk *data_chunk = def->mem_chunk;
378 GST_DEBUG(GST_CAT_BUFFER,"destroying default buffer pool %p\n", pool);
380 g_mutex_free (pool->lock);
381 g_mem_chunk_reset(data_chunk);