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_create (GstBufferPool *pool, guint64 location, gint size, gpointer user_data);
32 static void gst_buffer_pool_default_buffer_destroy (GstBufferPool *pool, GstBuffer *buffer, gpointer user_data);
33 static void gst_buffer_pool_default_pool_destroy_hook (GstBufferPool *pool, gpointer user_data);
35 typedef struct _GstBufferPoolDefault GstBufferPoolDefault;
37 struct _GstBufferPoolDefault {
42 _gst_buffer_pool_initialize (void)
44 _default_pools = g_hash_table_new(NULL,NULL);
45 _default_pool_lock = g_mutex_new ();
49 * gst_buffer_pool_new:
51 * Create a new buffer pool.
53 * Returns: new buffer pool
56 gst_buffer_pool_new (void)
60 pool = g_new0 (GstBufferPool, 1);
61 GST_DEBUG (GST_CAT_BUFFER,"allocating new buffer pool %p\n", pool);
63 /* all hooks and user data set to NULL or 0 by g_new0 */
65 pool->lock = g_mutex_new ();
67 atomic_set (&pool->refcount, 1);
76 * gst_buffer_pool_ref:
77 * @pool: the GstBufferPool to reference
79 * Increment the refcount of this buffer pool.
82 gst_buffer_pool_ref (GstBufferPool *pool)
84 g_return_if_fail (pool != NULL);
86 GST_DEBUG(GST_CAT_BUFFER,"referencing buffer pool %p from %d\n", pool, GST_BUFFER_POOL_REFCOUNT(pool));
89 atomic_inc (&(pool->refcount));
91 g_return_if_fail (pool->refcount > 0);
92 GST_BUFFER_POOL_LOCK (pool);
94 GST_BUFFER_POOL_UNLOCK (pool);
99 * gst_buffer_pool_ref_by_count:
100 * @pool: the GstBufferPool to reference
103 * Increment the refcount of this buffer pool by the given number.
106 gst_buffer_pool_ref_by_count (GstBufferPool *pool, int count)
108 g_return_if_fail (pool != NULL);
109 g_return_if_fail (count > 0);
112 g_return_if_fail (atomic_read (&(pool->refcount)) > 0);
113 atomic_add (count, &(pool->refcount));
115 g_return_if_fail (pool->refcount > 0);
116 GST_BUFFER_POOL_LOCK (pool);
117 pool->refcount += count;
118 GST_BUFFER_POOL_UNLOCK (pool);
123 * gst_buffer_pool_unref:
124 * @pool: the GstBufferPool to unref
126 * Decrement the refcount of this buffer pool. If the refcount is
127 * zero and the pool is a default implementation,
128 * the buffer pool will be destroyed.
131 gst_buffer_pool_unref (GstBufferPool *pool)
135 g_return_if_fail (pool != NULL);
137 GST_DEBUG(GST_CAT_BUFFER, "unreferencing buffer pool %p from %d\n", pool, GST_BUFFER_POOL_REFCOUNT(pool));
140 g_return_if_fail (atomic_read (&(pool->refcount)) > 0);
141 zero = atomic_dec_and_test (&(pool->refcount));
143 g_return_if_fail (pool->refcount > 0);
144 GST_BUFFER_POOL_LOCK (pool);
146 zero = (pool->refcount == 0);
147 GST_BUFFER_POOL_UNLOCK (pool);
150 /* if we ended up with the refcount at zero, destroy the buffer pool*/
152 gst_buffer_pool_destroy (pool);
157 * gst_buffer_pool_set_buffer_create_function:
158 * @pool: the pool to set the buffer create function for
159 * @create: the create function
160 * @user_data: any user data to be passed in the create function
162 * Sets the function that will be called when a buffer is created
166 gst_buffer_pool_set_buffer_create_function (GstBufferPool *pool,
167 GstBufferPoolBufferCreateFunction create,
170 g_return_if_fail (pool != NULL);
172 pool->new_buffer = create;
173 pool->new_buffer_user_data = user_data;
177 * gst_buffer_pool_set_buffer_destroy_function:
178 * @pool: the pool to set the buffer destroy function for
179 * @destroy: the destroy function
180 * @user_data: any user data to be passed to the destroy function
182 * Sets the function that will be called when a buffer is destroyed
186 gst_buffer_pool_set_buffer_destroy_function (GstBufferPool *pool,
187 GstBufferPoolBufferDestroyFunction destroy,
190 g_return_if_fail (pool != NULL);
192 pool->destroy_buffer = destroy;
193 pool->destroy_buffer_user_data = user_data;
197 * gst_buffer_pool_set_pool_destroy_hook:
198 * @pool: the pool to set the destroy hook for
199 * @destroy: the destroy function
200 * @user_data: any user data to be passed to the destroy hook
202 * Sets the function that will be called before a bufferpool is destroyed.
203 * You can take care of you private_data here.
206 gst_buffer_pool_set_pool_destroy_hook (GstBufferPool *pool,
207 GstBufferPoolPoolDestroyHook destroy,
210 g_return_if_fail (pool != NULL);
212 pool->destroy_pool_hook = destroy;
213 pool->destroy_pool_user_data = user_data;
217 * gst_buffer_pool_destroy:
218 * @pool: the pool to destroy
220 * Frees the memory for this bufferpool, calls the destroy hook.
223 gst_buffer_pool_destroy (GstBufferPool *pool)
225 g_return_if_fail (pool != NULL);
227 if (pool->destroy_pool_hook)
228 pool->destroy_pool_hook (pool, pool->destroy_pool_user_data);
234 * gst_buffer_pool_get_default:
235 * @oldpool: instance of GstBufferPool which is no longer required (or NULL if it doesn't exist)
236 * @buffer_size: the number of bytes this buffer will store
237 * @pool_size: the default number of buffers to be preallocated
239 * Returns an instance of a buffer pool using the default
240 * implementation. If a buffer pool instance with the same buffer_size
241 * already exists this will be returned, otherwise a new instance will
244 * Returns: an instance of GstBufferPool
247 gst_buffer_pool_get_default (GstBufferPool *oldpool, guint buffer_size, guint pool_size)
250 GMemChunk *data_chunk;
251 guint real_buffer_size;
252 GstBufferPoolDefault *def;
254 // round up to the nearest 32 bytes for cache-line and other efficiencies
255 real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
257 // check for an existing GstBufferPool with the same real_buffer_size
258 // (we won't worry about the pool_size)
259 g_mutex_lock (_default_pool_lock);
260 pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
261 g_mutex_unlock (_default_pool_lock);
264 if (oldpool != pool){
265 gst_buffer_pool_ref(pool);
267 if (oldpool != NULL){
268 gst_buffer_pool_unref(oldpool);
275 data_chunk = g_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size,
276 real_buffer_size * pool_size, G_ALLOC_AND_FREE);
278 pool = gst_buffer_pool_new();
279 gst_buffer_pool_set_buffer_create_function (pool, gst_buffer_pool_default_buffer_create, data_chunk);
280 gst_buffer_pool_set_buffer_destroy_function (pool, gst_buffer_pool_default_buffer_destroy, data_chunk);
281 gst_buffer_pool_set_pool_destroy_hook (pool, gst_buffer_pool_default_pool_destroy_hook, data_chunk);
283 def = g_new0 (GstBufferPoolDefault, 1);
284 def->size = buffer_size;
285 pool->private_data = def;
287 g_mutex_lock (_default_pool_lock);
288 g_hash_table_insert(_default_pools,GINT_TO_POINTER(real_buffer_size),pool);
289 g_mutex_unlock (_default_pool_lock);
291 GST_DEBUG(GST_CAT_BUFFER,"new buffer pool %p bytes:%d size:%d\n", pool, real_buffer_size, pool_size);
293 if (oldpool != NULL){
294 gst_buffer_pool_unref(oldpool);
300 gst_buffer_pool_default_buffer_create (GstBufferPool *pool, guint64 location /*unused*/,
301 gint size /*unused*/, gpointer user_data)
303 GMemChunk *data_chunk = (GMemChunk*)user_data;
305 GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->private_data;
307 gst_buffer_pool_ref(pool);
308 buffer = gst_buffer_new();
309 GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p",buffer,pool);
311 g_mutex_lock (pool->lock);
312 GST_BUFFER_DATA(buffer) = g_mem_chunk_alloc(data_chunk);
313 g_mutex_unlock (pool->lock);
315 GST_BUFFER_FLAG_SET(buffer,GST_BUFFER_DONTFREE);
316 GST_BUFFER_SIZE(buffer) = def->size;
317 GST_BUFFER_MAXSIZE(buffer) = def->size;
323 gst_buffer_pool_default_buffer_destroy (GstBufferPool *pool, GstBuffer *buffer, gpointer user_data)
325 GMemChunk *data_chunk = (GMemChunk*)user_data;
326 gpointer data = GST_BUFFER_DATA(buffer);
328 g_mutex_lock (pool->lock);
329 g_mem_chunk_free (data_chunk,data);
330 g_mutex_unlock (pool->lock);
333 gst_buffer_pool_unref(pool);
334 gst_buffer_destroy (buffer);
338 gst_buffer_pool_default_pool_destroy_hook (GstBufferPool *pool, gpointer user_data)
340 GMemChunk *data_chunk = (GMemChunk*)user_data;
342 GST_DEBUG(GST_CAT_BUFFER,"destroying default buffer pool %p\n", pool);
344 if (pool->private_data)
345 g_free (pool->private_data);
347 g_mem_chunk_reset(data_chunk);