diff --git a/Gir_GstBase.toml b/Gir_GstBase.toml index 8bc2bcb31..de9b128da 100644 --- a/Gir_GstBase.toml +++ b/Gir_GstBase.toml @@ -94,6 +94,7 @@ status = "generate" [[object]] name = "GstBase.Aggregator" status = "generate" +subclassing = true version = "1.14" [[object.function]] diff --git a/gstreamer-base/Cargo.toml b/gstreamer-base/Cargo.toml index ee380dccf..849236b42 100644 --- a/gstreamer-base/Cargo.toml +++ b/gstreamer-base/Cargo.toml @@ -13,6 +13,7 @@ keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"] build = "build.rs" [dependencies] +libc = "0.2" bitflags = "1.0" glib-sys = { git = "https://github.com/gtk-rs/sys" } gobject-sys = { git = "https://github.com/gtk-rs/sys" } diff --git a/gstreamer-base/src/aggregator.rs b/gstreamer-base/src/aggregator.rs index 91e322128..87aad8357 100644 --- a/gstreamer-base/src/aggregator.rs +++ b/gstreamer-base/src/aggregator.rs @@ -8,10 +8,12 @@ use ffi; use glib::translate::*; -use glib::IsA; +use glib::{IsA, IsClassFor}; use gst; use Aggregator; +use std::ops; + pub trait AggregatorExtManual { fn finish_buffer(&self, buffer: gst::Buffer) -> gst::FlowReturn; } @@ -26,3 +28,27 @@ impl> AggregatorExtManual for O { } } } + +#[repr(C)] +pub struct AggregatorClass(ffi::GstAggregatorClass); + +unsafe impl IsClassFor for AggregatorClass { + type Instance = Aggregator; +} + +unsafe impl Send for AggregatorClass {} +unsafe impl Sync for AggregatorClass {} + +impl ops::Deref for AggregatorClass { + type Target = gst::ElementClass; + + fn deref(&self) -> &Self::Target { + self.upcast_ref() + } +} + +impl ops::DerefMut for AggregatorClass { + fn deref_mut(&mut self) -> &mut Self::Target { + self.upcast_ref_mut() + } +} diff --git a/gstreamer-base/src/auto/aggregator.rs b/gstreamer-base/src/auto/aggregator.rs index e48453d3f..1286b302c 100644 --- a/gstreamer-base/src/auto/aggregator.rs +++ b/gstreamer-base/src/auto/aggregator.rs @@ -2,6 +2,7 @@ // from gir-files (https://github.com/gtk-rs/gir-files) // DO NOT EDIT +use AggregatorClass; use ffi; use glib; use glib::StaticType; @@ -21,7 +22,7 @@ use std::mem::transmute; use std::ptr; glib_wrapper! { - pub struct Aggregator(Object): [ + pub struct Aggregator(Object): [ gst::Element => gst_ffi::GstElement, gst::Object => gst_ffi::GstObject, ]; diff --git a/gstreamer-base/src/lib.rs b/gstreamer-base/src/lib.rs index bf48575b6..8482399dd 100644 --- a/gstreamer-base/src/lib.rs +++ b/gstreamer-base/src/lib.rs @@ -13,6 +13,8 @@ extern crate gstreamer as gst; extern crate gstreamer_base_sys as ffi; extern crate gstreamer_sys as gst_ffi; +extern crate libc; + #[macro_use] extern crate glib; @@ -44,6 +46,8 @@ pub use flow_combiner::*; #[cfg(any(feature = "v1_14", feature = "dox"))] mod aggregator; #[cfg(any(feature = "v1_14", feature = "dox"))] +pub use aggregator::AggregatorClass; +#[cfg(any(feature = "v1_14", feature = "dox"))] mod aggregator_pad; #[cfg(any(feature = "v1_14", feature = "dox"))] pub use aggregator_pad::AggregatorPadClass; diff --git a/gstreamer-base/src/subclass/aggregator.rs b/gstreamer-base/src/subclass/aggregator.rs new file mode 100644 index 000000000..9650c5e60 --- /dev/null +++ b/gstreamer-base/src/subclass/aggregator.rs @@ -0,0 +1,734 @@ +// Copyright (C) 2017,2018 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc; + +use ffi; +use glib_ffi; +use gst_ffi; + +use glib::translate::*; +use prelude::*; + +use glib::subclass::prelude::*; +use gst; +use gst::subclass::prelude::*; + +use std::ptr; + +use Aggregator; +use AggregatorClass; +use AggregatorPad; + +pub trait AggregatorImpl: ElementImpl + Send + Sync + 'static { + fn flush(&self, aggregator: &Aggregator) -> gst::FlowReturn { + self.parent_flush(aggregator) + } + + fn clip( + &self, + aggregator: &Aggregator, + aggregator_pad: &AggregatorPad, + buffer: gst::Buffer, + ) -> Option { + self.parent_clip(aggregator, aggregator_pad, buffer) + } + + fn finish_buffer(&self, aggregator: &Aggregator, buffer: gst::Buffer) -> gst::FlowReturn { + self.parent_finish_buffer(aggregator, buffer) + } + + fn sink_event( + &self, + aggregator: &Aggregator, + aggregator_pad: &AggregatorPad, + event: gst::Event, + ) -> bool { + self.parent_sink_event(aggregator, aggregator_pad, event) + } + + fn sink_query( + &self, + aggregator: &Aggregator, + aggregator_pad: &AggregatorPad, + query: &mut gst::QueryRef, + ) -> bool { + self.parent_sink_query(aggregator, aggregator_pad, query) + } + + fn src_event(&self, aggregator: &Aggregator, event: gst::Event) -> bool { + self.parent_src_event(aggregator, event) + } + + fn src_query(&self, aggregator: &Aggregator, query: &mut gst::QueryRef) -> bool { + self.parent_src_query(aggregator, query) + } + + fn src_activate(&self, aggregator: &Aggregator, mode: gst::PadMode, active: bool) -> bool { + self.parent_src_activate(aggregator, mode, active) + } + + fn aggregate(&self, aggregator: &Aggregator, timeout: bool) -> gst::FlowReturn; + + fn start(&self, aggregator: &Aggregator) -> bool { + self.parent_start(aggregator) + } + + fn stop(&self, aggregator: &Aggregator) -> bool { + self.parent_stop(aggregator) + } + + fn get_next_time(&self, aggregator: &Aggregator) -> gst::ClockTime { + self.parent_get_next_time(aggregator) + } + + fn create_new_pad( + &self, + aggregator: &Aggregator, + templ: &gst::PadTemplate, + req_name: Option<&str>, + caps: Option<&gst::CapsRef>, + ) -> Option { + self.parent_create_new_pad(aggregator, templ, req_name, caps) + } + + fn update_src_caps( + &self, + aggregator: &Aggregator, + caps: &gst::CapsRef, + ) -> Result { + self.parent_update_src_caps(aggregator, caps) + } + + fn fixate_src_caps(&self, aggregator: &Aggregator, caps: gst::Caps) -> gst::Caps { + self.parent_fixate_src_caps(aggregator, caps) + } + + fn negotiated_src_caps(&self, aggregator: &Aggregator, caps: &gst::CapsRef) -> bool { + self.parent_negotiated_src_caps(aggregator, caps) + } + + fn parent_flush(&self, aggregator: &Aggregator) -> gst::FlowReturn { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .flush + .map(|f| from_glib(f(aggregator.to_glib_none().0))) + .unwrap_or(gst::FlowReturn::Ok) + } + } + + fn parent_clip( + &self, + aggregator: &Aggregator, + aggregator_pad: &AggregatorPad, + buffer: gst::Buffer, + ) -> Option { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + match (*parent_class).clip { + None => Some(buffer), + Some(ref func) => from_glib_full(func( + aggregator.to_glib_none().0, + aggregator_pad.to_glib_none().0, + buffer.into_ptr(), + )), + } + } + } + + fn parent_finish_buffer( + &self, + aggregator: &Aggregator, + buffer: gst::Buffer, + ) -> gst::FlowReturn { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .finish_buffer + .map(|f| from_glib(f(aggregator.to_glib_none().0, buffer.into_ptr()))) + .unwrap_or(gst::FlowReturn::Ok) + } + } + + fn parent_sink_event( + &self, + aggregator: &Aggregator, + aggregator_pad: &AggregatorPad, + event: gst::Event, + ) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .sink_event + .map(|f| { + from_glib(f( + aggregator.to_glib_none().0, + aggregator_pad.to_glib_none().0, + event.into_ptr(), + )) + }) + .unwrap_or(false) + } + } + + fn parent_sink_query( + &self, + aggregator: &Aggregator, + aggregator_pad: &AggregatorPad, + query: &mut gst::QueryRef, + ) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .sink_query + .map(|f| { + from_glib(f( + aggregator.to_glib_none().0, + aggregator_pad.to_glib_none().0, + query.as_mut_ptr(), + )) + }) + .unwrap_or(false) + } + } + + fn parent_src_event(&self, aggregator: &Aggregator, event: gst::Event) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .src_event + .map(|f| from_glib(f(aggregator.to_glib_none().0, event.into_ptr()))) + .unwrap_or(false) + } + } + + fn parent_src_query(&self, aggregator: &Aggregator, query: &mut gst::QueryRef) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .src_query + .map(|f| from_glib(f(aggregator.to_glib_none().0, query.as_mut_ptr()))) + .unwrap_or(false) + } + } + + fn parent_src_activate( + &self, + aggregator: &Aggregator, + mode: gst::PadMode, + active: bool, + ) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .src_activate + .map(|f| { + from_glib(f( + aggregator.to_glib_none().0, + mode.to_glib(), + active.to_glib(), + )) + }) + .unwrap_or(false) + } + } + + fn parent_aggregate(&self, aggregator: &Aggregator, timeout: bool) -> gst::FlowReturn { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .aggregate + .map(|f| from_glib(f(aggregator.to_glib_none().0, timeout.to_glib()))) + .unwrap_or(gst::FlowReturn::Error) + } + } + + fn parent_start(&self, aggregator: &Aggregator) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .start + .map(|f| from_glib(f(aggregator.to_glib_none().0))) + .unwrap_or(false) + } + } + + fn parent_stop(&self, aggregator: &Aggregator) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .stop + .map(|f| from_glib(f(aggregator.to_glib_none().0))) + .unwrap_or(false) + } + } + + fn parent_get_next_time(&self, aggregator: &Aggregator) -> gst::ClockTime { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .get_next_time + .map(|f| from_glib(f(aggregator.to_glib_none().0))) + .unwrap_or(gst::CLOCK_TIME_NONE) + } + } + + fn parent_create_new_pad( + &self, + aggregator: &Aggregator, + templ: &gst::PadTemplate, + req_name: Option<&str>, + caps: Option<&gst::CapsRef>, + ) -> Option { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .create_new_pad + .map(|f| { + from_glib_full(f( + aggregator.to_glib_none().0, + templ.to_glib_none().0, + req_name.to_glib_none().0, + caps.map(|c| c.as_ptr()).unwrap_or(ptr::null()), + )) + }) + .unwrap_or(None) + } + } + + fn parent_update_src_caps( + &self, + aggregator: &Aggregator, + caps: &gst::CapsRef, + ) -> Result { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .update_src_caps + .map(|f| { + let mut out_caps = ptr::null_mut(); + let flow_ret: gst::FlowReturn = from_glib(f( + aggregator.to_glib_none().0, + caps.as_mut_ptr(), + &mut out_caps, + )); + flow_ret.into_result_value(|| from_glib_full(out_caps)) + }) + .unwrap_or(Err(gst::FlowError::Error)) + } + } + + fn parent_fixate_src_caps(&self, aggregator: &Aggregator, caps: gst::Caps) -> gst::Caps { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + + match (*parent_class).fixate_src_caps { + Some(ref f) => from_glib_full(f(aggregator.to_glib_none().0, caps.into_ptr())), + None => caps, + } + } + } + + fn parent_negotiated_src_caps(&self, aggregator: &Aggregator, caps: &gst::CapsRef) -> bool { + unsafe { + let data = self.get_type_data(); + let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .negotiated_src_caps + .map(|f| from_glib(f(aggregator.to_glib_none().0, caps.as_mut_ptr()))) + .unwrap_or(false) + } + } +} + +unsafe impl IsSubclassable for AggregatorClass +where + ::Instance: PanicPoison, +{ + fn override_vfuncs(&mut self) { + >::override_vfuncs(self); + unsafe { + let klass = &mut *(self as *const Self as *mut ffi::GstAggregatorClass); + klass.flush = Some(aggregator_flush::); + klass.clip = Some(aggregator_clip::); + klass.finish_buffer = Some(aggregator_finish_buffer::); + klass.sink_event = Some(aggregator_sink_event::); + klass.sink_query = Some(aggregator_sink_query::); + klass.src_event = Some(aggregator_src_event::); + klass.src_query = Some(aggregator_src_query::); + klass.src_activate = Some(aggregator_src_activate::); + klass.aggregate = Some(aggregator_aggregate::); + klass.start = Some(aggregator_start::); + klass.stop = Some(aggregator_stop::); + klass.get_next_time = Some(aggregator_get_next_time::); + klass.create_new_pad = Some(aggregator_create_new_pad::); + klass.update_src_caps = Some(aggregator_update_src_caps::); + klass.fixate_src_caps = Some(aggregator_fixate_src_caps::); + klass.negotiated_src_caps = Some(aggregator_negotiated_src_caps::); + } + } +} + +unsafe extern "C" fn aggregator_flush( + ptr: *mut ffi::GstAggregator, +) -> gst_ffi::GstFlowReturn +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), gst::FlowReturn::Error, { + imp.flush(&wrap) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_clip( + ptr: *mut ffi::GstAggregator, + aggregator_pad: *mut ffi::GstAggregatorPad, + buffer: *mut gst_ffi::GstBuffer, +) -> *mut gst_ffi::GstBuffer +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + let ret = gst_panic_to_error!(&wrap, &instance.panicked(), None, { + imp.clip( + &wrap, + &from_glib_borrow(aggregator_pad), + from_glib_full(buffer), + ) + }); + + ret.map(|r| r.into_ptr()).unwrap_or(ptr::null_mut()) +} + +unsafe extern "C" fn aggregator_finish_buffer( + ptr: *mut ffi::GstAggregator, + buffer: *mut gst_ffi::GstBuffer, +) -> gst_ffi::GstFlowReturn +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), gst::FlowReturn::Error, { + imp.finish_buffer(&wrap, from_glib_full(buffer)) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_sink_event( + ptr: *mut ffi::GstAggregator, + aggregator_pad: *mut ffi::GstAggregatorPad, + event: *mut gst_ffi::GstEvent, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { + imp.sink_event( + &wrap, + &from_glib_borrow(aggregator_pad), + from_glib_full(event), + ) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_sink_query( + ptr: *mut ffi::GstAggregator, + aggregator_pad: *mut ffi::GstAggregatorPad, + query: *mut gst_ffi::GstQuery, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { + imp.sink_query( + &wrap, + &from_glib_borrow(aggregator_pad), + gst::QueryRef::from_mut_ptr(query), + ) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_src_event( + ptr: *mut ffi::GstAggregator, + event: *mut gst_ffi::GstEvent, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { + imp.src_event(&wrap, from_glib_full(event)) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_src_query( + ptr: *mut ffi::GstAggregator, + query: *mut gst_ffi::GstQuery, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { + imp.src_query(&wrap, gst::QueryRef::from_mut_ptr(query)) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_src_activate( + ptr: *mut ffi::GstAggregator, + mode: gst_ffi::GstPadMode, + active: glib_ffi::gboolean, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { + imp.src_activate(&wrap, from_glib(mode), from_glib(active)) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_aggregate( + ptr: *mut ffi::GstAggregator, + timeout: glib_ffi::gboolean, +) -> gst_ffi::GstFlowReturn +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), gst::FlowReturn::Error, { + imp.aggregate(&wrap, from_glib(timeout)) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_start( + ptr: *mut ffi::GstAggregator, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { imp.start(&wrap) }).to_glib() +} + +unsafe extern "C" fn aggregator_stop( + ptr: *mut ffi::GstAggregator, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { imp.stop(&wrap) }).to_glib() +} + +unsafe extern "C" fn aggregator_get_next_time( + ptr: *mut ffi::GstAggregator, +) -> gst_ffi::GstClockTime +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), gst::CLOCK_TIME_NONE, { + imp.get_next_time(&wrap) + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_create_new_pad( + ptr: *mut ffi::GstAggregator, + templ: *mut gst_ffi::GstPadTemplate, + req_name: *const libc::c_char, + caps: *const gst_ffi::GstCaps, +) -> *mut ffi::GstAggregatorPad +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), None, { + let req_name: Option = from_glib_none(req_name); + + // FIXME: Easier way to convert Option to Option<&str>? + let mut _tmp = String::new(); + let req_name = match req_name { + Some(n) => { + _tmp = n; + Some(_tmp.as_str()) + } + None => None, + }; + + imp.create_new_pad( + &wrap, + &from_glib_borrow(templ), + req_name, + if caps.is_null() { + None + } else { + Some(gst::CapsRef::from_ptr(caps)) + }, + ) + }) + .to_glib_full() +} + +unsafe extern "C" fn aggregator_update_src_caps( + ptr: *mut ffi::GstAggregator, + caps: *mut gst_ffi::GstCaps, + res: *mut *mut gst_ffi::GstCaps, +) -> gst_ffi::GstFlowReturn +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + *res = ptr::null_mut(); + + gst_panic_to_error!(&wrap, &instance.panicked(), gst::FlowReturn::Error, { + match imp.update_src_caps(&wrap, gst::CapsRef::from_ptr(caps)) { + Ok(res_caps) => { + *res = res_caps.into_ptr(); + gst::FlowReturn::Ok + } + Err(err) => err.into(), + } + }) + .to_glib() +} + +unsafe extern "C" fn aggregator_fixate_src_caps( + ptr: *mut ffi::GstAggregator, + caps: *mut gst_ffi::GstCaps, +) -> *mut gst_ffi::GstCaps +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), gst::Caps::new_empty(), { + imp.fixate_src_caps(&wrap, from_glib_full(caps)) + }) + .into_ptr() +} + +unsafe extern "C" fn aggregator_negotiated_src_caps( + ptr: *mut ffi::GstAggregator, + caps: *mut gst_ffi::GstCaps, +) -> glib_ffi::gboolean +where + T: AggregatorImpl, + T::Instance: PanicPoison, +{ + glib_floating_reference_guard!(ptr); + let instance = &*(ptr as *mut T::Instance); + let imp = instance.get_impl(); + let wrap: Aggregator = from_glib_borrow(ptr); + + gst_panic_to_error!(&wrap, &instance.panicked(), false, { + imp.negotiated_src_caps(&wrap, gst::CapsRef::from_ptr(caps)) + }) + .to_glib() +} diff --git a/gstreamer-base/src/subclass/mod.rs b/gstreamer-base/src/subclass/mod.rs index 125739c46..758bee920 100644 --- a/gstreamer-base/src/subclass/mod.rs +++ b/gstreamer-base/src/subclass/mod.rs @@ -14,10 +14,14 @@ pub mod base_transform; pub use self::base_transform::BaseTransformMode; +#[cfg(any(feature = "v1_14", feature = "dox"))] +pub mod aggregator; #[cfg(any(feature = "v1_14", feature = "dox"))] pub mod aggregator_pad; pub mod prelude { + #[cfg(any(feature = "v1_14", feature = "dox"))] + pub use super::aggregator::AggregatorImpl; #[cfg(any(feature = "v1_14", feature = "dox"))] pub use super::aggregator_pad::AggregatorPadImpl; pub use super::base_sink::BaseSinkImpl;