| 1 | // Take a look at the license at the top of the repository in the LICENSE file. |
| 2 | |
| 3 | #[cfg (not(feature = "v1_26" ))] |
| 4 | use {crate::value::GstValueExt, std::str::FromStr}; |
| 5 | |
| 6 | use glib::{prelude::*, subclass::prelude::*, translate::*}; |
| 7 | |
| 8 | use super::prelude::*; |
| 9 | use crate::{ |
| 10 | ffi, Bin, Buffer, BufferList, Element, Event, FlowError, FlowSuccess, Message, MiniObject, |
| 11 | Object, Pad, PadLinkError, PadLinkSuccess, QueryRef, StateChange, StateChangeError, |
| 12 | StateChangeSuccess, Tracer, |
| 13 | }; |
| 14 | |
| 15 | #[allow (unused_variables)] |
| 16 | pub trait TracerImpl: TracerImplExt + GstObjectImpl + Send + Sync { |
| 17 | // rustdoc-stripper-ignore-next |
| 18 | /// Whether to use `gst::Structure` style "params" and automatically pass |
| 19 | /// them to the corresponding properties during instantiation. |
| 20 | const USE_STRUCTURE_PARAMS: bool = false; |
| 21 | |
| 22 | fn bin_add_post(&self, ts: u64, bin: &Bin, element: &Element, success: bool) {} |
| 23 | fn bin_add_pre(&self, ts: u64, bin: &Bin, element: &Element) {} |
| 24 | fn bin_remove_post(&self, ts: u64, bin: &Bin, success: bool) {} |
| 25 | fn bin_remove_pre(&self, ts: u64, bin: &Bin, element: &Element) {} |
| 26 | fn element_new(&self, ts: u64, element: &Element) {} |
| 27 | fn element_add_pad(&self, ts: u64, element: &Element, pad: &Pad) {} |
| 28 | fn element_remove_pad(&self, ts: u64, element: &Element, pad: &Pad) {} |
| 29 | fn element_change_state_post( |
| 30 | &self, |
| 31 | ts: u64, |
| 32 | element: &Element, |
| 33 | change: StateChange, |
| 34 | result: Result<StateChangeSuccess, StateChangeError>, |
| 35 | ) { |
| 36 | } |
| 37 | fn element_change_state_pre(&self, ts: u64, element: &Element, change: StateChange) {} |
| 38 | fn element_post_message_post(&self, ts: u64, element: &Element, success: bool) {} |
| 39 | fn element_post_message_pre(&self, ts: u64, element: &Element, message: &Message) {} |
| 40 | fn element_query_post(&self, ts: u64, element: &Element, query: &QueryRef, success: bool) {} |
| 41 | fn element_query_pre(&self, ts: u64, element: &Element, query: &QueryRef) {} |
| 42 | // rustdoc-stripper-ignore-next |
| 43 | /// Hook to be called before the GstMiniObject has been fully initialized. |
| 44 | fn mini_object_created(&self, ts: u64, object: std::ptr::NonNull<ffi::GstMiniObject>) {} |
| 45 | // rustdoc-stripper-ignore-next |
| 46 | /// Hook to be called after the GstMiniObject has been finalized. |
| 47 | fn mini_object_destroyed(&self, ts: u64, object: std::ptr::NonNull<ffi::GstMiniObject>) {} |
| 48 | fn mini_object_reffed(&self, ts: u64, object: &MiniObject, new_refcount: i32) {} |
| 49 | fn mini_object_unreffed(&self, ts: u64, object: &MiniObject, new_refcount: i32) {} |
| 50 | fn object_created(&self, ts: u64, object: &Object) {} |
| 51 | // rustdoc-stripper-ignore-next |
| 52 | /// Hook to be called after the GstObject has been finalized. |
| 53 | fn object_destroyed(&self, ts: u64, object: std::ptr::NonNull<ffi::GstObject>) {} |
| 54 | fn object_reffed(&self, ts: u64, object: &Object, new_refcount: i32) {} |
| 55 | fn object_unreffed(&self, ts: u64, object: &Object, new_refcount: i32) {} |
| 56 | fn pad_link_post( |
| 57 | &self, |
| 58 | ts: u64, |
| 59 | src: &Pad, |
| 60 | sink: &Pad, |
| 61 | result: Result<PadLinkSuccess, PadLinkError>, |
| 62 | ) { |
| 63 | } |
| 64 | fn pad_link_pre(&self, ts: u64, src: &Pad, sink: &Pad) {} |
| 65 | fn pad_pull_range_post(&self, ts: u64, pad: &Pad, result: Result<&Buffer, FlowError>) {} |
| 66 | fn pad_pull_range_pre(&self, ts: u64, pad: &Pad, offset: u64, size: u32) {} |
| 67 | fn pad_push_event_post(&self, ts: u64, pad: &Pad, success: bool) {} |
| 68 | fn pad_push_event_pre(&self, ts: u64, pad: &Pad, event: &Event) {} |
| 69 | #[cfg (feature = "v1_22" )] |
| 70 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 71 | fn pad_chain_list_post(&self, ts: u64, pad: &Pad, result: Result<FlowSuccess, FlowError>) {} |
| 72 | #[cfg (feature = "v1_22" )] |
| 73 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 74 | fn pad_chain_list_pre(&self, ts: u64, pad: &Pad, buffer_list: &BufferList) {} |
| 75 | #[cfg (feature = "v1_22" )] |
| 76 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 77 | fn pad_chain_post(&self, ts: u64, pad: &Pad, result: Result<FlowSuccess, FlowError>) {} |
| 78 | #[cfg (feature = "v1_22" )] |
| 79 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 80 | fn pad_chain_pre(&self, ts: u64, pad: &Pad, buffer: &Buffer) {} |
| 81 | fn pad_push_list_post(&self, ts: u64, pad: &Pad, result: Result<FlowSuccess, FlowError>) {} |
| 82 | fn pad_push_list_pre(&self, ts: u64, pad: &Pad, buffer_list: &BufferList) {} |
| 83 | fn pad_push_post(&self, ts: u64, pad: &Pad, result: Result<FlowSuccess, FlowError>) {} |
| 84 | fn pad_push_pre(&self, ts: u64, pad: &Pad, buffer: &Buffer) {} |
| 85 | fn pad_query_post(&self, ts: u64, pad: &Pad, query: &QueryRef, success: bool) {} |
| 86 | fn pad_query_pre(&self, ts: u64, pad: &Pad, query: &QueryRef) {} |
| 87 | fn pad_unlink_post(&self, ts: u64, src: &Pad, sink: &Pad, success: bool) {} |
| 88 | fn pad_unlink_pre(&self, ts: u64, src: &Pad, sink: &Pad) {} |
| 89 | #[cfg (feature = "v1_20" )] |
| 90 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
| 91 | fn plugin_feature_loaded(&self, ts: u64, feature: &crate::PluginFeature) {} |
| 92 | } |
| 93 | |
| 94 | #[cfg (not(feature = "v1_26" ))] |
| 95 | fn format_available_properties(class: &glib::object::ObjectClass) -> String { |
| 96 | class |
| 97 | .list_properties() |
| 98 | .iter() |
| 99 | .filter(|p| { |
| 100 | p.flags().contains(glib::ParamFlags::WRITABLE) |
| 101 | && p.name() != "parent" |
| 102 | && p.name() != "params" |
| 103 | }) |
| 104 | .map(|p| format!(" {}: {}" , p.name(), p.blurb().map_or("" , |b| b))) |
| 105 | .collect::<Vec<_>>() |
| 106 | .join(sep:" \n" ) |
| 107 | } |
| 108 | |
| 109 | #[cfg (not(feature = "v1_26" ))] |
| 110 | fn emit_property_warning(obj: &glib::Object, msg: &str) { |
| 111 | let props: String = format_available_properties(obj.class()); |
| 112 | glib::g_warning!("gsttracer" , " {}\nAvailable properties: \n{}" , msg, props); |
| 113 | } |
| 114 | |
| 115 | unsafe impl<T: TracerImpl> IsSubclassable<T> for Tracer { |
| 116 | fn class_init(class: &mut glib::Class<Self>) { |
| 117 | Self::parent_class_init::<T>(class); |
| 118 | |
| 119 | #[cfg (feature = "v1_26" )] |
| 120 | { |
| 121 | let class = class.as_mut(); |
| 122 | unsafe { |
| 123 | ffi::gst_tracer_class_set_use_structure_params( |
| 124 | class, |
| 125 | T::USE_STRUCTURE_PARAMS.into_glib(), |
| 126 | ); |
| 127 | } |
| 128 | } |
| 129 | #[cfg (not(feature = "v1_26" ))] |
| 130 | unsafe { |
| 131 | if T::USE_STRUCTURE_PARAMS { |
| 132 | use std::sync::OnceLock; |
| 133 | static TRACER_CONSTRUCTED_FUNC: OnceLock< |
| 134 | unsafe extern "C" fn(*mut glib::gobject_ffi::GObject), |
| 135 | > = OnceLock::new(); |
| 136 | |
| 137 | let class = |
| 138 | &mut *(class.as_mut() as *mut _ as *mut glib::gobject_ffi::GObjectClass); |
| 139 | TRACER_CONSTRUCTED_FUNC.get_or_init(|| class.constructed.unwrap()); |
| 140 | unsafe extern "C" fn constructed(objptr: *mut glib::gobject_ffi::GObject) { |
| 141 | let obj = glib::Object::from_glib_borrow(objptr); |
| 142 | let params = obj.property::<Option<String>>("params" ); |
| 143 | |
| 144 | let Some(params) = params else { |
| 145 | TRACER_CONSTRUCTED_FUNC.get().unwrap()(objptr); |
| 146 | |
| 147 | return; |
| 148 | }; |
| 149 | |
| 150 | if params.is_empty() { |
| 151 | TRACER_CONSTRUCTED_FUNC.get().unwrap()(objptr); |
| 152 | |
| 153 | return; |
| 154 | } |
| 155 | |
| 156 | let s = match crate::Structure::from_str(&format!("tracer-settings, {}" , params)) |
| 157 | { |
| 158 | Ok(s) => s, |
| 159 | Err(err) => { |
| 160 | emit_property_warning( |
| 161 | &obj, |
| 162 | &format!( |
| 163 | "Can't setup tracer {err:?}: invalid parameters ' {params}'" |
| 164 | ), |
| 165 | ); |
| 166 | return; |
| 167 | } |
| 168 | }; |
| 169 | |
| 170 | let class = obj.class(); |
| 171 | |
| 172 | for (field, field_value) in s.iter() { |
| 173 | let pspec = match class.find_property(field.as_str()) { |
| 174 | Some(p) => p, |
| 175 | None => { |
| 176 | emit_property_warning( |
| 177 | &obj, |
| 178 | &format!( |
| 179 | "Can't setup tracer: property ' {}' not found" , |
| 180 | field.as_str() |
| 181 | ), |
| 182 | ); |
| 183 | return; |
| 184 | } |
| 185 | }; |
| 186 | |
| 187 | let value = if field_value.type_() == pspec.value_type() { |
| 188 | field_value.to_value() |
| 189 | } else if field_value.type_() == glib::types::Type::STRING { |
| 190 | let str_val = field_value.get::<String>().unwrap(); |
| 191 | #[cfg (feature = "v1_20" )] |
| 192 | { |
| 193 | match glib::Value::deserialize_with_pspec(&str_val, &pspec) { |
| 194 | Ok(v) => v, |
| 195 | Err(_) => { |
| 196 | emit_property_warning(&obj, &format!("Can't instantiate tracer: invalid property '{}' value: '{}'" , field.as_str(), str_val)); |
| 197 | return; |
| 198 | } |
| 199 | } |
| 200 | } |
| 201 | #[cfg (not(feature = "v1_20" ))] |
| 202 | { |
| 203 | match glib::Value::deserialize(&str_val, pspec.value_type()) { |
| 204 | Ok(v) => v, |
| 205 | Err(_) => { |
| 206 | emit_property_warning(&obj, &format!("Can't instantiate tracer: invalid property ' {}' value: ' {}'" , field.as_str(), str_val)); |
| 207 | return; |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | } else { |
| 212 | emit_property_warning(&obj, &format!( |
| 213 | "Can't setup tracer: property ' {}' type mismatch, expected {}, got {}" , |
| 214 | field.as_str(), |
| 215 | pspec.value_type().name(), |
| 216 | field_value.type_().name() |
| 217 | )); |
| 218 | return; |
| 219 | }; |
| 220 | |
| 221 | crate::debug!(crate::CAT_RUST, "Setting property {field:?}" ); |
| 222 | obj.set_property(field.as_str(), &value); |
| 223 | } |
| 224 | |
| 225 | TRACER_CONSTRUCTED_FUNC.get().unwrap()(objptr); |
| 226 | } |
| 227 | |
| 228 | class.constructed = Some(constructed); |
| 229 | } |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | pub trait TracerImplExt: ObjectSubclass { |
| 235 | // rustdoc-stripper-ignore-next |
| 236 | /// Register a corresponding hook to be called for this tracer when certain events occur. |
| 237 | /// |
| 238 | /// Upon an event a corresponding method in `TracerImpl` will be called. |
| 239 | fn register_hook(&self, hook: TracerHook); |
| 240 | } |
| 241 | |
| 242 | macro_rules! define_tracer_hooks { |
| 243 | ($($(#[$attr:meta])* $name: ident($quark: literal) = |$this: ident, $ts: ident, $($cb_arg: ident: $cb_arg_ty: ty),*| $impl: block;)*) => { |
| 244 | pub enum TracerHook { |
| 245 | $($(#[$attr])* $name),* |
| 246 | } |
| 247 | impl<T: TracerImpl> TracerImplExt for T { |
| 248 | fn register_hook(&self, hook: TracerHook) { |
| 249 | use TracerHook::*; |
| 250 | let (hook_type, callback) = match hook { |
| 251 | $($(#[$attr])* $name => { |
| 252 | #[allow(non_snake_case)] |
| 253 | unsafe extern "C" fn callback<T: TracerImpl>( |
| 254 | $this: *mut ffi::GstTracer, |
| 255 | $ts: u64, |
| 256 | $($cb_arg: $cb_arg_ty),* |
| 257 | ) { |
| 258 | let $this = Tracer::from_glib_borrow($this); |
| 259 | let $this = T::from_obj($this.unsafe_cast_ref()); |
| 260 | $impl |
| 261 | } |
| 262 | ( |
| 263 | concat!($quark, " \0" ), |
| 264 | callback::<T> as unsafe extern "C" fn(_, _, $($cb_arg_ty),*) as *const () |
| 265 | ) |
| 266 | },)* |
| 267 | }; |
| 268 | unsafe { |
| 269 | let instance = self.obj(); |
| 270 | ffi::gst_tracing_register_hook( |
| 271 | instance.to_glib_none().0 as *mut ffi::GstTracer, |
| 272 | hook_type.as_ptr() as *const _, |
| 273 | Some(std::mem::transmute::<*const (), extern "C" fn()>(callback)), |
| 274 | ); |
| 275 | } |
| 276 | } |
| 277 | } |
| 278 | }; |
| 279 | } |
| 280 | |
| 281 | define_tracer_hooks! { |
| 282 | BinAddPost("bin-add-post" ) = |this, ts, b: *mut ffi::GstBin, e: *mut ffi::GstElement, r: glib::ffi::gboolean| { |
| 283 | let b = Bin::from_glib_borrow(b); |
| 284 | let e = Element::from_glib_borrow(e); |
| 285 | this.bin_add_post(ts, &b, &e, bool::from_glib(r)) |
| 286 | }; |
| 287 | BinAddPre("bin-add-pre" ) = |this, ts, b: *mut ffi::GstBin, e: *mut ffi::GstElement| { |
| 288 | let b = Bin::from_glib_borrow(b); |
| 289 | let e = Element::from_glib_borrow(e); |
| 290 | this.bin_add_pre(ts, &b, &e) |
| 291 | }; |
| 292 | BinRemovePost("bin-remove-post" ) = |this, ts, b: *mut ffi::GstBin, r: glib::ffi::gboolean| { |
| 293 | let b = Bin::from_glib_borrow(b); |
| 294 | this.bin_remove_post(ts, &b, bool::from_glib(r)) |
| 295 | }; |
| 296 | BinRemovePre("bin-remove-pre" ) = |this, ts, b: *mut ffi::GstBin, e: *mut ffi::GstElement| { |
| 297 | let b = Bin::from_glib_borrow(b); |
| 298 | let e = Element::from_glib_borrow(e); |
| 299 | this.bin_remove_pre(ts, &b, &e) |
| 300 | }; |
| 301 | ElementNew("element-new" ) = |this, ts, e: *mut ffi::GstElement| { |
| 302 | let e = Element::from_glib_borrow(e); |
| 303 | this.element_new(ts, &e) |
| 304 | }; |
| 305 | ElementAddPad("element-add-pad" ) = |this, ts, e: *mut ffi::GstElement, p: *mut ffi::GstPad| { |
| 306 | let e = Element::from_glib_borrow(e); |
| 307 | let p = Pad::from_glib_borrow(p); |
| 308 | this.element_add_pad(ts, &e, &p) |
| 309 | }; |
| 310 | ElementRemovePad("element-remove-pad" ) = |this, ts, e: *mut ffi::GstElement, p: *mut ffi::GstPad| { |
| 311 | let e = Element::from_glib_borrow(e); |
| 312 | let p = Pad::from_glib_borrow(p); |
| 313 | this.element_remove_pad(ts, &e, &p) |
| 314 | }; |
| 315 | ElementChangeStatePost("element-change-state-post" ) = |this, ts, e: *mut ffi::GstElement, c: ffi::GstStateChange, r: ffi::GstStateChangeReturn| { |
| 316 | let e = Element::from_glib_borrow(e); |
| 317 | this.element_change_state_post(ts, &e, StateChange::from_glib(c), try_from_glib(r)) |
| 318 | }; |
| 319 | ElementChangeStatePre("element-change-state-pre" ) = |this, ts, e: *mut ffi::GstElement, c: ffi::GstStateChange| { |
| 320 | let e = Element::from_glib_borrow(e); |
| 321 | this.element_change_state_pre(ts, &e, StateChange::from_glib(c)) |
| 322 | }; |
| 323 | ElementPostMessagePost("element-post-message-post" ) = |this, ts, e: *mut ffi::GstElement, r: glib::ffi::gboolean| { |
| 324 | let e = Element::from_glib_borrow(e); |
| 325 | this.element_post_message_post(ts, &e, bool::from_glib(r)) |
| 326 | }; |
| 327 | ElementPostMessagePre("element-post-message-pre" ) = |this, ts, e: *mut ffi::GstElement, m: *mut ffi::GstMessage| { |
| 328 | let e = Element::from_glib_borrow(e); |
| 329 | let m = Message::from_glib_borrow(m); |
| 330 | this.element_post_message_pre(ts, &e, &m) |
| 331 | }; |
| 332 | ElementQueryPost("element-query-post" ) = |this, ts, e: *mut ffi::GstElement, q: *mut ffi::GstQuery, r: glib::ffi::gboolean| { |
| 333 | let e = Element::from_glib_borrow(e); |
| 334 | let q = QueryRef::from_ptr(q); |
| 335 | this.element_query_post(ts, &e, q, bool::from_glib(r)) |
| 336 | }; |
| 337 | ElementQueryPre("element-query-pre" ) = |this, ts, e: *mut ffi::GstElement, q: *mut ffi::GstQuery| { |
| 338 | let e = Element::from_glib_borrow(e); |
| 339 | let q = QueryRef::from_ptr(q); |
| 340 | this.element_query_pre(ts, &e, q) |
| 341 | }; |
| 342 | // TODO: unclear what to do here as the `GstMiniObject` here is not fully initialized yet… |
| 343 | MiniObjectCreated("mini-object-created" ) = |this, ts, o: *mut ffi::GstMiniObject| { |
| 344 | this.mini_object_created(ts, std::ptr::NonNull::new_unchecked(o)) |
| 345 | }; |
| 346 | // TODO: unclear what to do here as the `GstMiniObject` here is no longer valid… |
| 347 | MiniObjectDestroyed("mini-object-destroyed" ) = |this, ts, o: *mut ffi::GstMiniObject| { |
| 348 | this.mini_object_destroyed(ts, std::ptr::NonNull::new_unchecked(o)) |
| 349 | }; |
| 350 | MiniObjectReffed("mini-object-reffed" ) = |this, ts, o: *mut ffi::GstMiniObject, rc: libc::c_int| { |
| 351 | let o = MiniObject::from_glib_borrow(o); |
| 352 | this.mini_object_reffed(ts, &o, rc) |
| 353 | }; |
| 354 | MiniObjectUnreffed("mini-object-unreffed" ) = |this, ts, o: *mut ffi::GstMiniObject, rc: libc::c_int| { |
| 355 | let o = MiniObject::from_glib_borrow(o); |
| 356 | this.mini_object_unreffed(ts, &o, rc) |
| 357 | }; |
| 358 | ObjectCreated("object-created" ) = |this, ts, o: *mut ffi::GstObject| { |
| 359 | let o = Object::from_glib_borrow(o); |
| 360 | this.object_created(ts, &o) |
| 361 | }; |
| 362 | // TODO: unclear what to do here as the `GstObject` here is no longer valid… |
| 363 | ObjectDestroyed("object-destroyed" ) = |this, ts, o: *mut ffi::GstObject| { |
| 364 | this.object_destroyed(ts, std::ptr::NonNull::new_unchecked(o)) |
| 365 | }; |
| 366 | ObjectReffed("object-reffed" ) = |this, ts, o: *mut ffi::GstObject, rc: libc::c_int| { |
| 367 | let o = Object::from_glib_borrow(o); |
| 368 | this.object_reffed(ts, &o, rc) |
| 369 | }; |
| 370 | ObjectUnreffed("object-unreffed" ) = |this, ts, o: *mut ffi::GstObject, rc: libc::c_int| { |
| 371 | let o = Object::from_glib_borrow(o); |
| 372 | this.object_unreffed(ts, &o, rc) |
| 373 | }; |
| 374 | PadLinkPost("pad-link-post" ) = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad, r: ffi::GstPadLinkReturn| { |
| 375 | let src = Pad::from_glib_borrow(src); |
| 376 | let sink = Pad::from_glib_borrow(sink); |
| 377 | this.pad_link_post(ts, &src, &sink, try_from_glib(r)) |
| 378 | }; |
| 379 | PadLinkPre("pad-link-pre" ) = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad| { |
| 380 | let src = Pad::from_glib_borrow(src); |
| 381 | let sink = Pad::from_glib_borrow(sink); |
| 382 | this.pad_link_pre(ts, &src, &sink) |
| 383 | }; |
| 384 | PadPullRangePost("pad-pull-range-post" ) = |this, ts, p: *mut ffi::GstPad, b: *mut ffi::GstBuffer, r: ffi::GstFlowReturn| { |
| 385 | let p = Pad::from_glib_borrow(p); |
| 386 | let res: Result::<FlowSuccess, FlowError> = try_from_glib(r); |
| 387 | match res { |
| 388 | Ok(_) => { |
| 389 | this.pad_pull_range_post(ts, &p, Ok(&from_glib_borrow(b))) |
| 390 | } |
| 391 | Err(err) => { |
| 392 | this.pad_pull_range_post(ts, &p, Err(err)) |
| 393 | } |
| 394 | } |
| 395 | }; |
| 396 | PadPullRangePre("pad-pull-range-pre" ) = |this, ts, p: *mut ffi::GstPad, o: u64, s: libc::c_uint| { |
| 397 | let p = Pad::from_glib_borrow(p); |
| 398 | this.pad_pull_range_pre(ts, &p, o, s) |
| 399 | }; |
| 400 | PadPushEventPost("pad-push-event-post" ) = |this, ts, p: *mut ffi::GstPad, r: glib::ffi::gboolean| { |
| 401 | let p = Pad::from_glib_borrow(p); |
| 402 | this.pad_push_event_post(ts, &p, bool::from_glib(r)) |
| 403 | }; |
| 404 | PadPushEventPre("pad-push-event-pre" ) = |this, ts, p: *mut ffi::GstPad, e: *mut ffi::GstEvent| { |
| 405 | let p = Pad::from_glib_borrow(p); |
| 406 | let e = Event::from_glib_borrow(e); |
| 407 | this.pad_push_event_pre(ts, &p, &e) |
| 408 | }; |
| 409 | PadPushListPost("pad-push-list-post" ) = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| { |
| 410 | let p = Pad::from_glib_borrow(p); |
| 411 | this.pad_push_list_post(ts, &p, try_from_glib(r)) |
| 412 | }; |
| 413 | PadPushListPre("pad-push-list-pre" ) = |this, ts, p: *mut ffi::GstPad, bl: *mut ffi::GstBufferList| { |
| 414 | let p = Pad::from_glib_borrow(p); |
| 415 | let bl = BufferList::from_glib_borrow(bl); |
| 416 | this.pad_push_list_pre(ts, &p, &bl) |
| 417 | }; |
| 418 | PadPushPost("pad-push-post" ) = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| { |
| 419 | let p = Pad::from_glib_borrow(p); |
| 420 | this.pad_push_post(ts, &p, try_from_glib(r)) |
| 421 | }; |
| 422 | PadPushPre("pad-push-pre" ) = |this, ts, p: *mut ffi::GstPad, b: *mut ffi::GstBuffer| { |
| 423 | let p = Pad::from_glib_borrow(p); |
| 424 | let b = Buffer::from_glib_borrow(b); |
| 425 | this.pad_push_pre(ts, &p, &b) |
| 426 | }; |
| 427 | #[cfg (feature = "v1_22" )] |
| 428 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 429 | PadChainListPost("pad-chain-list-post" ) = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| { |
| 430 | let p = Pad::from_glib_borrow(p); |
| 431 | this.pad_chain_list_post(ts, &p, try_from_glib(r)) |
| 432 | }; |
| 433 | #[cfg (feature = "v1_22" )] |
| 434 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 435 | PadChainListPre("pad-chain-list-pre" ) = |this, ts, p: *mut ffi::GstPad, bl: *mut ffi::GstBufferList| { |
| 436 | let p = Pad::from_glib_borrow(p); |
| 437 | let bl = BufferList::from_glib_borrow(bl); |
| 438 | this.pad_chain_list_pre(ts, &p, &bl) |
| 439 | }; |
| 440 | #[cfg (feature = "v1_22" )] |
| 441 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 442 | PadChainPost("pad-chain-post" ) = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| { |
| 443 | let p = Pad::from_glib_borrow(p); |
| 444 | this.pad_chain_post(ts, &p, try_from_glib(r)) |
| 445 | }; |
| 446 | #[cfg (feature = "v1_22" )] |
| 447 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
| 448 | PadChainPre("pad-chain-pre" ) = |this, ts, p: *mut ffi::GstPad, b: *mut ffi::GstBuffer| { |
| 449 | let p = Pad::from_glib_borrow(p); |
| 450 | let b = Buffer::from_glib_borrow(b); |
| 451 | this.pad_chain_pre(ts, &p, &b) |
| 452 | }; |
| 453 | PadQueryPost("pad-query-post" ) = |this, ts, p: *mut ffi::GstPad, q: *mut ffi::GstQuery, r: glib::ffi::gboolean| { |
| 454 | let p = Pad::from_glib_borrow(p); |
| 455 | let q = QueryRef::from_ptr(q); |
| 456 | this.pad_query_post(ts, &p, q, bool::from_glib(r)) |
| 457 | }; |
| 458 | PadQueryPre("pad-query-pre" ) = |this, ts, p: *mut ffi::GstPad, q: *mut ffi::GstQuery| { |
| 459 | let p = Pad::from_glib_borrow(p); |
| 460 | let q = QueryRef::from_ptr(q); |
| 461 | this.pad_query_pre(ts, &p, q) |
| 462 | }; |
| 463 | PadUnlinkPost("pad-unlink-post" ) = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad, r: glib::ffi::gboolean| { |
| 464 | let src = Pad::from_glib_borrow(src); |
| 465 | let sink = Pad::from_glib_borrow(sink); |
| 466 | this.pad_unlink_post(ts, &src, &sink, bool::from_glib(r)) |
| 467 | }; |
| 468 | PadUnlinkPre("pad-unlink-pre" ) = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad| { |
| 469 | let src = Pad::from_glib_borrow(src); |
| 470 | let sink = Pad::from_glib_borrow(sink); |
| 471 | this.pad_unlink_pre(ts, &src, &sink) |
| 472 | }; |
| 473 | #[cfg (feature = "v1_20" )] |
| 474 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
| 475 | PluginFeatureLoaded("plugin-feature-loaded" ) = |this, ts, feature: *mut ffi::GstPluginFeature| { |
| 476 | let feature = crate::PluginFeature::from_glib_borrow(feature); |
| 477 | this.plugin_feature_loaded(ts, &feature) |
| 478 | }; |
| 479 | } |
| 480 | |