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::element_panic_to_error!(imp, gst::FlowReturn::Error, { imp.flush().into() })
797 .into_glib()
798 }
799}
800
801unsafe extern "C" fn aggregator_clip<T: AggregatorImpl>(
802 ptr: *mut ffi::GstAggregator,
803 aggregator_pad: *mut ffi::GstAggregatorPad,
804 buffer: *mut gst::ffi::GstBuffer,
805) -> *mut gst::ffi::GstBuffer {
806 unsafe {
807 let instance = &*(ptr as *mut T::Instance);
808 let imp = instance.imp();
809
810 let ret = gst::element_panic_to_error!(imp, None, {
811 imp.clip(&from_glib_borrow(aggregator_pad), from_glib_full(buffer))
812 });
813
814 ret.map(|r| r.into_glib_ptr()).unwrap_or(ptr::null_mut())
815 }
816}
817
818unsafe extern "C" fn aggregator_finish_buffer<T: AggregatorImpl>(
819 ptr: *mut ffi::GstAggregator,
820 buffer: *mut gst::ffi::GstBuffer,
821) -> gst::ffi::GstFlowReturn {
822 unsafe {
823 let instance = &*(ptr as *mut T::Instance);
824 let imp = instance.imp();
825
826 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
827 imp.finish_buffer(from_glib_full(buffer)).into()
828 })
829 .into_glib()
830 }
831}
832
833#[cfg(feature = "v1_18")]
834#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
835unsafe extern "C" fn aggregator_finish_buffer_list<T: AggregatorImpl>(
836 ptr: *mut ffi::GstAggregator,
837 buffer_list: *mut gst::ffi::GstBufferList,
838) -> gst::ffi::GstFlowReturn {
839 unsafe {
840 let instance = &*(ptr as *mut T::Instance);
841 let imp = instance.imp();
842
843 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
844 imp.finish_buffer_list(from_glib_full(buffer_list)).into()
845 })
846 .into_glib()
847 }
848}
849
850unsafe extern "C" fn aggregator_sink_event<T: AggregatorImpl>(
851 ptr: *mut ffi::GstAggregator,
852 aggregator_pad: *mut ffi::GstAggregatorPad,
853 event: *mut gst::ffi::GstEvent,
854) -> glib::ffi::gboolean {
855 unsafe {
856 let instance = &*(ptr as *mut T::Instance);
857 let imp = instance.imp();
858
859 gst::element_panic_to_error!(imp, false, {
860 imp.sink_event(&from_glib_borrow(aggregator_pad), from_glib_full(event))
861 })
862 .into_glib()
863 }
864}
865
866#[cfg(feature = "v1_18")]
867#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
868unsafe extern "C" fn aggregator_sink_event_pre_queue<T: AggregatorImpl>(
869 ptr: *mut ffi::GstAggregator,
870 aggregator_pad: *mut ffi::GstAggregatorPad,
871 event: *mut gst::ffi::GstEvent,
872) -> gst::ffi::GstFlowReturn {
873 unsafe {
874 let instance = &*(ptr as *mut T::Instance);
875 let imp = instance.imp();
876
877 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
878 imp.sink_event_pre_queue(&from_glib_borrow(aggregator_pad), from_glib_full(event))
879 .into()
880 })
881 .into_glib()
882 }
883}
884
885unsafe extern "C" fn aggregator_sink_query<T: AggregatorImpl>(
886 ptr: *mut ffi::GstAggregator,
887 aggregator_pad: *mut ffi::GstAggregatorPad,
888 query: *mut gst::ffi::GstQuery,
889) -> glib::ffi::gboolean {
890 unsafe {
891 let instance = &*(ptr as *mut T::Instance);
892 let imp = instance.imp();
893
894 gst::element_panic_to_error!(imp, false, {
895 imp.sink_query(
896 &from_glib_borrow(aggregator_pad),
897 gst::QueryRef::from_mut_ptr(query),
898 )
899 })
900 .into_glib()
901 }
902}
903
904#[cfg(feature = "v1_18")]
905#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
906unsafe extern "C" fn aggregator_sink_query_pre_queue<T: AggregatorImpl>(
907 ptr: *mut ffi::GstAggregator,
908 aggregator_pad: *mut ffi::GstAggregatorPad,
909 query: *mut gst::ffi::GstQuery,
910) -> glib::ffi::gboolean {
911 unsafe {
912 let instance = &*(ptr as *mut T::Instance);
913 let imp = instance.imp();
914
915 gst::element_panic_to_error!(imp, false, {
916 imp.sink_query_pre_queue(
917 &from_glib_borrow(aggregator_pad),
918 gst::QueryRef::from_mut_ptr(query),
919 )
920 })
921 .into_glib()
922 }
923}
924
925unsafe extern "C" fn aggregator_src_event<T: AggregatorImpl>(
926 ptr: *mut ffi::GstAggregator,
927 event: *mut gst::ffi::GstEvent,
928) -> glib::ffi::gboolean {
929 unsafe {
930 let instance = &*(ptr as *mut T::Instance);
931 let imp = instance.imp();
932
933 gst::element_panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) })
934 .into_glib()
935 }
936}
937
938unsafe extern "C" fn aggregator_src_query<T: AggregatorImpl>(
939 ptr: *mut ffi::GstAggregator,
940 query: *mut gst::ffi::GstQuery,
941) -> glib::ffi::gboolean {
942 unsafe {
943 let instance = &*(ptr as *mut T::Instance);
944 let imp = instance.imp();
945
946 gst::element_panic_to_error!(imp, false, {
947 imp.src_query(gst::QueryRef::from_mut_ptr(query))
948 })
949 .into_glib()
950 }
951}
952
953unsafe extern "C" fn aggregator_src_activate<T: AggregatorImpl>(
954 ptr: *mut ffi::GstAggregator,
955 mode: gst::ffi::GstPadMode,
956 active: glib::ffi::gboolean,
957) -> glib::ffi::gboolean {
958 unsafe {
959 let instance = &*(ptr as *mut T::Instance);
960 let imp = instance.imp();
961
962 gst::element_panic_to_error!(imp, false, {
963 match imp.src_activate(from_glib(mode), from_glib(active)) {
964 Ok(()) => true,
965 Err(err) => {
966 err.log_with_imp(imp);
967 false
968 }
969 }
970 })
971 .into_glib()
972 }
973}
974
975unsafe extern "C" fn aggregator_aggregate<T: AggregatorImpl>(
976 ptr: *mut ffi::GstAggregator,
977 timeout: glib::ffi::gboolean,
978) -> gst::ffi::GstFlowReturn {
979 unsafe {
980 let instance = &*(ptr as *mut T::Instance);
981 let imp = instance.imp();
982
983 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
984 imp.aggregate(from_glib(timeout)).into()
985 })
986 .into_glib()
987 }
988}
989
990unsafe extern "C" fn aggregator_start<T: AggregatorImpl>(
991 ptr: *mut ffi::GstAggregator,
992) -> glib::ffi::gboolean {
993 unsafe {
994 let instance = &*(ptr as *mut T::Instance);
995 let imp = instance.imp();
996
997 gst::element_panic_to_error!(imp, false, {
998 match imp.start() {
999 Ok(()) => true,
1000 Err(err) => {
1001 imp.post_error_message(err);
1002 false
1003 }
1004 }
1005 })
1006 .into_glib()
1007 }
1008}
1009
1010unsafe extern "C" fn aggregator_stop<T: AggregatorImpl>(
1011 ptr: *mut ffi::GstAggregator,
1012) -> glib::ffi::gboolean {
1013 unsafe {
1014 let instance = &*(ptr as *mut T::Instance);
1015 let imp = instance.imp();
1016
1017 gst::element_panic_to_error!(imp, false, {
1018 match imp.stop() {
1019 Ok(()) => true,
1020 Err(err) => {
1021 imp.post_error_message(err);
1022 false
1023 }
1024 }
1025 })
1026 .into_glib()
1027 }
1028}
1029
1030unsafe extern "C" fn aggregator_get_next_time<T: AggregatorImpl>(
1031 ptr: *mut ffi::GstAggregator,
1032) -> gst::ffi::GstClockTime {
1033 unsafe {
1034 let instance = &*(ptr as *mut T::Instance);
1035 let imp = instance.imp();
1036
1037 gst::element_panic_to_error!(imp, gst::ClockTime::NONE, { imp.next_time() }).into_glib()
1038 }
1039}
1040
1041unsafe extern "C" fn aggregator_create_new_pad<T: AggregatorImpl>(
1042 ptr: *mut ffi::GstAggregator,
1043 templ: *mut gst::ffi::GstPadTemplate,
1044 req_name: *const libc::c_char,
1045 caps: *const gst::ffi::GstCaps,
1046) -> *mut ffi::GstAggregatorPad {
1047 unsafe {
1048 let instance = &*(ptr as *mut T::Instance);
1049 let imp = instance.imp();
1050
1051 gst::element_panic_to_error!(imp, None, {
1052 let req_name: Borrowed<Option<glib::GString>> = from_glib_borrow(req_name);
1053
1054 imp.create_new_pad(
1055 &from_glib_borrow(templ),
1056 req_name.as_ref().as_ref().map(|s| s.as_str()),
1057 Option::<gst::Caps>::from_glib_borrow(caps)
1058 .as_ref()
1059 .as_ref(),
1060 )
1061 })
1062 .into_glib_ptr()
1063 }
1064}
1065
1066unsafe extern "C" fn aggregator_update_src_caps<T: AggregatorImpl>(
1067 ptr: *mut ffi::GstAggregator,
1068 caps: *mut gst::ffi::GstCaps,
1069 res: *mut *mut gst::ffi::GstCaps,
1070) -> gst::ffi::GstFlowReturn {
1071 unsafe {
1072 let instance = &*(ptr as *mut T::Instance);
1073 let imp = instance.imp();
1074
1075 *res = ptr::null_mut();
1076
1077 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
1078 match imp.update_src_caps(&from_glib_borrow(caps)) {
1079 Ok(res_caps) => {
1080 *res = res_caps.into_glib_ptr();
1081 gst::FlowReturn::Ok
1082 }
1083 Err(err) => err.into(),
1084 }
1085 })
1086 .into_glib()
1087 }
1088}
1089
1090unsafe extern "C" fn aggregator_fixate_src_caps<T: AggregatorImpl>(
1091 ptr: *mut ffi::GstAggregator,
1092 caps: *mut gst::ffi::GstCaps,
1093) -> *mut gst::ffi::GstCaps {
1094 unsafe {
1095 let instance = &*(ptr as *mut T::Instance);
1096 let imp = instance.imp();
1097
1098 gst::element_panic_to_error!(imp, gst::Caps::new_empty(), {
1099 imp.fixate_src_caps(from_glib_full(caps))
1100 })
1101 .into_glib_ptr()
1102 }
1103}
1104
1105unsafe extern "C" fn aggregator_negotiated_src_caps<T: AggregatorImpl>(
1106 ptr: *mut ffi::GstAggregator,
1107 caps: *mut gst::ffi::GstCaps,
1108) -> glib::ffi::gboolean {
1109 unsafe {
1110 let instance = &*(ptr as *mut T::Instance);
1111 let imp = instance.imp();
1112
1113 gst::element_panic_to_error!(imp, false, {
1114 match imp.negotiated_src_caps(&from_glib_borrow(caps)) {
1115 Ok(()) => true,
1116 Err(err) => {
1117 err.log_with_imp(imp);
1118 false
1119 }
1120 }
1121 })
1122 .into_glib()
1123 }
1124}
1125
1126unsafe extern "C" fn aggregator_propose_allocation<T: AggregatorImpl>(
1127 ptr: *mut ffi::GstAggregator,
1128 pad: *mut ffi::GstAggregatorPad,
1129 decide_query: *mut gst::ffi::GstQuery,
1130 query: *mut gst::ffi::GstQuery,
1131) -> glib::ffi::gboolean {
1132 unsafe {
1133 let instance = &*(ptr as *mut T::Instance);
1134 let imp = instance.imp();
1135 let decide_query = if decide_query.is_null() {
1136 None
1137 } else {
1138 match gst::QueryRef::from_ptr(decide_query).view() {
1139 gst::QueryView::Allocation(allocation) => Some(allocation),
1140 _ => unreachable!(),
1141 }
1142 };
1143 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
1144 gst::QueryViewMut::Allocation(allocation) => allocation,
1145 _ => unreachable!(),
1146 };
1147
1148 gst::element_panic_to_error!(imp, false, {
1149 match imp.propose_allocation(&from_glib_borrow(pad), decide_query, query) {
1150 Ok(()) => true,
1151 Err(err) => {
1152 err.log_with_imp(imp);
1153 false
1154 }
1155 }
1156 })
1157 .into_glib()
1158 }
1159}
1160
1161unsafe extern "C" fn aggregator_decide_allocation<T: AggregatorImpl>(
1162 ptr: *mut ffi::GstAggregator,
1163 query: *mut gst::ffi::GstQuery,
1164) -> glib::ffi::gboolean {
1165 unsafe {
1166 let instance = &*(ptr as *mut T::Instance);
1167 let imp = instance.imp();
1168 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
1169 gst::QueryViewMut::Allocation(allocation) => allocation,
1170 _ => unreachable!(),
1171 };
1172
1173 gst::element_panic_to_error!(imp, false, {
1174 match imp.decide_allocation(query) {
1175 Ok(()) => true,
1176 Err(err) => {
1177 err.log_with_imp(imp);
1178 false
1179 }
1180 }
1181 })
1182 .into_glib()
1183 }
1184}
1185
1186#[cfg(feature = "v1_18")]
1187#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1188unsafe extern "C" fn aggregator_negotiate<T: AggregatorImpl>(
1189 ptr: *mut ffi::GstAggregator,
1190) -> glib::ffi::gboolean {
1191 unsafe {
1192 let instance = &*(ptr as *mut T::Instance);
1193 let imp = instance.imp();
1194
1195 gst::element_panic_to_error!(imp, false, { imp.negotiate() }).into_glib()
1196 }
1197}
1198
1199#[cfg(feature = "v1_18")]
1200#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1201unsafe extern "C" fn aggregator_peek_next_sample<T: AggregatorImpl>(
1202 ptr: *mut ffi::GstAggregator,
1203 pad: *mut ffi::GstAggregatorPad,
1204) -> *mut gst::ffi::GstSample {
1205 unsafe {
1206 let instance = &*(ptr as *mut T::Instance);
1207 let imp = instance.imp();
1208
1209 gst::element_panic_to_error!(imp, None, { imp.peek_next_sample(&from_glib_borrow(pad)) })
1210 .into_glib_ptr()
1211 }
1212}
1213
1214#[cfg(feature = "v1_30")]
1215#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
1216unsafe extern "C" fn aggregator_prepare_allocator<T: AggregatorImpl>(
1217 ptr: *mut ffi::GstAggregator,
1218 caps: *mut gst::ffi::GstCaps,
1219) -> glib::ffi::gboolean {
1220 unsafe {
1221 let instance = &*(ptr as *mut T::Instance);
1222 let imp = instance.imp();
1223 let caps = Option::<gst::Caps>::from_glib_none(caps);
1224
1225 gst::element_panic_to_error!(imp, false, {
1226 match imp.prepare_allocator(caps.as_ref()) {
1227 Ok(()) => true,
1228 Err(err) => {
1229 err.log_with_imp(imp);
1230 false
1231 }
1232 }
1233 })
1234 .into_glib()
1235 }
1236}