Skip to main content

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::{AudioEncoder, AudioInfo, ffi, prelude::*};
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    ///
145    /// calls ``decide_allocation()``.
146    /// ## `caps`
147    /// the negotiated [`gst::Caps`][crate::gst::Caps]
148    ///
149    /// # Returns
150    ///
151    /// whether the [`gst::Allocator`][crate::gst::Allocator] could be configured.
152    #[cfg(feature = "v1_30")]
153    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
154    fn prepare_allocator(&self, caps: Option<&gst::Caps>) -> Result<(), gst::LoggableError> {
155        self.parent_prepare_allocator(caps)
156    }
157}
158
159pub trait AudioEncoderImplExt: AudioEncoderImpl {
160    fn parent_open(&self) -> Result<(), gst::ErrorMessage> {
161        unsafe {
162            let data = Self::type_data();
163            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
164            (*parent_class)
165                .open
166                .map(|f| {
167                    if from_glib(f(self
168                        .obj()
169                        .unsafe_cast_ref::<AudioEncoder>()
170                        .to_glib_none()
171                        .0))
172                    {
173                        Ok(())
174                    } else {
175                        Err(gst::error_msg!(
176                            gst::CoreError::StateChange,
177                            ["Parent function `open` failed"]
178                        ))
179                    }
180                })
181                .unwrap_or(Ok(()))
182        }
183    }
184
185    fn parent_close(&self) -> Result<(), gst::ErrorMessage> {
186        unsafe {
187            let data = Self::type_data();
188            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
189            (*parent_class)
190                .close
191                .map(|f| {
192                    if from_glib(f(self
193                        .obj()
194                        .unsafe_cast_ref::<AudioEncoder>()
195                        .to_glib_none()
196                        .0))
197                    {
198                        Ok(())
199                    } else {
200                        Err(gst::error_msg!(
201                            gst::CoreError::StateChange,
202                            ["Parent function `close` failed"]
203                        ))
204                    }
205                })
206                .unwrap_or(Ok(()))
207        }
208    }
209
210    fn parent_start(&self) -> Result<(), gst::ErrorMessage> {
211        unsafe {
212            let data = Self::type_data();
213            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
214            (*parent_class)
215                .start
216                .map(|f| {
217                    if from_glib(f(self
218                        .obj()
219                        .unsafe_cast_ref::<AudioEncoder>()
220                        .to_glib_none()
221                        .0))
222                    {
223                        Ok(())
224                    } else {
225                        Err(gst::error_msg!(
226                            gst::CoreError::StateChange,
227                            ["Parent function `start` failed"]
228                        ))
229                    }
230                })
231                .unwrap_or(Ok(()))
232        }
233    }
234
235    fn parent_stop(&self) -> Result<(), gst::ErrorMessage> {
236        unsafe {
237            let data = Self::type_data();
238            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
239            (*parent_class)
240                .stop
241                .map(|f| {
242                    if from_glib(f(self
243                        .obj()
244                        .unsafe_cast_ref::<AudioEncoder>()
245                        .to_glib_none()
246                        .0))
247                    {
248                        Ok(())
249                    } else {
250                        Err(gst::error_msg!(
251                            gst::CoreError::StateChange,
252                            ["Parent function `stop` failed"]
253                        ))
254                    }
255                })
256                .unwrap_or(Ok(()))
257        }
258    }
259
260    fn parent_set_format(&self, info: &AudioInfo) -> Result<(), gst::LoggableError> {
261        unsafe {
262            let data = Self::type_data();
263            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
264            (*parent_class)
265                .set_format
266                .map(|f| {
267                    gst::result_from_gboolean!(
268                        f(
269                            self.obj()
270                                .unsafe_cast_ref::<AudioEncoder>()
271                                .to_glib_none()
272                                .0,
273                            info.to_glib_none().0 as *mut _
274                        ),
275                        gst::CAT_RUST,
276                        "parent function `set_format` failed"
277                    )
278                })
279                .unwrap_or(Ok(()))
280        }
281    }
282
283    fn parent_handle_frame(
284        &self,
285        buffer: Option<&gst::Buffer>,
286    ) -> Result<gst::FlowSuccess, gst::FlowError> {
287        unsafe {
288            let data = Self::type_data();
289            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
290            (*parent_class)
291                .handle_frame
292                .map(|f| {
293                    try_from_glib(f(
294                        self.obj()
295                            .unsafe_cast_ref::<AudioEncoder>()
296                            .to_glib_none()
297                            .0,
298                        buffer
299                            .map(|buffer| buffer.as_mut_ptr() as *mut *mut gst::ffi::GstBuffer)
300                            .unwrap_or(ptr::null_mut()),
301                    ))
302                })
303                .unwrap_or(Err(gst::FlowError::Error))
304        }
305    }
306
307    fn parent_pre_push(&self, buffer: gst::Buffer) -> Result<Option<gst::Buffer>, gst::FlowError> {
308        unsafe {
309            let data = Self::type_data();
310            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
311            if let Some(f) = (*parent_class).pre_push {
312                let mut buffer = buffer.into_glib_ptr();
313                gst::FlowSuccess::try_from_glib(f(
314                    self.obj()
315                        .unsafe_cast_ref::<AudioEncoder>()
316                        .to_glib_none()
317                        .0,
318                    &mut buffer,
319                ))
320                .map(|_| from_glib_full(buffer))
321            } else {
322                Ok(Some(buffer))
323            }
324        }
325    }
326
327    fn parent_flush(&self) {
328        unsafe {
329            let data = Self::type_data();
330            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
331            (*parent_class)
332                .flush
333                .map(|f| {
334                    f(self
335                        .obj()
336                        .unsafe_cast_ref::<AudioEncoder>()
337                        .to_glib_none()
338                        .0)
339                })
340                .unwrap_or(())
341        }
342    }
343
344    fn parent_negotiate(&self) -> Result<(), gst::LoggableError> {
345        unsafe {
346            let data = Self::type_data();
347            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
348            (*parent_class)
349                .negotiate
350                .map(|f| {
351                    gst::result_from_gboolean!(
352                        f(self
353                            .obj()
354                            .unsafe_cast_ref::<AudioEncoder>()
355                            .to_glib_none()
356                            .0),
357                        gst::CAT_RUST,
358                        "Parent function `negotiate` failed"
359                    )
360                })
361                .unwrap_or(Ok(()))
362        }
363    }
364
365    fn parent_caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
366        unsafe {
367            let data = Self::type_data();
368            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
369            (*parent_class)
370                .getcaps
371                .map(|f| {
372                    from_glib_full(f(
373                        self.obj()
374                            .unsafe_cast_ref::<AudioEncoder>()
375                            .to_glib_none()
376                            .0,
377                        filter.to_glib_none().0,
378                    ))
379                })
380                .unwrap_or_else(|| {
381                    self.obj()
382                        .unsafe_cast_ref::<AudioEncoder>()
383                        .proxy_getcaps(None, filter)
384                })
385        }
386    }
387
388    fn parent_sink_event(&self, event: gst::Event) -> bool {
389        unsafe {
390            let data = Self::type_data();
391            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
392            let f = (*parent_class)
393                .sink_event
394                .expect("Missing parent function `sink_event`");
395            from_glib(f(
396                self.obj()
397                    .unsafe_cast_ref::<AudioEncoder>()
398                    .to_glib_none()
399                    .0,
400                event.into_glib_ptr(),
401            ))
402        }
403    }
404
405    fn parent_sink_query(&self, query: &mut gst::QueryRef) -> bool {
406        unsafe {
407            let data = Self::type_data();
408            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
409            let f = (*parent_class)
410                .sink_query
411                .expect("Missing parent function `sink_query`");
412            from_glib(f(
413                self.obj()
414                    .unsafe_cast_ref::<AudioEncoder>()
415                    .to_glib_none()
416                    .0,
417                query.as_mut_ptr(),
418            ))
419        }
420    }
421
422    fn parent_src_event(&self, event: gst::Event) -> bool {
423        unsafe {
424            let data = Self::type_data();
425            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
426            let f = (*parent_class)
427                .src_event
428                .expect("Missing parent function `src_event`");
429            from_glib(f(
430                self.obj()
431                    .unsafe_cast_ref::<AudioEncoder>()
432                    .to_glib_none()
433                    .0,
434                event.into_glib_ptr(),
435            ))
436        }
437    }
438
439    fn parent_src_query(&self, query: &mut gst::QueryRef) -> bool {
440        unsafe {
441            let data = Self::type_data();
442            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
443            let f = (*parent_class)
444                .src_query
445                .expect("Missing parent function `src_query`");
446            from_glib(f(
447                self.obj()
448                    .unsafe_cast_ref::<AudioEncoder>()
449                    .to_glib_none()
450                    .0,
451                query.as_mut_ptr(),
452            ))
453        }
454    }
455
456    fn parent_propose_allocation(
457        &self,
458        query: &mut gst::query::Allocation,
459    ) -> Result<(), gst::LoggableError> {
460        unsafe {
461            let data = Self::type_data();
462            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
463            (*parent_class)
464                .propose_allocation
465                .map(|f| {
466                    gst::result_from_gboolean!(
467                        f(
468                            self.obj()
469                                .unsafe_cast_ref::<AudioEncoder>()
470                                .to_glib_none()
471                                .0,
472                            query.as_mut_ptr(),
473                        ),
474                        gst::CAT_RUST,
475                        "Parent function `propose_allocation` failed",
476                    )
477                })
478                .unwrap_or(Ok(()))
479        }
480    }
481
482    fn parent_decide_allocation(
483        &self,
484        query: &mut gst::query::Allocation,
485    ) -> Result<(), gst::LoggableError> {
486        unsafe {
487            let data = Self::type_data();
488            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
489            (*parent_class)
490                .decide_allocation
491                .map(|f| {
492                    gst::result_from_gboolean!(
493                        f(
494                            self.obj()
495                                .unsafe_cast_ref::<AudioEncoder>()
496                                .to_glib_none()
497                                .0,
498                            query.as_mut_ptr(),
499                        ),
500                        gst::CAT_RUST,
501                        "Parent function `decide_allocation` failed",
502                    )
503                })
504                .unwrap_or(Ok(()))
505        }
506    }
507
508    #[cfg(feature = "v1_30")]
509    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
510    fn parent_prepare_allocator(&self, caps: Option<&gst::Caps>) -> Result<(), gst::LoggableError> {
511        unsafe {
512            let data = Self::type_data();
513            let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioEncoderClass;
514            (*parent_class)
515                .prepare_allocator
516                .map(|f| {
517                    gst::result_from_gboolean!(
518                        f(
519                            self.obj()
520                                .unsafe_cast_ref::<AudioEncoder>()
521                                .to_glib_none()
522                                .0,
523                            caps.to_glib_none().0
524                        ),
525                        gst::CAT_RUST,
526                        "Parent function `prepare_allocator` failed",
527                    )
528                })
529                .unwrap_or(Ok(()))
530        }
531    }
532}
533
534impl<T: AudioEncoderImpl> AudioEncoderImplExt for T {}
535
536unsafe impl<T: AudioEncoderImpl> IsSubclassable<T> for AudioEncoder {
537    fn class_init(klass: &mut glib::Class<Self>) {
538        Self::parent_class_init::<T>(klass);
539        let klass = klass.as_mut();
540        klass.open = Some(audio_encoder_open::<T>);
541        klass.close = Some(audio_encoder_close::<T>);
542        klass.start = Some(audio_encoder_start::<T>);
543        klass.stop = Some(audio_encoder_stop::<T>);
544        klass.set_format = Some(audio_encoder_set_format::<T>);
545        klass.handle_frame = Some(audio_encoder_handle_frame::<T>);
546        klass.pre_push = Some(audio_encoder_pre_push::<T>);
547        klass.flush = Some(audio_encoder_flush::<T>);
548        klass.negotiate = Some(audio_encoder_negotiate::<T>);
549        klass.getcaps = Some(audio_encoder_getcaps::<T>);
550        klass.sink_event = Some(audio_encoder_sink_event::<T>);
551        klass.src_event = Some(audio_encoder_src_event::<T>);
552        klass.sink_query = Some(audio_encoder_sink_query::<T>);
553        klass.src_query = Some(audio_encoder_src_query::<T>);
554        klass.propose_allocation = Some(audio_encoder_propose_allocation::<T>);
555        klass.decide_allocation = Some(audio_encoder_decide_allocation::<T>);
556        #[cfg(feature = "v1_30")]
557        {
558            klass.prepare_allocator = Some(audio_encoder_prepare_allocator::<T>);
559        }
560    }
561}
562
563unsafe extern "C" fn audio_encoder_open<T: AudioEncoderImpl>(
564    ptr: *mut ffi::GstAudioEncoder,
565) -> glib::ffi::gboolean {
566    unsafe {
567        let instance = &*(ptr as *mut T::Instance);
568        let imp = instance.imp();
569
570        gst::element_panic_to_error!(imp, false, {
571            match imp.open() {
572                Ok(()) => true,
573                Err(err) => {
574                    imp.post_error_message(err);
575                    false
576                }
577            }
578        })
579        .into_glib()
580    }
581}
582
583unsafe extern "C" fn audio_encoder_close<T: AudioEncoderImpl>(
584    ptr: *mut ffi::GstAudioEncoder,
585) -> glib::ffi::gboolean {
586    unsafe {
587        let instance = &*(ptr as *mut T::Instance);
588        let imp = instance.imp();
589
590        gst::element_panic_to_error!(imp, false, {
591            match imp.close() {
592                Ok(()) => true,
593                Err(err) => {
594                    imp.post_error_message(err);
595                    false
596                }
597            }
598        })
599        .into_glib()
600    }
601}
602
603unsafe extern "C" fn audio_encoder_start<T: AudioEncoderImpl>(
604    ptr: *mut ffi::GstAudioEncoder,
605) -> glib::ffi::gboolean {
606    unsafe {
607        let instance = &*(ptr as *mut T::Instance);
608        let imp = instance.imp();
609
610        gst::element_panic_to_error!(imp, false, {
611            match imp.start() {
612                Ok(()) => true,
613                Err(err) => {
614                    imp.post_error_message(err);
615                    false
616                }
617            }
618        })
619        .into_glib()
620    }
621}
622
623unsafe extern "C" fn audio_encoder_stop<T: AudioEncoderImpl>(
624    ptr: *mut ffi::GstAudioEncoder,
625) -> glib::ffi::gboolean {
626    unsafe {
627        let instance = &*(ptr as *mut T::Instance);
628        let imp = instance.imp();
629
630        gst::element_panic_to_error!(imp, false, {
631            match imp.stop() {
632                Ok(()) => true,
633                Err(err) => {
634                    imp.post_error_message(err);
635                    false
636                }
637            }
638        })
639        .into_glib()
640    }
641}
642
643unsafe extern "C" fn audio_encoder_set_format<T: AudioEncoderImpl>(
644    ptr: *mut ffi::GstAudioEncoder,
645    info: *mut ffi::GstAudioInfo,
646) -> glib::ffi::gboolean {
647    unsafe {
648        let instance = &*(ptr as *mut T::Instance);
649        let imp = instance.imp();
650
651        gst::element_panic_to_error!(imp, false, {
652            match imp.set_format(&from_glib_none(info)) {
653                Ok(()) => true,
654                Err(err) => {
655                    err.log_with_imp(imp);
656                    false
657                }
658            }
659        })
660        .into_glib()
661    }
662}
663
664unsafe extern "C" fn audio_encoder_handle_frame<T: AudioEncoderImpl>(
665    ptr: *mut ffi::GstAudioEncoder,
666    buffer: *mut *mut gst::ffi::GstBuffer,
667) -> gst::ffi::GstFlowReturn {
668    unsafe {
669        // FIXME: Misgenerated in gstreamer-audio-sys
670        let buffer = buffer as *mut gst::ffi::GstBuffer;
671        let instance = &*(ptr as *mut T::Instance);
672        let imp = instance.imp();
673
674        gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
675            imp.handle_frame(Option::<gst::Buffer>::from_glib_none(buffer).as_ref())
676                .into()
677        })
678        .into_glib()
679    }
680}
681
682unsafe extern "C" fn audio_encoder_pre_push<T: AudioEncoderImpl>(
683    ptr: *mut ffi::GstAudioEncoder,
684    buffer: *mut *mut gst::ffi::GstBuffer,
685) -> gst::ffi::GstFlowReturn {
686    unsafe {
687        let instance = &*(ptr as *mut T::Instance);
688        let imp = instance.imp();
689
690        gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
691            match imp.pre_push(from_glib_full(*buffer)) {
692                Ok(Some(new_buffer)) => {
693                    *buffer = new_buffer.into_glib_ptr();
694                    Ok(gst::FlowSuccess::Ok)
695                }
696                Ok(None) => {
697                    *buffer = ptr::null_mut();
698                    Ok(gst::FlowSuccess::Ok)
699                }
700                Err(err) => Err(err),
701            }
702            .into()
703        })
704        .into_glib()
705    }
706}
707
708unsafe extern "C" fn audio_encoder_flush<T: AudioEncoderImpl>(ptr: *mut ffi::GstAudioEncoder) {
709    unsafe {
710        let instance = &*(ptr as *mut T::Instance);
711        let imp = instance.imp();
712
713        gst::element_panic_to_error!(imp, (), { AudioEncoderImpl::flush(imp,) })
714    }
715}
716
717unsafe extern "C" fn audio_encoder_negotiate<T: AudioEncoderImpl>(
718    ptr: *mut ffi::GstAudioEncoder,
719) -> glib::ffi::gboolean {
720    unsafe {
721        let instance = &*(ptr as *mut T::Instance);
722        let imp = instance.imp();
723
724        gst::element_panic_to_error!(imp, false, {
725            match imp.negotiate() {
726                Ok(()) => true,
727                Err(err) => {
728                    err.log_with_imp(imp);
729                    false
730                }
731            }
732        })
733        .into_glib()
734    }
735}
736
737unsafe extern "C" fn audio_encoder_getcaps<T: AudioEncoderImpl>(
738    ptr: *mut ffi::GstAudioEncoder,
739    filter: *mut gst::ffi::GstCaps,
740) -> *mut gst::ffi::GstCaps {
741    unsafe {
742        let instance = &*(ptr as *mut T::Instance);
743        let imp = instance.imp();
744
745        gst::element_panic_to_error!(imp, gst::Caps::new_empty(), {
746            AudioEncoderImpl::caps(
747                imp,
748                Option::<gst::Caps>::from_glib_borrow(filter)
749                    .as_ref()
750                    .as_ref(),
751            )
752        })
753        .into_glib_ptr()
754    }
755}
756
757unsafe extern "C" fn audio_encoder_sink_event<T: AudioEncoderImpl>(
758    ptr: *mut ffi::GstAudioEncoder,
759    event: *mut gst::ffi::GstEvent,
760) -> glib::ffi::gboolean {
761    unsafe {
762        let instance = &*(ptr as *mut T::Instance);
763        let imp = instance.imp();
764
765        gst::element_panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) })
766            .into_glib()
767    }
768}
769
770unsafe extern "C" fn audio_encoder_sink_query<T: AudioEncoderImpl>(
771    ptr: *mut ffi::GstAudioEncoder,
772    query: *mut gst::ffi::GstQuery,
773) -> glib::ffi::gboolean {
774    unsafe {
775        let instance = &*(ptr as *mut T::Instance);
776        let imp = instance.imp();
777
778        gst::element_panic_to_error!(imp, false, {
779            imp.sink_query(gst::QueryRef::from_mut_ptr(query))
780        })
781        .into_glib()
782    }
783}
784
785unsafe extern "C" fn audio_encoder_src_event<T: AudioEncoderImpl>(
786    ptr: *mut ffi::GstAudioEncoder,
787    event: *mut gst::ffi::GstEvent,
788) -> glib::ffi::gboolean {
789    unsafe {
790        let instance = &*(ptr as *mut T::Instance);
791        let imp = instance.imp();
792
793        gst::element_panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) })
794            .into_glib()
795    }
796}
797
798unsafe extern "C" fn audio_encoder_src_query<T: AudioEncoderImpl>(
799    ptr: *mut ffi::GstAudioEncoder,
800    query: *mut gst::ffi::GstQuery,
801) -> glib::ffi::gboolean {
802    unsafe {
803        let instance = &*(ptr as *mut T::Instance);
804        let imp = instance.imp();
805
806        gst::element_panic_to_error!(imp, false, {
807            imp.src_query(gst::QueryRef::from_mut_ptr(query))
808        })
809        .into_glib()
810    }
811}
812
813unsafe extern "C" fn audio_encoder_propose_allocation<T: AudioEncoderImpl>(
814    ptr: *mut ffi::GstAudioEncoder,
815    query: *mut gst::ffi::GstQuery,
816) -> glib::ffi::gboolean {
817    unsafe {
818        let instance = &*(ptr as *mut T::Instance);
819        let imp = instance.imp();
820        let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
821            gst::QueryViewMut::Allocation(allocation) => allocation,
822            _ => unreachable!(),
823        };
824
825        gst::element_panic_to_error!(imp, false, {
826            match imp.propose_allocation(query) {
827                Ok(()) => true,
828                Err(err) => {
829                    err.log_with_imp(imp);
830                    false
831                }
832            }
833        })
834        .into_glib()
835    }
836}
837
838unsafe extern "C" fn audio_encoder_decide_allocation<T: AudioEncoderImpl>(
839    ptr: *mut ffi::GstAudioEncoder,
840    query: *mut gst::ffi::GstQuery,
841) -> glib::ffi::gboolean {
842    unsafe {
843        let instance = &*(ptr as *mut T::Instance);
844        let imp = instance.imp();
845        let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
846            gst::QueryViewMut::Allocation(allocation) => allocation,
847            _ => unreachable!(),
848        };
849
850        gst::element_panic_to_error!(imp, false, {
851            match imp.decide_allocation(query) {
852                Ok(()) => true,
853                Err(err) => {
854                    err.log_with_imp(imp);
855                    false
856                }
857            }
858        })
859        .into_glib()
860    }
861}
862
863#[cfg(feature = "v1_30")]
864#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
865unsafe extern "C" fn audio_encoder_prepare_allocator<T: AudioEncoderImpl>(
866    ptr: *mut ffi::GstAudioEncoder,
867    caps: *mut gst::ffi::GstCaps,
868) -> glib::ffi::gboolean {
869    unsafe {
870        let instance = &*(ptr as *mut T::Instance);
871        let imp = instance.imp();
872        let caps = Option::<gst::Caps>::from_glib_none(caps);
873
874        gst::element_panic_to_error!(imp, false, {
875            match imp.prepare_allocator(caps.as_ref()) {
876                Ok(()) => true,
877                Err(err) => {
878                    err.log_with_imp(imp);
879                    false
880                }
881            }
882        })
883        .into_glib()
884    }
885}