1use std::ptr;
4
5use glib::{prelude::*, translate::*};
6use gst::subclass::prelude::*;
7
8use crate::{Aggregator, AggregatorPad, ffi};
9
10pub trait AggregatorImpl: ElementImpl + ObjectSubclass<Type: IsA<Aggregator>> {
11 fn flush(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
16 self.parent_flush()
17 }
18
19 fn clip(&self, aggregator_pad: &AggregatorPad, buffer: gst::Buffer) -> Option<gst::Buffer> {
35 self.parent_clip(aggregator_pad, buffer)
36 }
37
38 #[cfg(feature = "v1_18")]
44 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
45 fn finish_buffer_list(
46 &self,
47 buffer_list: gst::BufferList,
48 ) -> Result<gst::FlowSuccess, gst::FlowError> {
49 self.parent_finish_buffer_list(buffer_list)
50 }
51
52 fn finish_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
58 self.parent_finish_buffer(buffer)
59 }
60
61 fn sink_event(&self, aggregator_pad: &AggregatorPad, event: gst::Event) -> bool {
68 self.parent_sink_event(aggregator_pad, event)
69 }
70
71 #[cfg(feature = "v1_18")]
78 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
79 fn sink_event_pre_queue(
80 &self,
81 aggregator_pad: &AggregatorPad,
82 event: gst::Event,
83 ) -> Result<gst::FlowSuccess, gst::FlowError> {
84 self.parent_sink_event_pre_queue(aggregator_pad, event)
85 }
86
87 fn sink_query(&self, aggregator_pad: &AggregatorPad, query: &mut gst::QueryRef) -> bool {
91 self.parent_sink_query(aggregator_pad, query)
92 }
93
94 #[cfg(feature = "v1_18")]
98 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
99 fn sink_query_pre_queue(
100 &self,
101 aggregator_pad: &AggregatorPad,
102 query: &mut gst::QueryRef,
103 ) -> bool {
104 self.parent_sink_query_pre_queue(aggregator_pad, query)
105 }
106
107 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 {
119 self.parent_src_query(query)
120 }
121
122 fn src_activate(&self, mode: gst::PadMode, active: bool) -> Result<(), gst::LoggableError> {
126 self.parent_src_activate(mode, active)
127 }
128
129 fn aggregate(&self, timeout: bool) -> Result<gst::FlowSuccess, gst::FlowError> {
137 self.parent_aggregate(timeout)
138 }
139
140 fn start(&self) -> Result<(), gst::ErrorMessage> {
145 self.parent_start()
146 }
147
148 fn stop(&self) -> Result<(), gst::ErrorMessage> {
152 self.parent_stop()
153 }
154
155 fn next_time(&self) -> Option<gst::ClockTime> {
162 self.parent_next_time()
163 }
164
165 fn create_new_pad(
179 &self,
180 templ: &gst::PadTemplate,
181 req_name: Option<&str>,
182 caps: Option<&gst::Caps>,
183 ) -> Option<AggregatorPad> {
184 self.parent_create_new_pad(templ, req_name, caps)
185 }
186
187 fn update_src_caps(&self, caps: &gst::Caps) -> Result<gst::Caps, gst::FlowError> {
193 self.parent_update_src_caps(caps)
194 }
195
196 fn fixate_src_caps(&self, caps: gst::Caps) -> gst::Caps {
206 self.parent_fixate_src_caps(caps)
207 }
208
209 fn negotiated_src_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
212 self.parent_negotiated_src_caps(caps)
213 }
214
215 fn propose_allocation(
218 &self,
219 pad: &AggregatorPad,
220 decide_query: Option<&gst::query::Allocation>,
221 query: &mut gst::query::Allocation,
222 ) -> Result<(), gst::LoggableError> {
223 self.parent_propose_allocation(pad, decide_query, query)
224 }
225
226 fn decide_allocation(
232 &self,
233 query: &mut gst::query::Allocation,
234 ) -> Result<(), gst::LoggableError> {
235 self.parent_decide_allocation(query)
236 }
237
238 #[cfg(feature = "v1_30")]
248 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
249 fn prepare_allocator(&self, caps: Option<&gst::Caps>) -> Result<(), gst::LoggableError> {
250 self.parent_prepare_allocator(caps)
251 }
252
253 #[cfg(feature = "v1_18")]
261 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
262 fn negotiate(&self) -> bool {
263 self.parent_negotiate()
264 }
265
266 #[cfg(feature = "v1_18")]
280 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
281 fn peek_next_sample(&self, pad: &AggregatorPad) -> Option<gst::Sample> {
282 self.parent_peek_next_sample(pad)
283 }
284}
285
286pub trait AggregatorImplExt: AggregatorImpl {
287 fn parent_flush(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
288 unsafe {
289 let data = Self::type_data();
290 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
291 (*parent_class)
292 .flush
293 .map(|f| {
294 try_from_glib(f(self
295 .obj()
296 .unsafe_cast_ref::<Aggregator>()
297 .to_glib_none()
298 .0))
299 })
300 .unwrap_or(Ok(gst::FlowSuccess::Ok))
301 }
302 }
303
304 fn parent_clip(
305 &self,
306 aggregator_pad: &AggregatorPad,
307 buffer: gst::Buffer,
308 ) -> Option<gst::Buffer> {
309 unsafe {
310 let data = Self::type_data();
311 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
312 match (*parent_class).clip {
313 None => Some(buffer),
314 Some(ref func) => from_glib_full(func(
315 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
316 aggregator_pad.to_glib_none().0,
317 buffer.into_glib_ptr(),
318 )),
319 }
320 }
321 }
322
323 fn parent_finish_buffer(
324 &self,
325 buffer: gst::Buffer,
326 ) -> Result<gst::FlowSuccess, gst::FlowError> {
327 unsafe {
328 let data = Self::type_data();
329 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
330 let f = (*parent_class)
331 .finish_buffer
332 .expect("Missing parent function `finish_buffer`");
333 try_from_glib(f(
334 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
335 buffer.into_glib_ptr(),
336 ))
337 }
338 }
339
340 #[cfg(feature = "v1_18")]
341 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
342 fn parent_finish_buffer_list(
343 &self,
344 buffer_list: gst::BufferList,
345 ) -> Result<gst::FlowSuccess, gst::FlowError> {
346 unsafe {
347 let data = Self::type_data();
348 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
349 let f = (*parent_class)
350 .finish_buffer_list
351 .expect("Missing parent function `finish_buffer_list`");
352 try_from_glib(f(
353 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
354 buffer_list.into_glib_ptr(),
355 ))
356 }
357 }
358
359 fn parent_sink_event(&self, aggregator_pad: &AggregatorPad, event: gst::Event) -> bool {
360 unsafe {
361 let data = Self::type_data();
362 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
363 let f = (*parent_class)
364 .sink_event
365 .expect("Missing parent function `sink_event`");
366 from_glib(f(
367 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
368 aggregator_pad.to_glib_none().0,
369 event.into_glib_ptr(),
370 ))
371 }
372 }
373
374 #[cfg(feature = "v1_18")]
375 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
376 fn parent_sink_event_pre_queue(
377 &self,
378 aggregator_pad: &AggregatorPad,
379 event: gst::Event,
380 ) -> Result<gst::FlowSuccess, gst::FlowError> {
381 unsafe {
382 let data = Self::type_data();
383 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
384 let f = (*parent_class)
385 .sink_event_pre_queue
386 .expect("Missing parent function `sink_event_pre_queue`");
387 try_from_glib(f(
388 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
389 aggregator_pad.to_glib_none().0,
390 event.into_glib_ptr(),
391 ))
392 }
393 }
394
395 fn parent_sink_query(&self, aggregator_pad: &AggregatorPad, query: &mut gst::QueryRef) -> bool {
396 unsafe {
397 let data = Self::type_data();
398 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
399 let f = (*parent_class)
400 .sink_query
401 .expect("Missing parent function `sink_query`");
402 from_glib(f(
403 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
404 aggregator_pad.to_glib_none().0,
405 query.as_mut_ptr(),
406 ))
407 }
408 }
409
410 #[cfg(feature = "v1_18")]
411 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
412 fn parent_sink_query_pre_queue(
413 &self,
414 aggregator_pad: &AggregatorPad,
415 query: &mut gst::QueryRef,
416 ) -> bool {
417 unsafe {
418 let data = Self::type_data();
419 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
420 let f = (*parent_class)
421 .sink_query_pre_queue
422 .expect("Missing parent function `sink_query`");
423 from_glib(f(
424 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
425 aggregator_pad.to_glib_none().0,
426 query.as_mut_ptr(),
427 ))
428 }
429 }
430
431 fn parent_src_event(&self, event: gst::Event) -> bool {
432 unsafe {
433 let data = Self::type_data();
434 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
435 let f = (*parent_class)
436 .src_event
437 .expect("Missing parent function `src_event`");
438 from_glib(f(
439 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
440 event.into_glib_ptr(),
441 ))
442 }
443 }
444
445 fn parent_src_query(&self, query: &mut gst::QueryRef) -> bool {
446 unsafe {
447 let data = Self::type_data();
448 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
449 let f = (*parent_class)
450 .src_query
451 .expect("Missing parent function `src_query`");
452 from_glib(f(
453 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
454 query.as_mut_ptr(),
455 ))
456 }
457 }
458
459 fn parent_src_activate(
460 &self,
461 mode: gst::PadMode,
462 active: bool,
463 ) -> Result<(), gst::LoggableError> {
464 unsafe {
465 let data = Self::type_data();
466 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
467 match (*parent_class).src_activate {
468 None => Ok(()),
469 Some(f) => gst::result_from_gboolean!(
470 f(
471 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
472 mode.into_glib(),
473 active.into_glib()
474 ),
475 gst::CAT_RUST,
476 "Parent function `src_activate` failed"
477 ),
478 }
479 }
480 }
481
482 fn parent_aggregate(&self, timeout: bool) -> Result<gst::FlowSuccess, gst::FlowError> {
483 unsafe {
484 let data = Self::type_data();
485 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
486 let f = (*parent_class)
487 .aggregate
488 .expect("Missing parent function `aggregate`");
489 try_from_glib(f(
490 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
491 timeout.into_glib(),
492 ))
493 }
494 }
495
496 fn parent_start(&self) -> Result<(), gst::ErrorMessage> {
497 unsafe {
498 let data = Self::type_data();
499 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
500 (*parent_class)
501 .start
502 .map(|f| {
503 if from_glib(f(self
504 .obj()
505 .unsafe_cast_ref::<Aggregator>()
506 .to_glib_none()
507 .0))
508 {
509 Ok(())
510 } else {
511 Err(gst::error_msg!(
512 gst::CoreError::Failed,
513 ["Parent function `start` failed"]
514 ))
515 }
516 })
517 .unwrap_or(Ok(()))
518 }
519 }
520
521 fn parent_stop(&self) -> Result<(), gst::ErrorMessage> {
522 unsafe {
523 let data = Self::type_data();
524 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
525 (*parent_class)
526 .stop
527 .map(|f| {
528 if from_glib(f(self
529 .obj()
530 .unsafe_cast_ref::<Aggregator>()
531 .to_glib_none()
532 .0))
533 {
534 Ok(())
535 } else {
536 Err(gst::error_msg!(
537 gst::CoreError::Failed,
538 ["Parent function `stop` failed"]
539 ))
540 }
541 })
542 .unwrap_or(Ok(()))
543 }
544 }
545
546 fn parent_next_time(&self) -> Option<gst::ClockTime> {
547 unsafe {
548 let data = Self::type_data();
549 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
550 (*parent_class)
551 .get_next_time
552 .map(|f| {
553 from_glib(f(self
554 .obj()
555 .unsafe_cast_ref::<Aggregator>()
556 .to_glib_none()
557 .0))
558 })
559 .unwrap_or(gst::ClockTime::NONE)
560 }
561 }
562
563 fn parent_create_new_pad(
564 &self,
565 templ: &gst::PadTemplate,
566 req_name: Option<&str>,
567 caps: Option<&gst::Caps>,
568 ) -> Option<AggregatorPad> {
569 unsafe {
570 let data = Self::type_data();
571 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
572 let f = (*parent_class)
573 .create_new_pad
574 .expect("Missing parent function `create_new_pad`");
575 from_glib_full(f(
576 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
577 templ.to_glib_none().0,
578 req_name.to_glib_none().0,
579 caps.to_glib_none().0,
580 ))
581 }
582 }
583
584 fn parent_update_src_caps(&self, caps: &gst::Caps) -> Result<gst::Caps, gst::FlowError> {
585 unsafe {
586 let data = Self::type_data();
587 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
588 let f = (*parent_class)
589 .update_src_caps
590 .expect("Missing parent function `update_src_caps`");
591
592 let mut out_caps = ptr::null_mut();
593 gst::FlowSuccess::try_from_glib(f(
594 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
595 caps.as_mut_ptr(),
596 &mut out_caps,
597 ))
598 .map(|_| from_glib_full(out_caps))
599 }
600 }
601
602 fn parent_fixate_src_caps(&self, caps: gst::Caps) -> gst::Caps {
603 unsafe {
604 let data = Self::type_data();
605 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
606
607 let f = (*parent_class)
608 .fixate_src_caps
609 .expect("Missing parent function `fixate_src_caps`");
610 from_glib_full(f(
611 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
612 caps.into_glib_ptr(),
613 ))
614 }
615 }
616
617 fn parent_negotiated_src_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
618 unsafe {
619 let data = Self::type_data();
620 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
621 (*parent_class)
622 .negotiated_src_caps
623 .map(|f| {
624 gst::result_from_gboolean!(
625 f(
626 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
627 caps.to_glib_none().0
628 ),
629 gst::CAT_RUST,
630 "Parent function `negotiated_src_caps` failed"
631 )
632 })
633 .unwrap_or(Ok(()))
634 }
635 }
636
637 fn parent_propose_allocation(
638 &self,
639 pad: &AggregatorPad,
640 decide_query: Option<&gst::query::Allocation>,
641 query: &mut gst::query::Allocation,
642 ) -> Result<(), gst::LoggableError> {
643 unsafe {
644 let data = Self::type_data();
645 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
646 (*parent_class)
647 .propose_allocation
648 .map(|f| {
649 gst::result_from_gboolean!(
650 f(
651 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
652 pad.to_glib_none().0,
653 decide_query
654 .as_ref()
655 .map(|q| q.as_mut_ptr())
656 .unwrap_or(ptr::null_mut()),
657 query.as_mut_ptr()
658 ),
659 gst::CAT_RUST,
660 "Parent function `propose_allocation` failed",
661 )
662 })
663 .unwrap_or(Ok(()))
664 }
665 }
666
667 fn parent_decide_allocation(
668 &self,
669 query: &mut gst::query::Allocation,
670 ) -> Result<(), gst::LoggableError> {
671 unsafe {
672 let data = Self::type_data();
673 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
674 (*parent_class)
675 .decide_allocation
676 .map(|f| {
677 gst::result_from_gboolean!(
678 f(
679 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
680 query.as_mut_ptr(),
681 ),
682 gst::CAT_RUST,
683 "Parent function `decide_allocation` failed",
684 )
685 })
686 .unwrap_or(Ok(()))
687 }
688 }
689
690 #[cfg(feature = "v1_30")]
691 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
692 fn parent_prepare_allocator(&self, caps: Option<&gst::Caps>) -> Result<(), gst::LoggableError> {
693 unsafe {
694 let data = Self::type_data();
695 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
696 (*parent_class)
697 .prepare_allocator
698 .map(|f| {
699 gst::result_from_gboolean!(
700 f(
701 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
702 caps.to_glib_none().0
703 ),
704 gst::CAT_RUST,
705 "Parent function `prepare_allocator` failed",
706 )
707 })
708 .unwrap_or(Ok(()))
709 }
710 }
711
712 #[cfg(feature = "v1_18")]
713 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
714 fn parent_negotiate(&self) -> bool {
715 unsafe {
716 let data = Self::type_data();
717 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
718 (*parent_class)
719 .negotiate
720 .map(|f| {
721 from_glib(f(self
722 .obj()
723 .unsafe_cast_ref::<Aggregator>()
724 .to_glib_none()
725 .0))
726 })
727 .unwrap_or(true)
728 }
729 }
730
731 #[cfg(feature = "v1_18")]
732 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
733 fn parent_peek_next_sample(&self, pad: &AggregatorPad) -> Option<gst::Sample> {
734 unsafe {
735 let data = Self::type_data();
736 let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass;
737 (*parent_class)
738 .peek_next_sample
739 .map(|f| {
740 from_glib_full(f(
741 self.obj().unsafe_cast_ref::<Aggregator>().to_glib_none().0,
742 pad.to_glib_none().0,
743 ))
744 })
745 .unwrap_or(None)
746 }
747 }
748}
749
750impl<T: AggregatorImpl> AggregatorImplExt for T {}
751
752unsafe impl<T: AggregatorImpl> IsSubclassable<T> for Aggregator {
753 fn class_init(klass: &mut glib::Class<Self>) {
754 Self::parent_class_init::<T>(klass);
755 let klass = klass.as_mut();
756 klass.flush = Some(aggregator_flush::<T>);
757 klass.clip = Some(aggregator_clip::<T>);
758 klass.finish_buffer = Some(aggregator_finish_buffer::<T>);
759 klass.sink_event = Some(aggregator_sink_event::<T>);
760 klass.sink_query = Some(aggregator_sink_query::<T>);
761 klass.src_event = Some(aggregator_src_event::<T>);
762 klass.src_query = Some(aggregator_src_query::<T>);
763 klass.src_activate = Some(aggregator_src_activate::<T>);
764 klass.aggregate = Some(aggregator_aggregate::<T>);
765 klass.start = Some(aggregator_start::<T>);
766 klass.stop = Some(aggregator_stop::<T>);
767 klass.get_next_time = Some(aggregator_get_next_time::<T>);
768 klass.create_new_pad = Some(aggregator_create_new_pad::<T>);
769 klass.update_src_caps = Some(aggregator_update_src_caps::<T>);
770 klass.fixate_src_caps = Some(aggregator_fixate_src_caps::<T>);
771 klass.negotiated_src_caps = Some(aggregator_negotiated_src_caps::<T>);
772 klass.propose_allocation = Some(aggregator_propose_allocation::<T>);
773 klass.decide_allocation = Some(aggregator_decide_allocation::<T>);
774 #[cfg(feature = "v1_18")]
775 {
776 klass.sink_event_pre_queue = Some(aggregator_sink_event_pre_queue::<T>);
777 klass.sink_query_pre_queue = Some(aggregator_sink_query_pre_queue::<T>);
778 klass.negotiate = Some(aggregator_negotiate::<T>);
779 klass.peek_next_sample = Some(aggregator_peek_next_sample::<T>);
780 klass.finish_buffer_list = Some(aggregator_finish_buffer_list::<T>);
781 }
782 #[cfg(feature = "v1_30")]
783 {
784 klass.prepare_allocator = Some(aggregator_prepare_allocator::<T>);
785 }
786 }
787}
788
789unsafe extern "C" fn aggregator_flush<T: AggregatorImpl>(
790 ptr: *mut ffi::GstAggregator,
791) -> gst::ffi::GstFlowReturn {
792 unsafe {
793 let instance = &*(ptr as *mut T::Instance);
794 let imp = instance.imp();
795
796 gst::panic_to_error!(imp, gst::FlowReturn::Error, { imp.flush().into() }).into_glib()
797 }
798}
799
800unsafe extern "C" fn aggregator_clip<T: AggregatorImpl>(
801 ptr: *mut ffi::GstAggregator,
802 aggregator_pad: *mut ffi::GstAggregatorPad,
803 buffer: *mut gst::ffi::GstBuffer,
804) -> *mut gst::ffi::GstBuffer {
805 unsafe {
806 let instance = &*(ptr as *mut T::Instance);
807 let imp = instance.imp();
808
809 let ret = gst::panic_to_error!(imp, None, {
810 imp.clip(&from_glib_borrow(aggregator_pad), from_glib_full(buffer))
811 });
812
813 ret.map(|r| r.into_glib_ptr()).unwrap_or(ptr::null_mut())
814 }
815}
816
817unsafe extern "C" fn aggregator_finish_buffer<T: AggregatorImpl>(
818 ptr: *mut ffi::GstAggregator,
819 buffer: *mut gst::ffi::GstBuffer,
820) -> gst::ffi::GstFlowReturn {
821 unsafe {
822 let instance = &*(ptr as *mut T::Instance);
823 let imp = instance.imp();
824
825 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
826 imp.finish_buffer(from_glib_full(buffer)).into()
827 })
828 .into_glib()
829 }
830}
831
832#[cfg(feature = "v1_18")]
833#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
834unsafe extern "C" fn aggregator_finish_buffer_list<T: AggregatorImpl>(
835 ptr: *mut ffi::GstAggregator,
836 buffer_list: *mut gst::ffi::GstBufferList,
837) -> gst::ffi::GstFlowReturn {
838 unsafe {
839 let instance = &*(ptr as *mut T::Instance);
840 let imp = instance.imp();
841
842 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
843 imp.finish_buffer_list(from_glib_full(buffer_list)).into()
844 })
845 .into_glib()
846 }
847}
848
849unsafe extern "C" fn aggregator_sink_event<T: AggregatorImpl>(
850 ptr: *mut ffi::GstAggregator,
851 aggregator_pad: *mut ffi::GstAggregatorPad,
852 event: *mut gst::ffi::GstEvent,
853) -> glib::ffi::gboolean {
854 unsafe {
855 let instance = &*(ptr as *mut T::Instance);
856 let imp = instance.imp();
857
858 gst::panic_to_error!(imp, false, {
859 imp.sink_event(&from_glib_borrow(aggregator_pad), from_glib_full(event))
860 })
861 .into_glib()
862 }
863}
864
865#[cfg(feature = "v1_18")]
866#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
867unsafe extern "C" fn aggregator_sink_event_pre_queue<T: AggregatorImpl>(
868 ptr: *mut ffi::GstAggregator,
869 aggregator_pad: *mut ffi::GstAggregatorPad,
870 event: *mut gst::ffi::GstEvent,
871) -> gst::ffi::GstFlowReturn {
872 unsafe {
873 let instance = &*(ptr as *mut T::Instance);
874 let imp = instance.imp();
875
876 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
877 imp.sink_event_pre_queue(&from_glib_borrow(aggregator_pad), from_glib_full(event))
878 .into()
879 })
880 .into_glib()
881 }
882}
883
884unsafe extern "C" fn aggregator_sink_query<T: AggregatorImpl>(
885 ptr: *mut ffi::GstAggregator,
886 aggregator_pad: *mut ffi::GstAggregatorPad,
887 query: *mut gst::ffi::GstQuery,
888) -> glib::ffi::gboolean {
889 unsafe {
890 let instance = &*(ptr as *mut T::Instance);
891 let imp = instance.imp();
892
893 gst::panic_to_error!(imp, false, {
894 imp.sink_query(
895 &from_glib_borrow(aggregator_pad),
896 gst::QueryRef::from_mut_ptr(query),
897 )
898 })
899 .into_glib()
900 }
901}
902
903#[cfg(feature = "v1_18")]
904#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
905unsafe extern "C" fn aggregator_sink_query_pre_queue<T: AggregatorImpl>(
906 ptr: *mut ffi::GstAggregator,
907 aggregator_pad: *mut ffi::GstAggregatorPad,
908 query: *mut gst::ffi::GstQuery,
909) -> glib::ffi::gboolean {
910 unsafe {
911 let instance = &*(ptr as *mut T::Instance);
912 let imp = instance.imp();
913
914 gst::panic_to_error!(imp, false, {
915 imp.sink_query_pre_queue(
916 &from_glib_borrow(aggregator_pad),
917 gst::QueryRef::from_mut_ptr(query),
918 )
919 })
920 .into_glib()
921 }
922}
923
924unsafe extern "C" fn aggregator_src_event<T: AggregatorImpl>(
925 ptr: *mut ffi::GstAggregator,
926 event: *mut gst::ffi::GstEvent,
927) -> glib::ffi::gboolean {
928 unsafe {
929 let instance = &*(ptr as *mut T::Instance);
930 let imp = instance.imp();
931
932 gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
933 }
934}
935
936unsafe extern "C" fn aggregator_src_query<T: AggregatorImpl>(
937 ptr: *mut ffi::GstAggregator,
938 query: *mut gst::ffi::GstQuery,
939) -> glib::ffi::gboolean {
940 unsafe {
941 let instance = &*(ptr as *mut T::Instance);
942 let imp = instance.imp();
943
944 gst::panic_to_error!(imp, false, {
945 imp.src_query(gst::QueryRef::from_mut_ptr(query))
946 })
947 .into_glib()
948 }
949}
950
951unsafe extern "C" fn aggregator_src_activate<T: AggregatorImpl>(
952 ptr: *mut ffi::GstAggregator,
953 mode: gst::ffi::GstPadMode,
954 active: glib::ffi::gboolean,
955) -> glib::ffi::gboolean {
956 unsafe {
957 let instance = &*(ptr as *mut T::Instance);
958 let imp = instance.imp();
959
960 gst::panic_to_error!(imp, false, {
961 match imp.src_activate(from_glib(mode), from_glib(active)) {
962 Ok(()) => true,
963 Err(err) => {
964 err.log_with_imp(imp);
965 false
966 }
967 }
968 })
969 .into_glib()
970 }
971}
972
973unsafe extern "C" fn aggregator_aggregate<T: AggregatorImpl>(
974 ptr: *mut ffi::GstAggregator,
975 timeout: glib::ffi::gboolean,
976) -> gst::ffi::GstFlowReturn {
977 unsafe {
978 let instance = &*(ptr as *mut T::Instance);
979 let imp = instance.imp();
980
981 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
982 imp.aggregate(from_glib(timeout)).into()
983 })
984 .into_glib()
985 }
986}
987
988unsafe extern "C" fn aggregator_start<T: AggregatorImpl>(
989 ptr: *mut ffi::GstAggregator,
990) -> glib::ffi::gboolean {
991 unsafe {
992 let instance = &*(ptr as *mut T::Instance);
993 let imp = instance.imp();
994
995 gst::panic_to_error!(imp, false, {
996 match imp.start() {
997 Ok(()) => true,
998 Err(err) => {
999 imp.post_error_message(err);
1000 false
1001 }
1002 }
1003 })
1004 .into_glib()
1005 }
1006}
1007
1008unsafe extern "C" fn aggregator_stop<T: AggregatorImpl>(
1009 ptr: *mut ffi::GstAggregator,
1010) -> glib::ffi::gboolean {
1011 unsafe {
1012 let instance = &*(ptr as *mut T::Instance);
1013 let imp = instance.imp();
1014
1015 gst::panic_to_error!(imp, false, {
1016 match imp.stop() {
1017 Ok(()) => true,
1018 Err(err) => {
1019 imp.post_error_message(err);
1020 false
1021 }
1022 }
1023 })
1024 .into_glib()
1025 }
1026}
1027
1028unsafe extern "C" fn aggregator_get_next_time<T: AggregatorImpl>(
1029 ptr: *mut ffi::GstAggregator,
1030) -> gst::ffi::GstClockTime {
1031 unsafe {
1032 let instance = &*(ptr as *mut T::Instance);
1033 let imp = instance.imp();
1034
1035 gst::panic_to_error!(imp, gst::ClockTime::NONE, { imp.next_time() }).into_glib()
1036 }
1037}
1038
1039unsafe extern "C" fn aggregator_create_new_pad<T: AggregatorImpl>(
1040 ptr: *mut ffi::GstAggregator,
1041 templ: *mut gst::ffi::GstPadTemplate,
1042 req_name: *const libc::c_char,
1043 caps: *const gst::ffi::GstCaps,
1044) -> *mut ffi::GstAggregatorPad {
1045 unsafe {
1046 let instance = &*(ptr as *mut T::Instance);
1047 let imp = instance.imp();
1048
1049 gst::panic_to_error!(imp, None, {
1050 let req_name: Borrowed<Option<glib::GString>> = from_glib_borrow(req_name);
1051
1052 imp.create_new_pad(
1053 &from_glib_borrow(templ),
1054 req_name.as_ref().as_ref().map(|s| s.as_str()),
1055 Option::<gst::Caps>::from_glib_borrow(caps)
1056 .as_ref()
1057 .as_ref(),
1058 )
1059 })
1060 .into_glib_ptr()
1061 }
1062}
1063
1064unsafe extern "C" fn aggregator_update_src_caps<T: AggregatorImpl>(
1065 ptr: *mut ffi::GstAggregator,
1066 caps: *mut gst::ffi::GstCaps,
1067 res: *mut *mut gst::ffi::GstCaps,
1068) -> gst::ffi::GstFlowReturn {
1069 unsafe {
1070 let instance = &*(ptr as *mut T::Instance);
1071 let imp = instance.imp();
1072
1073 *res = ptr::null_mut();
1074
1075 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
1076 match imp.update_src_caps(&from_glib_borrow(caps)) {
1077 Ok(res_caps) => {
1078 *res = res_caps.into_glib_ptr();
1079 gst::FlowReturn::Ok
1080 }
1081 Err(err) => err.into(),
1082 }
1083 })
1084 .into_glib()
1085 }
1086}
1087
1088unsafe extern "C" fn aggregator_fixate_src_caps<T: AggregatorImpl>(
1089 ptr: *mut ffi::GstAggregator,
1090 caps: *mut gst::ffi::GstCaps,
1091) -> *mut gst::ffi::GstCaps {
1092 unsafe {
1093 let instance = &*(ptr as *mut T::Instance);
1094 let imp = instance.imp();
1095
1096 gst::panic_to_error!(imp, gst::Caps::new_empty(), {
1097 imp.fixate_src_caps(from_glib_full(caps))
1098 })
1099 .into_glib_ptr()
1100 }
1101}
1102
1103unsafe extern "C" fn aggregator_negotiated_src_caps<T: AggregatorImpl>(
1104 ptr: *mut ffi::GstAggregator,
1105 caps: *mut gst::ffi::GstCaps,
1106) -> glib::ffi::gboolean {
1107 unsafe {
1108 let instance = &*(ptr as *mut T::Instance);
1109 let imp = instance.imp();
1110
1111 gst::panic_to_error!(imp, false, {
1112 match imp.negotiated_src_caps(&from_glib_borrow(caps)) {
1113 Ok(()) => true,
1114 Err(err) => {
1115 err.log_with_imp(imp);
1116 false
1117 }
1118 }
1119 })
1120 .into_glib()
1121 }
1122}
1123
1124unsafe extern "C" fn aggregator_propose_allocation<T: AggregatorImpl>(
1125 ptr: *mut ffi::GstAggregator,
1126 pad: *mut ffi::GstAggregatorPad,
1127 decide_query: *mut gst::ffi::GstQuery,
1128 query: *mut gst::ffi::GstQuery,
1129) -> glib::ffi::gboolean {
1130 unsafe {
1131 let instance = &*(ptr as *mut T::Instance);
1132 let imp = instance.imp();
1133 let decide_query = if decide_query.is_null() {
1134 None
1135 } else {
1136 match gst::QueryRef::from_ptr(decide_query).view() {
1137 gst::QueryView::Allocation(allocation) => Some(allocation),
1138 _ => unreachable!(),
1139 }
1140 };
1141 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
1142 gst::QueryViewMut::Allocation(allocation) => allocation,
1143 _ => unreachable!(),
1144 };
1145
1146 gst::panic_to_error!(imp, false, {
1147 match imp.propose_allocation(&from_glib_borrow(pad), decide_query, query) {
1148 Ok(()) => true,
1149 Err(err) => {
1150 err.log_with_imp(imp);
1151 false
1152 }
1153 }
1154 })
1155 .into_glib()
1156 }
1157}
1158
1159unsafe extern "C" fn aggregator_decide_allocation<T: AggregatorImpl>(
1160 ptr: *mut ffi::GstAggregator,
1161 query: *mut gst::ffi::GstQuery,
1162) -> glib::ffi::gboolean {
1163 unsafe {
1164 let instance = &*(ptr as *mut T::Instance);
1165 let imp = instance.imp();
1166 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
1167 gst::QueryViewMut::Allocation(allocation) => allocation,
1168 _ => unreachable!(),
1169 };
1170
1171 gst::panic_to_error!(imp, false, {
1172 match imp.decide_allocation(query) {
1173 Ok(()) => true,
1174 Err(err) => {
1175 err.log_with_imp(imp);
1176 false
1177 }
1178 }
1179 })
1180 .into_glib()
1181 }
1182}
1183
1184#[cfg(feature = "v1_18")]
1185#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1186unsafe extern "C" fn aggregator_negotiate<T: AggregatorImpl>(
1187 ptr: *mut ffi::GstAggregator,
1188) -> glib::ffi::gboolean {
1189 unsafe {
1190 let instance = &*(ptr as *mut T::Instance);
1191 let imp = instance.imp();
1192
1193 gst::panic_to_error!(imp, false, { imp.negotiate() }).into_glib()
1194 }
1195}
1196
1197#[cfg(feature = "v1_18")]
1198#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1199unsafe extern "C" fn aggregator_peek_next_sample<T: AggregatorImpl>(
1200 ptr: *mut ffi::GstAggregator,
1201 pad: *mut ffi::GstAggregatorPad,
1202) -> *mut gst::ffi::GstSample {
1203 unsafe {
1204 let instance = &*(ptr as *mut T::Instance);
1205 let imp = instance.imp();
1206
1207 gst::panic_to_error!(imp, None, { imp.peek_next_sample(&from_glib_borrow(pad)) })
1208 .into_glib_ptr()
1209 }
1210}
1211
1212#[cfg(feature = "v1_30")]
1213#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
1214unsafe extern "C" fn aggregator_prepare_allocator<T: AggregatorImpl>(
1215 ptr: *mut ffi::GstAggregator,
1216 caps: *mut gst::ffi::GstCaps,
1217) -> glib::ffi::gboolean {
1218 unsafe {
1219 let instance = &*(ptr as *mut T::Instance);
1220 let imp = instance.imp();
1221 let caps = Option::<gst::Caps>::from_glib_none(caps);
1222
1223 gst::panic_to_error!(imp, false, {
1224 match imp.prepare_allocator(caps.as_ref()) {
1225 Ok(()) => true,
1226 Err(err) => {
1227 err.log_with_imp(imp);
1228 false
1229 }
1230 }
1231 })
1232 .into_glib()
1233 }
1234}