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