source: trunk/third/gstreamer/gst/gstdata.c @ 21005

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