Skip to main content

gstreamer_audio/subclass/
audio_decoder.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{mem, ptr};
4
5use glib::translate::*;
6use gst::subclass::prelude::*;
7
8use crate::{AudioDecoder, ffi, prelude::*};
9
10pub trait AudioDecoderImpl: ElementImpl + ObjectSubclass<Type: IsA<AudioDecoder>> {
11    fn open(&self) -> Result<(), gst::ErrorMessage> {
12        self.parent_open()
13    }
14
15    fn close(&self) -> Result<(), gst::ErrorMessage> {
16        self.parent_close()
17    }
18
19    fn start(&self) -> Result<(), gst::ErrorMessage> {
20        self.parent_start()
21    }
22
23    fn stop(&self) -> Result<(), gst::ErrorMessage> {
24        self.parent_stop()
25    }
26
27    fn set_format(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
28        self.parent_set_format(caps)
29    }
30
31    fn parse(&self, adapter: &gst_base::Adapter) -> Result<(u32, u32), gst::FlowError> {
32        self.parent_parse(adapter)
33    }
34
35    fn handle_frame(
36        &self,
37        buffer: Option<&gst::Buffer>,
38    ) -> Result<gst::FlowSuccess, gst::FlowError> {
39        self.parent_handle_frame(buffer)
40    }
41
42    fn pre_push(&self, buffer: gst::Buffer) -> Result<Option<gst::Buffer>, gst::FlowError> {
43        self.parent_pre_push(buffer)
44    }
45
46    fn flush(&self, hard: bool) {
47        self.parent_flush(hard)
48    }
49
50    fn negotiate(&self) -> Result<(), gst::LoggableError> {
51        self.parent_negotiate()
52    }
53
54    fn caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
55        self.parent_caps(filter)
56    }
57
58    fn sink_event(&self, event: gst::Event) -> bool {
59        self.parent_sink_event(event)
60    }
61
62    fn sink_query(&self, query: &mut gst::QueryRef) -> bool {
63        self.parent_sink_query(query)
64    }
65
66    fn src_event(&self, event: gst::Event) -> bool {
67        self.parent_src_event(event)
68    }
69
70    fn src_query(&self, query: &mut gst::QueryRef) -> bool {
71        self.parent_src_query(query)
72    }
73
74    fn propose_allocation(
75        &self,
76        query: &mut gst::query::Allocation,
77    ) -> Result<(), gst::LoggableError> {
78        self.parent_propose_allocation(query)
79    }
80
81    fn decide_allocation(
82        &self,
83        query: &mut gst::query::Allocation,
84    ) -> Result<(), gst::LoggableError> {
85        self.parent_decide_allocation(query)
86    }
87}
88
89pub trait AudioDecoderImplExt: AudioDecoderImpl {
90    fn parent_open(&self) -> Result<(), gst::ErrorMessage> {
91        unsafe {
92            let data = Self::type_data();
93            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
94            (*parent_class)
95                .open
96                .map(|f| {
97                    if from_glib(f(self
98                        .obj()
99                        .unsafe_cast_ref::<AudioDecoder>()
100                        .to_glib_none()
101                        .0))
102                    {
103                        Ok(())
104                    } else {
105                        Err(gst::error_msg!(
106                            gst::CoreError::StateChange,
107                            ["Parent function `open` failed"]
108                        ))
109                    }
110                })
111                .unwrap_or(Ok(()))
112        }
113    }
114
115    fn parent_close(&self) -> Result<(), gst::ErrorMessage> {
116        unsafe {
117            let data = Self::type_data();
118            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
119            (*parent_class)
120                .close
121                .map(|f| {
122                    if from_glib(f(self
123                        .obj()
124                        .unsafe_cast_ref::<AudioDecoder>()
125                        .to_glib_none()
126                        .0))
127                    {
128                        Ok(())
129                    } else {
130                        Err(gst::error_msg!(
131                            gst::CoreError::StateChange,
132                            ["Parent function `close` failed"]
133                        ))
134                    }
135                })
136                .unwrap_or(Ok(()))
137        }
138    }
139
140    fn parent_start(&self) -> Result<(), gst::ErrorMessage> {
141        unsafe {
142            let data = Self::type_data();
143            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
144            (*parent_class)
145                .start
146                .map(|f| {
147                    if from_glib(f(self
148                        .obj()
149                        .unsafe_cast_ref::<AudioDecoder>()
150                        .to_glib_none()
151                        .0))
152                    {
153                        Ok(())
154                    } else {
155                        Err(gst::error_msg!(
156                            gst::CoreError::StateChange,
157                            ["Parent function `start` failed"]
158                        ))
159                    }
160                })
161                .unwrap_or(Ok(()))
162        }
163    }
164
165    fn parent_stop(&self) -> Result<(), gst::ErrorMessage> {
166        unsafe {
167            let data = Self::type_data();
168            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
169            (*parent_class)
170                .stop
171                .map(|f| {
172                    if from_glib(f(self
173                        .obj()
174                        .unsafe_cast_ref::<AudioDecoder>()
175                        .to_glib_none()
176                        .0))
177                    {
178                        Ok(())
179                    } else {
180                        Err(gst::error_msg!(
181                            gst::CoreError::StateChange,
182                            ["Parent function `stop` failed"]
183                        ))
184                    }
185                })
186                .unwrap_or(Ok(()))
187        }
188    }
189
190    fn parent_set_format(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
191        unsafe {
192            let data = Self::type_data();
193            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
194            (*parent_class)
195                .set_format
196                .map(|f| {
197                    gst::result_from_gboolean!(
198                        f(
199                            self.obj()
200                                .unsafe_cast_ref::<AudioDecoder>()
201                                .to_glib_none()
202                                .0,
203                            caps.to_glib_none().0
204                        ),
205                        gst::CAT_RUST,
206                        "parent function `set_format` failed"
207                    )
208                })
209                .unwrap_or(Ok(()))
210        }
211    }
212
213    fn parent_parse(&self, adapter: &gst_base::Adapter) -> Result<(u32, u32), gst::FlowError> {
214        unsafe {
215            let data = Self::type_data();
216            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
217            (*parent_class)
218                .parse
219                .map(|f| {
220                    let mut offset = mem::MaybeUninit::uninit();
221                    let mut len = mem::MaybeUninit::uninit();
222                    gst::FlowSuccess::try_from_glib(f(
223                        self.obj()
224                            .unsafe_cast_ref::<AudioDecoder>()
225                            .to_glib_none()
226                            .0,
227                        adapter.to_glib_none().0,
228                        offset.as_mut_ptr(),
229                        len.as_mut_ptr(),
230                    ))
231                    .map(|_| {
232                        let offset = offset.assume_init();
233                        let len = len.assume_init();
234                        assert!(offset >= 0);
235                        assert!(len >= 0);
236                        (offset as u32, len as u32)
237                    })
238                })
239                .unwrap_or_else(|| Ok((0, adapter.available() as u32)))
240        }
241    }
242
243    fn parent_handle_frame(
244        &self,
245        buffer: Option<&gst::Buffer>,
246    ) -> Result<gst::FlowSuccess, gst::FlowError> {
247        unsafe {
248            let data = Self::type_data();
249            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
250            (*parent_class)
251                .handle_frame
252                .map(|f| {
253                    try_from_glib(f(
254                        self.obj()
255                            .unsafe_cast_ref::<AudioDecoder>()
256                            .to_glib_none()
257                            .0,
258                        buffer
259                            .map(|buffer| buffer.as_mut_ptr() as *mut *mut gst::ffi::GstBuffer)
260                            .unwrap_or(ptr::null_mut()),
261                    ))
262                })
263                .unwrap_or(Err(gst::FlowError::Error))
264        }
265    }
266
267    fn parent_pre_push(&self, buffer: gst::Buffer) -> Result<Option<gst::Buffer>, gst::FlowError> {
268        unsafe {
269            let data = Self::type_data();
270            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
271            if let Some(f) = (*parent_class).pre_push {
272                let mut buffer = buffer.into_glib_ptr();
273                gst::FlowSuccess::try_from_glib(f(
274                    self.obj()
275                        .unsafe_cast_ref::<AudioDecoder>()
276                        .to_glib_none()
277                        .0,
278                    &mut buffer,
279                ))
280                .map(|_| from_glib_full(buffer))
281            } else {
282                Ok(Some(buffer))
283            }
284        }
285    }
286
287    fn parent_flush(&self, hard: bool) {
288        unsafe {
289            let data = Self::type_data();
290            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
291            (*parent_class)
292                .flush
293                .map(|f| {
294                    f(
295                        self.obj()
296                            .unsafe_cast_ref::<AudioDecoder>()
297                            .to_glib_none()
298                            .0,
299                        hard.into_glib(),
300                    )
301                })
302                .unwrap_or(())
303        }
304    }
305
306    fn parent_negotiate(&self) -> Result<(), gst::LoggableError> {
307        unsafe {
308            let data = Self::type_data();
309            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
310            (*parent_class)
311                .negotiate
312                .map(|f| {
313                    gst::result_from_gboolean!(
314                        f(self
315                            .obj()
316                            .unsafe_cast_ref::<AudioDecoder>()
317                            .to_glib_none()
318                            .0),
319                        gst::CAT_RUST,
320                        "Parent function `negotiate` failed"
321                    )
322                })
323                .unwrap_or(Ok(()))
324        }
325    }
326
327    fn parent_caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
328        unsafe {
329            let data = Self::type_data();
330            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
331            (*parent_class)
332                .getcaps
333                .map(|f| {
334                    from_glib_full(f(
335                        self.obj()
336                            .unsafe_cast_ref::<AudioDecoder>()
337                            .to_glib_none()
338                            .0,
339                        filter.to_glib_none().0,
340                    ))
341                })
342                .unwrap_or_else(|| {
343                    self.obj()
344                        .unsafe_cast_ref::<AudioDecoder>()
345                        .proxy_getcaps(None, filter)
346                })
347        }
348    }
349
350    fn parent_sink_event(&self, event: gst::Event) -> bool {
351        unsafe {
352            let data = Self::type_data();
353            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
354            let f = (*parent_class)
355                .sink_event
356                .expect("Missing parent function `sink_event`");
357            from_glib(f(
358                self.obj()
359                    .unsafe_cast_ref::<AudioDecoder>()
360                    .to_glib_none()
361                    .0,
362                event.into_glib_ptr(),
363            ))
364        }
365    }
366
367    fn parent_sink_query(&self, query: &mut gst::QueryRef) -> bool {
368        unsafe {
369            let data = Self::type_data();
370            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
371            let f = (*parent_class)
372                .sink_query
373                .expect("Missing parent function `sink_query`");
374            from_glib(f(
375                self.obj()
376                    .unsafe_cast_ref::<AudioDecoder>()
377                    .to_glib_none()
378                    .0,
379                query.as_mut_ptr(),
380            ))
381        }
382    }
383
384    fn parent_src_event(&self, event: gst::Event) -> bool {
385        unsafe {
386            let data = Self::type_data();
387            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
388            let f = (*parent_class)
389                .src_event
390                .expect("Missing parent function `src_event`");
391            from_glib(f(
392                self.obj()
393                    .unsafe_cast_ref::<AudioDecoder>()
394                    .to_glib_none()
395                    .0,
396                event.into_glib_ptr(),
397            ))
398        }
399    }
400
401    fn parent_src_query(&self, query: &mut gst::QueryRef) -> bool {
402        unsafe {
403            let data = Self::type_data();
404            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
405            let f = (*parent_class)
406                .src_query
407                .expect("Missing parent function `src_query`");
408            from_glib(f(
409                self.obj()
410                    .unsafe_cast_ref::<AudioDecoder>()
411                    .to_glib_none()
412                    .0,
413                query.as_mut_ptr(),
414            ))
415        }
416    }
417
418    fn parent_propose_allocation(
419        &self,
420        query: &mut gst::query::Allocation,
421    ) -> Result<(), gst::LoggableError> {
422        unsafe {
423            let data = Self::type_data();
424            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
425            (*parent_class)
426                .propose_allocation
427                .map(|f| {
428                    gst::result_from_gboolean!(
429                        f(
430                            self.obj()
431                                .unsafe_cast_ref::<AudioDecoder>()
432                                .to_glib_none()
433                                .0,
434                            query.as_mut_ptr(),
435                        ),
436                        gst::CAT_RUST,
437                        "Parent function `propose_allocation` failed",
438                    )
439                })
440                .unwrap_or(Ok(()))
441        }
442    }
443
444    fn parent_decide_allocation(
445        &self,
446        query: &mut gst::query::Allocation,
447    ) -> Result<(), gst::LoggableError> {
448        unsafe {
449            let data = Self::type_data();
450            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioDecoderClass;
451            (*parent_class)
452                .decide_allocation
453                .map(|f| {
454                    gst::result_from_gboolean!(
455                        f(
456                            self.obj()
457                                .unsafe_cast_ref::<AudioDecoder>()
458                                .to_glib_none()
459                                .0,
460                            query.as_mut_ptr(),
461                        ),
462                        gst::CAT_RUST,
463                        "Parent function `decide_allocation` failed",
464                    )
465                })
466                .unwrap_or(Ok(()))
467        }
468    }
469}
470
471impl<T: AudioDecoderImpl> AudioDecoderImplExt for T {}
472
473unsafe impl<T: AudioDecoderImpl> IsSubclassable<T> for AudioDecoder {
474    fn class_init(klass: &mut glib::Class<Self>) {
475        Self::parent_class_init::<T>(klass);
476        let klass = klass.as_mut();
477        klass.open = Some(audio_decoder_open::<T>);
478        klass.close = Some(audio_decoder_close::<T>);
479        klass.start = Some(audio_decoder_start::<T>);
480        klass.stop = Some(audio_decoder_stop::<T>);
481        klass.set_format = Some(audio_decoder_set_format::<T>);
482        klass.parse = Some(audio_decoder_parse::<T>);
483        klass.handle_frame = Some(audio_decoder_handle_frame::<T>);
484        klass.pre_push = Some(audio_decoder_pre_push::<T>);
485        klass.flush = Some(audio_decoder_flush::<T>);
486        klass.negotiate = Some(audio_decoder_negotiate::<T>);
487        klass.getcaps = Some(audio_decoder_getcaps::<T>);
488        klass.sink_event = Some(audio_decoder_sink_event::<T>);
489        klass.src_event = Some(audio_decoder_src_event::<T>);
490        klass.sink_query = Some(audio_decoder_sink_query::<T>);
491        klass.src_query = Some(audio_decoder_src_query::<T>);
492        klass.propose_allocation = Some(audio_decoder_propose_allocation::<T>);
493        klass.decide_allocation = Some(audio_decoder_decide_allocation::<T>);
494    }
495}
496
497unsafe extern "C" fn audio_decoder_open<T: AudioDecoderImpl>(
498    ptr: *mut ffi::GstAudioDecoder,
499) -> glib::ffi::gboolean {
500    unsafe {
501        let instance = &*(ptr as *mut T::Instance);
502        let imp = instance.imp();
503
504        gst::panic_to_error!(imp, false, {
505            match imp.open() {
506                Ok(()) => true,
507                Err(err) => {
508                    imp.post_error_message(err);
509                    false
510                }
511            }
512        })
513        .into_glib()
514    }
515}
516
517unsafe extern "C" fn audio_decoder_close<T: AudioDecoderImpl>(
518    ptr: *mut ffi::GstAudioDecoder,
519) -> glib::ffi::gboolean {
520    unsafe {
521        let instance = &*(ptr as *mut T::Instance);
522        let imp = instance.imp();
523
524        gst::panic_to_error!(imp, false, {
525            match imp.close() {
526                Ok(()) => true,
527                Err(err) => {
528                    imp.post_error_message(err);
529                    false
530                }
531            }
532        })
533        .into_glib()
534    }
535}
536
537unsafe extern "C" fn audio_decoder_start<T: AudioDecoderImpl>(
538    ptr: *mut ffi::GstAudioDecoder,
539) -> glib::ffi::gboolean {
540    unsafe {
541        let instance = &*(ptr as *mut T::Instance);
542        let imp = instance.imp();
543
544        gst::panic_to_error!(imp, false, {
545            match imp.start() {
546                Ok(()) => true,
547                Err(err) => {
548                    imp.post_error_message(err);
549                    false
550                }
551            }
552        })
553        .into_glib()
554    }
555}
556
557unsafe extern "C" fn audio_decoder_stop<T: AudioDecoderImpl>(
558    ptr: *mut ffi::GstAudioDecoder,
559) -> glib::ffi::gboolean {
560    unsafe {
561        let instance = &*(ptr as *mut T::Instance);
562        let imp = instance.imp();
563
564        gst::panic_to_error!(imp, false, {
565            match imp.stop() {
566                Ok(()) => true,
567                Err(err) => {
568                    imp.post_error_message(err);
569                    false
570                }
571            }
572        })
573        .into_glib()
574    }
575}
576
577unsafe extern "C" fn audio_decoder_set_format<T: AudioDecoderImpl>(
578    ptr: *mut ffi::GstAudioDecoder,
579    caps: *mut gst::ffi::GstCaps,
580) -> glib::ffi::gboolean {
581    unsafe {
582        let instance = &*(ptr as *mut T::Instance);
583        let imp = instance.imp();
584
585        gst::panic_to_error!(imp, false, {
586            match imp.set_format(&from_glib_borrow(caps)) {
587                Ok(()) => true,
588                Err(err) => {
589                    err.log_with_imp(imp);
590                    false
591                }
592            }
593        })
594        .into_glib()
595    }
596}
597
598unsafe extern "C" fn audio_decoder_parse<T: AudioDecoderImpl>(
599    ptr: *mut ffi::GstAudioDecoder,
600    adapter: *mut gst_base::ffi::GstAdapter,
601    offset: *mut i32,
602    len: *mut i32,
603) -> gst::ffi::GstFlowReturn {
604    unsafe {
605        let instance = &*(ptr as *mut T::Instance);
606        let imp = instance.imp();
607
608        gst::panic_to_error!(imp, gst::FlowReturn::Error, {
609            match imp.parse(&from_glib_borrow(adapter)) {
610                Ok((new_offset, new_len)) => {
611                    assert!(new_offset <= i32::MAX as u32);
612                    assert!(new_len <= i32::MAX as u32);
613                    *offset = new_offset as i32;
614                    *len = new_len as i32;
615                    Ok(gst::FlowSuccess::Ok)
616                }
617                Err(err) => Err(err),
618            }
619            .into()
620        })
621        .into_glib()
622    }
623}
624
625unsafe extern "C" fn audio_decoder_handle_frame<T: AudioDecoderImpl>(
626    ptr: *mut ffi::GstAudioDecoder,
627    buffer: *mut *mut gst::ffi::GstBuffer,
628) -> gst::ffi::GstFlowReturn {
629    unsafe {
630        // FIXME: Misgenerated in gstreamer-audio-sys
631        let buffer = buffer as *mut gst::ffi::GstBuffer;
632        let instance = &*(ptr as *mut T::Instance);
633        let imp = instance.imp();
634
635        gst::panic_to_error!(imp, gst::FlowReturn::Error, {
636            imp.handle_frame(Option::<gst::Buffer>::from_glib_none(buffer).as_ref())
637                .into()
638        })
639        .into_glib()
640    }
641}
642
643unsafe extern "C" fn audio_decoder_pre_push<T: AudioDecoderImpl>(
644    ptr: *mut ffi::GstAudioDecoder,
645    buffer: *mut *mut gst::ffi::GstBuffer,
646) -> gst::ffi::GstFlowReturn {
647    unsafe {
648        let instance = &*(ptr as *mut T::Instance);
649        let imp = instance.imp();
650
651        gst::panic_to_error!(imp, gst::FlowReturn::Error, {
652            match imp.pre_push(from_glib_full(*buffer)) {
653                Ok(Some(new_buffer)) => {
654                    *buffer = new_buffer.into_glib_ptr();
655                    Ok(gst::FlowSuccess::Ok)
656                }
657                Ok(None) => {
658                    *buffer = ptr::null_mut();
659                    Ok(gst::FlowSuccess::Ok)
660                }
661                Err(err) => Err(err),
662            }
663            .into()
664        })
665        .into_glib()
666    }
667}
668
669unsafe extern "C" fn audio_decoder_flush<T: AudioDecoderImpl>(
670    ptr: *mut ffi::GstAudioDecoder,
671    hard: glib::ffi::gboolean,
672) {
673    unsafe {
674        let instance = &*(ptr as *mut T::Instance);
675        let imp = instance.imp();
676
677        gst::panic_to_error!(imp, (), { AudioDecoderImpl::flush(imp, from_glib(hard)) })
678    }
679}
680
681unsafe extern "C" fn audio_decoder_negotiate<T: AudioDecoderImpl>(
682    ptr: *mut ffi::GstAudioDecoder,
683) -> glib::ffi::gboolean {
684    unsafe {
685        let instance = &*(ptr as *mut T::Instance);
686        let imp = instance.imp();
687
688        gst::panic_to_error!(imp, false, {
689            match imp.negotiate() {
690                Ok(()) => true,
691                Err(err) => {
692                    err.log_with_imp(imp);
693                    false
694                }
695            }
696        })
697        .into_glib()
698    }
699}
700
701unsafe extern "C" fn audio_decoder_getcaps<T: AudioDecoderImpl>(
702    ptr: *mut ffi::GstAudioDecoder,
703    filter: *mut gst::ffi::GstCaps,
704) -> *mut gst::ffi::GstCaps {
705    unsafe {
706        let instance = &*(ptr as *mut T::Instance);
707        let imp = instance.imp();
708
709        gst::panic_to_error!(imp, gst::Caps::new_empty(), {
710            AudioDecoderImpl::caps(
711                imp,
712                Option::<gst::Caps>::from_glib_borrow(filter)
713                    .as_ref()
714                    .as_ref(),
715            )
716        })
717        .into_glib_ptr()
718    }
719}
720
721unsafe extern "C" fn audio_decoder_sink_event<T: AudioDecoderImpl>(
722    ptr: *mut ffi::GstAudioDecoder,
723    event: *mut gst::ffi::GstEvent,
724) -> glib::ffi::gboolean {
725    unsafe {
726        let instance = &*(ptr as *mut T::Instance);
727        let imp = instance.imp();
728
729        gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib()
730    }
731}
732
733unsafe extern "C" fn audio_decoder_sink_query<T: AudioDecoderImpl>(
734    ptr: *mut ffi::GstAudioDecoder,
735    query: *mut gst::ffi::GstQuery,
736) -> glib::ffi::gboolean {
737    unsafe {
738        let instance = &*(ptr as *mut T::Instance);
739        let imp = instance.imp();
740
741        gst::panic_to_error!(imp, false, {
742            imp.sink_query(gst::QueryRef::from_mut_ptr(query))
743        })
744        .into_glib()
745    }
746}
747
748unsafe extern "C" fn audio_decoder_src_event<T: AudioDecoderImpl>(
749    ptr: *mut ffi::GstAudioDecoder,
750    event: *mut gst::ffi::GstEvent,
751) -> glib::ffi::gboolean {
752    unsafe {
753        let instance = &*(ptr as *mut T::Instance);
754        let imp = instance.imp();
755
756        gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
757    }
758}
759
760unsafe extern "C" fn audio_decoder_src_query<T: AudioDecoderImpl>(
761    ptr: *mut ffi::GstAudioDecoder,
762    query: *mut gst::ffi::GstQuery,
763) -> glib::ffi::gboolean {
764    unsafe {
765        let instance = &*(ptr as *mut T::Instance);
766        let imp = instance.imp();
767
768        gst::panic_to_error!(imp, false, {
769            imp.src_query(gst::QueryRef::from_mut_ptr(query))
770        })
771        .into_glib()
772    }
773}
774
775unsafe extern "C" fn audio_decoder_propose_allocation<T: AudioDecoderImpl>(
776    ptr: *mut ffi::GstAudioDecoder,
777    query: *mut gst::ffi::GstQuery,
778) -> glib::ffi::gboolean {
779    unsafe {
780        let instance = &*(ptr as *mut T::Instance);
781        let imp = instance.imp();
782        let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
783            gst::QueryViewMut::Allocation(allocation) => allocation,
784            _ => unreachable!(),
785        };
786
787        gst::panic_to_error!(imp, false, {
788            match imp.propose_allocation(query) {
789                Ok(()) => true,
790                Err(err) => {
791                    err.log_with_imp(imp);
792                    false
793                }
794            }
795        })
796        .into_glib()
797    }
798}
799
800unsafe extern "C" fn audio_decoder_decide_allocation<T: AudioDecoderImpl>(
801    ptr: *mut ffi::GstAudioDecoder,
802    query: *mut gst::ffi::GstQuery,
803) -> glib::ffi::gboolean {
804    unsafe {
805        let instance = &*(ptr as *mut T::Instance);
806        let imp = instance.imp();
807        let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
808            gst::QueryViewMut::Allocation(allocation) => allocation,
809            _ => unreachable!(),
810        };
811
812        gst::panic_to_error!(imp, false, {
813            match imp.decide_allocation(query) {
814                Ok(()) => true,
815                Err(err) => {
816                    err.log_with_imp(imp);
817                    false
818                }
819            }
820        })
821        .into_glib()
822    }
823}