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 | |