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