gstreamer/subclass/
plugin.rs1pub 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 #[allow(unused)]
46 enum OptionalPtr<T>{
47 Null,
48 Some(*const T),
49 }
50 #[allow(unused)]
51 impl<T: Sized> OptionalPtr<T> {
52 const fn with(self, value: *const T) -> Self {
53 Self::Some(value)
54 }
55 const fn ptr(self) -> *const T {
56 match self {
57 Self::Null => std::ptr::null(),
58 Self::Some(ptr) => ptr
59 }
60 }
61 }
62 OptionalPtr::Null
63 $(.with(concat!($release_datetime, "\0").as_ptr() as _))?
64 .ptr()
65 },
66 _gst_reserved: [0 as $crate::glib::ffi::gpointer; 4],
67 });
68
69 pub fn plugin_register_static() -> Result<(), $crate::glib::BoolError> {
70 unsafe {
71 $crate::glib::result_from_gboolean!(
72 $crate::ffi::gst_plugin_register_static(
73 $crate::subclass::MAJOR_VERSION,
74 $crate::subclass::MINOR_VERSION,
75 concat!(stringify!($name), "\0") as *const str as *const _,
76 concat!($description, "\0") as *const str as _,
77 Some(plugin_init_trampoline),
78 concat!($version, "\0") as *const str as *const _,
79 concat!($license, "\0") as *const str as *const _,
80 concat!($source, "\0") as *const str as *const _,
81 concat!($package, "\0") as *const str as *const _,
82 concat!($origin, "\0") as *const str as *const _,
83 ),
84 "Failed to register the plugin"
85 )
86 }
87 }
88
89 $crate::pastey::item! {
90 #[no_mangle]
91 #[allow(clippy::missing_safety_doc)]
92 pub unsafe extern "C" fn [<gst_plugin_ $name _register>] () {
93 let _ = plugin_register_static();
94 }
95
96 #[no_mangle]
97 #[allow(clippy::missing_safety_doc)]
98 pub unsafe extern "C" fn [<gst_plugin_ $name _get_desc>] () -> *const $crate::ffi::GstPluginDesc {
99 &GST_PLUGIN_DESC.0
100 }
101 }
102
103 #[allow(clippy::missing_safety_doc)]
104 unsafe extern "C" fn plugin_init_trampoline(plugin: *mut $crate::ffi::GstPlugin) -> $crate::glib::ffi::gboolean {
105 let panic_result = std::panic::catch_unwind(
106 std::panic::AssertUnwindSafe(|| super::$plugin_init(&$crate::glib::translate::from_glib_borrow(plugin)))
107 );
108
109 match panic_result {
110 Ok(register_result) => match register_result {
111 Ok(_) => $crate::glib::ffi::GTRUE,
112 Err(err) => {
113 $crate::error!($crate::CAT_PLUGIN_LOADING, "Failed to register plugin: {}", err);
114 $crate::glib::ffi::GFALSE
115 }
116 }
117 Err(err) => {
118 let cause = err.downcast_ref::<&str>().copied()
119 .or_else(|| err.downcast_ref::<String>().map(|s| s.as_str()));
120 if let Some(cause) = cause {
121 $crate::error!($crate::CAT_PLUGIN_LOADING, "Failed to initialize plugin due to panic: {}", cause);
122 } else {
123 $crate::error!($crate::CAT_PLUGIN_LOADING, "Failed to initialize plugin due to panic");
124 }
125
126 $crate::glib::ffi::GFALSE
127 }
128 }
129 }
130 }
131 pub use self::plugin_desc::plugin_register_static;
132 };
133);
134
135#[cfg(test)]
136mod tests {
137 fn plugin_init(_plugin: &crate::Plugin) -> Result<(), glib::BoolError> {
138 Ok(())
139 }
140
141 crate::plugin_define!(
142 gst_rs_plugin_test,
143 env!("CARGO_PKG_DESCRIPTION"),
144 plugin_init,
145 env!("CARGO_PKG_VERSION"),
146 "MIT/X11",
147 env!("CARGO_PKG_NAME"),
148 env!("CARGO_PKG_NAME"),
149 env!("CARGO_PKG_REPOSITORY")
150 );
151
152 #[test]
153 fn plugin_register() {
154 crate::init().unwrap();
155 plugin_register_static().unwrap();
156 }
157}