gstreamer/subclass/
plugin.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3pub const MAJOR_VERSION: i32 = 1;
4
5cfg_if::cfg_if! {
6    if #[cfg(feature = "v1_22")] {
7        pub const MINOR_VERSION: i32 = 22;
8    } else if #[cfg(feature = "v1_20")] {
9        pub const MINOR_VERSION: i32 = 20;
10    } else if #[cfg(feature = "v1_18")] {
11        pub const MINOR_VERSION: i32 = 18;
12    } else if #[cfg(feature = "v1_16")] {
13        pub const MINOR_VERSION: i32 = 16;
14    } else {
15        pub const MINOR_VERSION: i32 = 14;
16    }
17}
18
19#[macro_export]
20macro_rules! plugin_define(
21    ($name:ident, $description:expr, $plugin_init:ident,
22     $version:expr, $license:expr, $source:expr,
23     $package:expr, $origin:expr $(, $release_datetime:expr)?) => {
24        pub mod plugin_desc {
25            #[repr(transparent)]
26            pub struct GstPluginDesc($crate::ffi::GstPluginDesc);
27            unsafe impl Send for GstPluginDesc {}
28            unsafe impl Sync for GstPluginDesc {}
29
30            static GST_PLUGIN_DESC: GstPluginDesc = GstPluginDesc($crate::ffi::GstPluginDesc {
31                major_version: $crate::subclass::MAJOR_VERSION,
32                minor_version: $crate::subclass::MINOR_VERSION,
33                name: concat!(stringify!($name), "\0") as *const str as *const _,
34                description: concat!($description, "\0") as *const str as *const _,
35                plugin_init: Some(plugin_init_trampoline),
36                version: concat!($version, "\0") as *const str as *const _,
37                license: concat!($license, "\0") as *const str as *const _,
38                source: concat!($source, "\0") as *const str as *const _,
39                package: concat!($package, "\0") as *const str as *const _,
40                origin: concat!($origin, "\0") as *const str as *const _,
41                release_datetime: {
42                    // NB: if this looks a lot like `Option`, it is not a coincidence. Alas,
43                    // Option::or is not `const` and neither is `unwrap_or` so we have to roll our
44                    // own oli-obk-ified enum instead.
45                    enum OptionalPtr<T>{
46                        Null,
47                        Some(*const T),
48                    }
49                    impl<T: Sized> OptionalPtr<T> {
50                        const fn with(self, value: *const T) -> Self {
51                            Self::Some(value)
52                        }
53                        const fn ptr(self) -> *const T {
54                            match self {
55                                Self::Null => std::ptr::null(),
56                                Self::Some(ptr) => ptr
57                            }
58                        }
59                    }
60                    OptionalPtr::Null
61                      $(.with(concat!($release_datetime, "\0").as_ptr() as _))?
62                        .ptr()
63                },
64                _gst_reserved: [0 as $crate::glib::ffi::gpointer; 4],
65            });
66
67            pub fn plugin_register_static() -> Result<(), $crate::glib::BoolError> {
68                unsafe {
69                    $crate::glib::result_from_gboolean!(
70                        $crate::ffi::gst_plugin_register_static(
71                            $crate::subclass::MAJOR_VERSION,
72                            $crate::subclass::MINOR_VERSION,
73                            concat!(stringify!($name), "\0") as *const str as *const _,
74                            concat!($description, "\0") as *const str as _,
75                            Some(plugin_init_trampoline),
76                            concat!($version, "\0") as *const str as *const _,
77                            concat!($license, "\0") as *const str as *const _,
78                            concat!($source, "\0") as *const str as *const _,
79                            concat!($package, "\0") as *const str as *const _,
80                            concat!($origin, "\0") as *const str as *const _,
81                        ),
82                        "Failed to register the plugin"
83                    )
84                }
85            }
86
87            $crate::paste::item! {
88                #[no_mangle]
89                #[allow(clippy::missing_safety_doc)]
90                pub unsafe extern "C" fn [<gst_plugin_ $name _register>] () {
91                    let _ = plugin_register_static();
92                }
93
94                #[no_mangle]
95                #[allow(clippy::missing_safety_doc)]
96                pub unsafe extern "C" fn [<gst_plugin_ $name _get_desc>] () -> *const $crate::ffi::GstPluginDesc {
97                    &GST_PLUGIN_DESC.0
98                }
99            }
100
101            #[allow(clippy::missing_safety_doc)]
102            unsafe extern "C" fn plugin_init_trampoline(plugin: *mut $crate::ffi::GstPlugin) -> $crate::glib::ffi::gboolean {
103                let panic_result = std::panic::catch_unwind(
104                    std::panic::AssertUnwindSafe(|| super::$plugin_init(&$crate::glib::translate::from_glib_borrow(plugin)))
105                );
106
107                match panic_result {
108                    Ok(register_result) => match register_result {
109                        Ok(_) => $crate::glib::ffi::GTRUE,
110                        Err(err) => {
111                            $crate::error!($crate::CAT_PLUGIN_LOADING, "Failed to register plugin: {}", err);
112                            $crate::glib::ffi::GFALSE
113                        }
114                    }
115                    Err(err) => {
116                        let cause = err.downcast_ref::<&str>().copied()
117                            .or_else(|| err.downcast_ref::<String>().map(|s| s.as_str()));
118                        if let Some(cause) = cause {
119                            $crate::error!($crate::CAT_PLUGIN_LOADING, "Failed to initialize plugin due to panic: {}", cause);
120                        } else {
121                            $crate::error!($crate::CAT_PLUGIN_LOADING, "Failed to initialize plugin due to panic");
122                        }
123
124                        $crate::glib::ffi::GFALSE
125                    }
126                }
127            }
128        }
129        pub use self::plugin_desc::plugin_register_static;
130    };
131);