Skip to main content

gstreamer_base/subclass/
aggregator.rs

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