gstreamer_audio/subclass/
audio_encoder.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::ptr;
4
5use glib::translate::*;
6use gst::subclass::prelude::*;
7
8use crate::{ffi, prelude::*, AudioEncoder, AudioInfo};
9
10pub trait AudioEncoderImpl: ElementImpl + ObjectSubclass<Type: IsA<AudioEncoder>> {
11    /// Optional.
12    ///  Called when the element changes to GST_STATE_READY.
13    ///  Allows opening external resources.
14    fn open(&self) -> Result<(), gst::ErrorMessage> {
15        self.parent_open()
16    }
17
18    /// Optional.
19    ///  Called when the element changes to GST_STATE_NULL.
20    ///  Allows closing external resources.
21    fn close(&self) -> Result<(), gst::ErrorMessage> {
22        self.parent_close()
23    }
24
25    /// Optional.
26    ///  Called when the element starts processing.
27    ///  Allows opening external resources.
28    fn start(&self) -> Result<(), gst::ErrorMessage> {
29        self.parent_start()
30    }
31
32    /// Optional.
33    ///  Called when the element stops processing.
34    ///  Allows closing external resources.
35    fn stop(&self) -> Result<(), gst::ErrorMessage> {
36        self.parent_stop()
37    }
38
39    /// Notifies subclass of incoming data format.
40    ///  GstAudioInfo contains the format according to provided caps.
41    fn set_format(&self, info: &AudioInfo) -> Result<(), gst::LoggableError> {
42        self.parent_set_format(info)
43    }
44
45    /// Provides input samples (or NULL to clear any remaining data)
46    ///  according to directions as configured by the subclass
47    ///  using the API. Input data ref management is performed
48    ///  by base class, subclass should not care or intervene,
49    ///  and input data is only valid until next call to base class,
50    ///  most notably a call to [`AudioEncoderExt::finish_frame()`][crate::prelude::AudioEncoderExt::finish_frame()].
51    fn handle_frame(
52        &self,
53        buffer: Option<&gst::Buffer>,
54    ) -> Result<gst::FlowSuccess, gst::FlowError> {
55        self.parent_handle_frame(buffer)
56    }
57
58    /// Optional.
59    ///  Called just prior to pushing (encoded data) buffer downstream.
60    ///  Subclass has full discretionary access to buffer,
61    ///  and a not OK flow return will abort downstream pushing.
62    fn pre_push(&self, buffer: gst::Buffer) -> Result<Option<gst::Buffer>, gst::FlowError> {
63        self.parent_pre_push(buffer)
64    }
65
66    /// Optional.
67    ///  Instructs subclass to clear any codec caches and discard
68    ///  any pending samples and not yet returned encoded data.
69    fn flush(&self) {
70        self.parent_flush()
71    }
72
73    /// Negotiate with downstream elements to currently configured [`gst::Caps`][crate::gst::Caps].
74    /// Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
75    /// negotiate fails.
76    ///
77    /// # Returns
78    ///
79    /// [`true`] if the negotiation succeeded, else [`false`].
80    fn negotiate(&self) -> Result<(), gst::LoggableError> {
81        self.parent_negotiate()
82    }
83
84    fn caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
85        self.parent_caps(filter)
86    }
87
88    /// Optional.
89    ///  Event handler on the sink pad. Subclasses should chain up to
90    ///  the parent implementation to invoke the default handler.
91    fn sink_event(&self, event: gst::Event) -> bool {
92        self.parent_sink_event(event)
93    }
94
95    /// Optional.
96    ///  Query handler on the sink pad. This function should
97    ///  return TRUE if the query could be performed. Subclasses
98    ///  should chain up to the parent implementation to invoke the
99    ///  default handler. Since: 1.6
100    fn sink_query(&self, query: &mut gst::QueryRef) -> bool {
101        self.parent_sink_query(query)
102    }
103
104    /// Optional.
105    ///  Event handler on the src pad. Subclasses should chain up to
106    ///  the parent implementation to invoke the default handler.
107    fn src_event(&self, event: gst::Event) -> bool {
108        self.parent_src_event(event)
109    }
110
111    /// Optional.
112    ///  Query handler on the source pad. This function should
113    ///  return TRUE if the query could be performed. Subclasses
114    ///  should chain up to the parent implementation to invoke the
115    ///  default handler. Since: 1.6
116    fn src_query(&self, query: &mut gst::QueryRef) -> bool {
117        self.parent_src_query(query)
118    }
119
120    /// Optional.
121    ///  Propose buffer allocation parameters for upstream elements.
122    ///  Subclasses should chain up to the parent implementation to
123    ///  invoke the default handler.
124    fn propose_allocation(
125        &self,
126        query: &mut gst::query::Allocation,
127    ) -> Result<(), gst::LoggableError> {
128        self.parent_propose_allocation(query)
129    }
130
131    /// Optional.
132    ///  Setup the allocation parameters for allocating output
133    ///  buffers. The passed in query contains the result of the
134    ///  downstream allocation query.
135    ///  Subclasses should chain up to the parent implementation to
136    ///  invoke the default handler.
137    fn decide_allocation(
138        &self,
139        query: &mut gst::query::Allocation,
140    ) -> Result<(), gst::LoggableError> {
141        self.parent_decide_allocation(query)
142    }
143}
144
145pub trait AudioEncoderImplExt: AudioEncoderImpl {
146    fn parent_open(&self) -> Result<(), gst::ErrorMessage> {
147        unsafe {
148            let data = Self::type_data();
149            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
150            (*parent_class)
151                .open
152                .map(|f| {
153                    if from_glib(f(self
154                        .obj()
155                        .unsafe_cast_ref::<AudioEncoder>()
156                        .to_glib_none()
157                        .0))
158                    {
159                        Ok(())
160                    } else {
161                        Err(gst::error_msg!(
162                            gst::CoreError::StateChange,
163                            ["Parent function `open` failed"]
164                        ))
165                    }
166                })
167                .unwrap_or(Ok(()))
168        }
169    }
170
171    fn parent_close(&self) -> Result<(), gst::ErrorMessage> {
172        unsafe {
173            let data = Self::type_data();
174            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
175            (*parent_class)
176                .close
177                .map(|f| {
178                    if from_glib(f(self
179                        .obj()
180                        .unsafe_cast_ref::<AudioEncoder>()
181                        .to_glib_none()
182                        .0))
183                    {
184                        Ok(())
185                    } else {
186                        Err(gst::error_msg!(
187                            gst::CoreError::StateChange,
188                            ["Parent function `close` failed"]
189                        ))
190                    }
191                })
192                .unwrap_or(Ok(()))
193        }
194    }
195
196    fn parent_start(&self) -> Result<(), gst::ErrorMessage> {
197        unsafe {
198            let data = Self::type_data();
199            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
200            (*parent_class)
201                .start
202                .map(|f| {
203                    if from_glib(f(self
204                        .obj()
205                        .unsafe_cast_ref::<AudioEncoder>()
206                        .to_glib_none()
207                        .0))
208                    {
209                        Ok(())
210                    } else {
211                        Err(gst::error_msg!(
212                            gst::CoreError::StateChange,
213                            ["Parent function `start` failed"]
214                        ))
215                    }
216                })
217                .unwrap_or(Ok(()))
218        }
219    }
220
221    fn parent_stop(&self) -> Result<(), gst::ErrorMessage> {
222        unsafe {
223            let data = Self::type_data();
224            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
225            (*parent_class)
226                .stop
227                .map(|f| {
228                    if from_glib(f(self
229                        .obj()
230                        .unsafe_cast_ref::<AudioEncoder>()
231                        .to_glib_none()
232                        .0))
233                    {
234                        Ok(())
235                    } else {
236                        Err(gst::error_msg!(
237                            gst::CoreError::StateChange,
238                            ["Parent function `stop` failed"]
239                        ))
240                    }
241                })
242                .unwrap_or(Ok(()))
243        }
244    }
245
246    fn parent_set_format(&self, info: &AudioInfo) -> Result<(), gst::LoggableError> {
247        unsafe {
248            let data = Self::type_data();
249            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
250            (*parent_class)
251                .set_format
252                .map(|f| {
253                    gst::result_from_gboolean!(
254                        f(
255                            self.obj()
256                                .unsafe_cast_ref::<AudioEncoder>()
257                                .to_glib_none()
258                                .0,
259                            info.to_glib_none().0 as *mut _
260                        ),
261                        gst::CAT_RUST,
262                        "parent function `set_format` failed"
263                    )
264                })
265                .unwrap_or(Ok(()))
266        }
267    }
268
269    fn parent_handle_frame(
270        &self,
271        buffer: Option<&gst::Buffer>,
272    ) -> Result<gst::FlowSuccess, gst::FlowError> {
273        unsafe {
274            let data = Self::type_data();
275            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
276            (*parent_class)
277                .handle_frame
278                .map(|f| {
279                    try_from_glib(f(
280                        self.obj()
281                            .unsafe_cast_ref::<AudioEncoder>()
282                            .to_glib_none()
283                            .0,
284                        buffer
285                            .map(|buffer| buffer.as_mut_ptr() as *mut *mut gst::ffi::GstBuffer)
286                            .unwrap_or(ptr::null_mut()),
287                    ))
288                })
289                .unwrap_or(Err(gst::FlowError::Error))
290        }
291    }
292
293    fn parent_pre_push(&self, buffer: gst::Buffer) -> Result<Option<gst::Buffer>, gst::FlowError> {
294        unsafe {
295            let data = Self::type_data();
296            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
297            if let Some(f) = (*parent_class).pre_push {
298                let mut buffer = buffer.into_glib_ptr();
299                gst::FlowSuccess::try_from_glib(f(
300                    self.obj()
301                        .unsafe_cast_ref::<AudioEncoder>()
302                        .to_glib_none()
303                        .0,
304                    &mut buffer,
305                ))
306                .map(|_| from_glib_full(buffer))
307            } else {
308                Ok(Some(buffer))
309            }
310        }
311    }
312
313    fn parent_flush(&self) {
314        unsafe {
315            let data = Self::type_data();
316            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
317            (*parent_class)
318                .flush
319                .map(|f| {
320                    f(self
321                        .obj()
322                        .unsafe_cast_ref::<AudioEncoder>()
323                        .to_glib_none()
324                        .0)
325                })
326                .unwrap_or(())
327        }
328    }
329
330    fn parent_negotiate(&self) -> Result<(), gst::LoggableError> {
331        unsafe {
332            let data = Self::type_data();
333            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
334            (*parent_class)
335                .negotiate
336                .map(|f| {
337                    gst::result_from_gboolean!(
338                        f(self
339                            .obj()
340                            .unsafe_cast_ref::<AudioEncoder>()
341                            .to_glib_none()
342                            .0),
343                        gst::CAT_RUST,
344                        "Parent function `negotiate` failed"
345                    )
346                })
347                .unwrap_or(Ok(()))
348        }
349    }
350
351    fn parent_caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
352        unsafe {
353            let data = Self::type_data();
354            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
355            (*parent_class)
356                .getcaps
357                .map(|f| {
358                    from_glib_full(f(
359                        self.obj()
360                            .unsafe_cast_ref::<AudioEncoder>()
361                            .to_glib_none()
362                            .0,
363                        filter.to_glib_none().0,
364                    ))
365                })
366                .unwrap_or_else(|| {
367                    self.obj()
368                        .unsafe_cast_ref::<AudioEncoder>()
369                        .proxy_getcaps(None, filter)
370                })
371        }
372    }
373
374    fn parent_sink_event(&self, event: gst::Event) -> bool {
375        unsafe {
376            let data = Self::type_data();
377            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
378            let f = (*parent_class)
379                .sink_event
380                .expect("Missing parent function `sink_event`");
381            from_glib(f(
382                self.obj()
383                    .unsafe_cast_ref::<AudioEncoder>()
384                    .to_glib_none()
385                    .0,
386                event.into_glib_ptr(),
387            ))
388        }
389    }
390
391    fn parent_sink_query(&self, query: &mut gst::QueryRef) -> bool {
392        unsafe {
393            let data = Self::type_data();
394            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
395            let f = (*parent_class)
396                .sink_query
397                .expect("Missing parent function `sink_query`");
398            from_glib(f(
399                self.obj()
400                    .unsafe_cast_ref::<AudioEncoder>()
401                    .to_glib_none()
402                    .0,
403                query.as_mut_ptr(),
404            ))
405        }
406    }
407
408    fn parent_src_event(&self, event: gst::Event) -> bool {
409        unsafe {
410            let data = Self::type_data();
411            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
412            let f = (*parent_class)
413                .src_event
414                .expect("Missing parent function `src_event`");
415            from_glib(f(
416                self.obj()
417                    .unsafe_cast_ref::<AudioEncoder>()
418                    .to_glib_none()
419                    .0,
420                event.into_glib_ptr(),
421            ))
422        }
423    }
424
425    fn parent_src_query(&self, query: &mut gst::QueryRef) -> bool {
426        unsafe {
427            let data = Self::type_data();
428            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
429            let f = (*parent_class)
430                .src_query
431                .expect("Missing parent function `src_query`");
432            from_glib(f(
433                self.obj()
434                    .unsafe_cast_ref::<AudioEncoder>()
435                    .to_glib_none()
436                    .0,
437                query.as_mut_ptr(),
438            ))
439        }
440    }
441
442    fn parent_propose_allocation(
443        &self,
444        query: &mut gst::query::Allocation,
445    ) -> Result<(), gst::LoggableError> {
446        unsafe {
447            let data = Self::type_data();
448            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
449            (*parent_class)
450                .propose_allocation
451                .map(|f| {
452                    gst::result_from_gboolean!(
453                        f(
454                            self.obj()
455                                .unsafe_cast_ref::<AudioEncoder>()
456                                .to_glib_none()
457                                .0,
458                            query.as_mut_ptr(),
459                        ),
460                        gst::CAT_RUST,
461                        "Parent function `propose_allocation` failed",
462                    )
463                })
464                .unwrap_or(Ok(()))
465        }
466    }
467
468    fn parent_decide_allocation(
469        &self,
470        query: &mut gst::query::Allocation,
471    ) -> Result<(), gst::LoggableError> {
472        unsafe {
473            let data = Self::type_data();
474            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
475            (*parent_class)
476                .decide_allocation
477                .map(|f| {
478                    gst::result_from_gboolean!(
479                        f(
480                            self.obj()
481                                .unsafe_cast_ref::<AudioEncoder>()
482                                .to_glib_none()
483                                .0,
484                            query.as_mut_ptr(),
485                        ),
486                        gst::CAT_RUST,
487                        "Parent function `decide_allocation` failed",
488                    )
489                })
490                .unwrap_or(Ok(()))
491        }
492    }
493}
494
495impl<T: AudioEncoderImpl> AudioEncoderImplExt for T {}
496
497unsafe impl<T: AudioEncoderImpl> IsSubclassable<T> for AudioEncoder {
498    fn class_init(klass: &mut glib::Class<Self>) {
499        Self::parent_class_init::<T>(klass);
500        let klass = klass.as_mut();
501        klass.open = Some(audio_encoder_open::<T>);
502        klass.close = Some(audio_encoder_close::<T>);
503        klass.start = Some(audio_encoder_start::<T>);
504        klass.stop = Some(audio_encoder_stop::<T>);
505        klass.set_format = Some(audio_encoder_set_format::<T>);
506        klass.handle_frame = Some(audio_encoder_handle_frame::<T>);
507        klass.pre_push = Some(audio_encoder_pre_push::<T>);
508        klass.flush = Some(audio_encoder_flush::<T>);
509        klass.negotiate = Some(audio_encoder_negotiate::<T>);
510        klass.getcaps = Some(audio_encoder_getcaps::<T>);
511        klass.sink_event = Some(audio_encoder_sink_event::<T>);
512        klass.src_event = Some(audio_encoder_src_event::<T>);
513        klass.sink_query = Some(audio_encoder_sink_query::<T>);
514        klass.src_query = Some(audio_encoder_src_query::<T>);
515        klass.propose_allocation = Some(audio_encoder_propose_allocation::<T>);
516        klass.decide_allocation = Some(audio_encoder_decide_allocation::<T>);
517    }
518}
519
520unsafe extern "C" fn audio_encoder_open<T: AudioEncoderImpl>(
521    ptr: *mut ffi::GstAudioEncoder,
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.open() {
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_encoder_close<T: AudioEncoderImpl>(
539    ptr: *mut ffi::GstAudioEncoder,
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.close() {
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_encoder_start<T: AudioEncoderImpl>(
557    ptr: *mut ffi::GstAudioEncoder,
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.start() {
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_encoder_stop<T: AudioEncoderImpl>(
575    ptr: *mut ffi::GstAudioEncoder,
576) -> glib::ffi::gboolean {
577    let instance = &*(ptr as *mut T::Instance);
578    let imp = instance.imp();
579
580    gst::panic_to_error!(imp, false, {
581        match imp.stop() {
582            Ok(()) => true,
583            Err(err) => {
584                imp.post_error_message(err);
585                false
586            }
587        }
588    })
589    .into_glib()
590}
591
592unsafe extern "C" fn audio_encoder_set_format<T: AudioEncoderImpl>(
593    ptr: *mut ffi::GstAudioEncoder,
594    info: *mut ffi::GstAudioInfo,
595) -> glib::ffi::gboolean {
596    let instance = &*(ptr as *mut T::Instance);
597    let imp = instance.imp();
598
599    gst::panic_to_error!(imp, false, {
600        match imp.set_format(&from_glib_none(info)) {
601            Ok(()) => true,
602            Err(err) => {
603                err.log_with_imp(imp);
604                false
605            }
606        }
607    })
608    .into_glib()
609}
610
611unsafe extern "C" fn audio_encoder_handle_frame<T: AudioEncoderImpl>(
612    ptr: *mut ffi::GstAudioEncoder,
613    buffer: *mut *mut gst::ffi::GstBuffer,
614) -> gst::ffi::GstFlowReturn {
615    // FIXME: Misgenerated in gstreamer-audio-sys
616    let buffer = buffer as *mut gst::ffi::GstBuffer;
617    let instance = &*(ptr as *mut T::Instance);
618    let imp = instance.imp();
619
620    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
621        imp.handle_frame(Option::<gst::Buffer>::from_glib_none(buffer).as_ref())
622            .into()
623    })
624    .into_glib()
625}
626
627unsafe extern "C" fn audio_encoder_pre_push<T: AudioEncoderImpl>(
628    ptr: *mut ffi::GstAudioEncoder,
629    buffer: *mut *mut gst::ffi::GstBuffer,
630) -> gst::ffi::GstFlowReturn {
631    let instance = &*(ptr as *mut T::Instance);
632    let imp = instance.imp();
633
634    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
635        match imp.pre_push(from_glib_full(*buffer)) {
636            Ok(Some(new_buffer)) => {
637                *buffer = new_buffer.into_glib_ptr();
638                Ok(gst::FlowSuccess::Ok)
639            }
640            Ok(None) => {
641                *buffer = ptr::null_mut();
642                Ok(gst::FlowSuccess::Ok)
643            }
644            Err(err) => Err(err),
645        }
646        .into()
647    })
648    .into_glib()
649}
650
651unsafe extern "C" fn audio_encoder_flush<T: AudioEncoderImpl>(ptr: *mut ffi::GstAudioEncoder) {
652    let instance = &*(ptr as *mut T::Instance);
653    let imp = instance.imp();
654
655    gst::panic_to_error!(imp, (), { AudioEncoderImpl::flush(imp,) })
656}
657
658unsafe extern "C" fn audio_encoder_negotiate<T: AudioEncoderImpl>(
659    ptr: *mut ffi::GstAudioEncoder,
660) -> glib::ffi::gboolean {
661    let instance = &*(ptr as *mut T::Instance);
662    let imp = instance.imp();
663
664    gst::panic_to_error!(imp, false, {
665        match imp.negotiate() {
666            Ok(()) => true,
667            Err(err) => {
668                err.log_with_imp(imp);
669                false
670            }
671        }
672    })
673    .into_glib()
674}
675
676unsafe extern "C" fn audio_encoder_getcaps<T: AudioEncoderImpl>(
677    ptr: *mut ffi::GstAudioEncoder,
678    filter: *mut gst::ffi::GstCaps,
679) -> *mut gst::ffi::GstCaps {
680    let instance = &*(ptr as *mut T::Instance);
681    let imp = instance.imp();
682
683    gst::panic_to_error!(imp, gst::Caps::new_empty(), {
684        AudioEncoderImpl::caps(
685            imp,
686            Option::<gst::Caps>::from_glib_borrow(filter)
687                .as_ref()
688                .as_ref(),
689        )
690    })
691    .into_glib_ptr()
692}
693
694unsafe extern "C" fn audio_encoder_sink_event<T: AudioEncoderImpl>(
695    ptr: *mut ffi::GstAudioEncoder,
696    event: *mut gst::ffi::GstEvent,
697) -> glib::ffi::gboolean {
698    let instance = &*(ptr as *mut T::Instance);
699    let imp = instance.imp();
700
701    gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib()
702}
703
704unsafe extern "C" fn audio_encoder_sink_query<T: AudioEncoderImpl>(
705    ptr: *mut ffi::GstAudioEncoder,
706    query: *mut gst::ffi::GstQuery,
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, {
712        imp.sink_query(gst::QueryRef::from_mut_ptr(query))
713    })
714    .into_glib()
715}
716
717unsafe extern "C" fn audio_encoder_src_event<T: AudioEncoderImpl>(
718    ptr: *mut ffi::GstAudioEncoder,
719    event: *mut gst::ffi::GstEvent,
720) -> glib::ffi::gboolean {
721    let instance = &*(ptr as *mut T::Instance);
722    let imp = instance.imp();
723
724    gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
725}
726
727unsafe extern "C" fn audio_encoder_src_query<T: AudioEncoderImpl>(
728    ptr: *mut ffi::GstAudioEncoder,
729    query: *mut gst::ffi::GstQuery,
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, {
735        imp.src_query(gst::QueryRef::from_mut_ptr(query))
736    })
737    .into_glib()
738}
739
740unsafe extern "C" fn audio_encoder_propose_allocation<T: AudioEncoderImpl>(
741    ptr: *mut ffi::GstAudioEncoder,
742    query: *mut gst::ffi::GstQuery,
743) -> glib::ffi::gboolean {
744    let instance = &*(ptr as *mut T::Instance);
745    let imp = instance.imp();
746    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
747        gst::QueryViewMut::Allocation(allocation) => allocation,
748        _ => unreachable!(),
749    };
750
751    gst::panic_to_error!(imp, false, {
752        match imp.propose_allocation(query) {
753            Ok(()) => true,
754            Err(err) => {
755                err.log_with_imp(imp);
756                false
757            }
758        }
759    })
760    .into_glib()
761}
762
763unsafe extern "C" fn audio_encoder_decide_allocation<T: AudioEncoderImpl>(
764    ptr: *mut ffi::GstAudioEncoder,
765    query: *mut gst::ffi::GstQuery,
766) -> glib::ffi::gboolean {
767    let instance = &*(ptr as *mut T::Instance);
768    let imp = instance.imp();
769    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
770        gst::QueryViewMut::Allocation(allocation) => allocation,
771        _ => unreachable!(),
772    };
773
774    gst::panic_to_error!(imp, false, {
775        match imp.decide_allocation(query) {
776            Ok(()) => true,
777            Err(err) => {
778                err.log_with_imp(imp);
779                false
780            }
781        }
782    })
783    .into_glib()
784}