gst_plugin/
pad.rs

1// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::mem;
10use std::ptr;
11
12use glib_ffi;
13use gobject_ffi;
14use gst_ffi;
15
16use glib;
17use glib::translate::*;
18use gst;
19use gst::prelude::*;
20
21use gobject_subclass::anyimpl::*;
22use gobject_subclass::object::*;
23
24pub trait PadImpl<T: PadBase>: AnyImpl + ObjectImpl<T> + Send + Sync + 'static {
25    fn linked(&self, pad: &T, peer: &gst::Pad) {
26        pad.parent_linked(peer)
27    }
28
29    fn unlinked(&self, pad: &T, peer: &gst::Pad) {
30        pad.parent_unlinked(peer)
31    }
32}
33
34any_impl!(PadBase, PadImpl);
35
36pub unsafe trait PadBase: IsA<gst::Pad> + ObjectType {
37    fn parent_linked(&self, peer: &gst::Pad) {
38        unsafe {
39            let klass = self.get_class();
40            let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstPadClass;
41            (*parent_klass)
42                .linked
43                .map(|f| f(self.to_glib_none().0, peer.to_glib_none().0))
44                .unwrap_or(())
45        }
46    }
47
48    fn parent_unlinked(&self, peer: &gst::Pad) {
49        unsafe {
50            let klass = self.get_class();
51            let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstPadClass;
52            (*parent_klass)
53                .unlinked
54                .map(|f| f(self.to_glib_none().0, peer.to_glib_none().0))
55                .unwrap_or(())
56        }
57    }
58}
59
60pub unsafe trait PadClassExt<T: PadBase>
61where
62    T::ImplType: PadImpl<T>,
63{
64    fn override_vfuncs(&mut self, _: &ClassInitToken) {
65        unsafe {
66            let klass = &mut *(self as *const Self as *mut gst_ffi::GstPadClass);
67            klass.linked = Some(pad_linked::<T>);
68            klass.unlinked = Some(pad_unlinked::<T>);
69        }
70    }
71}
72
73glib_wrapper! {
74    pub struct Pad(Object<InstanceStruct<Pad>>):
75        [gst::Pad => gst_ffi::GstPad,
76         gst::Object => gst_ffi::GstObject];
77
78    match fn {
79        get_type => || get_type::<Pad>(),
80    }
81}
82
83unsafe impl<T: IsA<gst::Pad> + ObjectType> PadBase for T {}
84pub type PadClass = ClassStruct<Pad>;
85
86// FIXME: Boilerplate
87unsafe impl PadClassExt<Pad> for PadClass {}
88unsafe impl ObjectClassExt<Pad> for PadClass {}
89
90unsafe impl Send for Pad {}
91unsafe impl Sync for Pad {}
92
93#[macro_export]
94macro_rules! box_pad_impl(
95    ($name:ident) => {
96        box_object_impl!($name);
97
98        impl<T: PadBase> PadImpl<T> for Box<$name<T>>
99        {
100            fn linked(&self, pad: &T, peer: &gst::Pad) {
101                let imp: &$name<T> = self.as_ref();
102                imp.linked(pad, peer)
103            }
104
105            fn unlinked(&self, pad: &T, peer: &gst::Pad) {
106                let imp: &$name<T> = self.as_ref();
107                imp.unlinked(pad, peer)
108            }
109        }
110    };
111);
112box_pad_impl!(PadImpl);
113
114impl ObjectType for Pad {
115    const NAME: &'static str = "RsPad";
116    type ParentType = gst::Pad;
117    type ImplType = Box<PadImpl<Self>>;
118    type InstanceStructType = InstanceStruct<Self>;
119
120    fn class_init(token: &ClassInitToken, klass: &mut PadClass) {
121        ObjectClassExt::override_vfuncs(klass, token);
122        PadClassExt::override_vfuncs(klass, token);
123    }
124
125    object_type_fns!();
126}
127
128unsafe extern "C" fn pad_linked<T: PadBase>(ptr: *mut gst_ffi::GstPad, peer: *mut gst_ffi::GstPad)
129where
130    T::ImplType: PadImpl<T>,
131{
132    floating_reference_guard!(ptr);
133    let pad = &*(ptr as *mut T::InstanceStructType);
134    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
135    let imp = pad.get_impl();
136
137    imp.linked(&wrap, &from_glib_borrow(peer))
138}
139
140unsafe extern "C" fn pad_unlinked<T: PadBase>(ptr: *mut gst_ffi::GstPad, peer: *mut gst_ffi::GstPad)
141where
142    T::ImplType: PadImpl<T>,
143{
144    floating_reference_guard!(ptr);
145    let pad = &*(ptr as *mut T::InstanceStructType);
146    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
147    let imp = pad.get_impl();
148
149    imp.unlinked(&wrap, &from_glib_borrow(peer))
150}