gst_plugin/
base_src.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 BaseSrcImpl<T: BaseSrcBase>:
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 is_seekable(&self, _element: &T) -> bool {
43        false
44    }
45
46    fn get_size(&self, _element: &T) -> Option<u64> {
47        None
48    }
49
50    fn fill(
51        &self,
52        _element: &T,
53        _offset: u64,
54        _length: u32,
55        _buffer: &mut gst::BufferRef,
56    ) -> gst::FlowReturn {
57        unimplemented!()
58    }
59
60    fn create(
61        &self,
62        element: &T,
63        offset: u64,
64        length: u32,
65    ) -> Result<gst::Buffer, gst::FlowReturn> {
66        element.parent_create(offset, length)
67    }
68
69    fn do_seek(&self, element: &T, segment: &mut gst::Segment) -> bool {
70        element.parent_do_seek(segment)
71    }
72
73    fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool {
74        element.parent_query(query)
75    }
76
77    fn event(&self, element: &T, event: &gst::Event) -> bool {
78        element.parent_event(event)
79    }
80
81    fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option<gst::Caps> {
82        element.parent_get_caps(filter)
83    }
84
85    fn negotiate(&self, element: &T) -> bool {
86        element.parent_negotiate()
87    }
88
89    fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool {
90        element.parent_set_caps(caps)
91    }
92
93    fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps {
94        element.parent_fixate(caps)
95    }
96
97    fn unlock(&self, _element: &T) -> bool {
98        true
99    }
100
101    fn unlock_stop(&self, _element: &T) -> bool {
102        true
103    }
104}
105
106any_impl!(BaseSrcBase, BaseSrcImpl, PanicPoison);
107
108pub unsafe trait BaseSrcBase:
109    IsA<gst::Element> + IsA<gst_base::BaseSrc> + ObjectType
110{
111    fn parent_create(&self, offset: u64, length: u32) -> Result<gst::Buffer, gst::FlowReturn> {
112        unsafe {
113            let klass = self.get_class();
114            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
115            (*parent_klass)
116                .create
117                .map(|f| {
118                    let mut buffer: *mut gst_ffi::GstBuffer = ptr::null_mut();
119                    // FIXME: Wrong signature in -sys bindings
120                    // https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys/issues/3
121                    let buffer_ref = &mut buffer as *mut _ as *mut gst_ffi::GstBuffer;
122                    match from_glib(f(self.to_glib_none().0, offset, length, buffer_ref)) {
123                        gst::FlowReturn::Ok => Ok(from_glib_full(buffer)),
124                        ret => Err(ret),
125                    }
126                })
127                .unwrap_or(Err(gst::FlowReturn::Error))
128        }
129    }
130
131    fn parent_do_seek(&self, segment: &mut gst::Segment) -> bool {
132        unsafe {
133            let klass = self.get_class();
134            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
135            (*parent_klass)
136                .do_seek
137                .map(|f| from_glib(f(self.to_glib_none().0, segment.to_glib_none_mut().0)))
138                .unwrap_or(false)
139        }
140    }
141
142    fn parent_query(&self, query: &mut gst::QueryRef) -> bool {
143        unsafe {
144            let klass = self.get_class();
145            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
146            (*parent_klass)
147                .query
148                .map(|f| from_glib(f(self.to_glib_none().0, query.as_mut_ptr())))
149                .unwrap_or(false)
150        }
151    }
152
153    fn parent_event(&self, event: &gst::Event) -> bool {
154        unsafe {
155            let klass = self.get_class();
156            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
157            (*parent_klass)
158                .event
159                .map(|f| from_glib(f(self.to_glib_none().0, event.to_glib_none().0)))
160                .unwrap_or(false)
161        }
162    }
163
164    fn parent_get_caps(&self, filter: Option<&gst::CapsRef>) -> Option<gst::Caps> {
165        unsafe {
166            let klass = self.get_class();
167            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
168            let filter_ptr = if let Some(filter) = filter {
169                filter.as_mut_ptr()
170            } else {
171                ptr::null_mut()
172            };
173
174            (*parent_klass)
175                .get_caps
176                .map(|f| from_glib_full(f(self.to_glib_none().0, filter_ptr)))
177                .unwrap_or(None)
178        }
179    }
180
181    fn parent_negotiate(&self) -> bool {
182        unsafe {
183            let klass = self.get_class();
184            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
185            (*parent_klass)
186                .negotiate
187                .map(|f| from_glib(f(self.to_glib_none().0)))
188                .unwrap_or(false)
189        }
190    }
191
192    fn parent_set_caps(&self, caps: &gst::CapsRef) -> bool {
193        unsafe {
194            let klass = self.get_class();
195            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
196            (*parent_klass)
197                .set_caps
198                .map(|f| from_glib(f(self.to_glib_none().0, caps.as_mut_ptr())))
199                .unwrap_or(true)
200        }
201    }
202
203    fn parent_fixate(&self, caps: gst::Caps) -> gst::Caps {
204        unsafe {
205            let klass = self.get_class();
206            let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
207
208            match (*parent_klass).fixate {
209                Some(fixate) => from_glib_full(fixate(self.to_glib_none().0, caps.into_ptr())),
210                None => caps,
211            }
212        }
213    }
214}
215
216pub unsafe trait BaseSrcClassExt<T: BaseSrcBase>
217where
218    T::ImplType: BaseSrcImpl<T>,
219    T::InstanceStructType: PanicPoison,
220{
221    fn override_vfuncs(&mut self, _: &ClassInitToken) {
222        unsafe {
223            let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseSrcClass);
224            klass.start = Some(base_src_start::<T>);
225            klass.stop = Some(base_src_stop::<T>);
226            klass.is_seekable = Some(base_src_is_seekable::<T>);
227            klass.get_size = Some(base_src_get_size::<T>);
228            klass.fill = Some(base_src_fill::<T>);
229            klass.create = Some(base_src_create::<T>);
230            klass.do_seek = Some(base_src_do_seek::<T>);
231            klass.query = Some(base_src_query::<T>);
232            klass.event = Some(base_src_event::<T>);
233            klass.get_caps = Some(base_src_get_caps::<T>);
234            klass.negotiate = Some(base_src_negotiate::<T>);
235            klass.set_caps = Some(base_src_set_caps::<T>);
236            klass.fixate = Some(base_src_fixate::<T>);
237            klass.unlock = Some(base_src_unlock::<T>);
238            klass.unlock_stop = Some(base_src_unlock_stop::<T>);
239        }
240    }
241}
242
243glib_wrapper! {
244    pub struct BaseSrc(Object<ElementInstanceStruct<BaseSrc>>):
245        [gst_base::BaseSrc => gst_base_ffi::GstBaseSrc,
246         gst::Element => gst_ffi::GstElement,
247         gst::Object => gst_ffi::GstObject];
248
249    match fn {
250        get_type => || get_type::<BaseSrc>(),
251    }
252}
253
254unsafe impl<T: IsA<gst::Element> + IsA<gst_base::BaseSrc> + ObjectType> BaseSrcBase for T {}
255pub type BaseSrcClass = ClassStruct<BaseSrc>;
256
257// FIXME: Boilerplate
258unsafe impl BaseSrcClassExt<BaseSrc> for BaseSrcClass {}
259unsafe impl ElementClassExt<BaseSrc> for BaseSrcClass {}
260unsafe impl ObjectClassExt<BaseSrc> for BaseSrcClass {}
261
262unsafe impl Send for BaseSrc {}
263unsafe impl Sync for BaseSrc {}
264
265#[macro_export]
266macro_rules! box_base_src_impl(
267    ($name:ident) => {
268        box_element_impl!($name);
269
270        impl<T: BaseSrcBase> BaseSrcImpl<T> for Box<$name<T>>
271        where
272            T::InstanceStructType: PanicPoison
273        {
274            fn start(&self, element: &T) -> bool {
275                let imp: &$name<T> = self.as_ref();
276                imp.start(element)
277            }
278
279            fn stop(&self, element: &T) -> bool {
280                let imp: &$name<T> = self.as_ref();
281                imp.stop(element)
282            }
283
284            fn is_seekable(&self, element: &T) -> bool {
285                let imp: &$name<T> = self.as_ref();
286                imp.is_seekable(element)
287            }
288
289            fn get_size(&self, element: &T) -> Option<u64> {
290                let imp: &$name<T> = self.as_ref();
291                imp.get_size(element)
292            }
293
294            fn fill(
295                &self,
296                element: &T,
297                offset: u64,
298                length: u32,
299                buffer: &mut gst::BufferRef,
300            ) -> gst::FlowReturn {
301                let imp: &$name<T> = self.as_ref();
302                imp.fill(element, offset, length, buffer)
303            }
304
305            fn create(
306                &self,
307                element: &T,
308                offset: u64,
309                length: u32,
310            ) -> Result<gst::Buffer, gst::FlowReturn> {
311                let imp: &$name<T> = self.as_ref();
312                imp.create(element, offset, length)
313            }
314
315            fn do_seek(&self, element: &T, segment: &mut gst::Segment) -> bool {
316                let imp: &$name<T> = self.as_ref();
317                imp.do_seek(element, segment)
318            }
319
320            fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool {
321                let imp: &$name<T> = self.as_ref();
322                BaseSrcImpl::query(imp, element, query)
323            }
324
325            fn event(&self, element: &T, event: &gst::Event) -> bool {
326                let imp: &$name<T> = self.as_ref();
327                imp.event(element, event)
328            }
329
330            fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option<gst::Caps> {
331                let imp: &$name<T> = self.as_ref();
332                imp.get_caps(element, filter)
333            }
334
335            fn negotiate(&self, element: &T) -> bool {
336                let imp: &$name<T> = self.as_ref();
337                imp.negotiate(element)
338            }
339
340            fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool {
341                let imp: &$name<T> = self.as_ref();
342                imp.set_caps(element, caps)
343            }
344
345            fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps {
346                let imp: &$name<T> = self.as_ref();
347                imp.fixate(element, caps)
348            }
349
350            fn unlock(&self, element: &T) -> bool {
351                let imp: &$name<T> = self.as_ref();
352                imp.unlock(element)
353            }
354
355            fn unlock_stop(&self, element: &T) -> bool {
356                let imp: &$name<T> = self.as_ref();
357                imp.unlock_stop(element)
358            }
359        }
360    };
361);
362box_base_src_impl!(BaseSrcImpl);
363
364impl ObjectType for BaseSrc {
365    const NAME: &'static str = "RsBaseSrc";
366    type ParentType = gst_base::BaseSrc;
367    type ImplType = Box<BaseSrcImpl<Self>>;
368    type InstanceStructType = ElementInstanceStruct<Self>;
369
370    fn class_init(token: &ClassInitToken, klass: &mut BaseSrcClass) {
371        ObjectClassExt::override_vfuncs(klass, token);
372        ElementClassExt::override_vfuncs(klass, token);
373        BaseSrcClassExt::override_vfuncs(klass, token);
374    }
375
376    object_type_fns!();
377}
378
379unsafe extern "C" fn base_src_start<T: BaseSrcBase>(
380    ptr: *mut gst_base_ffi::GstBaseSrc,
381) -> glib_ffi::gboolean
382where
383    T::ImplType: BaseSrcImpl<T>,
384    T::InstanceStructType: PanicPoison,
385{
386    floating_reference_guard!(ptr);
387    let element = &*(ptr as *mut T::InstanceStructType);
388    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
389    let imp = element.get_impl();
390
391    panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib()
392}
393
394unsafe extern "C" fn base_src_stop<T: BaseSrcBase>(
395    ptr: *mut gst_base_ffi::GstBaseSrc,
396) -> glib_ffi::gboolean
397where
398    T::ImplType: BaseSrcImpl<T>,
399    T::InstanceStructType: PanicPoison,
400{
401    floating_reference_guard!(ptr);
402    let element = &*(ptr as *mut T::InstanceStructType);
403    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
404    let imp = element.get_impl();
405
406    panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib()
407}
408
409unsafe extern "C" fn base_src_is_seekable<T: BaseSrcBase>(
410    ptr: *mut gst_base_ffi::GstBaseSrc,
411) -> glib_ffi::gboolean
412where
413    T::ImplType: BaseSrcImpl<T>,
414    T::InstanceStructType: PanicPoison,
415{
416    floating_reference_guard!(ptr);
417    let element = &*(ptr as *mut T::InstanceStructType);
418    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
419    let imp = element.get_impl();
420
421    panic_to_error!(&wrap, &element.panicked(), false, {
422        imp.is_seekable(&wrap)
423    })
424    .to_glib()
425}
426
427unsafe extern "C" fn base_src_get_size<T: BaseSrcBase>(
428    ptr: *mut gst_base_ffi::GstBaseSrc,
429    size: *mut u64,
430) -> glib_ffi::gboolean
431where
432    T::ImplType: BaseSrcImpl<T>,
433    T::InstanceStructType: PanicPoison,
434{
435    floating_reference_guard!(ptr);
436    let element = &*(ptr as *mut T::InstanceStructType);
437    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
438    let imp = element.get_impl();
439
440    panic_to_error!(&wrap, &element.panicked(), false, {
441        match imp.get_size(&wrap) {
442            Some(s) => {
443                *size = s;
444                true
445            }
446            None => false,
447        }
448    })
449    .to_glib()
450}
451
452unsafe extern "C" fn base_src_fill<T: BaseSrcBase>(
453    ptr: *mut gst_base_ffi::GstBaseSrc,
454    offset: u64,
455    length: u32,
456    buffer: *mut gst_ffi::GstBuffer,
457) -> gst_ffi::GstFlowReturn
458where
459    T::ImplType: BaseSrcImpl<T>,
460    T::InstanceStructType: PanicPoison,
461{
462    floating_reference_guard!(ptr);
463    let element = &*(ptr as *mut T::InstanceStructType);
464    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
465    let imp = element.get_impl();
466    let buffer = gst::BufferRef::from_mut_ptr(buffer);
467
468    panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, {
469        imp.fill(&wrap, offset, length, buffer)
470    })
471    .to_glib()
472}
473
474unsafe extern "C" fn base_src_create<T: BaseSrcBase>(
475    ptr: *mut gst_base_ffi::GstBaseSrc,
476    offset: u64,
477    length: u32,
478    buffer_ptr: *mut gst_ffi::GstBuffer,
479) -> gst_ffi::GstFlowReturn
480where
481    T::ImplType: BaseSrcImpl<T>,
482    T::InstanceStructType: PanicPoison,
483{
484    floating_reference_guard!(ptr);
485    let element = &*(ptr as *mut T::InstanceStructType);
486    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
487    let imp = element.get_impl();
488    // FIXME: Wrong signature in -sys bindings
489    // https://gitlab.freedesktop.org/gstreamer/gstreamer-rs-sys/issues/3
490    let buffer_ptr = buffer_ptr as *mut *mut gst_ffi::GstBuffer;
491
492    panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, {
493        match imp.create(&wrap, offset, length) {
494            Ok(buffer) => {
495                *buffer_ptr = buffer.into_ptr();
496                gst::FlowReturn::Ok
497            }
498            Err(err) => err,
499        }
500    })
501    .to_glib()
502}
503
504unsafe extern "C" fn base_src_do_seek<T: BaseSrcBase>(
505    ptr: *mut gst_base_ffi::GstBaseSrc,
506    segment: *mut gst_ffi::GstSegment,
507) -> glib_ffi::gboolean
508where
509    T::ImplType: BaseSrcImpl<T>,
510    T::InstanceStructType: PanicPoison,
511{
512    floating_reference_guard!(ptr);
513    let element = &*(ptr as *mut T::InstanceStructType);
514    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
515    let imp = element.get_impl();
516
517    panic_to_error!(&wrap, &element.panicked(), false, {
518        imp.do_seek(&wrap, &mut from_glib_borrow(segment))
519    })
520    .to_glib()
521}
522
523unsafe extern "C" fn base_src_query<T: BaseSrcBase>(
524    ptr: *mut gst_base_ffi::GstBaseSrc,
525    query_ptr: *mut gst_ffi::GstQuery,
526) -> glib_ffi::gboolean
527where
528    T::ImplType: BaseSrcImpl<T>,
529    T::InstanceStructType: PanicPoison,
530{
531    floating_reference_guard!(ptr);
532    let element = &*(ptr as *mut T::InstanceStructType);
533    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
534    let imp = element.get_impl();
535    let query = gst::QueryRef::from_mut_ptr(query_ptr);
536
537    panic_to_error!(&wrap, &element.panicked(), false, {
538        BaseSrcImpl::query(imp, &wrap, query)
539    })
540    .to_glib()
541}
542
543unsafe extern "C" fn base_src_event<T: BaseSrcBase>(
544    ptr: *mut gst_base_ffi::GstBaseSrc,
545    event_ptr: *mut gst_ffi::GstEvent,
546) -> glib_ffi::gboolean
547where
548    T::ImplType: BaseSrcImpl<T>,
549    T::InstanceStructType: PanicPoison,
550{
551    floating_reference_guard!(ptr);
552    let element = &*(ptr as *mut T::InstanceStructType);
553    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
554    let imp = element.get_impl();
555
556    panic_to_error!(&wrap, &element.panicked(), false, {
557        imp.event(&wrap, &from_glib_borrow(event_ptr))
558    })
559    .to_glib()
560}
561
562unsafe extern "C" fn base_src_get_caps<T: BaseSrcBase>(
563    ptr: *mut gst_base_ffi::GstBaseSrc,
564    filter: *mut gst_ffi::GstCaps,
565) -> *mut gst_ffi::GstCaps
566where
567    T::ImplType: BaseSrcImpl<T>,
568    T::InstanceStructType: PanicPoison,
569{
570    floating_reference_guard!(ptr);
571    let element = &*(ptr as *mut T::InstanceStructType);
572    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
573    let imp = element.get_impl();
574    let filter = if filter.is_null() {
575        None
576    } else {
577        Some(gst::CapsRef::from_ptr(filter))
578    };
579
580    panic_to_error!(&wrap, &element.panicked(), None, {
581        imp.get_caps(&wrap, filter)
582    })
583    .map(|caps| caps.into_ptr())
584    .unwrap_or(ptr::null_mut())
585}
586
587unsafe extern "C" fn base_src_negotiate<T: BaseSrcBase>(
588    ptr: *mut gst_base_ffi::GstBaseSrc,
589) -> glib_ffi::gboolean
590where
591    T::ImplType: BaseSrcImpl<T>,
592    T::InstanceStructType: PanicPoison,
593{
594    floating_reference_guard!(ptr);
595    let element = &*(ptr as *mut T::InstanceStructType);
596    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
597    let imp = element.get_impl();
598
599    panic_to_error!(&wrap, &element.panicked(), false, { imp.negotiate(&wrap) }).to_glib()
600}
601
602unsafe extern "C" fn base_src_set_caps<T: BaseSrcBase>(
603    ptr: *mut gst_base_ffi::GstBaseSrc,
604    caps: *mut gst_ffi::GstCaps,
605) -> glib_ffi::gboolean
606where
607    T::ImplType: BaseSrcImpl<T>,
608    T::InstanceStructType: PanicPoison,
609{
610    floating_reference_guard!(ptr);
611    let element = &*(ptr as *mut T::InstanceStructType);
612    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
613    let imp = element.get_impl();
614    let caps = gst::CapsRef::from_ptr(caps);
615
616    panic_to_error!(&wrap, &element.panicked(), false, {
617        imp.set_caps(&wrap, caps)
618    })
619    .to_glib()
620}
621
622unsafe extern "C" fn base_src_fixate<T: BaseSrcBase>(
623    ptr: *mut gst_base_ffi::GstBaseSrc,
624    caps: *mut gst_ffi::GstCaps,
625) -> *mut gst_ffi::GstCaps
626where
627    T::ImplType: BaseSrcImpl<T>,
628    T::InstanceStructType: PanicPoison,
629{
630    floating_reference_guard!(ptr);
631    let element = &*(ptr as *mut T::InstanceStructType);
632    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
633    let imp = element.get_impl();
634    let caps = from_glib_full(caps);
635
636    panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), {
637        imp.fixate(&wrap, caps)
638    })
639    .into_ptr()
640}
641
642unsafe extern "C" fn base_src_unlock<T: BaseSrcBase>(
643    ptr: *mut gst_base_ffi::GstBaseSrc,
644) -> glib_ffi::gboolean
645where
646    T::ImplType: BaseSrcImpl<T>,
647    T::InstanceStructType: PanicPoison,
648{
649    floating_reference_guard!(ptr);
650    let element = &*(ptr as *mut T::InstanceStructType);
651    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
652    let imp = element.get_impl();
653
654    panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock(&wrap) }).to_glib()
655}
656
657unsafe extern "C" fn base_src_unlock_stop<T: BaseSrcBase>(
658    ptr: *mut gst_base_ffi::GstBaseSrc,
659) -> glib_ffi::gboolean
660where
661    T::ImplType: BaseSrcImpl<T>,
662    T::InstanceStructType: PanicPoison,
663{
664    floating_reference_guard!(ptr);
665    let element = &*(ptr as *mut T::InstanceStructType);
666    let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
667    let imp = element.get_impl();
668
669    panic_to_error!(&wrap, &element.panicked(), false, {
670        imp.unlock_stop(&wrap)
671    })
672    .to_glib()
673}