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.
197 * If this is not set, the default GstBuffer implementation will be used.
200 gst_buffer_pool_set_buffer_copy_function (GstBufferPool *pool,
201 GstBufferCopyFunc copy)
203 g_return_if_fail (pool != NULL);
205 pool->buffer_copy = copy;
209 * gst_buffer_pool_set_pool_destroy_hook:
210 * @pool: the pool to set the destroy hook for
211 * @destroy: the destroy function
213 * Sets the function that will be called before a bufferpool is destroyed.
214 * You can take care of you private_data here.
217 gst_buffer_pool_set_destroy_hook (GstBufferPool *pool,
218 GstBufferPoolDestroyHook destroy)
220 g_return_if_fail (pool != NULL);
222 pool->destroy_hook = destroy;
226 * gst_buffer_pool_set_user_data:
227 * @pool: the pool to set the user data for
228 * @user_data: any user data to be passed to the create/destroy buffer functions
229 * and the destroy hook
231 * You can put your private data here.
234 gst_buffer_pool_set_user_data (GstBufferPool *pool,
237 g_return_if_fail (pool != NULL);
239 pool->user_data = user_data;
243 * gst_buffer_pool_get_user_data:
244 * @pool: the pool to get the user data from
245 * @user_data: any user data to be passed to the create/destroy buffer functions
246 * and the destroy hook
251 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 * gst_buffer_pool_get_default:
278 * @buffer_size: the number of bytes this buffer will store
279 * @pool_size: the default number of buffers to be preallocated
281 * Returns an instance of a buffer pool using the default
282 * implementation. If a buffer pool instance with the same buffer_size
283 * already exists this will be returned, otherwise a new instance will
286 * Returns: an instance of GstBufferPool
289 gst_buffer_pool_get_default (guint buffer_size, guint pool_size)
292 GMemChunk *data_chunk;
293 guint real_buffer_size;
294 GstBufferPoolDefault *def;
296 // round up to the nearest 32 bytes for cache-line and other efficiencies
297 real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
299 // check for an existing GstBufferPool with the same real_buffer_size
300 // (we won't worry about the pool_size)
301 g_mutex_lock (_default_pool_lock);
302 pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
303 g_mutex_unlock (_default_pool_lock);
306 gst_buffer_pool_ref(pool);
310 data_chunk = g_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size,
311 real_buffer_size * pool_size, G_ALLOC_AND_FREE);
313 pool = gst_buffer_pool_new();
314 gst_buffer_pool_set_buffer_new_function (pool, gst_buffer_pool_default_buffer_new);
315 gst_buffer_pool_set_buffer_free_function (pool, gst_buffer_pool_default_buffer_free);
316 gst_buffer_pool_set_destroy_hook (pool, gst_buffer_pool_default_destroy_hook);
318 def = g_new0 (GstBufferPoolDefault, 1);
319 def->size = buffer_size;
320 def->mem_chunk = data_chunk;
321 pool->user_data = def;
323 g_mutex_lock (_default_pool_lock);
324 g_hash_table_insert(_default_pools,GINT_TO_POINTER(real_buffer_size),pool);
325 g_mutex_unlock (_default_pool_lock);
327 GST_DEBUG(GST_CAT_BUFFER,"new buffer pool %p bytes:%d size:%d\n", pool, real_buffer_size, pool_size);
333 gst_buffer_pool_default_buffer_new (GstBufferPool *pool, gint64 location /*unused*/,
334 gint size /*unused*/, gpointer user_data)
337 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
338 GMemChunk *data_chunk = def->mem_chunk;
340 gst_buffer_pool_ref(pool);
341 buffer = gst_buffer_new();
342 GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p",buffer,pool);
344 g_mutex_lock (pool->lock);
345 GST_BUFFER_DATA(buffer) = g_mem_chunk_alloc(data_chunk);
346 g_mutex_unlock (pool->lock);
348 GST_BUFFER_FLAG_SET(buffer,GST_BUFFER_DONTFREE);
349 GST_BUFFER_SIZE(buffer) = def->size;
350 GST_BUFFER_MAXSIZE(buffer) = def->size;
356 gst_buffer_pool_default_buffer_free (GstBuffer *buffer)
358 GstBufferPool *pool = buffer->pool;
359 GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->user_data;
360 GMemChunk *data_chunk = def->mem_chunk;
361 gpointer data = GST_BUFFER_DATA(buffer);
363 g_mutex_lock (pool->lock);
364 g_mem_chunk_free (data_chunk,data);
365 g_mutex_unlock (pool->lock);
368 gst_buffer_pool_unref(pool);
372 gst_buffer_pool_default_destroy_hook (GstBufferPool *pool, gpointer user_data)
374 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
375 GMemChunk *data_chunk = def->mem_chunk;
377 GST_DEBUG(GST_CAT_BUFFER,"destroying default buffer pool %p\n", pool);
379 g_mutex_free (pool->lock);
380 g_mem_chunk_reset(data_chunk);