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