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_destroy_function:
176 * @pool: the pool to set the buffer destroy function for
177 * @destroy: the destroy function
179 * Sets the function that will be called when a buffer is destroyed
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_pool_destroy_hook:
193 * @pool: the pool to set the destroy hook for
194 * @destroy: the destroy function
196 * Sets the function that will be called before a bufferpool is destroyed.
197 * You can take care of you private_data here.
200 gst_buffer_pool_set_pool_destroy_hook (GstBufferPool *pool,
201 GstBufferPoolDestroyHook destroy)
203 g_return_if_fail (pool != NULL);
205 pool->destroy_hook = destroy;
209 * gst_buffer_pool_set_user_data:
210 * @pool: the pool to set the user data for
211 * @user_data: any user data to be passed to the create/destroy buffer functions
212 * and the destroy hook
214 * You can put your private data here.
217 gst_buffer_pool_set_user_data (GstBufferPool *pool,
220 g_return_if_fail (pool != NULL);
222 pool->user_data = user_data;
226 * gst_buffer_pool_get_user_data:
227 * @pool: the pool to get the user data from
228 * @user_data: any user data to be passed to the create/destroy buffer functions
229 * and the destroy hook
234 gst_buffer_pool_get_user_data (GstBufferPool *pool,
237 g_return_val_if_fail (pool != NULL, NULL);
239 return pool->user_data;
243 * gst_buffer_pool_destroy:
244 * @pool: the pool to destroy
246 * Frees the memory for this bufferpool, calls the destroy hook.
249 gst_buffer_pool_destroy (GstBufferPool *pool)
251 g_return_if_fail (pool != NULL);
253 if (pool->destroy_hook)
254 pool->destroy_hook (pool, pool->user_data);
260 * gst_buffer_pool_get_default:
261 * @buffer_size: the number of bytes this buffer will store
262 * @pool_size: the default number of buffers to be preallocated
264 * Returns an instance of a buffer pool using the default
265 * implementation. If a buffer pool instance with the same buffer_size
266 * already exists this will be returned, otherwise a new instance will
269 * Returns: an instance of GstBufferPool
272 gst_buffer_pool_get_default (guint buffer_size, guint pool_size)
275 GMemChunk *data_chunk;
276 guint real_buffer_size;
277 GstBufferPoolDefault *def;
279 // round up to the nearest 32 bytes for cache-line and other efficiencies
280 real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
282 // check for an existing GstBufferPool with the same real_buffer_size
283 // (we won't worry about the pool_size)
284 g_mutex_lock (_default_pool_lock);
285 pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
286 g_mutex_unlock (_default_pool_lock);
289 gst_buffer_pool_ref(pool);
293 data_chunk = g_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size,
294 real_buffer_size * pool_size, G_ALLOC_AND_FREE);
296 pool = gst_buffer_pool_new();
297 gst_buffer_pool_set_buffer_new_function (pool, gst_buffer_pool_default_buffer_new);
298 gst_buffer_pool_set_buffer_free_function (pool, gst_buffer_pool_default_buffer_free);
299 gst_buffer_pool_set_destroy_hook (pool, gst_buffer_pool_default_destroy_hook);
301 def = g_new0 (GstBufferPoolDefault, 1);
302 def->size = buffer_size;
303 def->mem_chunk = data_chunk;
304 pool->user_data = def;
306 g_mutex_lock (_default_pool_lock);
307 g_hash_table_insert(_default_pools,GINT_TO_POINTER(real_buffer_size),pool);
308 g_mutex_unlock (_default_pool_lock);
310 GST_DEBUG(GST_CAT_BUFFER,"new buffer pool %p bytes:%d size:%d\n", pool, real_buffer_size, pool_size);
316 gst_buffer_pool_default_buffer_new (GstBufferPool *pool, gint64 location /*unused*/,
317 gint size /*unused*/, gpointer user_data)
320 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
321 GMemChunk *data_chunk = def->mem_chunk;
323 gst_buffer_pool_ref(pool);
324 buffer = gst_buffer_new();
325 GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p",buffer,pool);
327 g_mutex_lock (pool->lock);
328 GST_BUFFER_DATA(buffer) = g_mem_chunk_alloc(data_chunk);
329 g_mutex_unlock (pool->lock);
331 GST_BUFFER_FLAG_SET(buffer,GST_BUFFER_DONTFREE);
332 GST_BUFFER_SIZE(buffer) = def->size;
333 GST_BUFFER_MAXSIZE(buffer) = def->size;
339 gst_buffer_pool_default_buffer_free (GstBuffer *buffer)
341 GstBufferPool *pool = buffer->pool;
342 GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->user_data;
343 GMemChunk *data_chunk = def->mem_chunk;
344 gpointer data = GST_BUFFER_DATA(buffer);
346 g_mutex_lock (pool->lock);
347 g_mem_chunk_free (data_chunk,data);
348 g_mutex_unlock (pool->lock);
351 gst_buffer_pool_unref(pool);
355 gst_buffer_pool_default_destroy_hook (GstBufferPool *pool, gpointer user_data)
357 GstBufferPoolDefault *def = (GstBufferPoolDefault*) user_data;
358 GMemChunk *data_chunk = def->mem_chunk;
360 GST_DEBUG(GST_CAT_BUFFER,"destroying default buffer pool %p\n", pool);
362 g_mutex_free (pool->lock);
363 g_mem_chunk_reset(data_chunk);