add default bufferpool, clean up some code, add bufferpool testing to fakesrc
[platform/upstream/gstreamer.git] / gst / gstbufferpool-default.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstbufferpool-default.c: Private implementation of the default bufferpool
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include "gstbuffer.h"
24 #include "gstinfo.h"
25 #include "gstmemchunk.h"
26
27
28 /* methods prefixed with underscores to avoid namespace collisions with
29  * gstbuffer.c */
30
31 static GstBuffer*       _gst_buffer_pool_default_buffer_new     (GstBufferPool *pool,
32                                                                  guint64 offset,
33                                                                  guint size,
34                                                                  gpointer user_data);
35 static void             _gst_buffer_pool_default_buffer_free    (GstBufferPool *pool,
36                                                                  GstBuffer *buffer,
37                                                                  gpointer user_data);
38 static void             _gst_buffer_pool_default_free           (GstData *pool);
39
40
41 typedef struct _GstBufferPoolDefault GstBufferPoolDefault;
42
43 struct _GstBufferPoolDefault {
44   GstMemChunk *mem_chunk;
45   guint size;
46 };
47
48
49 static GMutex *_default_pool_lock = NULL;
50 static GHashTable *_default_pools = NULL;
51
52
53 /**
54  * _gst_buffer_pool_get_default:
55  * @buffer_size: the number of bytes this buffer will store
56  * @pool_size: the default number of buffers to be preallocated
57  *
58  * Returns an instance of a buffer pool using the default
59  * implementation.  If a buffer pool instance with the same buffer_size
60  * already exists this will be returned, otherwise a new instance will
61  * be created.
62  * 
63  * Returns: an instance of GstBufferPool
64  */
65 GstBufferPool*
66 _gst_buffer_pool_get_default (guint buffer_size, guint pool_size)
67 {
68   GstBufferPool *pool;
69   GstMemChunk *data_chunk;
70   guint real_buffer_size;
71   GstBufferPoolDefault *def;
72   
73   if (!_default_pool_lock) {
74     _default_pool_lock = g_mutex_new ();
75     _default_pools = g_hash_table_new (NULL, NULL);
76   }
77
78   /* round up to the nearest 32 bytes for cache-line and other efficiencies */
79   real_buffer_size = (((buffer_size-1) / 32) + 1) * 32;
80   
81   /* check for an existing GstBufferPool with the same real_buffer_size */
82   /* (we won't worry about the pool_size) */
83   g_mutex_lock (_default_pool_lock);
84   pool = (GstBufferPool*)g_hash_table_lookup(_default_pools,GINT_TO_POINTER(real_buffer_size));
85   g_mutex_unlock (_default_pool_lock);
86
87   if (pool != NULL){
88     gst_buffer_pool_ref (pool);
89     return pool;
90   }
91   
92   data_chunk = gst_mem_chunk_new ("GstBufferPoolDefault", real_buffer_size, 
93                                   real_buffer_size * pool_size, G_ALLOC_AND_FREE);
94     
95   def = g_new0 (GstBufferPoolDefault, 1);
96   def->size = buffer_size;
97   def->mem_chunk = data_chunk;
98
99   pool = gst_buffer_pool_new (_gst_buffer_pool_default_free,
100                               NULL, /* pool copy */
101                               _gst_buffer_pool_default_buffer_new,
102                               NULL, /* buffer copy */
103                               _gst_buffer_pool_default_buffer_free,
104                               def);
105   
106   g_mutex_lock (_default_pool_lock);
107   g_hash_table_insert (_default_pools, GINT_TO_POINTER (real_buffer_size), pool);
108   g_mutex_unlock (_default_pool_lock);
109   
110   GST_DEBUG (GST_CAT_BUFFER,"new default buffer pool %p bytes:%d size:%d",
111              pool, real_buffer_size, pool_size);
112   
113   return pool;
114 }
115
116 static GstBuffer* 
117 _gst_buffer_pool_default_buffer_new (GstBufferPool *pool, guint64 offset /*unused*/,
118                                     guint size /*unused*/, gpointer user_data)
119 {
120   GstBuffer *buffer;
121   GstBufferPoolDefault *def = (GstBufferPoolDefault*)user_data;
122   GstMemChunk *data_chunk = def->mem_chunk;
123   
124   buffer = gst_buffer_new ();
125   GST_INFO (GST_CAT_BUFFER, "creating new buffer %p from pool %p", buffer, pool);
126   
127   GST_BUFFER_DATA (buffer) = gst_mem_chunk_alloc (data_chunk);
128   
129   GST_BUFFER_SIZE (buffer)    = def->size;
130   GST_BUFFER_MAXSIZE (buffer) = def->size;
131   
132   return buffer;
133 }
134
135 static void
136 _gst_buffer_pool_default_buffer_free (GstBufferPool *pool, GstBuffer *buffer, gpointer user_data)
137 {
138   GstBufferPoolDefault *def = (GstBufferPoolDefault*)user_data;
139   GstMemChunk *data_chunk = def->mem_chunk;
140   gpointer data = GST_BUFFER_DATA (buffer);
141   
142   gst_mem_chunk_free (data_chunk, data);
143
144   GST_BUFFER_DATA (buffer) = NULL;
145
146   gst_buffer_default_free (buffer);
147 }
148
149 static void
150 _gst_buffer_pool_default_free (GstData *data) 
151 {
152   GstBufferPool *pool = (GstBufferPool*) data;
153   GstBufferPoolDefault *def = (GstBufferPoolDefault*) pool->user_data;
154   GstMemChunk *data_chunk = def->mem_chunk;
155   
156   GST_DEBUG (GST_CAT_BUFFER, "destroying default buffer pool %p", pool);
157   
158   /* this is broken right now, FIXME
159      gst_mem_chunk_destroy (data_chunk); */
160   
161   g_free (data_chunk);
162   g_free (def);
163
164   gst_buffer_pool_default_free (pool);
165 }