gst_plugin/
base_transform.rs

1// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::mem;
10use std::ptr;
11
12use glib_ffi;
13use gobject_ffi;
14use gst_base_ffi;
15use gst_ffi;
16
17use glib;
18use glib::translate::*;
19use gst;
20use gst::prelude::*;
21use gst_base;
22
23use gobject_subclass::anyimpl::*;
24use gobject_subclass::object::*;
25
26use element::*;
27use object::*;
28
29pub trait BaseTransformImpl<T: BaseTransformBase>:
30    AnyImpl + ObjectImpl<T> + ElementImpl<T> + Send + Sync + 'static
31where
32    T::InstanceStructType: PanicPoison,
33{
34    fn start(&self, _element: &T) -> bool {
35        true
36    }
37
38    fn stop(&self, _element: &T) -> bool {
39        true
40    }
41
42    fn transform_caps(
43        &self,
44        element: &T,
45        direction: gst::PadDirection,
46        caps: &gst::Caps,
47        filter: Option<&gst::Caps>,
48    ) -> gst::Caps {
49        element.parent_transform_caps(direction, caps, filter)
50    }
51
52    fn fixate_caps(
53        &self,
54        element: &T,
55        direction: gst::PadDirection,
56        caps: &gst::Caps,
57        othercaps: gst::Caps,
58    ) -> gst::Caps {
59        element.parent_fixate_caps(direction, caps, othercaps)
60    }
61
62    fn set_caps(&self, _element: &T, _incaps: &gst::Caps, _outcaps: &gst::Caps) -> bool {
63        true
64    }
65
66    fn accept_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps) -> bool {
67        element.parent_accept_caps(direction, caps)
68    }
69
70    fn query(&self, element: &T, direction: gst::PadDirection, query: &mut gst::QueryRef) -> bool {
71        element.parent_query(direction, query)
72    }
73
74    fn transform_size(
75        &self,
76        element: &T,
77        direction: gst::PadDirection,
78        caps: &gst::Caps,
79        size: usize,
80        othercaps: &gst::Caps,
81    ) -> Option<usize> {
82        element.parent_transform_size(direction, caps, size, othercaps)
83    }
84
85    fn get_unit_size(&self, _element: &T, _caps: &gst::Caps) -> Option<usize> {
86        unimplemented!();
87    }
88
89    fn sink_event(&self, element: &T, event: gst::Event) -> bool {
90        element.parent_sink_event(event)
91    }
92
93    fn src_event(&self, element: &T, event: gst::Event) -> bool {
94        element.parent_src_event(event)
95    }
96
97    fn transform(
98        &self,
99        _element: &T,
100        _inbuf: &gst::Buffer,
101        _outbuf: &mut gst::BufferRef,
102    ) -> gst::FlowReturn {
103        unimplemented!();
104    }
105
106    fn transform_ip(&self, _element: &T, _buf: &mut gst::BufferRef) -> gst::FlowReturn {
107        unimplemented!();
108    }
109
110    fn transform_ip_passthrough(&self, _element: &T, _buf: &gst::BufferRef) -> gst::FlowReturn {
111        unimplemented!();
112    }
113}
114
115any_impl!(BaseTransformBase, BaseTransformImpl, PanicPoison);
116
117pub unsafe trait BaseTransformBase:
118    IsA<gst::Element> + IsA<gst_base::BaseTransform> + ObjectType
119where
120    Self::InstanceStructType: PanicPoison,
121{
122    fn parent_transform_caps(
123        &self,
124        direction: gst::PadDirection,
125        caps: &gst::Caps,
126        filter: Option<&gst::Caps>,
127    ) -> gst::Caps {
128        unsafe {
129            let klass = self.get_class();
130            let parent_klass =
131                (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass;
132            match (*parent_klass).transform_caps {
133                Some(f) => from_glib_full(f(
134                    self.to_glib_none().0,
135                    direction.to_glib(),
136                    caps.to_glib_none().0,
137                    filter.to_glib_none().0,
138                )),
139                None => caps.clone(),
140            }
141        }
142    }
143
144    fn parent_fixate_caps(
145        &self,
146        direction: gst::PadDirection,
147        caps: &gst::Caps,
148        othercaps: gst::Caps,
149    ) -> gst::Caps {
150        unsafe {
151            let klass = self.get_class();
152            let parent_klass =
153                (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass;
154            match (*parent_klass).fixate_caps {
155                Some(f) => from_glib_full(f(
156                    self.to_glib_none().0,
157                    direction.to_glib(),
158                    caps.to_glib_none().0,
159                    othercaps.into_ptr(),
160                )),
161                None => othercaps,
162            }
163        }
164    }
165
166    fn parent_accept_caps(&self, direction: gst::PadDirection, caps: &gst::Caps) -> bool {
167        unsafe {
168            let klass = self.get_class();
169            let parent_klass =
170                (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass;
171            (*parent_klass)
172                .accept_caps
173                .map(|f| {
174                    from_glib(f(
175                        self.to_glib_none().0,
176                        direction.to_glib(),
177                        caps.to_glib_none().0,
178                    ))
179                })
180                .unwrap_or(false)
181        }
182    }
183
184    fn parent_query(&self, direction: gst::PadDirection, query: &mut gst::QueryRef) -> bool {
185        unsafe {
186            let klass = self.get_class();
187            let parent_klass =
188                (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass;
189            (*parent_klass)
190                .query
191                .map(|f| {
192                    from_glib(f(
193                        self.to_glib_none().0,
194                        direction.to_glib(),
195                        query.as_mut_ptr(),
196                    ))
197                })
198                .unwrap_or(false)
199        }
200    }
201
202    fn parent_transform_size(
203        &self,
204        direction: gst::PadDirection,
205        caps: &gst::Caps,
206        size: usize,
207        othercaps: &gst::Caps,
208    ) -> Option<usize> {
209        unsafe {
210            let klass = self.get_class();
211            let parent_klass =
212                (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass;
213            (*parent_klass)
214                .transform_size
215                .map(|f| {
216                    let mut othersize = 0;
217                    let res: bool = from_glib(f(
218                        self.to_glib_none().0,
219                        direction.to_glib(),
220                        caps.to_glib_none().0,
221                        size,
222                        othercaps.to_glib_none().0,
223                        &mut othersize,
224                    ));
225                    if res {
226                        Some(othersize)
227                    } else {
228                        None
229                    }
230                })
231                .unwrap_or(None)
232        }
233    }
234
235    fn parent_sink_event(&self, event: gst::Event) -> bool {
236        unsafe {
237            let klass = self.get_class();
238            let parent_klass =
239                (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass;
240            (*parent_klass)
241                .sink_event
242                .map(|f| from_glib(f(self.to_glib_none().0, event.into_ptr())))
243                .unwrap_or(false)
244        }
245    }
246
247    fn parent_src_event(&self, event: gst::Event) -> bool {
248        unsafe {
249            let klass = self.get_class();
250            let parent_klass =
251                (*klass).get_parent_class() as *const gst_base_ffi::GstBaseTransformClass;
252            (*parent_klass)
253                .src_event
254                .map(|f| from_glib(f(self.to_glib_none().0, event.into_ptr())))
255                .unwrap_or(false)
256        }
257    }
258}
259
260pub enum BaseTransformMode {
261    AlwaysInPlace,
262    NeverInPlace,
263    Both,
264}
265
266pub unsafe trait BaseTransformClassExt<T: BaseTransformBase>
267where
268    T::ImplType: BaseTransformImpl<T>,
269    T::InstanceStructType: PanicPoison,
270{
271    fn configure(
272        &mut self,
273        mode: BaseTransformMode,
274        passthrough_on_same_caps: bool,
275        transform_ip_on_passthrough: bool,
276    ) {
277        unsafe {
278            let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseTransformClass);
279
280            klass.passthrough_on_same_caps = passthrough_on_same_caps.to_glib();
281            klass.transform_ip_on_passthrough = transform_ip_on_passthrough.to_glib();
282
283            match mode {
284                BaseTransformMode::AlwaysInPlace => {
285                    klass.transform_ip = Some(base_transform_transform_ip::<T>);
286                }
287                BaseTransformMode::NeverInPlace => {
288                    klass.transform = Some(base_transform_transform::<T>);
289                }
290                BaseTransformMode::Both => {
291                    klass.transform = Some(base_transform_transform::<T>);
292                    klass.transform_ip = Some(base_transform_transform_ip::<T>);
293                }
294            }
295        }
296    }
297
298    fn override_vfuncs(&mut self, _: &ClassInitToken) {
299        unsafe {
300            let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseTransformClass);
301            klass.start = Some(base_transform_start::<T>);
302            klass.stop = Some(base_transform_stop::<T>);
303            klass.transform_caps = Some(base_transform_transform_caps::<T>);
304            klass.fixate_caps = Some(base_transform_fixate_caps::<T>);
305            klass.set_caps = Some(base_transform_set_caps::<T>);
306            klass.accept_caps = Some(base_transform_accept_caps::<T>);
307            klass.query = Some(base_transform_query::<T>);
308            klass.transform_size = Some(base_transform_transform_size::<T>);
309            klass.get_unit_size = Some(base_transform_get_unit_size::<T>);
310            klass.sink_event = Some(base_transform_sink_event::<T>);
311            klass.src_event = Some(base_transform_src_event::<T>);
312        }
313    }
314}
315
316glib_wrapper! {
317    pub struct BaseTransform(Object<ElementInstanceStruct<BaseTransform>>):
318        [gst_base::BaseTransform => gst_base_ffi::GstBaseTransform,
319         gst::Element => gst_ffi::GstElement,
320         gst::Object => gst_ffi::GstObject];
321
322    match fn {
323        get_type => || get_type::<BaseTransform>(),
324    }
325}
326
327unsafe impl<T: IsA<gst::Element> + IsA<gst_base::BaseTransform> + ObjectType> BaseTransformBase
328    for T
329where
330    T::InstanceStructType: PanicPoison,
331{
332}
333pub type BaseTransformClass = ClassStruct<BaseTransform>;
334
335// FIXME: Boilerplate
336unsafe impl BaseTransformClassExt<BaseTransform> for BaseTransformClass {}
337unsafe impl ElementClassExt<BaseTransform> for BaseTransformClass {}
338unsafe impl ObjectClassExt<BaseTransform> for BaseTransformClass {}
339
340unsafe impl Send for BaseTransform {}
341unsafe impl Sync for BaseTransform {}
342
343#[macro_export]
344macro_rules! box_base_transform_impl(
345    ($name:ident) => {
346        box_element_impl!($name);
347
348        impl<T: BaseTransformBase> BaseTransformImpl<T> for Box<$name<T>>
349        where
350            T::InstanceStructType: PanicPoison
351        {
352            fn start(&self, element: &T) -> bool {
353                let imp: &$name<T> = self.as_ref();
354                imp.start(element)
355            }
356
357            fn stop(&self, element: &T) -> bool {
358                let imp: &$name<T> = self.as_ref();
359                imp.stop(element)
360            }
361
362            fn transform_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps, filter: Option<&gst::Caps>) -> gst::Caps {
363                let imp: &$name<T> = self.as_ref();
364                imp.transform_caps(element, direction, caps, filter)
365            }
366
367            fn fixate_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps, othercaps: gst::Caps) -> gst::Caps {
368                let imp: &$name<T> = self.as_ref();
369                imp.fixate_caps(element, direction, caps, othercaps)
370            }
371
372            fn set_caps(&self, element: &T, incaps: &gst::Caps, outcaps: &gst::Caps) -> bool {
373                let imp: &$name<T> = self.as_ref();
374                imp.set_caps(element, incaps, outcaps)
375            }
376
377            fn accept_caps(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps) -> bool {
378                let imp: &$name<T> = self.as_ref();
379                imp.accept_caps(element, direction, caps)
380            }
381
382            fn query(&self, element: &T, direction: gst::PadDirection, query: &mut gst::QueryRef) -> bool {
383                let imp: &$name<T> = self.as_ref();
384                BaseTransformImpl::query(imp, element, direction, query)
385            }
386
387            fn transform_size(&self, element: &T, direction: gst::PadDirection, caps: &gst::Caps, size: usize, othercaps: &gst::Caps) -> Option<usize> {
388                let imp: &$name<T> = self.as_ref();
389                imp.transform_size(element, direction, caps, size, othercaps)
390            }
391
392            fn get_unit_size(&self, element: &T, caps: &gst::Caps) -> Option<usize> {
393                let imp: &$name<T> = self.as_ref();
394                imp.get_unit_size(element, caps)
395            }
396
397            fn sink_event(&self, element: &T, event: gst::Event) -> bool {
398                let imp: &$name<T> = self.as_ref();
399                imp.sink_event(element, event)
400            }
401
402            fn src_event(&self, element: &T, event: gst::Event) -> bool {
403                let imp: &$name<T> = self.as_ref();
404                imp.src_event(element, event)
405            }
406
407            fn transform(&self, element: &T, inbuf: &gst::Buffer, outbuf: &mut gst::BufferRef) -> gst::FlowReturn {
408                let imp: &$name<T> = self.as_ref();
409                imp.transform(element, inbuf, outbuf)
410            }
411
412            fn transform_ip(&self, element: &T, buf: &mut gst::BufferRef) -> gst::FlowReturn {
413                let imp: &$name<T> = self.as_ref();
414                imp.transform_ip(element, buf)
415            }
416
417            fn transform_ip_passthrough(&self, element: &T, buf: &gst::BufferRef) -> gst::FlowReturn {
418                let imp: &$name<T> = self.as_ref();
419                imp.transform_ip_passthrough(element, buf)
420            }
421        }
422    };
423);
424box_base_transform_impl!(BaseTransformImpl);
425
426impl ObjectType for BaseTransform {
427    const NAME: &'static str = "RsBaseTransform";
428    type ParentType = gst_base::BaseTransform;
429    type ImplType = Box<BaseTransformImpl<Self>>;
430    type InstanceStructType = ElementInstanceStruct<Self>;
431
432    fn class_init(token: &ClassInitToken, klass: &mut BaseTransformClass) {
433        ObjectClassExt::override_vfuncs(klass, token);
434        ElementClassExt::override_vfuncs(klass, token);
435        BaseTransformClassExt::override_vfuncs(klass, token);
436    }
437
438    object_type_fns!();
439}
440
441unsafe extern "C" fn base_transform_start<T: BaseTransformBase>(
442    ptr: *mut gst_base_ffi::GstBaseTransform,
443) -> glib_ffi::gboolean
444where
445    T::ImplType: BaseTransformImpl<T>,
446    T::InstanceStructType: PanicPoison,
447{
448    floating_reference_guard!(ptr);
449    let element = &*(ptr as *mut T::InstanceStructType);
450    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
451    let imp = element.get_impl();
452
453    panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib()
454}
455
456unsafe extern "C" fn base_transform_stop<T: BaseTransformBase>(
457    ptr: *mut gst_base_ffi::GstBaseTransform,
458) -> glib_ffi::gboolean
459where
460    T::ImplType: BaseTransformImpl<T>,
461    T::InstanceStructType: PanicPoison,
462{
463    floating_reference_guard!(ptr);
464    let element = &*(ptr as *mut T::InstanceStructType);
465    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
466    let imp = element.get_impl();
467
468    panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib()
469}
470
471unsafe extern "C" fn base_transform_transform_caps<T: BaseTransformBase>(
472    ptr: *mut gst_base_ffi::GstBaseTransform,
473    direction: gst_ffi::GstPadDirection,
474    caps: *mut gst_ffi::GstCaps,
475    filter: *mut gst_ffi::GstCaps,
476) -> *mut gst_ffi::GstCaps
477where
478    T::ImplType: BaseTransformImpl<T>,
479    T::InstanceStructType: PanicPoison,
480{
481    floating_reference_guard!(ptr);
482    let element = &*(ptr as *mut T::InstanceStructType);
483    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
484    let imp = element.get_impl();
485
486    panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), {
487        let filter = if filter.is_null() {
488            None
489        } else {
490            Some(from_glib_borrow(filter))
491        };
492
493        imp.transform_caps(
494            &wrap,
495            from_glib(direction),
496            &from_glib_borrow(caps),
497            filter.as_ref(),
498        )
499    })
500    .into_ptr()
501}
502
503unsafe extern "C" fn base_transform_fixate_caps<T: BaseTransformBase>(
504    ptr: *mut gst_base_ffi::GstBaseTransform,
505    direction: gst_ffi::GstPadDirection,
506    caps: *mut gst_ffi::GstCaps,
507    othercaps: *mut gst_ffi::GstCaps,
508) -> *mut gst_ffi::GstCaps
509where
510    T::ImplType: BaseTransformImpl<T>,
511    T::InstanceStructType: PanicPoison,
512{
513    floating_reference_guard!(ptr);
514    let element = &*(ptr as *mut T::InstanceStructType);
515    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
516    let imp = element.get_impl();
517
518    panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), {
519        imp.fixate_caps(
520            &wrap,
521            from_glib(direction),
522            &from_glib_borrow(caps),
523            from_glib_full(othercaps),
524        )
525    })
526    .into_ptr()
527}
528
529unsafe extern "C" fn base_transform_set_caps<T: BaseTransformBase>(
530    ptr: *mut gst_base_ffi::GstBaseTransform,
531    incaps: *mut gst_ffi::GstCaps,
532    outcaps: *mut gst_ffi::GstCaps,
533) -> glib_ffi::gboolean
534where
535    T::ImplType: BaseTransformImpl<T>,
536    T::InstanceStructType: PanicPoison,
537{
538    floating_reference_guard!(ptr);
539    let element = &*(ptr as *mut T::InstanceStructType);
540    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
541    let imp = element.get_impl();
542
543    panic_to_error!(&wrap, &element.panicked(), false, {
544        imp.set_caps(&wrap, &from_glib_borrow(incaps), &from_glib_borrow(outcaps))
545    })
546    .to_glib()
547}
548
549unsafe extern "C" fn base_transform_accept_caps<T: BaseTransformBase>(
550    ptr: *mut gst_base_ffi::GstBaseTransform,
551    direction: gst_ffi::GstPadDirection,
552    caps: *mut gst_ffi::GstCaps,
553) -> glib_ffi::gboolean
554where
555    T::ImplType: BaseTransformImpl<T>,
556    T::InstanceStructType: PanicPoison,
557{
558    floating_reference_guard!(ptr);
559    let element = &*(ptr as *mut T::InstanceStructType);
560    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
561    let imp = element.get_impl();
562
563    panic_to_error!(&wrap, &element.panicked(), false, {
564        imp.accept_caps(&wrap, from_glib(direction), &from_glib_borrow(caps))
565    })
566    .to_glib()
567}
568
569unsafe extern "C" fn base_transform_query<T: BaseTransformBase>(
570    ptr: *mut gst_base_ffi::GstBaseTransform,
571    direction: gst_ffi::GstPadDirection,
572    query: *mut gst_ffi::GstQuery,
573) -> glib_ffi::gboolean
574where
575    T::ImplType: BaseTransformImpl<T>,
576    T::InstanceStructType: PanicPoison,
577{
578    floating_reference_guard!(ptr);
579    let element = &*(ptr as *mut T::InstanceStructType);
580    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
581    let imp = element.get_impl();
582
583    panic_to_error!(&wrap, &element.panicked(), false, {
584        BaseTransformImpl::query(
585            imp,
586            &wrap,
587            from_glib(direction),
588            gst::QueryRef::from_mut_ptr(query),
589        )
590    })
591    .to_glib()
592}
593
594unsafe extern "C" fn base_transform_transform_size<T: BaseTransformBase>(
595    ptr: *mut gst_base_ffi::GstBaseTransform,
596    direction: gst_ffi::GstPadDirection,
597    caps: *mut gst_ffi::GstCaps,
598    size: usize,
599    othercaps: *mut gst_ffi::GstCaps,
600    othersize: *mut usize,
601) -> glib_ffi::gboolean
602where
603    T::ImplType: BaseTransformImpl<T>,
604    T::InstanceStructType: PanicPoison,
605{
606    floating_reference_guard!(ptr);
607    let element = &*(ptr as *mut T::InstanceStructType);
608    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
609    let imp = element.get_impl();
610
611    panic_to_error!(&wrap, &element.panicked(), false, {
612        match imp.transform_size(
613            &wrap,
614            from_glib(direction),
615            &from_glib_borrow(caps),
616            size,
617            &from_glib_borrow(othercaps),
618        ) {
619            Some(s) => {
620                *othersize = s;
621                true
622            }
623            None => false,
624        }
625    })
626    .to_glib()
627}
628
629unsafe extern "C" fn base_transform_get_unit_size<T: BaseTransformBase>(
630    ptr: *mut gst_base_ffi::GstBaseTransform,
631    caps: *mut gst_ffi::GstCaps,
632    size: *mut usize,
633) -> glib_ffi::gboolean
634where
635    T::ImplType: BaseTransformImpl<T>,
636    T::InstanceStructType: PanicPoison,
637{
638    floating_reference_guard!(ptr);
639    let element = &*(ptr as *mut T::InstanceStructType);
640    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
641    let imp = element.get_impl();
642
643    panic_to_error!(&wrap, &element.panicked(), false, {
644        match imp.get_unit_size(&wrap, &from_glib_borrow(caps)) {
645            Some(s) => {
646                *size = s;
647                true
648            }
649            None => false,
650        }
651    })
652    .to_glib()
653}
654
655unsafe extern "C" fn base_transform_sink_event<T: BaseTransformBase>(
656    ptr: *mut gst_base_ffi::GstBaseTransform,
657    event: *mut gst_ffi::GstEvent,
658) -> glib_ffi::gboolean
659where
660    T::ImplType: BaseTransformImpl<T>,
661    T::InstanceStructType: PanicPoison,
662{
663    floating_reference_guard!(ptr);
664    let element = &*(ptr as *mut T::InstanceStructType);
665    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
666    let imp = element.get_impl();
667
668    panic_to_error!(&wrap, &element.panicked(), false, {
669        imp.sink_event(&wrap, from_glib_full(event))
670    })
671    .to_glib()
672}
673
674unsafe extern "C" fn base_transform_src_event<T: BaseTransformBase>(
675    ptr: *mut gst_base_ffi::GstBaseTransform,
676    event: *mut gst_ffi::GstEvent,
677) -> glib_ffi::gboolean
678where
679    T::ImplType: BaseTransformImpl<T>,
680    T::InstanceStructType: PanicPoison,
681{
682    floating_reference_guard!(ptr);
683    let element = &*(ptr as *mut T::InstanceStructType);
684    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
685    let imp = element.get_impl();
686
687    panic_to_error!(&wrap, &element.panicked(), false, {
688        imp.src_event(&wrap, from_glib_full(event))
689    })
690    .to_glib()
691}
692
693unsafe extern "C" fn base_transform_transform<T: BaseTransformBase>(
694    ptr: *mut gst_base_ffi::GstBaseTransform,
695    inbuf: *mut gst_ffi::GstBuffer,
696    outbuf: *mut gst_ffi::GstBuffer,
697) -> gst_ffi::GstFlowReturn
698where
699    T::ImplType: BaseTransformImpl<T>,
700    T::InstanceStructType: PanicPoison,
701{
702    floating_reference_guard!(ptr);
703    let element = &*(ptr as *mut T::InstanceStructType);
704    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
705    let imp = element.get_impl();
706
707    panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, {
708        imp.transform(
709            &wrap,
710            &from_glib_borrow(inbuf),
711            gst::BufferRef::from_mut_ptr(outbuf),
712        )
713    })
714    .to_glib()
715}
716
717unsafe extern "C" fn base_transform_transform_ip<T: BaseTransformBase>(
718    ptr: *mut gst_base_ffi::GstBaseTransform,
719    buf: *mut *mut gst_ffi::GstBuffer,
720) -> gst_ffi::GstFlowReturn
721where
722    T::ImplType: BaseTransformImpl<T>,
723    T::InstanceStructType: PanicPoison,
724{
725    floating_reference_guard!(ptr);
726    let element = &*(ptr as *mut T::InstanceStructType);
727    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
728    let imp = element.get_impl();
729
730    // FIXME: Wrong signature in FFI
731    let buf = buf as *mut gst_ffi::GstBuffer;
732
733    panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, {
734        if from_glib(gst_base_ffi::gst_base_transform_is_passthrough(ptr)) {
735            imp.transform_ip_passthrough(&wrap, gst::BufferRef::from_ptr(buf))
736        } else {
737            imp.transform_ip(&wrap, gst::BufferRef::from_mut_ptr(buf))
738        }
739    })
740    .to_glib()
741}