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: 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    let instance = &*(ptr as *mut T::Instance);
619    let imp = instance.imp();
620
621    gst::panic_to_error!(imp, gst::FlowReturn::Error, { imp.flush().into() }).into_glib()
622}
623
624unsafe extern "C" fn aggregator_clip<T: AggregatorImpl>(
625    ptr: *mut ffi::GstAggregator,
626    aggregator_pad: *mut ffi::GstAggregatorPad,
627    buffer: *mut gst::ffi::GstBuffer,
628) -> *mut gst::ffi::GstBuffer {
629    let instance = &*(ptr as *mut T::Instance);
630    let imp = instance.imp();
631
632    let ret = gst::panic_to_error!(imp, None, {
633        imp.clip(&from_glib_borrow(aggregator_pad), from_glib_full(buffer))
634    });
635
636    ret.map(|r| r.into_glib_ptr()).unwrap_or(ptr::null_mut())
637}
638
639unsafe extern "C" fn aggregator_finish_buffer<T: AggregatorImpl>(
640    ptr: *mut ffi::GstAggregator,
641    buffer: *mut gst::ffi::GstBuffer,
642) -> gst::ffi::GstFlowReturn {
643    let instance = &*(ptr as *mut T::Instance);
644    let imp = instance.imp();
645
646    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
647        imp.finish_buffer(from_glib_full(buffer)).into()
648    })
649    .into_glib()
650}
651
652#[cfg(feature = "v1_18")]
653#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
654unsafe extern "C" fn aggregator_finish_buffer_list<T: AggregatorImpl>(
655    ptr: *mut ffi::GstAggregator,
656    buffer_list: *mut gst::ffi::GstBufferList,
657) -> gst::ffi::GstFlowReturn {
658    let instance = &*(ptr as *mut T::Instance);
659    let imp = instance.imp();
660
661    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
662        imp.finish_buffer_list(from_glib_full(buffer_list)).into()
663    })
664    .into_glib()
665}
666
667unsafe extern "C" fn aggregator_sink_event<T: AggregatorImpl>(
668    ptr: *mut ffi::GstAggregator,
669    aggregator_pad: *mut ffi::GstAggregatorPad,
670    event: *mut gst::ffi::GstEvent,
671) -> glib::ffi::gboolean {
672    let instance = &*(ptr as *mut T::Instance);
673    let imp = instance.imp();
674
675    gst::panic_to_error!(imp, false, {
676        imp.sink_event(&from_glib_borrow(aggregator_pad), from_glib_full(event))
677    })
678    .into_glib()
679}
680
681#[cfg(feature = "v1_18")]
682#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
683unsafe extern "C" fn aggregator_sink_event_pre_queue<T: AggregatorImpl>(
684    ptr: *mut ffi::GstAggregator,
685    aggregator_pad: *mut ffi::GstAggregatorPad,
686    event: *mut gst::ffi::GstEvent,
687) -> gst::ffi::GstFlowReturn {
688    let instance = &*(ptr as *mut T::Instance);
689    let imp = instance.imp();
690
691    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
692        imp.sink_event_pre_queue(&from_glib_borrow(aggregator_pad), from_glib_full(event))
693            .into()
694    })
695    .into_glib()
696}
697
698unsafe extern "C" fn aggregator_sink_query<T: AggregatorImpl>(
699    ptr: *mut ffi::GstAggregator,
700    aggregator_pad: *mut ffi::GstAggregatorPad,
701    query: *mut gst::ffi::GstQuery,
702) -> glib::ffi::gboolean {
703    let instance = &*(ptr as *mut T::Instance);
704    let imp = instance.imp();
705
706    gst::panic_to_error!(imp, false, {
707        imp.sink_query(
708            &from_glib_borrow(aggregator_pad),
709            gst::QueryRef::from_mut_ptr(query),
710        )
711    })
712    .into_glib()
713}
714
715#[cfg(feature = "v1_18")]
716#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
717unsafe extern "C" fn aggregator_sink_query_pre_queue<T: AggregatorImpl>(
718    ptr: *mut ffi::GstAggregator,
719    aggregator_pad: *mut ffi::GstAggregatorPad,
720    query: *mut gst::ffi::GstQuery,
721) -> glib::ffi::gboolean {
722    let instance = &*(ptr as *mut T::Instance);
723    let imp = instance.imp();
724
725    gst::panic_to_error!(imp, false, {
726        imp.sink_query_pre_queue(
727            &from_glib_borrow(aggregator_pad),
728            gst::QueryRef::from_mut_ptr(query),
729        )
730    })
731    .into_glib()
732}
733
734unsafe extern "C" fn aggregator_src_event<T: AggregatorImpl>(
735    ptr: *mut ffi::GstAggregator,
736    event: *mut gst::ffi::GstEvent,
737) -> glib::ffi::gboolean {
738    let instance = &*(ptr as *mut T::Instance);
739    let imp = instance.imp();
740
741    gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
742}
743
744unsafe extern "C" fn aggregator_src_query<T: AggregatorImpl>(
745    ptr: *mut ffi::GstAggregator,
746    query: *mut gst::ffi::GstQuery,
747) -> glib::ffi::gboolean {
748    let instance = &*(ptr as *mut T::Instance);
749    let imp = instance.imp();
750
751    gst::panic_to_error!(imp, false, {
752        imp.src_query(gst::QueryRef::from_mut_ptr(query))
753    })
754    .into_glib()
755}
756
757unsafe extern "C" fn aggregator_src_activate<T: AggregatorImpl>(
758    ptr: *mut ffi::GstAggregator,
759    mode: gst::ffi::GstPadMode,
760    active: glib::ffi::gboolean,
761) -> glib::ffi::gboolean {
762    let instance = &*(ptr as *mut T::Instance);
763    let imp = instance.imp();
764
765    gst::panic_to_error!(imp, false, {
766        match imp.src_activate(from_glib(mode), from_glib(active)) {
767            Ok(()) => true,
768            Err(err) => {
769                err.log_with_imp(imp);
770                false
771            }
772        }
773    })
774    .into_glib()
775}
776
777unsafe extern "C" fn aggregator_aggregate<T: AggregatorImpl>(
778    ptr: *mut ffi::GstAggregator,
779    timeout: glib::ffi::gboolean,
780) -> gst::ffi::GstFlowReturn {
781    let instance = &*(ptr as *mut T::Instance);
782    let imp = instance.imp();
783
784    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
785        imp.aggregate(from_glib(timeout)).into()
786    })
787    .into_glib()
788}
789
790unsafe extern "C" fn aggregator_start<T: AggregatorImpl>(
791    ptr: *mut ffi::GstAggregator,
792) -> glib::ffi::gboolean {
793    let instance = &*(ptr as *mut T::Instance);
794    let imp = instance.imp();
795
796    gst::panic_to_error!(imp, false, {
797        match imp.start() {
798            Ok(()) => true,
799            Err(err) => {
800                imp.post_error_message(err);
801                false
802            }
803        }
804    })
805    .into_glib()
806}
807
808unsafe extern "C" fn aggregator_stop<T: AggregatorImpl>(
809    ptr: *mut ffi::GstAggregator,
810) -> glib::ffi::gboolean {
811    let instance = &*(ptr as *mut T::Instance);
812    let imp = instance.imp();
813
814    gst::panic_to_error!(imp, false, {
815        match imp.stop() {
816            Ok(()) => true,
817            Err(err) => {
818                imp.post_error_message(err);
819                false
820            }
821        }
822    })
823    .into_glib()
824}
825
826unsafe extern "C" fn aggregator_get_next_time<T: AggregatorImpl>(
827    ptr: *mut ffi::GstAggregator,
828) -> gst::ffi::GstClockTime {
829    let instance = &*(ptr as *mut T::Instance);
830    let imp = instance.imp();
831
832    gst::panic_to_error!(imp, gst::ClockTime::NONE, { imp.next_time() }).into_glib()
833}
834
835unsafe extern "C" fn aggregator_create_new_pad<T: AggregatorImpl>(
836    ptr: *mut ffi::GstAggregator,
837    templ: *mut gst::ffi::GstPadTemplate,
838    req_name: *const libc::c_char,
839    caps: *const gst::ffi::GstCaps,
840) -> *mut ffi::GstAggregatorPad {
841    let instance = &*(ptr as *mut T::Instance);
842    let imp = instance.imp();
843
844    gst::panic_to_error!(imp, None, {
845        let req_name: Borrowed<Option<glib::GString>> = from_glib_borrow(req_name);
846
847        imp.create_new_pad(
848            &from_glib_borrow(templ),
849            req_name.as_ref().as_ref().map(|s| s.as_str()),
850            Option::<gst::Caps>::from_glib_borrow(caps)
851                .as_ref()
852                .as_ref(),
853        )
854    })
855    .into_glib_ptr()
856}
857
858unsafe extern "C" fn aggregator_update_src_caps<T: AggregatorImpl>(
859    ptr: *mut ffi::GstAggregator,
860    caps: *mut gst::ffi::GstCaps,
861    res: *mut *mut gst::ffi::GstCaps,
862) -> gst::ffi::GstFlowReturn {
863    let instance = &*(ptr as *mut T::Instance);
864    let imp = instance.imp();
865
866    *res = ptr::null_mut();
867
868    gst::panic_to_error!(imp, gst::FlowReturn::Error, {
869        match imp.update_src_caps(&from_glib_borrow(caps)) {
870            Ok(res_caps) => {
871                *res = res_caps.into_glib_ptr();
872                gst::FlowReturn::Ok
873            }
874            Err(err) => err.into(),
875        }
876    })
877    .into_glib()
878}
879
880unsafe extern "C" fn aggregator_fixate_src_caps<T: AggregatorImpl>(
881    ptr: *mut ffi::GstAggregator,
882    caps: *mut gst::ffi::GstCaps,
883) -> *mut gst::ffi::GstCaps {
884    let instance = &*(ptr as *mut T::Instance);
885    let imp = instance.imp();
886
887    gst::panic_to_error!(imp, gst::Caps::new_empty(), {
888        imp.fixate_src_caps(from_glib_full(caps))
889    })
890    .into_glib_ptr()
891}
892
893unsafe extern "C" fn aggregator_negotiated_src_caps<T: AggregatorImpl>(
894    ptr: *mut ffi::GstAggregator,
895    caps: *mut gst::ffi::GstCaps,
896) -> glib::ffi::gboolean {
897    let instance = &*(ptr as *mut T::Instance);
898    let imp = instance.imp();
899
900    gst::panic_to_error!(imp, false, {
901        match imp.negotiated_src_caps(&from_glib_borrow(caps)) {
902            Ok(()) => true,
903            Err(err) => {
904                err.log_with_imp(imp);
905                false
906            }
907        }
908    })
909    .into_glib()
910}
911
912unsafe extern "C" fn aggregator_propose_allocation<T: AggregatorImpl>(
913    ptr: *mut ffi::GstAggregator,
914    pad: *mut ffi::GstAggregatorPad,
915    decide_query: *mut gst::ffi::GstQuery,
916    query: *mut gst::ffi::GstQuery,
917) -> glib::ffi::gboolean {
918    let instance = &*(ptr as *mut T::Instance);
919    let imp = instance.imp();
920    let decide_query = if decide_query.is_null() {
921        None
922    } else {
923        match gst::QueryRef::from_ptr(decide_query).view() {
924            gst::QueryView::Allocation(allocation) => Some(allocation),
925            _ => unreachable!(),
926        }
927    };
928    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
929        gst::QueryViewMut::Allocation(allocation) => allocation,
930        _ => unreachable!(),
931    };
932
933    gst::panic_to_error!(imp, false, {
934        match imp.propose_allocation(&from_glib_borrow(pad), decide_query, query) {
935            Ok(()) => true,
936            Err(err) => {
937                err.log_with_imp(imp);
938                false
939            }
940        }
941    })
942    .into_glib()
943}
944
945unsafe extern "C" fn aggregator_decide_allocation<T: AggregatorImpl>(
946    ptr: *mut ffi::GstAggregator,
947    query: *mut gst::ffi::GstQuery,
948) -> glib::ffi::gboolean {
949    let instance = &*(ptr as *mut T::Instance);
950    let imp = instance.imp();
951    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
952        gst::QueryViewMut::Allocation(allocation) => allocation,
953        _ => unreachable!(),
954    };
955
956    gst::panic_to_error!(imp, false, {
957        match imp.decide_allocation(query) {
958            Ok(()) => true,
959            Err(err) => {
960                err.log_with_imp(imp);
961                false
962            }
963        }
964    })
965    .into_glib()
966}
967
968#[cfg(feature = "v1_18")]
969#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
970unsafe extern "C" fn aggregator_negotiate<T: AggregatorImpl>(
971    ptr: *mut ffi::GstAggregator,
972) -> glib::ffi::gboolean {
973    let instance = &*(ptr as *mut T::Instance);
974    let imp = instance.imp();
975
976    gst::panic_to_error!(imp, false, { imp.negotiate() }).into_glib()
977}
978
979#[cfg(feature = "v1_18")]
980#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
981unsafe extern "C" fn aggregator_peek_next_sample<T: AggregatorImpl>(
982    ptr: *mut ffi::GstAggregator,
983    pad: *mut ffi::GstAggregatorPad,
984) -> *mut gst::ffi::GstSample {
985    let instance = &*(ptr as *mut T::Instance);
986    let imp = instance.imp();
987
988    gst::panic_to_error!(imp, None, { imp.peek_next_sample(&from_glib_borrow(pad)) })
989        .into_glib_ptr()
990}