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};
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: &::Instance = &*(ptr as *mut T::Instance);
624 let imp: &T = 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: &::Instance = &*(ptr as *mut T::Instance);
635 let imp: &T = instance.imp();
636
637 let ret: Option = 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(default: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: &::Instance = &*(ptr as *mut T::Instance);
649 let imp: &T = instance.imp();
650
651 gstFlowReturn::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: &::Instance = &*(ptr as *mut T::Instance);
678 let imp: &T = instance.imp();
679
680 gstbool::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: &::Instance = &*(ptr as *mut T::Instance);
709 let imp: &T = instance.imp();
710
711 gstbool::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: &::Instance = &*(ptr as *mut T::Instance);
744 let imp: &T = 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: &::Instance = &*(ptr as *mut T::Instance);
754 let imp: &T = instance.imp();
755
756 gstbool::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: &::Instance = &*(ptr as *mut T::Instance);
768 let imp: &T = instance.imp();
769
770 gstbool::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: &::Instance = &*(ptr as *mut T::Instance);
787 let imp: &T = instance.imp();
788
789 gstFlowReturn::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: &::Instance = &*(ptr as *mut T::Instance);
799 let imp: &T = instance.imp();
800
801 gstbool::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: &::Instance = &*(ptr as *mut T::Instance);
817 let imp: &T = instance.imp();
818
819 gstbool::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: &::Instance = &*(ptr as *mut T::Instance);
835 let imp: &T = 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: &::Instance = &*(ptr as *mut T::Instance);
847 let imp: &T = instance.imp();
848
849 gstOption::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: &::Instance = &*(ptr as *mut T::Instance);
869 let imp: &T = instance.imp();
870
871 *res = ptr::null_mut();
872
873 gstFlowReturn::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: &::Instance = &*(ptr as *mut T::Instance);
890 let imp: &T = instance.imp();
891
892 gstCaps::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: &::Instance = &*(ptr as *mut T::Instance);
903 let imp: &T = instance.imp();
904
905 gstbool::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: &::Instance = &*(ptr as *mut T::Instance);
955 let imp: &T = instance.imp();
956 let query: &mut Allocation = match gst::QueryRef::from_mut_ptr(query).view_mut() {
957 gst::QueryViewMut::Allocation(allocation: &mut Allocation) => allocation,
958 _ => unreachable!(),
959 };
960
961 gstbool::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}
996