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