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