Home | History | Annotate | Download | only in src
      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 Intels 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 
     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 
     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 
     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 
     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  */
    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 
    115 static void mix_params_finalize (MixParams * obj)
    116 {
    117   /* do nothing */
    118 }
    119 
    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 
    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 
    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 
    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 
    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 
    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  */
    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 
    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 
    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  */
    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