]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - libs/gst/bytestream/adapter.c
ignore more
[glsdk/gstreamer0-10.git] / libs / gst / bytestream / adapter.c
1 /* GStreamer
2  * Copyright (C) 2004 Benjamin Otte <otte@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
20 #include "adapter.h"
21 #include <string.h>
23 /* default size for the assembled data buffer */
24 #define DEFAULT_SIZE 16
26 GST_DEBUG_CATEGORY_STATIC (gst_adapter_debug);
27 #define GST_CAT_DEFAULT gst_adapter_debug
29 #define _do_init(thing) \
30   GST_DEBUG_CATEGORY_INIT (gst_adapter_debug, "GstAdapter", 0, "object to splice and merge buffers to desired size")
31 GST_BOILERPLATE_FULL (GstAdapter, gst_adapter, GObject, G_TYPE_OBJECT, _do_init)
33      static void gst_adapter_dispose (GObject * object);
34      static void gst_adapter_finalize (GObject * object);
36      static void gst_adapter_base_init (gpointer g_class)
37 {
38 }
40 static void
41 gst_adapter_class_init (GstAdapterClass * klass)
42 {
43   GObjectClass *object = G_OBJECT_CLASS (klass);
45   object->dispose = gst_adapter_dispose;
46   object->finalize = gst_adapter_finalize;
47 }
49 static void
50 gst_adapter_init (GstAdapter * adapter)
51 {
52   adapter->assembled_data = g_malloc (DEFAULT_SIZE);
53   adapter->assembled_size = DEFAULT_SIZE;
54 }
56 static void
57 gst_adapter_dispose (GObject * object)
58 {
59   GstAdapter *adapter = GST_ADAPTER (object);
61   gst_adapter_clear (adapter);
63   GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
64 }
66 static void
67 gst_adapter_finalize (GObject * object)
68 {
69   GstAdapter *adapter = GST_ADAPTER (object);
71   g_free (adapter->assembled_data);
73   GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
74 }
76 /**
77  * gst_adapter_new:
78  *
79  * Creates a new #GstAdapter.
80  *
81  * Returns: a new #GstAdapter
82  */
83 GstAdapter *
84 gst_adapter_new (void)
85 {
86   return g_object_new (GST_TYPE_ADAPTER, NULL);
87 }
89 /**
90  * gst_adapter_clear:
91  * @adapter: the #GstAdapter to clear
92  *
93  * Removes all buffers from the @adapter.
94  */
95 void
96 gst_adapter_clear (GstAdapter * adapter)
97 {
98   g_return_if_fail (GST_IS_ADAPTER (adapter));
100   g_slist_foreach (adapter->buflist, (GFunc) gst_data_unref, NULL);
101   g_slist_free (adapter->buflist);
102   adapter->buflist = NULL;
103   adapter->size = 0;
104   adapter->skip = 0;
105   adapter->assembled_len = 0;
108 /**
109  * gst_adapter_push:
110  * @adapter: a #GstAdapter
111  * @buf: the #GstBuffer to queue into the adapter
112  *
113  * Adds the data from @buf to the data stored inside @adapter and takes 
114  * ownership of the buffer.
115  */
116 void
117 gst_adapter_push (GstAdapter * adapter, GstBuffer * buf)
119   g_return_if_fail (GST_IS_ADAPTER (adapter));
120   g_return_if_fail (GST_IS_BUFFER (buf));
122   adapter->size += GST_BUFFER_SIZE (buf);
123   adapter->buflist = g_slist_append (adapter->buflist, buf);
126 /**
127  * gst_adapter_peek:
128  * @adapter: a #GstAdapter
129  * @size: number of bytes to peek
130  *
131  * Gets the first @size bytes stored in the @adapter. If this many bytes are
132  * not available, it returns NULL. The returned pointer is valid until the next
133  * function is called on the adapter.
134  *
135  * Returns: a pointer to the first @size bytes of data or NULL
136  */
137 const guint8 *
138 gst_adapter_peek (GstAdapter * adapter, guint size)
140   GstBuffer *cur;
141   GSList *cur_list;
142   guint copied;
144   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
145   g_return_val_if_fail (size > 0, NULL);
147   if (size > adapter->size)
148     return NULL;
150   if (adapter->assembled_len >= size)
151     return adapter->assembled_data;
153   cur = adapter->buflist->data;
154   if (GST_BUFFER_SIZE (cur) >= size + adapter->skip)
155     return GST_BUFFER_DATA (cur) + adapter->skip;
157   if (adapter->assembled_size < size) {
158     adapter->assembled_size = (size / DEFAULT_SIZE + 1) * DEFAULT_SIZE;
159     GST_DEBUG_OBJECT (adapter, "setting size of internal buffer to %u\n",
160         adapter->assembled_size);
161     adapter->assembled_data =
162         g_realloc (adapter->assembled_data, adapter->assembled_size);
163   }
164   adapter->assembled_len = size;
165   copied = GST_BUFFER_SIZE (cur) - adapter->skip;
166   memcpy (adapter->assembled_data, GST_BUFFER_DATA (cur) + adapter->skip,
167       copied);
168   cur_list = g_slist_next (adapter->buflist);
169   while (copied < size) {
170     g_assert (cur_list);
171     cur = cur_list->data;
172     cur_list = g_slist_next (cur_list);
173     memcpy (adapter->assembled_data + copied, GST_BUFFER_DATA (cur),
174         MIN (GST_BUFFER_SIZE (cur), size - copied));
175     copied = MIN (size, copied + GST_BUFFER_SIZE (cur));
176   }
178   return adapter->assembled_data;
181 /**
182  * gst_adapter_flush:
183  * @adapter: a #GstAdapter
184  * @flush: number of bytes to flush
185  *
186  * Flushes the first @flush bytes of the @adapter.
187  */
188 void
189 gst_adapter_flush (GstAdapter * adapter, guint flush)
191   GstBuffer *cur;
193   g_return_if_fail (GST_IS_ADAPTER (adapter));
194   g_return_if_fail (flush > 0);
195   g_return_if_fail (flush <= adapter->size);
197   GST_LOG_OBJECT (adapter, "flushing %u bytes\n", flush);
198   adapter->size -= flush;
199   adapter->assembled_len = 0;
200   while (flush > 0) {
201     cur = adapter->buflist->data;
202     if (GST_BUFFER_SIZE (cur) <= flush + adapter->skip) {
203       /* can skip whole buffer */
204       flush -= GST_BUFFER_SIZE (cur) - adapter->skip;
205       adapter->skip = 0;
206       adapter->buflist = g_slist_remove (adapter->buflist, cur);
207       gst_data_unref (GST_DATA (cur));
208     } else {
209       adapter->skip += flush;
210       break;
211     }
212   }
215 /**
216  * gst_adapter_available:
217  * @adapter: a #GstAdapter
218  *
219  * Gets the maximum amount of bytes available, that is it returns the maximum 
220  * value that can be supplied to gst_adapter_peek() without that function 
221  * returning NULL.
222  *
223  * Returns: amount of bytes available in @adapter
224  */
225 guint
226 gst_adapter_available (GstAdapter * adapter)
228   g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
230   return adapter->size;
233 /**
234  * gst_adapter_available_fast:
235  * @adapter: a #GstAdapter
236  *
237  * Gets the maximum amount of bytes available without the need to do expensive
238  * operations (like copying the data into a temporary buffer).
239  *
240  * Returns: amount of bytes available in @adapter without expensive operations
241  */
242 guint
243 gst_adapter_available_fast (GstAdapter * adapter)
245   g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
247   if (!adapter->buflist)
248     return 0;
249   if (adapter->assembled_len)
250     return adapter->assembled_len;
251   g_assert (GST_BUFFER_SIZE (adapter->buflist->data) > adapter->skip);
252   return GST_BUFFER_SIZE (adapter->buflist->data) - adapter->skip;