1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
use ffi::*;
use util::*;
use reference::{Reference, Ref};

use std::os::raw::{c_void, c_char};

pub struct Object{
    object: *mut GstObject,
}


impl Drop for Object{
	fn drop(&mut self){
		unsafe{
			gst_object_unref(self.object as *mut c_void);
		}
	}
}

impl Object{
    pub unsafe fn new(object: *mut GstObject) -> Option<Object>{
        if object != ptr::null_mut(){
            Some(Object{ object: object })
        }else{
            None
        }
    }

    pub fn set_name(&mut self, name: &str) -> bool{
        let cname = CString::new(name).unwrap();
        unsafe{
            gst_object_set_name(self.object, cname.as_ptr()) != 0
        }
    }

    /// Returns the name of the object
    pub fn name(&self) -> String{
        unsafe{
            let c_str_name = gst_object_get_name(self.object);
            from_c_str!(c_str_name).to_string()
        }
    }

    pub fn flags(&self) -> u32{
        unsafe{
            let object: &mut GstObject = mem::transmute(self.object);
            object.flags
        }
    }

    pub fn is_flag_set(&self, flag: u32) -> bool{
        self.flags() & flag == flag
    }

    pub fn set_flag(&mut self, flag: u32){
        unsafe{
            let object: &mut GstObject = mem::transmute(self.object);
            object.flags |= flag
        }
    }

    pub fn unset_flag(&mut self, flag: u32){
        unsafe{
            let object: &mut GstObject = mem::transmute(self.object);
            object.flags |= !flag
        }
    }

    pub fn refcount(&self) -> usize{
        unsafe{
            let object: &mut GObject = mem::transmute(self.object);
            object.ref_count as usize
        }
    }

    pub fn lock<F: FnMut(&mut Object)>(&mut self, mut f: F){
        unsafe{
            let object: &mut GstObject = mem::transmute(self.object);
            g_mutex_lock(&mut object.lock);
            f(self);
            g_mutex_unlock(&mut object.lock);
        }
    }

    pub fn set_unique_name(&mut self) -> bool{
        unsafe{
            gst_object_set_name(self.object, ptr::null()) != 0
        }
    }

    pub fn set_parent(&mut self, parent: &Object) -> bool{
        unsafe{
            gst_object_set_parent(self.object, parent.object) != 0
        }
    }

    pub fn parent(&self) -> Option<Ref<Object>>{
        let parent = unsafe{ gst_object_get_parent(self.object) };
        if parent == ptr::null_mut(){
            None
        }else{
            Some(Ref::new(&Object{ object: parent }))
        }
    }

    pub fn unparent(&mut self){
        unsafe{
            gst_object_unparent(self.object);
        }
    }

    pub fn has_as_ancestor(&self, ancestor: &Object) -> bool{
        unsafe{
            gst_object_has_ancestor(self.object, ancestor.object) != 0
        }
    }

    pub fn path_string(&self) -> &str{
        unsafe{
            from_c_str!(gst_object_get_path_string(self.object))
        }
    }

    pub fn has_active_control_bindings(&self) -> bool{
        unsafe{
            gst_object_has_active_control_bindings(self.object) != 0
        }
    }

    pub fn disable_control_bindings(&mut self){
        unsafe{
            gst_object_set_control_bindings_disabled(self.object, 1)
        }
    }

    pub fn enable_control_bindings(&mut self){
        unsafe{
            gst_object_set_control_bindings_disabled(self.object, 0)
        }
    }

    pub fn disable_control_binding(&mut self, property_name: &str){
        unsafe{
            let cname = CString::new(property_name).unwrap();
            gst_object_set_control_binding_disabled(self.object, cname.as_ptr(), 1)
        }
    }

    pub fn enable_control_binding(&mut self, property_name: &str){
        unsafe{
            let cname = CString::new(property_name).unwrap();
            gst_object_set_control_binding_disabled(self.object, cname.as_ptr(), 0)
        }
    }

    pub fn set<T>(&mut self, name: &str, value: T)
    	where T: Property {
        value.set_to(name, self)
    }

    pub fn get<T>(&self, name: &str) -> T
    	where T: FromProperty {
        unsafe{
            let cname = CString::new(name).unwrap();
            let mut value = mem::uninitialized();
            g_object_get(self.gst_object() as *mut c_void, cname.as_ptr(), &mut value);
            T::from_property(value)
        }
    }

    pub unsafe fn signal_connect<T>(&mut self, signal: &str, callback: GCallback, data: &mut T)
        where Self:Sized{
        let csignal = CString::new(signal).unwrap();
        g_signal_connect_data(self.gst_object() as *mut c_void, csignal.as_ptr(), callback, mem::transmute(data), None, 0);
    }

    pub unsafe fn gst_object(&self) -> *const GstObject{
        self.object
    }

    pub unsafe fn gst_object_mut(&mut self) -> *mut GstObject{
        self.object
    }
}

impl Reference for Object{
    fn reference(&self) -> Object{
        unsafe{ gst_object_ref(self.object as *mut c_void) };
        Object{ object: self.object }
    }
}

impl ::Transfer<GstObject> for Object{
    unsafe fn transfer(self) -> *mut GstObject{
        let object = self.object;
        mem::forget(self);
        object
    }
}

pub trait Property{
    type Target;
    fn set_to(&self, key: &str, e: &mut Object);
}

pub trait FromProperty: Property{
    fn from_property(t: <Self as Property>::Target) -> Self;
}

impl<'a> Property for &'a str{
    type Target = *const c_char;
    #[inline]
    fn set_to(&self, key: &str, e: &mut Object){
        let cname = CString::new(key).unwrap();
        let c_str = CString::new(*self).unwrap();
        unsafe{
            g_object_set(e.gst_object() as *mut  c_void, cname.as_ptr(), c_str.as_ptr(), ptr::null::<gchar>());
        }
    }
}

impl<'a> FromProperty for &'a str{
    fn from_property(t: *const c_char) -> &'a str{
        unsafe{ from_c_str!(t) }
    }
}
pub trait RawProperty: Clone{
    #[inline]
    fn set_raw_to(&self, key: &str, e: &mut Object){
        let cname = CString::new(key).unwrap();
        unsafe{
            g_object_set(e.gst_object() as *mut  c_void, cname.as_ptr(), self.clone(), ptr::null::<gchar>());
        }
    }
}

impl<R: RawProperty> Property for R{
    type Target = R;
    #[inline]
    fn set_to(&self, key: &str, e: &mut Object){
        self.set_raw_to(key, e);
    }
}

impl<R: RawProperty> FromProperty for R{
    fn from_property(p: <Self as Property>::Target) -> Self{
        p
    }
}

impl RawProperty for i8{}
impl RawProperty for u8{}
impl RawProperty for i16{}
impl RawProperty for u16{}
impl RawProperty for i32{}
impl RawProperty for u32{}
impl RawProperty for i64{}
impl RawProperty for u64{}
impl RawProperty for f32{}
impl RawProperty for f64{}
impl RawProperty for bool{}