From fda2e3b7e34cf59e918bcece27bc2a8b260d0b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Fri, 15 Aug 2025 15:38:05 -0400 Subject: [PATCH 1/7] video_meta: Just make VideoMetaTransformScale a ffi wrapper This will simplify the code for the other ones instead of trying to reproduce the output. Part-of: --- gstreamer-video/src/video_meta.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/gstreamer-video/src/video_meta.rs b/gstreamer-video/src/video_meta.rs index e90959726..becc8ca35 100644 --- a/gstreamer-video/src/video_meta.rs +++ b/gstreamer-video/src/video_meta.rs @@ -1201,20 +1201,24 @@ pub mod tags { gst::impl_meta_tag!(Colorspace, crate::ffi::GST_META_TAG_VIDEO_COLORSPACE_STR); } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct VideoMetaTransformScale<'a> { - in_info: &'a crate::VideoInfo, - out_info: &'a crate::VideoInfo, -} +#[repr(transparent)] +#[doc(alias = "GstVideoMetaTransform")] +pub struct VideoMetaTransformScale(ffi::GstVideoMetaTransform); -impl<'a> VideoMetaTransformScale<'a> { - pub fn new(in_info: &'a crate::VideoInfo, out_info: &'a crate::VideoInfo) -> Self { +unsafe impl Sync for VideoMetaTransformScale {} +unsafe impl Send for VideoMetaTransformScale {} + +impl VideoMetaTransformScale { + pub fn new(in_info: &crate::VideoInfo, out_info: &crate::VideoInfo) -> Self { skip_assert_initialized!(); - VideoMetaTransformScale { in_info, out_info } + Self(ffi::GstVideoMetaTransform { + in_info: mut_override(in_info.to_glib_none().0), + out_info: mut_override(out_info.to_glib_none().0), + }) } } -unsafe impl<'a> gst::meta::MetaTransform<'a> for VideoMetaTransformScale<'a> { +unsafe impl<'a> gst::meta::MetaTransform<'a> for VideoMetaTransformScale { type GLibType = ffi::GstVideoMetaTransform; #[doc(alias = "gst_video_meta_transform_scale_get_quark")] @@ -1226,10 +1230,7 @@ unsafe impl<'a> gst::meta::MetaTransform<'a> for VideoMetaTransformScale<'a> { &self, _meta: &gst::MetaRef, ) -> Result { - Ok(ffi::GstVideoMetaTransform { - in_info: mut_override(self.in_info.to_glib_none().0), - out_info: mut_override(self.out_info.to_glib_none().0), - }) + Ok(self.0) } } From ccd799a0c21f2ba801b431059fa8a1afb3590a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Tue, 19 Aug 2025 12:09:12 -0400 Subject: [PATCH 2/7] meta: Make MetaTransformCopy transparent Part-of: --- gstreamer/src/meta.rs | 47 ++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/gstreamer/src/meta.rs b/gstreamer/src/meta.rs index 6a3857594..82f1d1e51 100644 --- a/gstreamer/src/meta.rs +++ b/gstreamer/src/meta.rs @@ -1109,19 +1109,31 @@ pub unsafe trait MetaTransform<'a> { fn to_raw(&self, meta: &MetaRef) -> Result; } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct MetaTransformCopy { - range: (Bound, Bound), - region: bool, -} +#[repr(transparent)] +#[doc(alias = "GstMetaTransformCopy")] +pub struct MetaTransformCopy(ffi::GstMetaTransformCopy); impl MetaTransformCopy { pub fn new(region: bool, range: impl RangeBounds) -> Self { skip_assert_initialized!(); - MetaTransformCopy { - range: (range.start_bound().cloned(), range.end_bound().cloned()), - region, - } + + let offset = match range.start_bound() { + Bound::Included(idx) => *idx, + Bound::Excluded(idx) => *idx + 1, + Bound::Unbounded => 0, + }; + + let size = match range.end_bound() { + Bound::Included(idx) => *idx + 1, + Bound::Excluded(idx) => *idx, + Bound::Unbounded => usize::MAX, + }; + + Self(ffi::GstMetaTransformCopy { + region: region.into_glib(), + offset, + size, + }) } } @@ -1134,15 +1146,9 @@ unsafe impl MetaTransform<'_> for MetaTransformCopy { } fn to_raw( &self, - meta: &MetaRef, + _meta: &MetaRef, ) -> Result { - let (offset, size) = meta.buffer.byte_range_into_offset_len(self.range)?; - - Ok(ffi::GstMetaTransformCopy { - region: self.region.into_glib(), - offset, - size, - }) + Ok(self.0) } } @@ -1304,8 +1310,11 @@ mod tests { { let meta = buffer.meta::().unwrap(); let buffer_dest = buffer_dest.get_mut().unwrap(); - meta.transform(buffer_dest, &MetaTransformCopy::new(false, ..)) - .unwrap(); + meta.transform( + buffer_dest, + &MetaTransformCopy::new(false, ..), + ) + .unwrap(); } let meta = buffer_dest.meta::().unwrap(); From f323ed058708e9aeae0f389329869b9193273bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Wed, 20 Aug 2025 08:25:08 -0400 Subject: [PATCH 3/7] meta: Replace to_raw with as_ptr in MetaTransform Simplifies the API Part-of: --- gstreamer-video/src/video_meta.rs | 9 +++------ gstreamer/src/meta.rs | 28 ++++++++++------------------ 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/gstreamer-video/src/video_meta.rs b/gstreamer-video/src/video_meta.rs index becc8ca35..503dba4b7 100644 --- a/gstreamer-video/src/video_meta.rs +++ b/gstreamer-video/src/video_meta.rs @@ -1218,7 +1218,7 @@ impl VideoMetaTransformScale { } } -unsafe impl<'a> gst::meta::MetaTransform<'a> for VideoMetaTransformScale { +unsafe impl gst::meta::MetaTransform for VideoMetaTransformScale { type GLibType = ffi::GstVideoMetaTransform; #[doc(alias = "gst_video_meta_transform_scale_get_quark")] @@ -1226,11 +1226,8 @@ unsafe impl<'a> gst::meta::MetaTransform<'a> for VideoMetaTransformScale { unsafe { from_glib(ffi::gst_video_meta_transform_scale_get_quark()) } } - fn to_raw( - &self, - _meta: &gst::MetaRef, - ) -> Result { - Ok(self.0) + fn as_ptr(&self) -> *const ffi::GstVideoMetaTransform { + &self.0 } } diff --git a/gstreamer/src/meta.rs b/gstreamer/src/meta.rs index 82f1d1e51..0895d2592 100644 --- a/gstreamer/src/meta.rs +++ b/gstreamer/src/meta.rs @@ -235,7 +235,7 @@ impl<'a, T> MetaRef<'a, T> { pub fn transform(&self, buffer: &mut BufferRef, data: &'a MT) -> Result<(), glib::BoolError> where T: MetaAPI, - MT: MetaTransform<'a>, + MT: MetaTransform, { unsafe { let info = *(*self.upcast_ref().as_ptr()).info; @@ -245,15 +245,13 @@ impl<'a, T> MetaRef<'a, T> { )); }; - let data = data.to_raw(self)?; - glib::result_from_gboolean!( transform_func( buffer.as_mut_ptr(), mut_override(self.upcast_ref().as_ptr()), mut_override(self.buffer.as_ptr()), MT::quark().into_glib(), - mut_override(&data) as *mut _, + mut_override(data.as_ptr() as *mut _), ), "Failed to transform meta" ) @@ -493,7 +491,7 @@ impl<'a, T, U> MetaRefMut<'a, T, U> { ) -> Result<(), glib::BoolError> where T: MetaAPI, - MT: MetaTransform<'a>, + MT: MetaTransform, { self.as_meta_ref().transform(buffer, data) } @@ -1103,10 +1101,10 @@ pub mod tags { ); } -pub unsafe trait MetaTransform<'a> { +pub unsafe trait MetaTransform { type GLibType; fn quark() -> glib::Quark; - fn to_raw(&self, meta: &MetaRef) -> Result; + fn as_ptr(&self) -> *const Self::GLibType; } #[repr(transparent)] @@ -1137,18 +1135,15 @@ impl MetaTransformCopy { } } -unsafe impl MetaTransform<'_> for MetaTransformCopy { +unsafe impl MetaTransform for MetaTransformCopy { type GLibType = ffi::GstMetaTransformCopy; fn quark() -> glib::Quark { static QUARK: std::sync::OnceLock = std::sync::OnceLock::new(); *QUARK.get_or_init(|| glib::Quark::from_static_str(glib::gstr!("gst-copy"))) } - fn to_raw( - &self, - _meta: &MetaRef, - ) -> Result { - Ok(self.0) + fn as_ptr(&self) -> *const ffi::GstMetaTransformCopy { + &self.0 } } @@ -1310,11 +1305,8 @@ mod tests { { let meta = buffer.meta::().unwrap(); let buffer_dest = buffer_dest.get_mut().unwrap(); - meta.transform( - buffer_dest, - &MetaTransformCopy::new(false, ..), - ) - .unwrap(); + meta.transform(buffer_dest, &MetaTransformCopy::new(false, ..)) + .unwrap(); } let meta = buffer_dest.meta::().unwrap(); From cee8516717b5c580ebc3e94626cdcc1a55f7fa5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Wed, 20 Aug 2025 09:26:20 -0400 Subject: [PATCH 4/7] meta: Remove explicit region from MetaTransformCopy Part-of: --- gstreamer/src/meta.rs | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/gstreamer/src/meta.rs b/gstreamer/src/meta.rs index 0895d2592..a7431570f 100644 --- a/gstreamer/src/meta.rs +++ b/gstreamer/src/meta.rs @@ -1112,19 +1112,27 @@ pub unsafe trait MetaTransform { pub struct MetaTransformCopy(ffi::GstMetaTransformCopy); impl MetaTransformCopy { - pub fn new(region: bool, range: impl RangeBounds) -> Self { + pub fn new(range: impl RangeBounds) -> Self { skip_assert_initialized!(); - let offset = match range.start_bound() { - Bound::Included(idx) => *idx, - Bound::Excluded(idx) => *idx + 1, - Bound::Unbounded => 0, - }; + let region = + !(range.start_bound() == Bound::Unbounded && range.end_bound() == Bound::Unbounded); - let size = match range.end_bound() { - Bound::Included(idx) => *idx + 1, - Bound::Excluded(idx) => *idx, - Bound::Unbounded => usize::MAX, + let (offset, size) = if region { + ( + match range.start_bound() { + Bound::Included(idx) => *idx, + Bound::Excluded(idx) => *idx + 1, + Bound::Unbounded => 0, + }, + match range.end_bound() { + Bound::Included(idx) => *idx + 1, + Bound::Excluded(idx) => *idx, + Bound::Unbounded => usize::MAX, + }, + ) + } else { + (0, usize::MAX) }; Self(ffi::GstMetaTransformCopy { @@ -1305,7 +1313,7 @@ mod tests { { let meta = buffer.meta::().unwrap(); let buffer_dest = buffer_dest.get_mut().unwrap(); - meta.transform(buffer_dest, &MetaTransformCopy::new(false, ..)) + meta.transform(buffer_dest, &MetaTransformCopy::new(..)) .unwrap(); } From c16e94ebdd92bad72951e1f85f807c59e264c53e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Wed, 20 Aug 2025 09:26:35 -0400 Subject: [PATCH 5/7] meta: Add accessor for MetaTransformCopy Part-of: --- gstreamer/src/meta.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gstreamer/src/meta.rs b/gstreamer/src/meta.rs index a7431570f..712a309d4 100644 --- a/gstreamer/src/meta.rs +++ b/gstreamer/src/meta.rs @@ -1141,6 +1141,20 @@ impl MetaTransformCopy { size, }) } + + pub fn range(&self) -> Option<(Bound, Bound)> { + if self.0.region == glib::ffi::GFALSE { + None + } else { + let end = if self.0.size == usize::MAX { + Bound::Unbounded + } else { + Bound::Excluded(self.0.size) + }; + + Some((Bound::Included(self.0.offset), end)) + } + } } unsafe impl MetaTransform for MetaTransformCopy { From 672c19dad029c238b19add502b7a181330284fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Wed, 20 Aug 2025 09:52:24 -0400 Subject: [PATCH 6/7] videometatransform: Add accessor for members Part-of: --- gstreamer-video/src/video_meta.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gstreamer-video/src/video_meta.rs b/gstreamer-video/src/video_meta.rs index 503dba4b7..f0258eaba 100644 --- a/gstreamer-video/src/video_meta.rs +++ b/gstreamer-video/src/video_meta.rs @@ -1216,6 +1216,14 @@ impl VideoMetaTransformScale { out_info: mut_override(out_info.to_glib_none().0), }) } + + pub fn in_info(&self) -> &crate::VideoInfo { + unsafe { &*(self.0.in_info as *const crate::VideoInfo) } + } + + pub fn out_info(&self) -> &crate::VideoInfo { + unsafe { &*(self.0.out_info as *const crate::VideoInfo) } + } } unsafe impl gst::meta::MetaTransform for VideoMetaTransformScale { From 032e9a7f75e336d73289f7ede056b2c9588bc12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Thu, 21 Aug 2025 09:33:23 -0400 Subject: [PATCH 7/7] meta: MetaTransformCopy accept 0.. as equivalent to .. If the range is 0.., then there is no region Part-of: --- gstreamer/src/meta.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gstreamer/src/meta.rs b/gstreamer/src/meta.rs index 712a309d4..6459c7d38 100644 --- a/gstreamer/src/meta.rs +++ b/gstreamer/src/meta.rs @@ -1115,8 +1115,8 @@ impl MetaTransformCopy { pub fn new(range: impl RangeBounds) -> Self { skip_assert_initialized!(); - let region = - !(range.start_bound() == Bound::Unbounded && range.end_bound() == Bound::Unbounded); + let region = !(matches!(range.start_bound(), Bound::Unbounded | Bound::Included(0)) + && range.end_bound() == Bound::Unbounded); let (offset, size) = if region { (