1#[cfg(not(feature = "v1_26"))]
4use {crate::value::GstValueExt, std::str::FromStr};
5
6use glib::{prelude::*, subclass::prelude::*, translate::*};
7
8use super::prelude::*;
9use crate::{
10 Bin, Buffer, BufferList, Element, Event, FlowError, FlowSuccess, Message, MiniObject, Object,
11 Pad, PadLinkError, PadLinkSuccess, QueryRef, StateChange, StateChangeError, StateChangeSuccess,
12 Tracer, ffi,
13};
14
15#[allow(unused_variables)]
16pub trait TracerImpl: GstObjectImpl + ObjectSubclass<Type: IsA<Tracer>> {
17 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 fn mini_object_created(&self, ts: u64, object: std::ptr::NonNull<ffi::GstMiniObject>) {}
45 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 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 #[cfg(feature = "v1_26")]
93 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
94 fn memory_init(&self, ts: u64, mem: &crate::MemoryRefTrace) {}
95 #[cfg(feature = "v1_26")]
96 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
97 fn memory_free_pre(&self, ts: u64, mem: &crate::MemoryRef) {}
98 #[cfg(feature = "v1_26")]
99 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
100 fn memory_free_post(&self, ts: u64, mem: std::ptr::NonNull<ffi::GstMemory>) {}
101
102 #[cfg(feature = "v1_28")]
103 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
104 fn pool_buffer_queued(&self, ts: u64, pool: &crate::BufferPool, buffer: &Buffer) {}
105 #[cfg(feature = "v1_28")]
106 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
107 fn pool_buffer_dequeued(&self, ts: u64, pool: &crate::BufferPool, buffer: &Buffer) {}
108}
109
110#[cfg(not(feature = "v1_26"))]
111fn format_available_properties(class: &glib::object::ObjectClass) -> String {
112 class
113 .list_properties()
114 .iter()
115 .filter(|p| {
116 p.flags().contains(glib::ParamFlags::WRITABLE)
117 && p.name() != "parent"
118 && p.name() != "params"
119 })
120 .map(|p| format!(" {}: {}", p.name(), p.blurb().map_or("", |b| b)))
121 .collect::<Vec<_>>()
122 .join("\n")
123}
124
125#[cfg(not(feature = "v1_26"))]
126fn emit_property_warning(obj: &glib::Object, msg: &str) {
127 let props = format_available_properties(obj.class());
128 glib::g_warning!("gsttracer", "{}\nAvailable properties:\n{}", msg, props);
129}
130
131unsafe impl<T: TracerImpl> IsSubclassable<T> for Tracer {
132 fn class_init(class: &mut glib::Class<Self>) {
133 Self::parent_class_init::<T>(class);
134
135 #[cfg(feature = "v1_26")]
136 {
137 let class = class.as_mut();
138 unsafe {
139 ffi::gst_tracer_class_set_use_structure_params(
140 class,
141 T::USE_STRUCTURE_PARAMS.into_glib(),
142 );
143 }
144 }
145 #[cfg(not(feature = "v1_26"))]
146 unsafe {
147 if T::USE_STRUCTURE_PARAMS {
148 use std::sync::OnceLock;
149 static TRACER_CONSTRUCTED_FUNC: OnceLock<
150 unsafe extern "C" fn(*mut glib::gobject_ffi::GObject),
151 > = OnceLock::new();
152
153 let class =
154 &mut *(class.as_mut() as *mut _ as *mut glib::gobject_ffi::GObjectClass);
155 TRACER_CONSTRUCTED_FUNC.get_or_init(|| class.constructed.unwrap());
156 unsafe extern "C" fn constructed(objptr: *mut glib::gobject_ffi::GObject) {
157 let obj = unsafe { glib::Object::from_glib_ptr_borrow(&objptr) };
158 let params = obj.property::<Option<String>>("params");
159
160 let Some(params) = params else {
161 unsafe {
162 TRACER_CONSTRUCTED_FUNC.get().unwrap()(objptr);
163 }
164
165 return;
166 };
167
168 if params.is_empty() {
169 unsafe {
170 TRACER_CONSTRUCTED_FUNC.get().unwrap()(objptr);
171 }
172
173 return;
174 }
175
176 let s = match crate::Structure::from_str(&format!("tracer-settings,{params}")) {
177 Ok(s) => s,
178 Err(err) => {
179 emit_property_warning(
180 obj,
181 &format!(
182 "Can't setup tracer {err:?}: invalid parameters '{params}'"
183 ),
184 );
185 return;
186 }
187 };
188
189 let class = obj.class();
190
191 for (field, field_value) in s.iter() {
192 let pspec = match class.find_property(field.as_str()) {
193 Some(p) => p,
194 None => {
195 emit_property_warning(
196 obj,
197 &format!(
198 "Can't setup tracer: property '{}' not found",
199 field.as_str()
200 ),
201 );
202 return;
203 }
204 };
205
206 let value = if field_value.type_() == pspec.value_type() {
207 field_value.to_value()
208 } else if field_value.type_() == glib::types::Type::STRING {
209 let str_val = field_value.get::<String>().unwrap();
210 #[cfg(feature = "v1_20")]
211 {
212 match glib::Value::deserialize_with_pspec(&str_val, &pspec) {
213 Ok(v) => v,
214 Err(_) => {
215 emit_property_warning(
216 obj,
217 &format!(
218 "Can't instantiate tracer: invalid property '{}' value: '{}'",
219 field.as_str(),
220 str_val
221 ),
222 );
223 return;
224 }
225 }
226 }
227 #[cfg(not(feature = "v1_20"))]
228 {
229 match glib::Value::deserialize(&str_val, pspec.value_type()) {
230 Ok(v) => v,
231 Err(_) => {
232 emit_property_warning(
233 obj,
234 &format!(
235 "Can't instantiate tracer: invalid property '{}' value: '{}'",
236 field.as_str(),
237 str_val
238 ),
239 );
240 return;
241 }
242 }
243 }
244 } else {
245 emit_property_warning(
246 obj,
247 &format!(
248 "Can't setup tracer: property '{}' type mismatch, expected {}, got {}",
249 field.as_str(),
250 pspec.value_type().name(),
251 field_value.type_().name()
252 ),
253 );
254 return;
255 };
256
257 crate::debug!(crate::CAT_RUST, "Setting property {field:?}");
258 obj.set_property(field.as_str(), &value);
259 }
260
261 unsafe {
262 TRACER_CONSTRUCTED_FUNC.get().unwrap()(objptr);
263 }
264 }
265
266 class.constructed = Some(constructed);
267 }
268 }
269 }
270}
271
272pub trait TracerImplExt: TracerImpl {
273 fn register_hook(&self, hook: TracerHook);
278}
279
280macro_rules! define_tracer_hooks {
281 ($($(#[$attr:meta])* $name: ident($quark: literal) = |$this: ident, $ts: ident, $($cb_arg: ident: $cb_arg_ty: ty),*| $impl: block;)*) => {
282 pub enum TracerHook {
283 $($(#[$attr])* $name),*
284 }
285 impl<T: TracerImpl> TracerImplExt for T {
286 fn register_hook(&self, hook: TracerHook) {
287 use TracerHook::*;
288 let (hook_type, callback) = match hook {
289 $($(#[$attr])* $name => {
290 #[allow(non_snake_case)]
291 unsafe extern "C" fn callback<T: TracerImpl>(
292 $this: *mut ffi::GstTracer,
293 $ts: u64,
294 $($cb_arg: $cb_arg_ty),*
295 ) { unsafe {
296 let $this = Tracer::from_glib_borrow($this);
297 let $this = T::from_obj($this.unsafe_cast_ref());
298 $impl
299 }}
300 (
301 concat!($quark, "\0"),
302 callback::<T> as unsafe extern "C" fn(_, _, $($cb_arg_ty),*) as *const ()
303 )
304 },)*
305 };
306 unsafe {
307 let instance = self.obj();
308 ffi::gst_tracing_register_hook(
309 instance.to_glib_none().0 as *mut ffi::GstTracer,
310 hook_type.as_ptr() as *const _,
311 Some(std::mem::transmute::<*const (), extern "C" fn()>(callback)),
312 );
313 }
314 }
315 }
316 };
317}
318
319define_tracer_hooks! {
320 BinAddPost("bin-add-post") = |this, ts, b: *mut ffi::GstBin, e: *mut ffi::GstElement, r: glib::ffi::gboolean| {
321 let b = Bin::from_glib_borrow(b);
322 let e = Element::from_glib_borrow(e);
323 this.bin_add_post(ts, &b, &e, bool::from_glib(r))
324 };
325 BinAddPre("bin-add-pre") = |this, ts, b: *mut ffi::GstBin, e: *mut ffi::GstElement| {
326 let b = Bin::from_glib_borrow(b);
327 let e = Element::from_glib_borrow(e);
328 this.bin_add_pre(ts, &b, &e)
329 };
330 BinRemovePost("bin-remove-post") = |this, ts, b: *mut ffi::GstBin, r: glib::ffi::gboolean| {
331 let b = Bin::from_glib_borrow(b);
332 this.bin_remove_post(ts, &b, bool::from_glib(r))
333 };
334 BinRemovePre("bin-remove-pre") = |this, ts, b: *mut ffi::GstBin, e: *mut ffi::GstElement| {
335 let b = Bin::from_glib_borrow(b);
336 let e = Element::from_glib_borrow(e);
337 this.bin_remove_pre(ts, &b, &e)
338 };
339 ElementNew("element-new") = |this, ts, e: *mut ffi::GstElement| {
340 let e = Element::from_glib_borrow(e);
341 this.element_new(ts, &e)
342 };
343 ElementAddPad("element-add-pad") = |this, ts, e: *mut ffi::GstElement, p: *mut ffi::GstPad| {
344 let e = Element::from_glib_borrow(e);
345 let p = Pad::from_glib_borrow(p);
346 this.element_add_pad(ts, &e, &p)
347 };
348 ElementRemovePad("element-remove-pad") = |this, ts, e: *mut ffi::GstElement, p: *mut ffi::GstPad| {
349 let e = Element::from_glib_borrow(e);
350 let p = Pad::from_glib_borrow(p);
351 this.element_remove_pad(ts, &e, &p)
352 };
353 ElementChangeStatePost("element-change-state-post") = |this, ts, e: *mut ffi::GstElement, c: ffi::GstStateChange, r: ffi::GstStateChangeReturn| {
354 let e = Element::from_glib_borrow(e);
355 this.element_change_state_post(ts, &e, StateChange::from_glib(c), try_from_glib(r))
356 };
357 ElementChangeStatePre("element-change-state-pre") = |this, ts, e: *mut ffi::GstElement, c: ffi::GstStateChange| {
358 let e = Element::from_glib_borrow(e);
359 this.element_change_state_pre(ts, &e, StateChange::from_glib(c))
360 };
361 ElementPostMessagePost("element-post-message-post") = |this, ts, e: *mut ffi::GstElement, r: glib::ffi::gboolean| {
362 let e = Element::from_glib_borrow(e);
363 this.element_post_message_post(ts, &e, bool::from_glib(r))
364 };
365 ElementPostMessagePre("element-post-message-pre") = |this, ts, e: *mut ffi::GstElement, m: *mut ffi::GstMessage| {
366 let e = Element::from_glib_borrow(e);
367 let m = Message::from_glib_borrow(m);
368 this.element_post_message_pre(ts, &e, &m)
369 };
370 ElementQueryPost("element-query-post") = |this, ts, e: *mut ffi::GstElement, q: *mut ffi::GstQuery, r: glib::ffi::gboolean| {
371 let e = Element::from_glib_borrow(e);
372 let q = QueryRef::from_ptr(q);
373 this.element_query_post(ts, &e, q, bool::from_glib(r))
374 };
375 ElementQueryPre("element-query-pre") = |this, ts, e: *mut ffi::GstElement, q: *mut ffi::GstQuery| {
376 let e = Element::from_glib_borrow(e);
377 let q = QueryRef::from_ptr(q);
378 this.element_query_pre(ts, &e, q)
379 };
380 MiniObjectCreated("mini-object-created") = |this, ts, o: *mut ffi::GstMiniObject| {
382 this.mini_object_created(ts, std::ptr::NonNull::new_unchecked(o))
383 };
384 MiniObjectDestroyed("mini-object-destroyed") = |this, ts, o: *mut ffi::GstMiniObject| {
386 this.mini_object_destroyed(ts, std::ptr::NonNull::new_unchecked(o))
387 };
388 MiniObjectReffed("mini-object-reffed") = |this, ts, o: *mut ffi::GstMiniObject, rc: libc::c_int| {
389 let o = MiniObject::from_glib_borrow(o);
390 this.mini_object_reffed(ts, &o, rc)
391 };
392 MiniObjectUnreffed("mini-object-unreffed") = |this, ts, o: *mut ffi::GstMiniObject, rc: libc::c_int| {
393 let o = MiniObject::from_glib_borrow(o);
394 this.mini_object_unreffed(ts, &o, rc)
395 };
396 ObjectCreated("object-created") = |this, ts, o: *mut ffi::GstObject| {
397 let o = Object::from_glib_borrow(o);
398 this.object_created(ts, &o)
399 };
400 ObjectDestroyed("object-destroyed") = |this, ts, o: *mut ffi::GstObject| {
402 this.object_destroyed(ts, std::ptr::NonNull::new_unchecked(o))
403 };
404 ObjectReffed("object-reffed") = |this, ts, o: *mut ffi::GstObject, rc: libc::c_int| {
405 let o = Object::from_glib_borrow(o);
406 this.object_reffed(ts, &o, rc)
407 };
408 ObjectUnreffed("object-unreffed") = |this, ts, o: *mut ffi::GstObject, rc: libc::c_int| {
409 let o = Object::from_glib_borrow(o);
410 this.object_unreffed(ts, &o, rc)
411 };
412 PadLinkPost("pad-link-post") = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad, r: ffi::GstPadLinkReturn| {
413 let src = Pad::from_glib_borrow(src);
414 let sink = Pad::from_glib_borrow(sink);
415 this.pad_link_post(ts, &src, &sink, try_from_glib(r))
416 };
417 PadLinkPre("pad-link-pre") = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad| {
418 let src = Pad::from_glib_borrow(src);
419 let sink = Pad::from_glib_borrow(sink);
420 this.pad_link_pre(ts, &src, &sink)
421 };
422 PadPullRangePost("pad-pull-range-post") = |this, ts, p: *mut ffi::GstPad, b: *mut ffi::GstBuffer, r: ffi::GstFlowReturn| {
423 let p = Pad::from_glib_borrow(p);
424 let res: Result::<FlowSuccess, FlowError> = try_from_glib(r);
425 match res {
426 Ok(_) => {
427 this.pad_pull_range_post(ts, &p, Ok(&from_glib_borrow(b)))
428 }
429 Err(err) => {
430 this.pad_pull_range_post(ts, &p, Err(err))
431 }
432 }
433 };
434 PadPullRangePre("pad-pull-range-pre") = |this, ts, p: *mut ffi::GstPad, o: u64, s: libc::c_uint| {
435 let p = Pad::from_glib_borrow(p);
436 this.pad_pull_range_pre(ts, &p, o, s)
437 };
438 PadPushEventPost("pad-push-event-post") = |this, ts, p: *mut ffi::GstPad, r: glib::ffi::gboolean| {
439 let p = Pad::from_glib_borrow(p);
440 this.pad_push_event_post(ts, &p, bool::from_glib(r))
441 };
442 PadPushEventPre("pad-push-event-pre") = |this, ts, p: *mut ffi::GstPad, e: *mut ffi::GstEvent| {
443 let p = Pad::from_glib_borrow(p);
444 let e = Event::from_glib_borrow(e);
445 this.pad_push_event_pre(ts, &p, &e)
446 };
447 PadPushListPost("pad-push-list-post") = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| {
448 let p = Pad::from_glib_borrow(p);
449 this.pad_push_list_post(ts, &p, try_from_glib(r))
450 };
451 PadPushListPre("pad-push-list-pre") = |this, ts, p: *mut ffi::GstPad, bl: *mut ffi::GstBufferList| {
452 let p = Pad::from_glib_borrow(p);
453 let bl = BufferList::from_glib_borrow(bl);
454 this.pad_push_list_pre(ts, &p, &bl)
455 };
456 PadPushPost("pad-push-post") = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| {
457 let p = Pad::from_glib_borrow(p);
458 this.pad_push_post(ts, &p, try_from_glib(r))
459 };
460 PadPushPre("pad-push-pre") = |this, ts, p: *mut ffi::GstPad, b: *mut ffi::GstBuffer| {
461 let p = Pad::from_glib_borrow(p);
462 let b = Buffer::from_glib_borrow(b);
463 this.pad_push_pre(ts, &p, &b)
464 };
465 #[cfg(feature = "v1_22")]
466 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
467 PadChainListPost("pad-chain-list-post") = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| {
468 let p = Pad::from_glib_borrow(p);
469 this.pad_chain_list_post(ts, &p, try_from_glib(r))
470 };
471 #[cfg(feature = "v1_22")]
472 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
473 PadChainListPre("pad-chain-list-pre") = |this, ts, p: *mut ffi::GstPad, bl: *mut ffi::GstBufferList| {
474 let p = Pad::from_glib_borrow(p);
475 let bl = BufferList::from_glib_borrow(bl);
476 this.pad_chain_list_pre(ts, &p, &bl)
477 };
478 #[cfg(feature = "v1_22")]
479 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
480 PadChainPost("pad-chain-post") = |this, ts, p: *mut ffi::GstPad, r: ffi::GstFlowReturn| {
481 let p = Pad::from_glib_borrow(p);
482 this.pad_chain_post(ts, &p, try_from_glib(r))
483 };
484 #[cfg(feature = "v1_22")]
485 #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
486 PadChainPre("pad-chain-pre") = |this, ts, p: *mut ffi::GstPad, b: *mut ffi::GstBuffer| {
487 let p = Pad::from_glib_borrow(p);
488 let b = Buffer::from_glib_borrow(b);
489 this.pad_chain_pre(ts, &p, &b)
490 };
491 PadQueryPost("pad-query-post") = |this, ts, p: *mut ffi::GstPad, q: *mut ffi::GstQuery, r: glib::ffi::gboolean| {
492 let p = Pad::from_glib_borrow(p);
493 let q = QueryRef::from_ptr(q);
494 this.pad_query_post(ts, &p, q, bool::from_glib(r))
495 };
496 PadQueryPre("pad-query-pre") = |this, ts, p: *mut ffi::GstPad, q: *mut ffi::GstQuery| {
497 let p = Pad::from_glib_borrow(p);
498 let q = QueryRef::from_ptr(q);
499 this.pad_query_pre(ts, &p, q)
500 };
501 PadUnlinkPost("pad-unlink-post") = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad, r: glib::ffi::gboolean| {
502 let src = Pad::from_glib_borrow(src);
503 let sink = Pad::from_glib_borrow(sink);
504 this.pad_unlink_post(ts, &src, &sink, bool::from_glib(r))
505 };
506 PadUnlinkPre("pad-unlink-pre") = |this, ts, src: *mut ffi::GstPad, sink: *mut ffi::GstPad| {
507 let src = Pad::from_glib_borrow(src);
508 let sink = Pad::from_glib_borrow(sink);
509 this.pad_unlink_pre(ts, &src, &sink)
510 };
511 #[cfg(feature = "v1_20")]
512 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
513 PluginFeatureLoaded("plugin-feature-loaded") = |this, ts, feature: *mut ffi::GstPluginFeature| {
514 let feature = crate::PluginFeature::from_glib_borrow(feature);
515 this.plugin_feature_loaded(ts, &feature)
516 };
517
518 #[cfg(feature = "v1_26")]
519 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
520 MemoryInit("memory-init") = |this, ts, memory: *mut ffi::GstMemory| {
521 let memory = crate::MemoryRefTrace::from_ptr(memory);
522 this.memory_init(ts, memory)
523 };
524 #[cfg(feature = "v1_26")]
525 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
526 MemoryFreePre("memory-free-pre") = |this, ts, memory: *mut ffi::GstMemory| {
527 let memory = crate::MemoryRef::from_ptr(memory);
528 this.memory_free_pre(ts, memory)
529 };
530 #[cfg(feature = "v1_26")]
531 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
532 MemoryFreePost("memory-free-post") = |this, ts, memory: *mut ffi::GstMemory| {
533 this.memory_free_post(ts, std::ptr::NonNull::new_unchecked(memory))
534 };
535 #[cfg(feature = "v1_28")]
536 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
537 PoolBufferQueued("pool-buffer-queued") = |this, ts, pool: *mut ffi::GstBufferPool, buffer: *mut ffi::GstBuffer| {
538 let pool = crate::BufferPool::from_glib_borrow(pool);
539 let b = Buffer::from_glib_borrow(buffer);
540
541 this.pool_buffer_queued(ts, &pool, &b)
542 };
543 #[cfg(feature = "v1_28")]
544 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
545 PoolBufferDequeued("pool-buffer-dequeued") = |this, ts, pool: *mut ffi::GstBufferPool, buffer: *mut ffi::GstBuffer| {
546 let pool = crate::BufferPool::from_glib_borrow(pool);
547 let b = Buffer::from_glib_borrow(buffer);
548
549 this.pool_buffer_dequeued(ts, &pool, &b)
550 };
551}