Add new --enable-fast-stack-trash option, defaults to on.
[platform/upstream/gstreamer.git] / gst / gstdata.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstdata.c: Data operations
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 /* this file makes too much noise for most debugging sessions */
24
25 #define GST_DEBUG_FORCE_DISABLE
26 #include "gst_private.h"
27
28 #include "gstatomic_impl.h"
29 #include "gstdata.h"
30 #include "gstdata_private.h"
31 #include "gstlog.h"
32
33 /**
34  * gst_data_init:
35  * @data: a #GstData to initialize
36  * @type: the type of this data
37  * @flags: flags for this data
38  * @free: a free function 
39  * @copy: a copy function 
40  *
41  * Initialize the given data structure with the given parameters. The free and copy 
42  * function will be called when this data is freed or copied respectively.
43  */
44 void
45 gst_data_init (GstData *data, GType type, guint16 flags, GstDataFreeFunction free, GstDataCopyFunction copy)
46 {
47   g_return_if_fail (data != NULL);
48
49   _GST_DATA_INIT (data, type, flags, free, copy);
50 }
51
52 /**
53  * gst_data_copy_into:
54  * @data: a #GstData to copy
55  * @target: the target #GstData to copy into
56  *
57  * Copy the GstData into the specified target GstData structure.
58  * Thos method is mainly used by subclasses when they want to copy
59  * the relevant GstData info.
60  */
61 void
62 gst_data_copy_into (const GstData *data, GstData *target)
63 {
64   g_return_if_fail (data != NULL);
65 }
66
67 /**
68  * gst_data_dispose:
69  * @data: a #GstData to dispose
70  *
71  * Free all the resources allocated in the gst_data_init() function, 
72  * mainly used by subclass implementors.
73  */
74 void
75 gst_data_dispose (GstData *data)
76 {
77   g_return_if_fail (data != NULL);
78
79   _GST_DATA_DISPOSE (data);
80 }
81
82 /**
83  * gst_data_copy:
84  * @data: a #GstData to copy
85  *
86  * Copies the given #GstData. This function will call the custom subclass
87  * copy function or return NULL if no function was provided by the subclass.
88  *
89  * Returns: a copy of the data or NULL if the data cannot be copied. The refcount
90  * of the original buffer is not changed so you should unref it when you don't
91  * need it anymore.
92  */
93 GstData*
94 gst_data_copy (const GstData *data) 
95 {
96   g_return_val_if_fail (data != NULL, NULL);
97
98   if (data->copy)
99     return data->copy (data); 
100
101   return NULL;
102 }
103
104 /**
105  * gst_data_is_writable:
106  * @data: a #GstData to copy
107  *
108  * Query if the gstdata needs to be copied before it can safely be modified.
109  *
110  * Returns: FALSE if the given #GstData is potentially shared and needs to
111  * be copied before it can be modified safely.
112  */
113 gboolean
114 gst_data_is_writable (GstData *data) 
115 {
116   gint refcount;
117
118   g_return_val_if_fail (data != NULL, FALSE);
119
120   refcount = gst_atomic_int_read (&data->refcount);
121
122   if (refcount == 1 && !GST_DATA_FLAG_IS_SET (data, GST_DATA_READONLY))
123     return FALSE;
124
125   return TRUE;
126 }
127
128 /**
129  * gst_data_copy_on_write:
130  * @data: a #GstData to copy
131  *
132  * Copies the given #GstData if the refcount is greater than 1 so that the
133  * #GstData object can be written to safely.
134  *
135  * Returns: a copy of the data if the refcount is > 1 or the buffer is 
136  * marked READONLY, data if the refcount == 1,
137  * or NULL if the data could not be copied. The refcount of the original buffer
138  * is decreased when a copy is made, so you are not supposed to use it after a
139  * call to this function.
140  */
141 GstData*
142 gst_data_copy_on_write (GstData *data) 
143 {
144   gint refcount;
145
146   g_return_val_if_fail (data != NULL, NULL);
147
148   refcount = gst_atomic_int_read (&data->refcount);
149
150   if (refcount == 1 && !GST_DATA_FLAG_IS_SET (data, GST_DATA_READONLY))
151     return GST_DATA (data);
152         
153   if (data->copy) {
154     GstData *copy = data->copy (data); 
155     gst_data_unref (data);
156     return copy; 
157   }
158
159   return NULL;
160 }
161
162 /**
163  * gst_data_free:
164  * @data: a #GstData to free
165  *
166  * Frees the given #GstData. This function will call the custom free function
167  * provided by the subclass. 
168  */
169 void
170 gst_data_free (GstData *data) 
171 {
172   if (!data)
173     return;
174
175   if (data->free)
176     data->free (data); 
177 }
178
179 /**
180  * gst_data_ref:
181  * @data: a #GstData to reference
182  *
183  * Increments the reference count of this data.
184  *
185  * Returns: the data
186  */
187 GstData* 
188 gst_data_ref (GstData *data) 
189 {
190   g_return_val_if_fail (data != NULL, NULL);
191   g_return_val_if_fail (GST_DATA_REFCOUNT_VALUE(data) > 0, NULL);
192
193   gst_atomic_int_inc (&data->refcount);
194
195   return data;
196 }
197
198 /**
199  * gst_data_ref_by_count:
200  * @data: a #GstData to reference
201  * @count: the number to increment the reference count by
202  *
203  * Increments the reference count of this data by the given number.
204  *
205  * Returns: the data
206  */
207 GstData* 
208 gst_data_ref_by_count (GstData *data, gint count)
209 {
210   g_return_val_if_fail (data != NULL, NULL);
211   g_return_val_if_fail (count >= 0, NULL);
212   g_return_val_if_fail (GST_DATA_REFCOUNT_VALUE(data) > 0, NULL);
213
214   gst_atomic_int_add (&data->refcount, count);
215
216   return data;
217 }
218
219 /**
220  * gst_data_unref:
221  * @data: a #GstData to unreference
222  *
223  * Decrements the refcount of this data. If the refcount is
224  * zero, the data will be freed.
225  *
226  * When you add data to a pipeline, the pipeline takes ownership of the
227  * data.  When the data has been used by some plugin, it must unref()s it.
228  * Applications usually don't need to unref() anything.
229  */
230 void 
231 gst_data_unref (GstData *data) 
232 {
233   gint zero;
234
235   g_return_if_fail (data != NULL);
236
237   GST_INFO (GST_CAT_BUFFER, "unref data %p, count before unref is %d", 
238             data, GST_DATA_REFCOUNT_VALUE (data));
239   g_return_if_fail (GST_DATA_REFCOUNT_VALUE (data) > 0);
240
241   zero = gst_atomic_int_dec_and_test (&data->refcount);
242
243   /* if we ended up with the refcount at zero, free the data */
244   if (zero) {
245     if (data->free) 
246       data->free (data); 
247   }
248 }