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