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