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
24static void mix_params_class_init (gpointer g_class, gpointer class_data);
25static void mix_params_init (GTypeInstance * instance, gpointer klass);
26
27static void mix_params_finalize(MixParams * obj);
28static gboolean mix_params_copy_default (MixParams *target, const MixParams *src);
29static MixParams *mix_params_dup_default(const MixParams *obj);
30static gboolean mix_params_equal_default (MixParams *first, MixParams *second);
31
32GType 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
66static 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
76static void mix_params_init (GTypeInstance * instance, gpointer klass)
77{
78  MixParams *obj = MIX_PARAMS_CAST (instance);
79
80  obj->refcount = 1;
81}
82
83gboolean 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 */
105static 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
115static void mix_params_finalize (MixParams * obj)
116{
117  /* do nothing */
118}
119
120MixParams *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
135static 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
146MixParams* 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
157MixParams* 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
166static 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
183void 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 */
202void 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
226gboolean 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
245static 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 */
267MixParams* 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