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: 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    let instance = &*(ptr as *mut T::Instance);
501    let imp = instance.imp();
502
503    gst::panic_to_error!(imp, false, {
504        match imp.open() {
505            Ok(()) => true,
506            Err(err) => {
507                imp.post_error_message(err);
508                false
509            }
510        }
511    })
512    .into_glib()
513}
514
515unsafe extern "C" fn audio_decoder_close<T: AudioDecoderImpl>(
516    ptr: *mut ffi::GstAudioDecoder,
517) -> glib::ffi::gboolean {
518    let instance = &*(ptr as *mut T::Instance);
519    let imp = instance.imp();
520
521    gst::panic_to_error!(imp, false, {
522        match imp.close() {
523            Ok(()) => true,
524            Err(err) => {
525                imp.post_error_message(err);
526                false
527            }
528        }
529    })
530    .into_glib()
531}
532
533unsafe extern "C" fn audio_decoder_start<T: AudioDecoderImpl>(
534    ptr: *mut ffi::GstAudioDecoder,
535) -> glib::ffi::gboolean {
536    let instance = &*(ptr as *mut T::Instance);
537    let imp = instance.imp();
538
539    gst::panic_to_error!(imp, false, {
540        match imp.start() {
541            Ok(()) => true,
542            Err(err) => {
543                imp.post_error_message(err);
544                false
545            }
546        }
547    })
548    .into_glib()
549}
550
551unsafe extern "C" fn audio_decoder_stop<T: AudioDecoderImpl>(
552    ptr: *mut ffi::GstAudioDecoder,
553) -> glib::ffi::gboolean {
554    let instance = &*(ptr as *mut T::Instance);
555    let imp = instance.imp();
556
557    gst::panic_to_error!(imp, false, {
558        match imp.stop() {
559            Ok(()) => true,
560            Err(err) => {
561                imp.post_error_message(err);
562                false
563            }
564        }
565    })
566    .into_glib()
567}
568
569unsafe extern "C" fn audio_decoder_set_format<T: AudioDecoderImpl>(
570    ptr: *mut ffi::GstAudioDecoder,
571    caps: *mut gst::ffi::GstCaps,
572) -> glib::ffi::gboolean {
573    let instance = &*(ptr as *mut T::Instance);
574    let imp = instance.imp();
575
576    gst::panic_to_error!(imp, false, {
577        match imp.set_format(&from_glib_borrow(caps)) {
578            Ok(()) => true,
579            Err(err) => {
580                err.log_with_imp(imp);
581                false
582            }
583        }
584    })
585    .into_glib()
586}
587
588unsafe extern "C" fn audio_decoder_parse<T: AudioDecoderImpl>(
589    ptr: *mut ffi::GstAudioDecoder,
590    adapter: *mut gst_base::ffi::GstAdapter,
591    offset: *mut i32,
592    len: *mut i32,
593) -> gst::ffi::GstFlowReturn {
594    let instance = &*(ptr as *mut T::Instance);
595    let imp = instance.imp();
596
597    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
598        match imp.parse(&from_glib_borrow(adapter)) {
599            Ok((new_offset, new_len)) => {
600                assert!(new_offset <= i32::MAX as u32);
601                assert!(new_len <= i32::MAX as u32);
602                *offset = new_offset as i32;
603                *len = new_len as i32;
604                Ok(gst::FlowSuccess::Ok)
605            }
606            Err(err) => Err(err),
607        }
608        .into()
609    })
610    .into_glib()
611}
612
613unsafe extern "C" fn audio_decoder_handle_frame<T: AudioDecoderImpl>(
614    ptr: *mut ffi::GstAudioDecoder,
615    buffer: *mut *mut gst::ffi::GstBuffer,
616) -> gst::ffi::GstFlowReturn {
617    // FIXME: Misgenerated in gstreamer-audio-sys
618    let buffer = buffer as *mut gst::ffi::GstBuffer;
619    let instance = &*(ptr as *mut T::Instance);
620    let imp = instance.imp();
621
622    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
623        imp.handle_frame(Option::<gst::Buffer>::from_glib_none(buffer).as_ref())
624            .into()
625    })
626    .into_glib()
627}
628
629unsafe extern "C" fn audio_decoder_pre_push<T: AudioDecoderImpl>(
630    ptr: *mut ffi::GstAudioDecoder,
631    buffer: *mut *mut gst::ffi::GstBuffer,
632) -> gst::ffi::GstFlowReturn {
633    let instance = &*(ptr as *mut T::Instance);
634    let imp = instance.imp();
635
636    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
637        match imp.pre_push(from_glib_full(*buffer)) {
638            Ok(Some(new_buffer)) => {
639                *buffer = new_buffer.into_glib_ptr();
640                Ok(gst::FlowSuccess::Ok)
641            }
642            Ok(None) => {
643                *buffer = ptr::null_mut();
644                Ok(gst::FlowSuccess::Ok)
645            }
646            Err(err) => Err(err),
647        }
648        .into()
649    })
650    .into_glib()
651}
652
653unsafe extern "C" fn audio_decoder_flush<T: AudioDecoderImpl>(
654    ptr: *mut ffi::GstAudioDecoder,
655    hard: glib::ffi::gboolean,
656) {
657    let instance = &*(ptr as *mut T::Instance);
658    let imp = instance.imp();
659
660    gst::panic_to_error!(imp, (), { AudioDecoderImpl::flush(imp, from_glib(hard)) })
661}
662
663unsafe extern "C" fn audio_decoder_negotiate<T: AudioDecoderImpl>(
664    ptr: *mut ffi::GstAudioDecoder,
665) -> glib::ffi::gboolean {
666    let instance = &*(ptr as *mut T::Instance);
667    let imp = instance.imp();
668
669    gst::panic_to_error!(imp, false, {
670        match imp.negotiate() {
671            Ok(()) => true,
672            Err(err) => {
673                err.log_with_imp(imp);
674                false
675            }
676        }
677    })
678    .into_glib()
679}
680
681unsafe extern "C" fn audio_decoder_getcaps<T: AudioDecoderImpl>(
682    ptr: *mut ffi::GstAudioDecoder,
683    filter: *mut gst::ffi::GstCaps,
684) -> *mut gst::ffi::GstCaps {
685    let instance = &*(ptr as *mut T::Instance);
686    let imp = instance.imp();
687
688    gst::panic_to_error!(imp, gst::Caps::new_empty(), {
689        AudioDecoderImpl::caps(
690            imp,
691            Option::<gst::Caps>::from_glib_borrow(filter)
692                .as_ref()
693                .as_ref(),
694        )
695    })
696    .into_glib_ptr()
697}
698
699unsafe extern "C" fn audio_decoder_sink_event<T: AudioDecoderImpl>(
700    ptr: *mut ffi::GstAudioDecoder,
701    event: *mut gst::ffi::GstEvent,
702) -> glib::ffi::gboolean {
703    let instance = &*(ptr as *mut T::Instance);
704    let imp = instance.imp();
705
706    gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib()
707}
708
709unsafe extern "C" fn audio_decoder_sink_query<T: AudioDecoderImpl>(
710    ptr: *mut ffi::GstAudioDecoder,
711    query: *mut gst::ffi::GstQuery,
712) -> glib::ffi::gboolean {
713    let instance = &*(ptr as *mut T::Instance);
714    let imp = instance.imp();
715
716    gst::panic_to_error!(imp, false, {
717        imp.sink_query(gst::QueryRef::from_mut_ptr(query))
718    })
719    .into_glib()
720}
721
722unsafe extern "C" fn audio_decoder_src_event<T: AudioDecoderImpl>(
723    ptr: *mut ffi::GstAudioDecoder,
724    event: *mut gst::ffi::GstEvent,
725) -> glib::ffi::gboolean {
726    let instance = &*(ptr as *mut T::Instance);
727    let imp = instance.imp();
728
729    gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
730}
731
732unsafe extern "C" fn audio_decoder_src_query<T: AudioDecoderImpl>(
733    ptr: *mut ffi::GstAudioDecoder,
734    query: *mut gst::ffi::GstQuery,
735) -> glib::ffi::gboolean {
736    let instance = &*(ptr as *mut T::Instance);
737    let imp = instance.imp();
738
739    gst::panic_to_error!(imp, false, {
740        imp.src_query(gst::QueryRef::from_mut_ptr(query))
741    })
742    .into_glib()
743}
744
745unsafe extern "C" fn audio_decoder_propose_allocation<T: AudioDecoderImpl>(
746    ptr: *mut ffi::GstAudioDecoder,
747    query: *mut gst::ffi::GstQuery,
748) -> glib::ffi::gboolean {
749    let instance = &*(ptr as *mut T::Instance);
750    let imp = instance.imp();
751    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
752        gst::QueryViewMut::Allocation(allocation) => allocation,
753        _ => unreachable!(),
754    };
755
756    gst::panic_to_error!(imp, false, {
757        match imp.propose_allocation(query) {
758            Ok(()) => true,
759            Err(err) => {
760                err.log_with_imp(imp);
761                false
762            }
763        }
764    })
765    .into_glib()
766}
767
768unsafe extern "C" fn audio_decoder_decide_allocation<T: AudioDecoderImpl>(
769    ptr: *mut ffi::GstAudioDecoder,
770    query: *mut gst::ffi::GstQuery,
771) -> glib::ffi::gboolean {
772    let instance = &*(ptr as *mut T::Instance);
773    let imp = instance.imp();
774    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
775        gst::QueryViewMut::Allocation(allocation) => allocation,
776        _ => unreachable!(),
777    };
778
779    gst::panic_to_error!(imp, false, {
780        match imp.decide_allocation(query) {
781            Ok(()) => true,
782            Err(err) => {
783                err.log_with_imp(imp);
784                false
785            }
786        }
787    })
788    .into_glib()
789}