From c31921e09345970a459f4685654640c89d91eb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 9 May 2018 12:20:59 +0300 Subject: [PATCH] Further work-arounds for floating reference handling changes between 1.12 and 1.14 This fixes various memory-safety issues caused by broken reference counting. We have to handle pre-1.14 and post-1.14 differently in constructors. See https://bugzilla.gnome.org/show_bug.cgi?id=743062#c30 --- Gir_Gst.toml | 18 ++++++++++ Gir_GstNet.toml | 5 +++ gstreamer-net/src/auto/net_time_provider.rs | 10 ------ gstreamer-net/src/lib.rs | 1 + gstreamer-net/src/net_time_provider.rs | 34 +++++++++++++++++++ gstreamer/src/auto/buffer_pool.rs | 15 --------- gstreamer/src/auto/device_monitor.rs | 15 --------- gstreamer/src/auto/stream.rs | 12 ------- gstreamer/src/auto/stream_collection.rs | 10 ------ gstreamer/src/buffer_pool.rs | 23 +++++++++++++ gstreamer/src/device_monitor.rs | 34 +++++++++++++++++++ gstreamer/src/lib.rs | 3 ++ gstreamer/src/stream.rs | 37 +++++++++++++++++++++ gstreamer/src/stream_collection.rs | 19 +++++++++++ 14 files changed, 174 insertions(+), 62 deletions(-) create mode 100644 gstreamer-net/src/net_time_provider.rs create mode 100644 gstreamer/src/device_monitor.rs create mode 100644 gstreamer/src/stream.rs diff --git a/Gir_Gst.toml b/Gir_Gst.toml index 2c5365235..a996a0888 100644 --- a/Gir_Gst.toml +++ b/Gir_Gst.toml @@ -440,6 +440,11 @@ status = "generate" [[object]] name = "Gst.DeviceMonitor" status = "generate" + [[object.function]] + name = "new" + # Work-around for 1.14 switch from transfer-floating to transfer-full + ignore = true + [[object.function]] name = "get_bus" [object.function.return] @@ -709,11 +714,19 @@ status = "generate" name = "Gst.Stream" status = "generate" trait = false + [[object.function]] + name = "new" + # Work-around for 1.14 switch from transfer-floating to transfer-full + ignore = true [[object]] name = "Gst.StreamCollection" status = "generate" trait = false + [[object.function]] + name = "new" + # Work-around for 1.14 switch from transfer-floating to transfer-full + ignore = true [[object]] name = "Gst.Plugin" @@ -833,6 +846,11 @@ status = "generate" # Takes ownership ignore = true + [[object.function]] + name = "new" + # Work-around for 1.14 switch from transfer-floating to transfer-full + ignore = true + [[object.function]] name = "set_active" [object.function.return] diff --git a/Gir_GstNet.toml b/Gir_GstNet.toml index b054a8f31..278bf0e17 100644 --- a/Gir_GstNet.toml +++ b/Gir_GstNet.toml @@ -65,3 +65,8 @@ trait = false name = "GstNet.NetTimeProvider" status = "generate" trait = false + + [[object.function]] + name = "new" + # Floating reference handling + ignore = true diff --git a/gstreamer-net/src/auto/net_time_provider.rs b/gstreamer-net/src/auto/net_time_provider.rs index 57adadde9..68b7d1bbc 100644 --- a/gstreamer-net/src/auto/net_time_provider.rs +++ b/gstreamer-net/src/auto/net_time_provider.rs @@ -5,7 +5,6 @@ use ffi; use glib::StaticType; use glib::Value; -use glib::object::IsA; use glib::signal::SignalHandlerId; use glib::signal::connect; use glib::translate::*; @@ -29,15 +28,6 @@ glib_wrapper! { } impl NetTimeProvider { - pub fn new<'a, P: IsA, Q: Into>>(clock: &P, address: Q, port: i32) -> NetTimeProvider { - assert_initialized_main_thread!(); - let address = address.into(); - let address = address.to_glib_none(); - unsafe { - from_glib_full(ffi::gst_net_time_provider_new(clock.to_glib_none().0, address.0, port)) - } - } - pub fn get_property_active(&self) -> bool { unsafe { let mut value = Value::from_type(::static_type()); diff --git a/gstreamer-net/src/lib.rs b/gstreamer-net/src/lib.rs index 3c6db4b37..8ac8a4d19 100644 --- a/gstreamer-net/src/lib.rs +++ b/gstreamer-net/src/lib.rs @@ -38,6 +38,7 @@ pub use glib::{Cast, Continue, Error, IsA, StaticType, ToValue, Type, TypedValue mod auto; pub use auto::*; mod net_client_clock; +mod net_time_provider; mod ntp_clock; mod ptp_clock; diff --git a/gstreamer-net/src/net_time_provider.rs b/gstreamer-net/src/net_time_provider.rs new file mode 100644 index 000000000..4756f150f --- /dev/null +++ b/gstreamer-net/src/net_time_provider.rs @@ -0,0 +1,34 @@ +// Copyright (C) 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 ffi; +use NetTimeProvider; + +use glib::IsA; +use glib::translate::*; +use gst; + +impl NetTimeProvider { + pub fn new<'a, P: IsA, Q: Into>>(clock: &P, address: Q, port: i32) -> NetTimeProvider { + assert_initialized_main_thread!(); + let address = address.into(); + let address = address.to_glib_none(); + + let (major, minor, _, _) = gst::version(); + if (major, minor) > (1, 12) { + unsafe { + from_glib_full(ffi::gst_net_time_provider_new(clock.to_glib_none().0, address.0, port)) + } + } else { + // Workaround for bad floating reference handling in 1.12. This issue was fixed for 1.13 + unsafe { + from_glib_none(ffi::gst_net_time_provider_new(clock.to_glib_none().0, address.0, port)) + } + } + } +} diff --git a/gstreamer/src/auto/buffer_pool.rs b/gstreamer/src/auto/buffer_pool.rs index 98e092357..98eb7ebfa 100644 --- a/gstreamer/src/auto/buffer_pool.rs +++ b/gstreamer/src/auto/buffer_pool.rs @@ -20,21 +20,6 @@ glib_wrapper! { } } -impl BufferPool { - pub fn new() -> BufferPool { - assert_initialized_main_thread!(); - unsafe { - from_glib_full(ffi::gst_buffer_pool_new()) - } - } -} - -impl Default for BufferPool { - fn default() -> Self { - Self::new() - } -} - unsafe impl Send for BufferPool {} unsafe impl Sync for BufferPool {} diff --git a/gstreamer/src/auto/device_monitor.rs b/gstreamer/src/auto/device_monitor.rs index 68e08a896..848f49d2c 100644 --- a/gstreamer/src/auto/device_monitor.rs +++ b/gstreamer/src/auto/device_monitor.rs @@ -30,21 +30,6 @@ glib_wrapper! { } } -impl DeviceMonitor { - pub fn new() -> DeviceMonitor { - assert_initialized_main_thread!(); - unsafe { - from_glib_full(ffi::gst_device_monitor_new()) - } - } -} - -impl Default for DeviceMonitor { - fn default() -> Self { - Self::new() - } -} - unsafe impl Send for DeviceMonitor {} unsafe impl Sync for DeviceMonitor {} diff --git a/gstreamer/src/auto/stream.rs b/gstreamer/src/auto/stream.rs index 84ffc0225..d6e0b68b0 100644 --- a/gstreamer/src/auto/stream.rs +++ b/gstreamer/src/auto/stream.rs @@ -29,18 +29,6 @@ glib_wrapper! { } impl Stream { - #[cfg(any(feature = "v1_10", feature = "dox"))] - pub fn new<'a, 'b, P: Into>, Q: Into>>(stream_id: P, caps: Q, type_: StreamType, flags: StreamFlags) -> Stream { - assert_initialized_main_thread!(); - let stream_id = stream_id.into(); - let stream_id = stream_id.to_glib_none(); - let caps = caps.into(); - let caps = caps.to_glib_none(); - unsafe { - from_glib_full(ffi::gst_stream_new(stream_id.0, caps.0, type_.to_glib(), flags.to_glib())) - } - } - #[cfg(any(feature = "v1_10", feature = "dox"))] pub fn get_caps(&self) -> Option { unsafe { diff --git a/gstreamer/src/auto/stream_collection.rs b/gstreamer/src/auto/stream_collection.rs index 5ae1bd545..f9836f01e 100644 --- a/gstreamer/src/auto/stream_collection.rs +++ b/gstreamer/src/auto/stream_collection.rs @@ -27,16 +27,6 @@ glib_wrapper! { } impl StreamCollection { - #[cfg(any(feature = "v1_10", feature = "dox"))] - pub fn new<'a, P: Into>>(upstream_id: P) -> StreamCollection { - assert_initialized_main_thread!(); - let upstream_id = upstream_id.into(); - let upstream_id = upstream_id.to_glib_none(); - unsafe { - from_glib_full(ffi::gst_stream_collection_new(upstream_id.0)) - } - } - #[cfg(any(feature = "v1_10", feature = "dox"))] pub fn add_stream(&self, stream: &Stream) -> bool { unsafe { diff --git a/gstreamer/src/buffer_pool.rs b/gstreamer/src/buffer_pool.rs index b32a07850..0f915f716 100644 --- a/gstreamer/src/buffer_pool.rs +++ b/gstreamer/src/buffer_pool.rs @@ -205,6 +205,29 @@ impl PartialEq for BufferPoolAcquireParams { impl Eq for BufferPoolAcquireParams {} +impl BufferPool { + pub fn new() -> BufferPool { + assert_initialized_main_thread!(); + let (major, minor, _, _) = ::version(); + if (major, minor) > (1, 12) { + unsafe { + from_glib_full(ffi::gst_buffer_pool_new()) + } + } else { + // Work-around for 1.14 switching from transfer-floating to transfer-full + unsafe { + from_glib_none(ffi::gst_buffer_pool_new()) + } + } + } +} + +impl Default for BufferPool { + fn default() -> Self { + Self::new() + } +} + pub trait BufferPoolExtManual { fn get_config(&self) -> BufferPoolConfig; fn set_config(&self, config: BufferPoolConfig) -> Result<(), glib::error::BoolError>; diff --git a/gstreamer/src/device_monitor.rs b/gstreamer/src/device_monitor.rs new file mode 100644 index 000000000..a15e62f74 --- /dev/null +++ b/gstreamer/src/device_monitor.rs @@ -0,0 +1,34 @@ +// Copyright (C) 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 DeviceMonitor; +use ffi; +use glib::translate::*; + +impl DeviceMonitor { + pub fn new() -> DeviceMonitor { + assert_initialized_main_thread!(); + let (major, minor, _, _) = ::version(); + if (major, minor) > (1, 12) { + unsafe { + from_glib_full(ffi::gst_device_monitor_new()) + } + } else { + // Work-around for 1.14 switching from transfer-floating to transfer-full + unsafe { + from_glib_none(ffi::gst_device_monitor_new()) + } + } + } +} + +impl Default for DeviceMonitor { + fn default() -> Self { + Self::new() + } +} diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index f0f397526..52b03ade8 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -122,6 +122,7 @@ cfg_if! { mod child_proxy; mod clock_time; mod date_time; +mod device_monitor; mod device_provider; mod enums; mod ghost_pad; @@ -168,6 +169,8 @@ pub use tag_setter::TagSetterExtManual; mod plugin; #[cfg(any(feature = "v1_10", feature = "dox"))] pub mod stream_collection; +#[cfg(any(feature = "v1_10", feature = "dox"))] +mod stream; mod typefind; pub use typefind::*; diff --git a/gstreamer/src/stream.rs b/gstreamer/src/stream.rs new file mode 100644 index 000000000..393a12b41 --- /dev/null +++ b/gstreamer/src/stream.rs @@ -0,0 +1,37 @@ +// Copyright (C) 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 Stream; +use StreamFlags; +use StreamType; +use Caps; +use ffi; +use glib::translate::*; + +impl Stream { + #[cfg(any(feature = "v1_10", feature = "dox"))] + pub fn new<'a, 'b, P: Into>, Q: Into>>(stream_id: P, caps: Q, type_: StreamType, flags: StreamFlags) -> Stream { + assert_initialized_main_thread!(); + let stream_id = stream_id.into(); + let stream_id = stream_id.to_glib_none(); + let caps = caps.into(); + let caps = caps.to_glib_none(); + + let (major, minor, _, _) = ::version(); + if (major, minor) > (1, 12) { + unsafe { + from_glib_full(ffi::gst_stream_new(stream_id.0, caps.0, type_.to_glib(), flags.to_glib())) + } + } else { + // Work-around for 1.14 switching from transfer-floating to transfer-full + unsafe { + from_glib_none(ffi::gst_stream_new(stream_id.0, caps.0, type_.to_glib(), flags.to_glib())) + } + } + } +} diff --git a/gstreamer/src/stream_collection.rs b/gstreamer/src/stream_collection.rs index 6c0d3c6e3..c0e1a44db 100644 --- a/gstreamer/src/stream_collection.rs +++ b/gstreamer/src/stream_collection.rs @@ -8,6 +8,8 @@ use Stream; use StreamCollection; +use ffi; +use glib::translate::*; pub struct Iter<'a> { collection: &'a StreamCollection, @@ -65,6 +67,23 @@ impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> ExactSizeIterator for Iter<'a> {} impl StreamCollection { + pub fn new<'a, P: Into>>(upstream_id: P) -> StreamCollection { + assert_initialized_main_thread!(); + let upstream_id = upstream_id.into(); + let upstream_id = upstream_id.to_glib_none(); + let (major, minor, _, _) = ::version(); + if (major, minor) > (1, 12) { + unsafe { + from_glib_full(ffi::gst_stream_collection_new(upstream_id.0)) + } + } else { + // Work-around for 1.14 switching from transfer-floating to transfer-full + unsafe { + from_glib_none(ffi::gst_stream_collection_new(upstream_id.0)) + } + } + } + pub fn iter(&self) -> Iter { Iter::new(self) }