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;
253 // round up to the nearest 32 bytes for cache-line and other efficiencies
254 real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
256 // check for an existing GstBufferPool with the same real_buffer_size
257 // (we won't worry about the pool_size)
258 g_mutex_lock (_default_pool_lock);
259 pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
260 g_mutex_unlock (_default_pool_lock);
263 if (oldpool != pool){
264 gst_buffer_pool_ref(pool);
266 if (oldpool != NULL){
267 gst_buffer_pool_unref(oldpool);
274 data_chunk = g_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size,
275 real_buffer_size * pool_size, G_ALLOC_AND_FREE);
277 pool = gst_buffer_pool_new();
278 gst_buffer_pool_set_buffer_create_function (pool, gst_buffer_pool_default_buffer_create, data_chunk);
279 gst_buffer_pool_set_buffer_destroy_function (pool, gst_buffer_pool_default_buffer_destroy, data_chunk);
280 gst_buffer_pool_set_pool_destroy_hook (pool, gst_buffer_pool_default_pool_destroy_hook, data_chunk);
282 g_mutex_lock (_default_pool_lock);
283 g_hash_table_insert(_default_pools,GINT_TO_POINTER(real_buffer_size),pool);
284 g_mutex_unlock (_default_pool_lock);
286 GST_DEBUG(GST_CAT_BUFFER,"new buffer pool %p bytes:%d size:%d\n", pool, real_buffer_size, pool_size);
288 if (oldpool != NULL){
289 gst_buffer_pool_unref(oldpool);
295 gst_buffer_pool_default_buffer_create (GstBufferPool *pool, guint64 location /*unused*/,
296 gint size /*unused*/, gpointer user_data)
298 GMemChunk *data_chunk = (GMemChunk*)user_data;
301 gst_buffer_pool_ref(pool);
302 buffer = gst_buffer_new();
303 GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p",buffer,pool);
304 GST_BUFFER_FLAG_SET(buffer,GST_BUFFER_DONTFREE);
306 g_mutex_lock (pool->lock);
307 GST_BUFFER_DATA(buffer) = g_mem_chunk_alloc(data_chunk);
308 g_mutex_unlock (pool->lock);
314 gst_buffer_pool_default_buffer_destroy (GstBufferPool *pool, GstBuffer *buffer, gpointer user_data)
316 GMemChunk *data_chunk = (GMemChunk*)user_data;
317 gpointer data = GST_BUFFER_DATA(buffer);
319 g_mutex_lock (pool->lock);
320 g_mem_chunk_free (data_chunk,data);
321 g_mutex_unlock (pool->lock);
324 gst_buffer_pool_unref(pool);
325 gst_buffer_destroy (buffer);
329 gst_buffer_pool_default_pool_destroy_hook (GstBufferPool *pool, gpointer user_data)
331 GMemChunk *data_chunk = (GMemChunk*)user_data;
333 GST_DEBUG(GST_CAT_BUFFER,"destroying default buffer pool %p\n", pool);
334 g_mem_chunk_reset(data_chunk);