1 /*
2 INTEL CONFIDENTIAL
3 Copyright 2009 Intel Corporation All Rights Reserved.
4 The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.
5
6 No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
7 */
8
9 /**
10 * SECTION:mixparams
11 * @short_description: Lightweight base class for the MIX media params
12 *
13 */
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17
18 #include "mixparams.h"
19 #include <gobject/gvaluecollector.h>
20
21
22 #define DEBUG_REFCOUNT
23
24 static void mix_params_class_init (gpointer g_class, gpointer class_data);
25 static void mix_params_init (GTypeInstance * instance, gpointer klass);
26
27 static void mix_params_finalize(MixParams * obj);
28 static gboolean mix_params_copy_default (MixParams *target, const MixParams *src);
29 static MixParams *mix_params_dup_default(const MixParams *obj);
30 static gboolean mix_params_equal_default (MixParams *first, MixParams *second);
31
mix_params_get_type(void)32 GType mix_params_get_type (void)
33 {
34 static GType _mix_params_type = 0;
35
36 if (G_UNLIKELY (_mix_params_type == 0)) {
37
38 GTypeInfo info = {
39 sizeof (MixParamsClass),
40 NULL,
41 NULL,
42 mix_params_class_init,
43 NULL,
44 NULL,
45 sizeof (MixParams),
46 0,
47 (GInstanceInitFunc) mix_params_init,
48 NULL
49 };
50
51 static const GTypeFundamentalInfo fundamental_info = {
52 (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE |
53 G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
54 };
55
56 info.value_table = NULL;
57
58 _mix_params_type = g_type_fundamental_next ();
59 g_type_register_fundamental (_mix_params_type, "MixParams", &info, &fundamental_info, G_TYPE_FLAG_ABSTRACT);
60
61 }
62
63 return _mix_params_type;
64 }
65
mix_params_class_init(gpointer g_class,gpointer class_data)66 static void mix_params_class_init (gpointer g_class, gpointer class_data)
67 {
68 MixParamsClass *klass = MIX_PARAMS_CLASS (g_class);
69
70 klass->dup = mix_params_dup_default;
71 klass->copy = mix_params_copy_default;
72 klass->finalize = mix_params_finalize;
73 klass->equal = mix_params_equal_default;
74 }
75
mix_params_init(GTypeInstance * instance,gpointer klass)76 static void mix_params_init (GTypeInstance * instance, gpointer klass)
77 {
78 MixParams *obj = MIX_PARAMS_CAST (instance);
79
80 obj->refcount = 1;
81 }
82
mix_params_copy(MixParams * target,const MixParams * src)83 gboolean mix_params_copy (MixParams *target, const MixParams *src)
84 {
85 /* Use the target object class. Because it knows what it is looking for. */
86 MixParamsClass *klass = MIX_PARAMS_GET_CLASS(target);
87 if (klass->copy)
88 {
89 return klass->copy(target, src);
90 }
91 else
92 {
93 return mix_params_copy_default(target, src);
94 }
95 }
96
97 /**
98 * mix_params_copy_default:
99 * @target: target
100 * @src: source
101 *
102 * The default copy method of this object. Perhap copy at this level.
103 * Assign this to the copy vmethod.
104 */
mix_params_copy_default(MixParams * target,const MixParams * src)105 static gboolean mix_params_copy_default (MixParams *target, const MixParams *src)
106 {
107 if (MIX_IS_PARAMS(target) && MIX_IS_PARAMS(src))
108 {
109 // TODO perform deep copy.
110 return TRUE;
111 }
112 return FALSE;
113 }
114
mix_params_finalize(MixParams * obj)115 static void mix_params_finalize (MixParams * obj)
116 {
117 /* do nothing */
118 }
119
mix_params_dup(const MixParams * obj)120 MixParams *mix_params_dup(const MixParams *obj)
121 {
122 MixParamsClass *klass = MIX_PARAMS_GET_CLASS(obj);
123
124 if (klass->dup)
125 {
126 return klass->dup(obj);
127 }
128 else if (MIX_IS_PARAMS(obj))
129 {
130 return mix_params_dup_default(obj);
131 }
132 return NULL;
133 }
134
mix_params_dup_default(const MixParams * obj)135 static MixParams *mix_params_dup_default(const MixParams *obj)
136 {
137 MixParams *ret = mix_params_new();
138 if (mix_params_copy(ret, obj))
139 {
140 return ret;
141 }
142
143 return NULL;
144 }
145
mix_params_new(GType type)146 MixParams* mix_params_new (GType type)
147 {
148 MixParams *obj;
149
150 /* we don't support dynamic types because they really aren't useful,
151 * and could cause refcount problems */
152 obj = (MixParams *) g_type_create_instance (type);
153
154 return obj;
155 }
156
mix_params_ref(MixParams * obj)157 MixParams* mix_params_ref (MixParams *obj)
158 {
159 g_return_val_if_fail(MIX_IS_PARAMS (obj), NULL);
160
161 g_atomic_int_inc(&obj->refcount);
162
163 return obj;
164 }
165
mix_params_free(MixParams * obj)166 static void mix_params_free(MixParams *obj)
167 {
168 MixParamsClass *klass = NULL;
169
170 klass = MIX_PARAMS_GET_CLASS(obj);
171 klass->finalize(obj);
172
173 /* Should we support recycling the object? */
174 /* If so, refcount handling is slightly different. */
175 /* i.e. If the refcount is still 0 we can really free the object, else the finalize method recycled the object -- but to where? */
176
177 if (g_atomic_int_get (&obj->refcount) == 0) {
178
179 g_type_free_instance ((GTypeInstance *) obj);
180 }
181 }
182
mix_params_unref(MixParams * obj)183 void mix_params_unref (MixParams *obj)
184 {
185 g_return_if_fail (obj != NULL);
186 g_return_if_fail (obj->refcount > 0);
187
188 if (G_UNLIKELY (g_atomic_int_dec_and_test (&obj->refcount))) {
189 mix_params_free (obj);
190 }
191 }
192
193 /**
194 * mix_params_replace:
195 * @olddata: pointer to a pointer to a object to be replaced
196 * @newdata: pointer to new object
197 *
198 * Modifies a pointer to point to a new object. The modification
199 * is done atomically, and the reference counts are updated correctly.
200 * Either @newdata and the value pointed to by @olddata may be NULL.
201 */
mix_params_replace(MixParams ** olddata,MixParams * newdata)202 void mix_params_replace (MixParams **olddata, MixParams *newdata)
203 {
204 MixParams *olddata_val;
205
206 g_return_if_fail (olddata != NULL);
207
208 olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
209
210 if (olddata_val == newdata)
211 return;
212
213 if (newdata)
214 mix_params_ref (newdata);
215
216 while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata, olddata_val, newdata))
217 {
218 olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
219 }
220
221 if (olddata_val)
222 mix_params_unref (olddata_val);
223
224 }
225
mix_params_equal(MixParams * first,MixParams * second)226 gboolean mix_params_equal (MixParams *first, MixParams *second)
227 {
228 if (MIX_IS_PARAMS(first))
229 {
230 MixParamsClass *klass = MIX_PARAMS_GET_CLASS(first);
231
232 if (klass->equal)
233 {
234 return klass->equal(first, second);
235 }
236 else
237 {
238 return mix_params_equal_default(first, second);
239 }
240 }
241 else
242 return FALSE;
243 }
244
mix_params_equal_default(MixParams * first,MixParams * second)245 static gboolean mix_params_equal_default (MixParams *first, MixParams *second)
246 {
247 if (MIX_IS_PARAMS(first) && MIX_IS_PARAMS(second))
248 {
249 gboolean ret = TRUE;
250
251 // Do data comparison here.
252
253 return ret;
254 }
255 else
256 return FALSE;
257 }
258
259 /**
260 * mix_value_dup_params:
261 * @value: a valid #GValue of %MIX_TYPE_PARAMS derived type
262 * @returns: object contents of @value
263 *
264 * Get the contents of a #MIX_TYPE_PARAMS derived #GValue,
265 * increasing its reference count.
266 */
mix_value_dup_params(const GValue * value)267 MixParams* mix_value_dup_params (const GValue * value)
268 {
269 g_return_val_if_fail (MIX_VALUE_HOLDS_PARAMS (value), NULL);
270
271 return mix_params_ref (value->data[0].v_pointer);
272 }
273
274
275