gstreamer_gl/subclass/
gl_base_filter.rs

1use ffi::GstGLBaseFilter;
2use glib::translate::*;
3use gst::{ffi::GstCaps, result_from_gboolean, Caps, LoggableError, CAT_RUST};
4use gst_base::subclass::prelude::*;
5
6use crate::{ffi, prelude::*, GLBaseFilter};
7
8pub trait GLBaseFilterImpl: GLBaseFilterImplExt + BaseTransformImpl {
9    fn gl_set_caps(&self, incaps: &Caps, outcaps: &Caps) -> Result<(), LoggableError> {
10        self.parent_gl_set_caps(incaps, outcaps)
11    }
12
13    fn gl_start(&self) -> Result<(), LoggableError> {
14        self.parent_gl_start()
15    }
16
17    fn gl_stop(&self) {
18        self.parent_gl_stop()
19    }
20}
21
22mod sealed {
23    pub trait Sealed {}
24    impl<T: super::GLBaseFilterImplExt> Sealed for T {}
25}
26
27pub trait GLBaseFilterImplExt: sealed::Sealed + ObjectSubclass {
28    fn parent_gl_set_caps(&self, incaps: &Caps, outcaps: &Caps) -> Result<(), LoggableError> {
29        unsafe {
30            let data = Self::type_data();
31            let parent_class = data.as_ref().parent_class() as *mut ffi::GstGLBaseFilterClass;
32
33            (*parent_class)
34                .gl_set_caps
35                .map(|f| {
36                    result_from_gboolean!(
37                        f(
38                            self.obj()
39                                .unsafe_cast_ref::<GLBaseFilter>()
40                                .to_glib_none()
41                                .0,
42                            incaps.to_glib_none().0,
43                            outcaps.to_glib_none().0,
44                        ),
45                        CAT_RUST,
46                        "Parent function `gl_set_caps` failed",
47                    )
48                })
49                .unwrap_or(Ok(()))
50        }
51    }
52
53    fn parent_gl_start(&self) -> Result<(), LoggableError> {
54        unsafe {
55            let data = Self::type_data();
56            let parent_class = data.as_ref().parent_class() as *mut ffi::GstGLBaseFilterClass;
57
58            (*parent_class)
59                .gl_start
60                .map(|f| {
61                    result_from_gboolean!(
62                        f(self
63                            .obj()
64                            .unsafe_cast_ref::<GLBaseFilter>()
65                            .to_glib_none()
66                            .0),
67                        CAT_RUST,
68                        "Parent function `gl_start` failed",
69                    )
70                })
71                .unwrap_or(Ok(()))
72        }
73    }
74
75    fn parent_gl_stop(&self) {
76        unsafe {
77            let data = Self::type_data();
78            let parent_class = data.as_ref().parent_class() as *mut ffi::GstGLBaseFilterClass;
79
80            if let Some(f) = (*parent_class).gl_stop {
81                f(self
82                    .obj()
83                    .unsafe_cast_ref::<GLBaseFilter>()
84                    .to_glib_none()
85                    .0)
86            }
87        }
88    }
89}
90
91impl<T: GLBaseFilterImpl> GLBaseFilterImplExt for T {}
92
93unsafe impl<T: GLBaseFilterImpl> IsSubclassable<T> for GLBaseFilter {
94    fn class_init(klass: &mut glib::Class<Self>) {
95        Self::parent_class_init::<T>(klass);
96        let klass = klass.as_mut();
97        klass.gl_set_caps = Some(gl_set_caps::<T>);
98        klass.gl_start = Some(gl_start::<T>);
99        klass.gl_stop = Some(gl_stop::<T>);
100    }
101}
102
103unsafe extern "C" fn gl_set_caps<T: GLBaseFilterImpl>(
104    ptr: *mut GstGLBaseFilter,
105    incaps: *mut GstCaps,
106    outcaps: *mut GstCaps,
107) -> glib::ffi::gboolean {
108    let instance = &*(ptr as *mut T::Instance);
109    let imp = instance.imp();
110
111    gst::panic_to_error!(imp, false, {
112        match imp.gl_set_caps(&from_glib_borrow(incaps), &from_glib_borrow(outcaps)) {
113            Ok(()) => true,
114            Err(err) => {
115                err.log_with_imp(imp);
116                false
117            }
118        }
119    })
120    .into_glib()
121}
122
123unsafe extern "C" fn gl_start<T: GLBaseFilterImpl>(
124    ptr: *mut GstGLBaseFilter,
125) -> glib::ffi::gboolean {
126    let instance = &*(ptr as *mut T::Instance);
127    let imp = instance.imp();
128
129    gst::panic_to_error!(imp, false, {
130        match imp.gl_start() {
131            Ok(()) => true,
132            Err(err) => {
133                err.log_with_imp(imp);
134                false
135            }
136        }
137    })
138    .into_glib()
139}
140
141unsafe extern "C" fn gl_stop<T: GLBaseFilterImpl>(ptr: *mut GstGLBaseFilter) {
142    let instance = &*(ptr as *mut T::Instance);
143    let imp = instance.imp();
144
145    gst::panic_to_error!(imp, (), { imp.gl_stop() })
146}