From 7e71c74505647c9b17b9f09adf735ec991749286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 16 Oct 2021 13:53:57 +0300 Subject: [PATCH] base: Add support for propose_allocation()/decide_allocation() in the base classes --- gstreamer-base/src/subclass/aggregator.rs | 142 ++++++++++++++++++ gstreamer-base/src/subclass/base_sink.rs | 63 ++++++++ gstreamer-base/src/subclass/base_src.rs | 63 ++++++++ gstreamer-base/src/subclass/base_transform.rs | 132 ++++++++++++++++ 4 files changed, 400 insertions(+) diff --git a/gstreamer-base/src/subclass/aggregator.rs b/gstreamer-base/src/subclass/aggregator.rs index 6c13a5e75..091262972 100644 --- a/gstreamer-base/src/subclass/aggregator.rs +++ b/gstreamer-base/src/subclass/aggregator.rs @@ -149,6 +149,24 @@ pub trait AggregatorImpl: AggregatorImplExt + ElementImpl { self.parent_negotiated_src_caps(aggregator, caps) } + fn propose_allocation( + &self, + element: &Self::Type, + pad: &AggregatorPad, + decide_query: &gst::QueryRef, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + self.parent_propose_allocation(element, pad, decide_query, query) + } + + fn decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + self.parent_decide_allocation(element, query) + } + #[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] fn negotiate(&self, aggregator: &Self::Type) -> bool { @@ -267,6 +285,20 @@ pub trait AggregatorImplExt: ObjectSubclass { caps: &gst::Caps, ) -> Result<(), gst::LoggableError>; + fn parent_propose_allocation( + &self, + element: &Self::Type, + pad: &AggregatorPad, + decide_query: &gst::QueryRef, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage>; + + fn parent_decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage>; + #[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] fn parent_negotiate(&self, aggregator: &Self::Type) -> bool; @@ -656,6 +688,64 @@ impl AggregatorImplExt for T { } } + fn parent_propose_allocation( + &self, + element: &Self::Type, + pad: &AggregatorPad, + decide_query: &gst::QueryRef, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .propose_allocation + .map(|f| { + if from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + pad.to_glib_none().0, + decide_query.as_mut_ptr(), + query.as_mut_ptr(), + )) { + Ok(()) + } else { + Err(gst::error_msg!( + gst::CoreError::StateChange, + ["Parent function `propose_allocation` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstAggregatorClass; + (*parent_class) + .decide_allocation + .map(|f| { + if from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + query.as_mut_ptr(), + )) { + Ok(()) + } else { + Err(gst::error_msg!( + gst::CoreError::StateChange, + ["Parent function `decide_allocation` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + #[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] fn parent_negotiate(&self, aggregator: &Self::Type) -> bool { @@ -717,6 +807,8 @@ unsafe impl IsSubclassable for Aggregator { 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::); + klass.propose_allocation = Some(aggregator_propose_allocation::); + klass.decide_allocation = Some(aggregator_decide_allocation::); #[cfg(any(feature = "v1_18", feature = "dox"))] { klass.sink_event_pre_queue = Some(aggregator_sink_event_pre_queue::); @@ -1075,6 +1167,56 @@ unsafe extern "C" fn aggregator_negotiated_src_caps( .into_glib() } +unsafe extern "C" fn aggregator_propose_allocation( + ptr: *mut ffi::GstAggregator, + pad: *mut ffi::GstAggregatorPad, + decide_query: *mut gst::ffi::GstQuery, + query: *mut gst::ffi::GstQuery, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + let decide_query = gst::QueryRef::from_ptr(decide_query); + let query = gst::QueryRef::from_mut_ptr(query); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + match imp.propose_allocation( + wrap.unsafe_cast_ref(), + &from_glib_borrow(pad), + decide_query, + query, + ) { + Ok(()) => true, + Err(err) => { + wrap.post_error_message(err); + false + } + } + }) + .into_glib() +} + +unsafe extern "C" fn aggregator_decide_allocation( + ptr: *mut ffi::GstAggregator, + query: *mut gst::ffi::GstQuery, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + let query = gst::QueryRef::from_mut_ptr(query); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + match imp.decide_allocation(wrap.unsafe_cast_ref(), query) { + Ok(()) => true, + Err(err) => { + wrap.post_error_message(err); + false + } + } + }) + .into_glib() +} + #[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] unsafe extern "C" fn aggregator_negotiate( diff --git a/gstreamer-base/src/subclass/base_sink.rs b/gstreamer-base/src/subclass/base_sink.rs index bb987c223..54065e86c 100644 --- a/gstreamer-base/src/subclass/base_sink.rs +++ b/gstreamer-base/src/subclass/base_sink.rs @@ -77,6 +77,14 @@ pub trait BaseSinkImpl: BaseSinkImplExt + ElementImpl { fn unlock_stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { self.parent_unlock_stop(element) } + + fn propose_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + self.parent_propose_allocation(element, query) + } } pub trait BaseSinkImplExt: ObjectSubclass { @@ -125,6 +133,12 @@ pub trait BaseSinkImplExt: ObjectSubclass { fn parent_unlock(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage>; fn parent_unlock_stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage>; + + fn parent_propose_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage>; } impl BaseSinkImplExt for T { @@ -385,6 +399,33 @@ impl BaseSinkImplExt for T { .unwrap_or(Ok(())) } } + + fn parent_propose_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstBaseSinkClass; + (*parent_class) + .propose_allocation + .map(|f| { + if from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + query.as_mut_ptr(), + )) { + Ok(()) + } else { + Err(gst::error_msg!( + gst::CoreError::StateChange, + ["Parent function `propose_allocation` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } } unsafe impl IsSubclassable for BaseSink { @@ -404,6 +445,7 @@ unsafe impl IsSubclassable for BaseSink { klass.fixate = Some(base_sink_fixate::); klass.unlock = Some(base_sink_unlock::); klass.unlock_stop = Some(base_sink_unlock_stop::); + klass.propose_allocation = Some(base_sink_propose_allocation::); } fn instance_init(instance: &mut glib::subclass::InitializingObject) { @@ -627,3 +669,24 @@ unsafe extern "C" fn base_sink_unlock_stop( }) .into_glib() } + +unsafe extern "C" fn base_sink_propose_allocation( + ptr: *mut ffi::GstBaseSink, + query: *mut gst::ffi::GstQuery, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + let query = gst::QueryRef::from_mut_ptr(query); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + match imp.propose_allocation(wrap.unsafe_cast_ref(), query) { + Ok(()) => true, + Err(err) => { + wrap.post_error_message(err); + false + } + } + }) + .into_glib() +} diff --git a/gstreamer-base/src/subclass/base_src.rs b/gstreamer-base/src/subclass/base_src.rs index 6c2a23545..310a97e86 100644 --- a/gstreamer-base/src/subclass/base_src.rs +++ b/gstreamer-base/src/subclass/base_src.rs @@ -107,6 +107,14 @@ pub trait BaseSrcImpl: BaseSrcImplExt + ElementImpl { fn unlock_stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> { self.parent_unlock_stop(element) } + + fn decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + self.parent_decide_allocation(element, query) + } } pub trait BaseSrcImplExt: ObjectSubclass { @@ -168,6 +176,12 @@ pub trait BaseSrcImplExt: ObjectSubclass { fn parent_unlock(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage>; fn parent_unlock_stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage>; + + fn parent_decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage>; } impl BaseSrcImplExt for T { @@ -569,6 +583,33 @@ impl BaseSrcImplExt for T { .unwrap_or(Ok(())) } } + + fn parent_decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstBaseSrcClass; + (*parent_class) + .decide_allocation + .map(|f| { + if from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + query.as_mut_ptr(), + )) { + Ok(()) + } else { + Err(gst::error_msg!( + gst::CoreError::StateChange, + ["Parent function `decide_allocation` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } } unsafe impl IsSubclassable for BaseSrc { @@ -592,6 +633,7 @@ unsafe impl IsSubclassable for BaseSrc { klass.fixate = Some(base_src_fixate::); klass.unlock = Some(base_src_unlock::); klass.unlock_stop = Some(base_src_unlock_stop::); + klass.decide_allocation = Some(base_src_decide_allocation::); } fn instance_init(instance: &mut glib::subclass::InitializingObject) { @@ -975,3 +1017,24 @@ unsafe extern "C" fn base_src_unlock_stop( }) .into_glib() } + +unsafe extern "C" fn base_src_decide_allocation( + ptr: *mut ffi::GstBaseSrc, + query: *mut gst::ffi::GstQuery, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + let query = gst::QueryRef::from_mut_ptr(query); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + match imp.decide_allocation(wrap.unsafe_cast_ref(), query) { + Ok(()) => true, + Err(err) => { + wrap.post_error_message(err); + false + } + } + }) + .into_glib() +} diff --git a/gstreamer-base/src/subclass/base_transform.rs b/gstreamer-base/src/subclass/base_transform.rs index b1259572e..8b092bc50 100644 --- a/gstreamer-base/src/subclass/base_transform.rs +++ b/gstreamer-base/src/subclass/base_transform.rs @@ -135,6 +135,23 @@ pub trait BaseTransformImpl: BaseTransformImplExt + ElementImpl { self.parent_transform_ip_passthrough(element, buf) } + fn propose_allocation( + &self, + element: &Self::Type, + decide_query: &gst::QueryRef, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + self.parent_propose_allocation(element, decide_query, query) + } + + fn decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + self.parent_decide_allocation(element, query) + } + fn copy_metadata( &self, element: &Self::Type, @@ -257,6 +274,19 @@ pub trait BaseTransformImplExt: ObjectSubclass { buf: &gst::Buffer, ) -> Result; + fn parent_propose_allocation( + &self, + element: &Self::Type, + decide_query: &gst::QueryRef, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage>; + + fn parent_decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage>; + fn parent_copy_metadata( &self, element: &Self::Type, @@ -684,6 +714,62 @@ impl BaseTransformImplExt for T { } } + fn parent_propose_allocation( + &self, + element: &Self::Type, + decide_query: &gst::QueryRef, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstBaseTransformClass; + (*parent_class) + .propose_allocation + .map(|f| { + if from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + decide_query.as_mut_ptr(), + query.as_mut_ptr(), + )) { + Ok(()) + } else { + Err(gst::error_msg!( + gst::CoreError::StateChange, + ["Parent function `propose_allocation` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + + fn parent_decide_allocation( + &self, + element: &Self::Type, + query: &mut gst::QueryRef, + ) -> Result<(), gst::ErrorMessage> { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstBaseTransformClass; + (*parent_class) + .decide_allocation + .map(|f| { + if from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + query.as_mut_ptr(), + )) { + Ok(()) + } else { + Err(gst::error_msg!( + gst::CoreError::StateChange, + ["Parent function `decide_allocation` failed"] + )) + } + }) + .unwrap_or(Ok(())) + } + } + fn parent_copy_metadata( &self, element: &Self::Type, @@ -846,6 +932,8 @@ unsafe impl IsSubclassable for BaseTransform { klass.sink_event = Some(base_transform_sink_event::); klass.src_event = Some(base_transform_src_event::); klass.transform_meta = Some(base_transform_transform_meta::); + klass.propose_allocation = Some(base_transform_propose_allocation::); + klass.decide_allocation = Some(base_transform_decide_allocation::); klass.copy_metadata = Some(base_transform_copy_metadata::); klass.before_transform = Some(base_transform_before_transform::); klass.submit_input_buffer = Some(base_transform_submit_input_buffer::); @@ -1231,6 +1319,50 @@ unsafe extern "C" fn base_transform_transform_meta( .into_glib() } +unsafe extern "C" fn base_transform_propose_allocation( + ptr: *mut ffi::GstBaseTransform, + decide_query: *mut gst::ffi::GstQuery, + query: *mut gst::ffi::GstQuery, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + let decide_query = gst::QueryRef::from_ptr(decide_query); + let query = gst::QueryRef::from_mut_ptr(query); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + match imp.propose_allocation(wrap.unsafe_cast_ref(), decide_query, query) { + Ok(()) => true, + Err(err) => { + wrap.post_error_message(err); + false + } + } + }) + .into_glib() +} + +unsafe extern "C" fn base_transform_decide_allocation( + ptr: *mut ffi::GstBaseTransform, + query: *mut gst::ffi::GstQuery, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.impl_(); + let wrap: Borrowed = from_glib_borrow(ptr); + let query = gst::QueryRef::from_mut_ptr(query); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + match imp.decide_allocation(wrap.unsafe_cast_ref(), query) { + Ok(()) => true, + Err(err) => { + wrap.post_error_message(err); + false + } + } + }) + .into_glib() +} + unsafe extern "C" fn base_transform_copy_metadata( ptr: *mut ffi::GstBaseTransform, inbuf: *mut gst::ffi::GstBuffer,