Switch from once_cell to std::sync::OnceLock where it makes sense

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1379>
This commit is contained in:
Sebastian Dröge 2024-01-29 17:31:21 +01:00
parent ce5dca918d
commit 193bcbf055
38 changed files with 229 additions and 212 deletions

24
Cargo.lock generated
View file

@ -504,6 +504,7 @@ dependencies = [
"memfd", "memfd",
"memmap2", "memmap2",
"objc", "objc",
"once_cell",
"pango", "pango",
"pangocairo", "pangocairo",
"raw-window-handle", "raw-window-handle",
@ -843,6 +844,7 @@ dependencies = [
"muldiv", "muldiv",
"num-integer", "num-integer",
"num-rational", "num-rational",
"once_cell",
"option-operations", "option-operations",
"paste", "paste",
"pin-project-lite", "pin-project-lite",
@ -863,6 +865,7 @@ dependencies = [
"gstreamer", "gstreamer",
"gstreamer-allocators-sys", "gstreamer-allocators-sys",
"libc", "libc",
"once_cell",
] ]
[[package]] [[package]]
@ -919,6 +922,7 @@ dependencies = [
"gstreamer-base", "gstreamer-base",
"itertools", "itertools",
"libc", "libc",
"once_cell",
"serde", "serde",
"serde_json", "serde_json",
"smallvec", "smallvec",
@ -1053,6 +1057,7 @@ dependencies = [
"gstreamer-gl-sys", "gstreamer-gl-sys",
"gstreamer-video", "gstreamer-video",
"libc", "libc",
"once_cell",
"serde", "serde",
"serde_json", "serde_json",
] ]
@ -1428,6 +1433,7 @@ dependencies = [
"gstreamer", "gstreamer",
"gstreamer-app", "gstreamer-app",
"gstreamer-video", "gstreamer-video",
"once_cell",
"thiserror", "thiserror",
] ]
@ -1471,6 +1477,7 @@ dependencies = [
"gstreamer-video-sys", "gstreamer-video-sys",
"itertools", "itertools",
"libc", "libc",
"once_cell",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",
@ -1747,17 +1754,6 @@ dependencies = [
"jni-sys", "jni-sys",
] ]
[[package]]
name = "nix"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
"libc",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.45" version = "0.1.45"
@ -2526,11 +2522,11 @@ dependencies = [
[[package]] [[package]]
name = "wayland-cursor" name = "wayland-cursor"
version = "0.31.0" version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44aa20ae986659d6c77d64d808a046996a932aa763913864dc40c359ef7ad5b" checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba"
dependencies = [ dependencies = [
"nix", "rustix",
"wayland-client", "wayland-client",
"xcursor", "xcursor",
] ]

View file

@ -42,6 +42,7 @@ uds = { version = "0.4", optional = true }
winit = { version = "0.29", optional = true, default-features = false, features = ["rwh_05"] } winit = { version = "0.29", optional = true, default-features = false, features = ["rwh_05"] }
atomic_refcell = "0.1" atomic_refcell = "0.1"
data-encoding = "2.0" data-encoding = "2.0"
once_cell = "1"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
windows = { version = "0.52", features=["Win32_Graphics_Direct3D11", windows = { version = "0.52", features=["Win32_Graphics_Direct3D11",

View file

@ -10,7 +10,6 @@ mod examples_common;
// Our custom compositor element is defined in this module. // Our custom compositor element is defined in this module.
mod cairo_compositor { mod cairo_compositor {
use glib::once_cell::sync::Lazy;
use gst_base::subclass::prelude::*; use gst_base::subclass::prelude::*;
use gst_video::{prelude::*, subclass::prelude::*}; use gst_video::{prelude::*, subclass::prelude::*};
@ -57,15 +56,16 @@ mod cairo_compositor {
// In this case a single property for configuring the background color of the // In this case a single property for configuring the background color of the
// composition. // composition.
fn properties() -> &'static [glib::ParamSpec] { fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { static PROPERTIES: std::sync::OnceLock<Vec<glib::ParamSpec>> =
std::sync::OnceLock::new();
PROPERTIES.get_or_init(|| {
vec![glib::ParamSpecUInt::builder("background-color") vec![glib::ParamSpecUInt::builder("background-color")
.nick("Background Color") .nick("Background Color")
.blurb("Background color as 0xRRGGBB") .blurb("Background color as 0xRRGGBB")
.default_value(Settings::default().background_color) .default_value(Settings::default().background_color)
.build()] .build()]
}); })
&PROPERTIES
} }
// Called by the application whenever the value of a property should be changed. // Called by the application whenever the value of a property should be changed.
@ -100,20 +100,24 @@ mod cairo_compositor {
// gst-inspect-1.0 and can also be programmatically retrieved from the gst::Registry // gst-inspect-1.0 and can also be programmatically retrieved from the gst::Registry
// after initial registration without having to load the plugin in memory. // after initial registration without having to load the plugin in memory.
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> { fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| { static ELEMENT_METADATA: std::sync::OnceLock<gst::subclass::ElementMetadata> =
std::sync::OnceLock::new();
Some(ELEMENT_METADATA.get_or_init(|| {
gst::subclass::ElementMetadata::new( gst::subclass::ElementMetadata::new(
"Cairo Compositor", "Cairo Compositor",
"Compositor/Video", "Compositor/Video",
"Cairo based compositor", "Cairo based compositor",
"Sebastian Dröge <sebastian@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>",
) )
}); }))
Some(&*ELEMENT_METADATA)
} }
fn pad_templates() -> &'static [gst::PadTemplate] { fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| { static PAD_TEMPLATES: std::sync::OnceLock<Vec<gst::PadTemplate>> =
std::sync::OnceLock::new();
PAD_TEMPLATES.get_or_init(|| {
// Create pad templates for our sink and source pad. These are later used for // Create pad templates for our sink and source pad. These are later used for
// actually creating the pads and beforehand already provide information to // actually creating the pads and beforehand already provide information to
// GStreamer about all possible pads that could exist for this type. // GStreamer about all possible pads that could exist for this type.
@ -148,9 +152,7 @@ mod cairo_compositor {
) )
.unwrap(), .unwrap(),
] ]
}); })
PAD_TEMPLATES.as_ref()
} }
// Notify via the child proxy interface whenever a new pad is added or removed. // Notify via the child proxy interface whenever a new pad is added or removed.
@ -457,7 +459,10 @@ mod cairo_compositor {
// In this case there are various properties for defining the position and otherwise // In this case there are various properties for defining the position and otherwise
// the appearance of the stream corresponding to this pad. // the appearance of the stream corresponding to this pad.
fn properties() -> &'static [glib::ParamSpec] { fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { static PROPERTIES: std::sync::OnceLock<Vec<glib::ParamSpec>> =
std::sync::OnceLock::new();
PROPERTIES.get_or_init(|| {
vec![ vec![
glib::ParamSpecDouble::builder("alpha") glib::ParamSpecDouble::builder("alpha")
.nick("Alpha") .nick("Alpha")
@ -495,9 +500,7 @@ mod cairo_compositor {
.default_value(Settings::default().ypos) .default_value(Settings::default().ypos)
.build(), .build(),
] ]
}); })
PROPERTIES.as_ref()
} }
// Called by the application whenever the value of a property should be changed. // Called by the application whenever the value of a property should be changed.

View file

@ -71,7 +71,6 @@ mod custom_meta {
mod imp { mod imp {
use std::{mem, ptr}; use std::{mem, ptr};
use glib::once_cell::sync::Lazy;
use glib::translate::*; use glib::translate::*;
pub(super) struct CustomMetaParams { pub(super) struct CustomMetaParams {
@ -87,8 +86,10 @@ mod custom_meta {
// Function to register the meta API and get a type back. // Function to register the meta API and get a type back.
pub(super) fn custom_meta_api_get_type() -> glib::Type { pub(super) fn custom_meta_api_get_type() -> glib::Type {
static TYPE: Lazy<glib::Type> = Lazy::new(|| unsafe { static TYPE: std::sync::OnceLock<glib::Type> = std::sync::OnceLock::new();
let t = from_glib(gst::ffi::gst_meta_api_type_register(
*TYPE.get_or_init(|| unsafe {
let t = glib::Type::from_glib(gst::ffi::gst_meta_api_type_register(
b"MyCustomMetaAPI\0".as_ptr() as *const _, b"MyCustomMetaAPI\0".as_ptr() as *const _,
// We provide no tags here as our meta is just a label and does // We provide no tags here as our meta is just a label and does
// not refer to any specific aspect of the buffer. // not refer to any specific aspect of the buffer.
@ -98,9 +99,7 @@ mod custom_meta {
assert_ne!(t, glib::Type::INVALID); assert_ne!(t, glib::Type::INVALID);
t t
}); })
*TYPE
} }
// Initialization function for our meta. This needs to ensure all fields are correctly // Initialization function for our meta. This needs to ensure all fields are correctly
@ -157,21 +156,24 @@ mod custom_meta {
unsafe impl Send for MetaInfo {} unsafe impl Send for MetaInfo {}
unsafe impl Sync for MetaInfo {} unsafe impl Sync for MetaInfo {}
static META_INFO: Lazy<MetaInfo> = Lazy::new(|| unsafe { static META_INFO: std::sync::OnceLock<MetaInfo> = std::sync::OnceLock::new();
MetaInfo(
ptr::NonNull::new(gst::ffi::gst_meta_register(
custom_meta_api_get_type().into_glib(),
b"MyCustomMeta\0".as_ptr() as *const _,
mem::size_of::<CustomMeta>(),
Some(custom_meta_init),
Some(custom_meta_free),
Some(custom_meta_transform),
) as *mut gst::ffi::GstMetaInfo)
.expect("Failed to register meta API"),
)
});
META_INFO.0.as_ptr() META_INFO
.get_or_init(|| unsafe {
MetaInfo(
ptr::NonNull::new(gst::ffi::gst_meta_register(
custom_meta_api_get_type().into_glib(),
b"MyCustomMeta\0".as_ptr() as *const _,
mem::size_of::<CustomMeta>(),
Some(custom_meta_init),
Some(custom_meta_free),
Some(custom_meta_transform),
) as *mut gst::ffi::GstMetaInfo)
.expect("Failed to register meta API"),
)
})
.0
.as_ptr()
} }
} }
} }

View file

@ -361,11 +361,11 @@ mod video_filter {
use std::{mem::ManuallyDrop, os::unix::prelude::FromRawFd}; use std::{mem::ManuallyDrop, os::unix::prelude::FromRawFd};
use anyhow::Error; use anyhow::Error;
use glib::once_cell::sync::Lazy;
use gst::{subclass::prelude::*, PadDirection, PadPresence, PadTemplate}; use gst::{subclass::prelude::*, PadDirection, PadPresence, PadTemplate};
use gst_app::gst_base::subclass::BaseTransformMode; use gst_app::gst_base::subclass::BaseTransformMode;
use gst_video::{prelude::*, subclass::prelude::*, VideoFrameRef}; use gst_video::{prelude::*, subclass::prelude::*, VideoFrameRef};
use memmap2::MmapMut; use memmap2::MmapMut;
use once_cell::sync::Lazy;
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new( gst::DebugCategory::new(
@ -430,7 +430,10 @@ mod video_filter {
impl ElementImpl for FdMemoryFadeInVideoFilter { impl ElementImpl for FdMemoryFadeInVideoFilter {
fn pad_templates() -> &'static [PadTemplate] { fn pad_templates() -> &'static [PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<PadTemplate>> = Lazy::new(|| { static PAD_TEMPLATES: std::sync::OnceLock<Vec<PadTemplate>> =
std::sync::OnceLock::new();
PAD_TEMPLATES.get_or_init(|| {
let caps = gst_video::VideoCapsBuilder::new() let caps = gst_video::VideoCapsBuilder::new()
.format(gst_video::VideoFormat::Bgra) .format(gst_video::VideoFormat::Bgra)
.build(); .build();
@ -440,9 +443,7 @@ mod video_filter {
PadTemplate::new("src", PadDirection::Src, PadPresence::Always, &caps) PadTemplate::new("src", PadDirection::Src, PadPresence::Always, &caps)
.unwrap(), .unwrap(),
] ]
}); })
PAD_TEMPLATES.as_ref()
} }
} }

View file

@ -32,13 +32,13 @@ void main () {
mod mirror { mod mirror {
use std::sync::Mutex; use std::sync::Mutex;
use glib::once_cell::sync::Lazy;
use gst_base::subclass::BaseTransformMode; use gst_base::subclass::BaseTransformMode;
use gst_gl::{ use gst_gl::{
prelude::*, prelude::*,
subclass::{prelude::*, GLFilterMode}, subclass::{prelude::*, GLFilterMode},
*, *,
}; };
use once_cell::sync::Lazy;
use super::{gl, FRAGMENT_SHADER}; use super::{gl, FRAGMENT_SHADER};

View file

@ -17,8 +17,8 @@ mod examples_common;
// Our custom FIR filter element is defined in this module // Our custom FIR filter element is defined in this module
mod fir_filter { mod fir_filter {
use byte_slice_cast::*; use byte_slice_cast::*;
use glib::once_cell::sync::Lazy;
use gst_base::subclass::prelude::*; use gst_base::subclass::prelude::*;
use once_cell::sync::Lazy;
// The debug category we use below for our filter // The debug category we use below for our filter
pub static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| { pub static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
@ -63,20 +63,24 @@ mod fir_filter {
// gst-inspect-1.0 and can also be programmatically retrieved from the gst::Registry // gst-inspect-1.0 and can also be programmatically retrieved from the gst::Registry
// after initial registration without having to load the plugin in memory. // after initial registration without having to load the plugin in memory.
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> { fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| { static ELEMENT_METADATA: std::sync::OnceLock<gst::subclass::ElementMetadata> =
std::sync::OnceLock::new();
Some(ELEMENT_METADATA.get_or_init(|| {
gst::subclass::ElementMetadata::new( gst::subclass::ElementMetadata::new(
"FIR Filter", "FIR Filter",
"Filter/Effect/Audio", "Filter/Effect/Audio",
"A FIR audio filter", "A FIR audio filter",
"Sebastian Dröge <sebastian@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>",
) )
}); }))
Some(&*ELEMENT_METADATA)
} }
fn pad_templates() -> &'static [gst::PadTemplate] { fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| { static PAD_TEMPLATES: std::sync::OnceLock<Vec<gst::PadTemplate>> =
std::sync::OnceLock::new();
PAD_TEMPLATES.get_or_init(|| {
// Create pad templates for our sink and source pad. These are later used for // Create pad templates for our sink and source pad. These are later used for
// actually creating the pads and beforehand already provide information to // actually creating the pads and beforehand already provide information to
// GStreamer about all possible pads that could exist for this type. // GStreamer about all possible pads that could exist for this type.
@ -107,9 +111,7 @@ mod fir_filter {
) )
.unwrap(), .unwrap(),
] ]
}); })
PAD_TEMPLATES.as_ref()
} }
} }

View file

@ -2,8 +2,9 @@
use std::{collections::VecDeque, sync::Mutex}; use std::{collections::VecDeque, sync::Mutex};
use glib::{once_cell::sync::Lazy, prelude::*}; use glib::prelude::*;
use gst_audio::subclass::prelude::*; use gst_audio::subclass::prelude::*;
use once_cell::sync::Lazy;
use byte_slice_cast::*; use byte_slice_cast::*;
@ -152,15 +153,14 @@ impl BaseTransformImpl for IirFilter {
impl AudioFilterImpl for IirFilter { impl AudioFilterImpl for IirFilter {
fn allowed_caps() -> &'static gst::Caps { fn allowed_caps() -> &'static gst::Caps {
static CAPS: Lazy<gst::Caps> = Lazy::new(|| { static CAPS: std::sync::OnceLock<gst::Caps> = std::sync::OnceLock::new();
CAPS.get_or_init(|| {
// On both of pads we can only handle F32 mono at any sample rate. // On both of pads we can only handle F32 mono at any sample rate.
gst_audio::AudioCapsBuilder::new_interleaved() gst_audio::AudioCapsBuilder::new_interleaved()
.format(gst_audio::AUDIO_FORMAT_F32) .format(gst_audio::AUDIO_FORMAT_F32)
.channels(1) .channels(1)
.build() .build()
}); })
&CAPS
} }
fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> { fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {

View file

@ -2,7 +2,7 @@
use std::sync::Mutex; use std::sync::Mutex;
use glib::{once_cell::sync::Lazy, prelude::*}; use glib::prelude::*;
use gst::prelude::*; use gst::prelude::*;
use gst_audio::subclass::prelude::*; use gst_audio::subclass::prelude::*;
@ -45,7 +45,9 @@ impl ObjectSubclass for Lowpass {
// Implementation of glib::Object virtual methods // Implementation of glib::Object virtual methods
impl ObjectImpl for Lowpass { impl ObjectImpl for Lowpass {
fn properties() -> &'static [glib::ParamSpec] { fn properties() -> &'static [glib::ParamSpec] {
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| { static PROPERTIES: std::sync::OnceLock<Vec<glib::ParamSpec>> = std::sync::OnceLock::new();
PROPERTIES.get_or_init(|| {
vec![glib::ParamSpecFloat::builder("cutoff") vec![glib::ParamSpecFloat::builder("cutoff")
.nick("Cutoff") .nick("Cutoff")
.blurb("Cutoff frequency in Hz") .blurb("Cutoff frequency in Hz")
@ -53,9 +55,7 @@ impl ObjectImpl for Lowpass {
.minimum(0.0) .minimum(0.0)
.mutable_playing() .mutable_playing()
.build()] .build()]
}); })
PROPERTIES.as_ref()
} }
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
@ -84,16 +84,16 @@ impl ElementImpl for Lowpass {
// gst-inspect-1.0 and can also be programmatically retrieved from the gst::Registry // gst-inspect-1.0 and can also be programmatically retrieved from the gst::Registry
// after initial registration without having to load the plugin in memory. // after initial registration without having to load the plugin in memory.
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> { fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| { static ELEMENT_METADATA: std::sync::OnceLock<gst::subclass::ElementMetadata> =
std::sync::OnceLock::new();
Some(ELEMENT_METADATA.get_or_init(|| {
gst::subclass::ElementMetadata::new( gst::subclass::ElementMetadata::new(
"Lowpass Filter", "Lowpass Filter",
"Filter/Effect/Audio", "Filter/Effect/Audio",
"A Lowpass audio filter", "A Lowpass audio filter",
"Sebastian Dröge <sebastian@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>",
) )
}); }))
Some(&*ELEMENT_METADATA)
} }
} }

View file

@ -18,6 +18,7 @@ libc = "0.2"
ffi = { package = "gstreamer-allocators-sys", path = "sys" } ffi = { package = "gstreamer-allocators-sys", path = "sys" }
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" } glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
gst = { package = "gstreamer", path = "../gstreamer" } gst = { package = "gstreamer", path = "../gstreamer" }
once_cell = "1"
[dev-dependencies] [dev-dependencies]
gir-format-check = "0.1" gir-format-check = "0.1"

View file

@ -1,7 +1,7 @@
// Take a look at the license at the top of the repository in the LICENSE file. // Take a look at the license at the top of the repository in the LICENSE file.
use glib::once_cell::sync::Lazy;
use gst::CapsFeatures; use gst::CapsFeatures;
use once_cell::sync::Lazy;
pub static CAPS_FEATURES_MEMORY_DMABUF: Lazy<CapsFeatures> = pub static CAPS_FEATURES_MEMORY_DMABUF: Lazy<CapsFeatures> =
Lazy::new(|| CapsFeatures::new([crate::CAPS_FEATURE_MEMORY_DMABUF])); Lazy::new(|| CapsFeatures::new([crate::CAPS_FEATURE_MEMORY_DMABUF]));

View file

@ -350,23 +350,23 @@ impl AppSink {
#[doc(alias = "gst_app_sink_set_callbacks")] #[doc(alias = "gst_app_sink_set_callbacks")]
pub fn set_callbacks(&self, callbacks: AppSinkCallbacks) { pub fn set_callbacks(&self, callbacks: AppSinkCallbacks) {
#[cfg(not(feature = "v1_18"))]
use glib::once_cell::sync::Lazy;
#[cfg(not(feature = "v1_18"))]
static SET_ONCE_QUARK: Lazy<glib::Quark> =
Lazy::new(|| glib::Quark::from_str("gstreamer-rs-app-sink-callbacks"));
unsafe { unsafe {
let sink = self.to_glib_none().0; let sink = self.to_glib_none().0;
#[cfg(not(feature = "v1_18"))] #[cfg(not(feature = "v1_18"))]
{ {
static SET_ONCE_QUARK: std::sync::OnceLock<glib::Quark> =
std::sync::OnceLock::new();
let set_once_quark = SET_ONCE_QUARK
.get_or_init(|| glib::Quark::from_str("gstreamer-rs-app-sink-callbacks"));
// This is not thread-safe before 1.16.3, see // This is not thread-safe before 1.16.3, see
// https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/merge_requests/570 // https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/merge_requests/570
if gst::version() < (1, 16, 3, 0) { if gst::version() < (1, 16, 3, 0) {
if !glib::gobject_ffi::g_object_get_qdata( if !glib::gobject_ffi::g_object_get_qdata(
sink as *mut _, sink as *mut _,
SET_ONCE_QUARK.into_glib(), set_once_quark.into_glib(),
) )
.is_null() .is_null()
{ {
@ -375,7 +375,7 @@ impl AppSink {
glib::gobject_ffi::g_object_set_qdata( glib::gobject_ffi::g_object_set_qdata(
sink as *mut _, sink as *mut _,
SET_ONCE_QUARK.into_glib(), set_once_quark.into_glib(),
1 as *mut _, 1 as *mut _,
); );
} }

View file

@ -223,22 +223,22 @@ impl AppSrc {
#[doc(alias = "gst_app_src_set_callbacks")] #[doc(alias = "gst_app_src_set_callbacks")]
pub fn set_callbacks(&self, callbacks: AppSrcCallbacks) { pub fn set_callbacks(&self, callbacks: AppSrcCallbacks) {
#[cfg(not(feature = "v1_18"))]
use glib::once_cell::sync::Lazy;
#[cfg(not(feature = "v1_18"))]
static SET_ONCE_QUARK: Lazy<glib::Quark> =
Lazy::new(|| glib::Quark::from_str("gstreamer-rs-app-src-callbacks"));
unsafe { unsafe {
let src = self.to_glib_none().0; let src = self.to_glib_none().0;
#[cfg(not(feature = "v1_18"))] #[cfg(not(feature = "v1_18"))]
{ {
static SET_ONCE_QUARK: std::sync::OnceLock<glib::Quark> =
std::sync::OnceLock::new();
let set_once_quark = SET_ONCE_QUARK
.get_or_init(|| glib::Quark::from_str("gstreamer-rs-app-src-callbacks"));
// This is not thread-safe before 1.16.3, see // This is not thread-safe before 1.16.3, see
// https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/merge_requests/570 // https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/merge_requests/570
if gst::version() < (1, 16, 3, 0) { if gst::version() < (1, 16, 3, 0) {
if !glib::gobject_ffi::g_object_get_qdata( if !glib::gobject_ffi::g_object_get_qdata(
src as *mut _, src as *mut _,
SET_ONCE_QUARK.into_glib(), set_once_quark.into_glib(),
) )
.is_null() .is_null()
{ {
@ -247,7 +247,7 @@ impl AppSrc {
glib::gobject_ffi::g_object_set_qdata( glib::gobject_ffi::g_object_set_qdata(
src as *mut _, src as *mut _,
SET_ONCE_QUARK.into_glib(), set_once_quark.into_glib(),
1 as *mut _, 1 as *mut _,
); );
} }

View file

@ -22,6 +22,7 @@ gst = { package = "gstreamer", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" } gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
serde = { version = "1.0", optional = true } serde = { version = "1.0", optional = true }
smallvec = "1.0" smallvec = "1.0"
once_cell = "1"
[dev-dependencies] [dev-dependencies]
itertools = "0.12" itertools = "0.12"

View file

@ -2,8 +2,8 @@
use std::str; use std::str;
use glib::once_cell::sync::Lazy;
use glib::translate::{from_glib, IntoGlib}; use glib::translate::{from_glib, IntoGlib};
use once_cell::sync::Lazy;
#[cfg(feature = "v1_18")] #[cfg(feature = "v1_18")]
pub static AUDIO_FORMATS_ALL: Lazy<Box<[crate::AudioFormat]>> = Lazy::new(|| unsafe { pub static AUDIO_FORMATS_ALL: Lazy<Box<[crate::AudioFormat]>> = Lazy::new(|| unsafe {

View file

@ -1,6 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file. // Take a look at the license at the top of the repository in the LICENSE file.
use glib::{once_cell::sync::Lazy, translate::*}; use glib::translate::*;
use gst_base::{prelude::*, subclass::prelude::*}; use gst_base::{prelude::*, subclass::prelude::*};
use crate::{AudioFilter, AudioInfo}; use crate::{AudioFilter, AudioInfo};
@ -52,10 +52,9 @@ pub trait AudioFilterImplExt: sealed::Sealed + ObjectSubclass {
); );
if templ.is_null() { if templ.is_null() {
static ANY_AUDIO_CAPS: Lazy<gst::Caps> = static ANY_AUDIO_CAPS: std::sync::OnceLock<gst::Caps> = std::sync::OnceLock::new();
Lazy::new(|| crate::AudioCapsBuilder::new().build());
return &ANY_AUDIO_CAPS; return ANY_AUDIO_CAPS.get_or_init(|| crate::AudioCapsBuilder::new().build());
} }
&*(&(*templ).caps as *const *mut gst::ffi::GstCaps as *const gst::Caps) &*(&(*templ).caps as *const *mut gst::ffi::GstCaps as *const gst::Caps)

View file

@ -1310,22 +1310,24 @@ mod tests {
impl ElementImpl for TestTransform { impl ElementImpl for TestTransform {
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> { fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
use glib::once_cell::sync::Lazy; static ELEMENT_METADATA: std::sync::OnceLock<gst::subclass::ElementMetadata> =
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| { std::sync::OnceLock::new();
Some(ELEMENT_METADATA.get_or_init(|| {
gst::subclass::ElementMetadata::new( gst::subclass::ElementMetadata::new(
"Test Transform", "Test Transform",
"Generic", "Generic",
"Does nothing", "Does nothing",
"Sebastian Dröge <sebastian@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>",
) )
}); }))
Some(&*ELEMENT_METADATA)
} }
fn pad_templates() -> &'static [gst::PadTemplate] { fn pad_templates() -> &'static [gst::PadTemplate] {
use glib::once_cell::sync::Lazy; static PAD_TEMPLATES: std::sync::OnceLock<Vec<gst::PadTemplate>> =
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| { std::sync::OnceLock::new();
PAD_TEMPLATES.get_or_init(|| {
let caps = gst::Caps::new_any(); let caps = gst::Caps::new_any();
vec![ vec![
gst::PadTemplate::new( gst::PadTemplate::new(
@ -1343,9 +1345,7 @@ mod tests {
) )
.unwrap(), .unwrap(),
] ]
}); })
PAD_TEMPLATES.as_ref()
} }
} }

View file

@ -24,6 +24,7 @@ gst = { package = "gstreamer", path = "../gstreamer" }
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" } gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" } gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
serde = { version = "1.0", optional = true } serde = { version = "1.0", optional = true }
once_cell = "1"
[dev-dependencies] [dev-dependencies]
gir-format-check = "0.1" gir-format-check = "0.1"

View file

@ -1,7 +1,7 @@
// Take a look at the license at the top of the repository in the LICENSE file. // Take a look at the license at the top of the repository in the LICENSE file.
use glib::once_cell::sync::Lazy;
use gst::CapsFeatures; use gst::CapsFeatures;
use once_cell::sync::Lazy;
pub static CAPS_FEATURES_MEMORY_GL_MEMORY: Lazy<CapsFeatures> = pub static CAPS_FEATURES_MEMORY_GL_MEMORY: Lazy<CapsFeatures> =
Lazy::new(|| CapsFeatures::new([crate::CAPS_FEATURE_MEMORY_GL_MEMORY])); Lazy::new(|| CapsFeatures::new([crate::CAPS_FEATURE_MEMORY_GL_MEMORY]));

View file

@ -49,9 +49,10 @@ unsafe extern "C" fn video_renderer_create_video_sink<T: PlayVideoRendererImpl>(
video_renderer: *mut ffi::GstPlayVideoRenderer, video_renderer: *mut ffi::GstPlayVideoRenderer,
play: *mut ffi::GstPlay, play: *mut ffi::GstPlay,
) -> *mut gst::ffi::GstElement { ) -> *mut gst::ffi::GstElement {
use glib::once_cell::sync::Lazy; static VIDEO_SINK_QUARK: std::sync::OnceLock<glib::Quark> = std::sync::OnceLock::new();
static VIDEO_SINK_QUARK: Lazy<glib::Quark> =
Lazy::new(|| glib::Quark::from_str("gstreamer-rs-play-video-sink")); let video_sink_quark =
VIDEO_SINK_QUARK.get_or_init(|| glib::Quark::from_str("gstreamer-rs-play-video-sink"));
let instance = &*(video_renderer as *mut T::Instance); let instance = &*(video_renderer as *mut T::Instance);
let imp = instance.imp(); let imp = instance.imp();
@ -62,7 +63,7 @@ unsafe extern "C" fn video_renderer_create_video_sink<T: PlayVideoRendererImpl>(
let old_sink_ptr = glib::gobject_ffi::g_object_get_qdata( let old_sink_ptr = glib::gobject_ffi::g_object_get_qdata(
video_renderer as *mut _, video_renderer as *mut _,
VIDEO_SINK_QUARK.into_glib(), video_sink_quark.into_glib(),
) as *mut gst::ffi::GstElement; ) as *mut gst::ffi::GstElement;
if !old_sink_ptr.is_null() && old_sink_ptr != sink_ptr { if !old_sink_ptr.is_null() && old_sink_ptr != sink_ptr {
panic!("Video sink must not change"); panic!("Video sink must not change");
@ -74,7 +75,7 @@ unsafe extern "C" fn video_renderer_create_video_sink<T: PlayVideoRendererImpl>(
glib::gobject_ffi::g_object_set_qdata_full( glib::gobject_ffi::g_object_set_qdata_full(
video_renderer as *mut _, video_renderer as *mut _,
VIDEO_SINK_QUARK.into_glib(), video_sink_quark.into_glib(),
glib::gobject_ffi::g_object_ref(sink_ptr as *mut _) as *mut _, glib::gobject_ffi::g_object_ref(sink_ptr as *mut _) as *mut _,
Some(unref), Some(unref),
); );

View file

@ -49,9 +49,10 @@ unsafe extern "C" fn video_renderer_create_video_sink<T: PlayerVideoRendererImpl
video_renderer: *mut ffi::GstPlayerVideoRenderer, video_renderer: *mut ffi::GstPlayerVideoRenderer,
player: *mut ffi::GstPlayer, player: *mut ffi::GstPlayer,
) -> *mut gst::ffi::GstElement { ) -> *mut gst::ffi::GstElement {
use glib::once_cell::sync::Lazy; static VIDEO_SINK_QUARK: std::sync::OnceLock<glib::Quark> = std::sync::OnceLock::new();
static VIDEO_SINK_QUARK: Lazy<glib::Quark> =
Lazy::new(|| glib::Quark::from_str("gstreamer-rs-player-video-sink")); let video_sink_quark =
VIDEO_SINK_QUARK.get_or_init(|| glib::Quark::from_str("gstreamer-rs-player-video-sink"));
let instance = &*(video_renderer as *mut T::Instance); let instance = &*(video_renderer as *mut T::Instance);
let imp = instance.imp(); let imp = instance.imp();
@ -62,7 +63,7 @@ unsafe extern "C" fn video_renderer_create_video_sink<T: PlayerVideoRendererImpl
let old_sink_ptr = glib::gobject_ffi::g_object_get_qdata( let old_sink_ptr = glib::gobject_ffi::g_object_get_qdata(
video_renderer as *mut _, video_renderer as *mut _,
VIDEO_SINK_QUARK.into_glib(), video_sink_quark.into_glib(),
) as *mut gst::ffi::GstElement; ) as *mut gst::ffi::GstElement;
if !old_sink_ptr.is_null() && old_sink_ptr != sink_ptr { if !old_sink_ptr.is_null() && old_sink_ptr != sink_ptr {
panic!("Video sink must not change"); panic!("Video sink must not change");
@ -74,7 +75,7 @@ unsafe extern "C" fn video_renderer_create_video_sink<T: PlayerVideoRendererImpl
glib::gobject_ffi::g_object_set_qdata_full( glib::gobject_ffi::g_object_set_qdata_full(
video_renderer as *mut _, video_renderer as *mut _,
VIDEO_SINK_QUARK.into_glib(), video_sink_quark.into_glib(),
glib::gobject_ffi::g_object_ref(sink_ptr as *mut _) as *mut _, glib::gobject_ffi::g_object_ref(sink_ptr as *mut _) as *mut _,
Some(unref), Some(unref),
); );

View file

@ -224,10 +224,10 @@ unsafe extern "C" fn factory_create_pipeline<T: RTSPMediaFactoryImpl>(
ptr: *mut ffi::GstRTSPMediaFactory, ptr: *mut ffi::GstRTSPMediaFactory,
media: *mut ffi::GstRTSPMedia, media: *mut ffi::GstRTSPMedia,
) -> *mut gst::ffi::GstElement { ) -> *mut gst::ffi::GstElement {
use glib::once_cell::sync::Lazy; static PIPELINE_QUARK: std::sync::OnceLock<glib::Quark> = std::sync::OnceLock::new();
static PIPELINE_QUARK: Lazy<glib::Quark> = let pipeline_quark =
Lazy::new(|| glib::Quark::from_str("gstreamer-rs-rtsp-media-pipeline")); PIPELINE_QUARK.get_or_init(|| glib::Quark::from_str("gstreamer-rs-rtsp-media-pipeline"));
let instance = &*(ptr as *mut T::Instance); let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp(); let imp = instance.imp();
@ -239,7 +239,7 @@ unsafe extern "C" fn factory_create_pipeline<T: RTSPMediaFactoryImpl>(
// FIXME We somehow need to ensure the pipeline actually stays alive... // FIXME We somehow need to ensure the pipeline actually stays alive...
glib::gobject_ffi::g_object_set_qdata_full( glib::gobject_ffi::g_object_set_qdata_full(
media as *mut _, media as *mut _,
PIPELINE_QUARK.into_glib(), pipeline_quark.into_glib(),
pipeline as *mut _, pipeline as *mut _,
Some(transmute::<_, unsafe extern "C" fn(glib::ffi::gpointer)>( Some(transmute::<_, unsafe extern "C" fn(glib::ffi::gpointer)>(
glib::gobject_ffi::g_object_unref as *const (), glib::gobject_ffi::g_object_unref as *const (),

View file

@ -19,6 +19,7 @@ rust-version = "1.70"
gst = { package = "gstreamer", path = "../gstreamer", features = ["v1_20"] } gst = { package = "gstreamer", path = "../gstreamer", features = ["v1_20"] }
gst_app = { package = "gstreamer-app", path = "../gstreamer-app", features = ["v1_20"] } gst_app = { package = "gstreamer-app", path = "../gstreamer-app", features = ["v1_20"] }
gst_video = { package = "gstreamer-video", path = "../gstreamer-video", features = ["v1_20"] } gst_video = { package = "gstreamer-video", path = "../gstreamer-video", features = ["v1_20"] }
once_cell = "1"
thiserror = "1" thiserror = "1"
[dev-dependencies] [dev-dependencies]

View file

@ -4,8 +4,8 @@ use std::{
sync::{atomic, Arc, Mutex, MutexGuard}, sync::{atomic, Arc, Mutex, MutexGuard},
}; };
use glib::once_cell::sync::Lazy;
use gst::{glib, prelude::*}; use gst::{glib, prelude::*};
use once_cell::sync::Lazy;
use thiserror::Error; use thiserror::Error;
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {

View file

@ -1,11 +1,7 @@
use std::{ffi::c_int, ptr}; use std::{ffi::c_int, ptr};
use glib::once_cell::sync::Lazy;
use glib::translate::*; use glib::translate::*;
static QUARK_ACTION_TYPE_FUNC: Lazy<glib::Quark> =
Lazy::new(|| glib::Quark::from_str("rs-action-type-function"));
#[derive(Debug)] #[derive(Debug)]
#[repr(transparent)] #[repr(transparent)]
#[doc(alias = "GstValidateActionParameter")] #[doc(alias = "GstValidateActionParameter")]
@ -193,6 +189,12 @@ impl<'a> ActionTypeBuilder<'a> {
} }
pub fn build(self) -> crate::ActionType { pub fn build(self) -> crate::ActionType {
static QUARK_ACTION_TYPE_FUNC: std::sync::OnceLock<glib::Quark> =
std::sync::OnceLock::new();
let quark_action_type_func =
QUARK_ACTION_TYPE_FUNC.get_or_init(|| glib::Quark::from_str("rs-action-type-function"));
unsafe extern "C" fn execute_func_trampoline( unsafe extern "C" fn execute_func_trampoline(
scenario: *mut ffi::GstValidateScenario, scenario: *mut ffi::GstValidateScenario,
action: *mut ffi::GstValidateAction, action: *mut ffi::GstValidateAction,
@ -203,7 +205,7 @@ impl<'a> ActionTypeBuilder<'a> {
let func: &ActionFunction = &*(gst::ffi::gst_mini_object_get_qdata( let func: &ActionFunction = &*(gst::ffi::gst_mini_object_get_qdata(
action_type as *mut gst::ffi::GstMiniObject, action_type as *mut gst::ffi::GstMiniObject,
QUARK_ACTION_TYPE_FUNC.into_glib(), QUARK_ACTION_TYPE_FUNC.get().unwrap().into_glib(),
) as *const Box<ActionFunction>); ) as *const Box<ActionFunction>);
(*func)(&scenario, action).into_glib() (*func)(&scenario, action).into_glib()
@ -232,7 +234,7 @@ impl<'a> ActionTypeBuilder<'a> {
gst::ffi::gst_mini_object_set_qdata( gst::ffi::gst_mini_object_set_qdata(
action_type as *mut gst::ffi::GstMiniObject, action_type as *mut gst::ffi::GstMiniObject,
QUARK_ACTION_TYPE_FUNC.into_glib(), quark_action_type_func.into_glib(),
Box::into_raw(Box::new(f)) as *mut _, Box::into_raw(Box::new(f)) as *mut _,
Some(destroy_notify), Some(destroy_notify),
); );

View file

@ -23,6 +23,7 @@ gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
futures-channel = "0.3" futures-channel = "0.3"
serde = { version = "1.0", optional = true, features = ["derive"] } serde = { version = "1.0", optional = true, features = ["derive"] }
thiserror = "1.0.49" thiserror = "1.0.49"
once_cell = "1"
[dev-dependencies] [dev-dependencies]
itertools = "0.12" itertools = "0.12"

View file

@ -1,7 +1,7 @@
// Take a look at the license at the top of the repository in the LICENSE file. // Take a look at the license at the top of the repository in the LICENSE file.
use glib::once_cell::sync::Lazy;
use gst::CapsFeatures; use gst::CapsFeatures;
use once_cell::sync::Lazy;
#[cfg(feature = "v1_16")] #[cfg(feature = "v1_16")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))] #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]

View file

@ -2,8 +2,8 @@
use std::str; use std::str;
use glib::once_cell::sync::Lazy;
use glib::translate::{from_glib, FromGlib, IntoGlib}; use glib::translate::{from_glib, FromGlib, IntoGlib};
use once_cell::sync::Lazy;
#[cfg(feature = "v1_18")] #[cfg(feature = "v1_18")]
pub static VIDEO_FORMATS_ALL: Lazy<Box<[crate::VideoFormat]>> = Lazy::new(|| unsafe { pub static VIDEO_FORMATS_ALL: Lazy<Box<[crate::VideoFormat]>> = Lazy::new(|| unsafe {

View file

@ -32,6 +32,7 @@ thiserror = "1"
smallvec = { version = "1.0", features = ["write"] } smallvec = { version = "1.0", features = ["write"] }
itertools = "0.12" itertools = "0.12"
pin-project-lite = "0.2" pin-project-lite = "0.2"
once_cell = "1"
[dev-dependencies] [dev-dependencies]
ron = "0.8" ron = "0.8"

View file

@ -192,23 +192,23 @@ impl Bus {
where where
F: Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static, F: Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static,
{ {
#[cfg(not(feature = "v1_18"))]
use glib::once_cell::sync::Lazy;
#[cfg(not(feature = "v1_18"))]
static SET_ONCE_QUARK: Lazy<glib::Quark> =
Lazy::new(|| glib::Quark::from_str("gstreamer-rs-sync-handler"));
unsafe { unsafe {
let bus = self.to_glib_none().0; let bus = self.to_glib_none().0;
#[cfg(not(feature = "v1_18"))] #[cfg(not(feature = "v1_18"))]
{ {
static SET_ONCE_QUARK: std::sync::OnceLock<glib::Quark> =
std::sync::OnceLock::new();
let set_once_quark = SET_ONCE_QUARK
.get_or_init(|| glib::Quark::from_str("gstreamer-rs-sync-handler"));
// This is not thread-safe before 1.16.3, see // This is not thread-safe before 1.16.3, see
// https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/merge_requests/416 // https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/merge_requests/416
if crate::version() < (1, 16, 3, 0) { if crate::version() < (1, 16, 3, 0) {
if !glib::gobject_ffi::g_object_get_qdata( if !glib::gobject_ffi::g_object_get_qdata(
bus as *mut _, bus as *mut _,
SET_ONCE_QUARK.into_glib(), set_once_quark.into_glib(),
) )
.is_null() .is_null()
{ {
@ -217,7 +217,7 @@ impl Bus {
glib::gobject_ffi::g_object_set_qdata( glib::gobject_ffi::g_object_set_qdata(
bus as *mut _, bus as *mut _,
SET_ONCE_QUARK.into_glib(), set_once_quark.into_glib(),
1 as *mut _, 1 as *mut _,
); );
} }

View file

@ -9,8 +9,8 @@ use std::{
ptr, str, ptr, str,
}; };
use glib::once_cell::sync::Lazy;
use glib::{translate::*, IntoGStr, StaticType}; use glib::{translate::*, IntoGStr, StaticType};
use once_cell::sync::Lazy;
#[doc(alias = "GstCapsFeatures")] #[doc(alias = "GstCapsFeatures")]
#[repr(transparent)] #[repr(transparent)]

View file

@ -356,12 +356,9 @@ unsafe extern "C" fn filter_boxed_unref(boxed: gpointer) {
} }
unsafe extern "C" fn filter_boxed_get_type() -> glib::Type { unsafe extern "C" fn filter_boxed_get_type() -> glib::Type {
use std::sync::Once; static TYPE: std::sync::OnceLock<glib::Type> = std::sync::OnceLock::new();
static mut TYPE: glib::Type = glib::Type::INVALID; *TYPE.get_or_init(|| {
static ONCE: Once = Once::new();
ONCE.call_once(|| {
let iter_type_name = { let iter_type_name = {
let mut idx = 0; let mut idx = 0;
@ -376,16 +373,16 @@ unsafe extern "C" fn filter_boxed_get_type() -> glib::Type {
} }
}; };
TYPE = from_glib(glib::gobject_ffi::g_boxed_type_register_static( let t = glib::Type::from_glib(glib::gobject_ffi::g_boxed_type_register_static(
iter_type_name.as_ptr(), iter_type_name.as_ptr(),
Some(filter_boxed_ref), Some(filter_boxed_ref),
Some(filter_boxed_unref), Some(filter_boxed_unref),
)); ));
assert!(TYPE.is_valid()); assert!(t.is_valid());
});
TYPE t
})
} }
unsafe extern "C" fn find_trampoline<T, F: FnMut(T) -> bool>( unsafe extern "C" fn find_trampoline<T, F: FnMut(T) -> bool>(

View file

@ -2,9 +2,9 @@
use std::{borrow::Cow, ffi::CStr, fmt, ptr}; use std::{borrow::Cow, ffi::CStr, fmt, ptr};
use glib::once_cell::sync::Lazy;
use glib::{ffi::gpointer, prelude::*, translate::*, IntoGStr, IntoOptionalGStr}; use glib::{ffi::gpointer, prelude::*, translate::*, IntoGStr, IntoOptionalGStr};
use libc::c_char; use libc::c_char;
use once_cell::sync::Lazy;
use crate::DebugLevel; use crate::DebugLevel;

View file

@ -1,6 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file. // Take a look at the license at the top of the repository in the LICENSE file.
use glib::{once_cell::sync::Lazy, translate::*, StaticType}; use glib::{translate::*, StaticType};
use std::{alloc, mem, ptr}; use std::{alloc, mem, ptr};
@ -141,49 +141,55 @@ unsafe extern "C" fn instance_init(
(*allocator).object.flags |= ffi::GST_ALLOCATOR_FLAG_CUSTOM_ALLOC; (*allocator).object.flags |= ffi::GST_ALLOCATOR_FLAG_CUSTOM_ALLOC;
} }
static RUST_ALLOCATOR: Lazy<crate::Allocator> = Lazy::new(|| unsafe { fn rust_allocator() -> &'static crate::Allocator {
struct TypeInfoWrap(glib::gobject_ffi::GTypeInfo); static RUST_ALLOCATOR: std::sync::OnceLock<crate::Allocator> = std::sync::OnceLock::new();
unsafe impl Send for TypeInfoWrap {}
unsafe impl Sync for TypeInfoWrap {}
static TYPE_INFO: TypeInfoWrap = TypeInfoWrap(glib::gobject_ffi::GTypeInfo { RUST_ALLOCATOR.get_or_init(|| unsafe {
class_size: mem::size_of::<ffi::GstAllocatorClass>() as u16, struct TypeInfoWrap(glib::gobject_ffi::GTypeInfo);
base_init: None, unsafe impl Send for TypeInfoWrap {}
base_finalize: None, unsafe impl Sync for TypeInfoWrap {}
class_init: Some(class_init),
class_finalize: None,
class_data: ptr::null_mut(),
instance_size: mem::size_of::<ffi::GstAllocator>() as u16,
n_preallocs: 0,
instance_init: Some(instance_init),
value_table: ptr::null(),
});
let type_name = { static TYPE_INFO: TypeInfoWrap = TypeInfoWrap(glib::gobject_ffi::GTypeInfo {
let mut idx = 0; class_size: mem::size_of::<ffi::GstAllocatorClass>() as u16,
base_init: None,
base_finalize: None,
class_init: Some(class_init),
class_finalize: None,
class_data: ptr::null_mut(),
instance_size: mem::size_of::<ffi::GstAllocator>() as u16,
n_preallocs: 0,
instance_init: Some(instance_init),
value_table: ptr::null(),
});
loop { let type_name = {
let type_name = glib::gformat!("GstRsAllocator-{}", idx); let mut idx = 0;
if glib::gobject_ffi::g_type_from_name(type_name.as_ptr())
== glib::gobject_ffi::G_TYPE_INVALID loop {
{ let type_name = glib::gformat!("GstRsAllocator-{}", idx);
break type_name; if glib::gobject_ffi::g_type_from_name(type_name.as_ptr())
== glib::gobject_ffi::G_TYPE_INVALID
{
break type_name;
}
idx += 1;
} }
idx += 1; };
}
};
let t = glib::gobject_ffi::g_type_register_static( let t = glib::gobject_ffi::g_type_register_static(
crate::Allocator::static_type().into_glib(), crate::Allocator::static_type().into_glib(),
type_name.as_ptr(), type_name.as_ptr(),
&TYPE_INFO.0, &TYPE_INFO.0,
0, 0,
); );
assert!(t != glib::gobject_ffi::G_TYPE_INVALID); assert!(t != glib::gobject_ffi::G_TYPE_INVALID);
from_glib_none(glib::gobject_ffi::g_object_newv(t, 0, ptr::null_mut()) as *mut ffi::GstAllocator) from_glib_none(
}); glib::gobject_ffi::g_object_newv(t, 0, ptr::null_mut()) as *mut ffi::GstAllocator
)
})
}
impl Memory { impl Memory {
#[doc(alias = "gst_memory_new_wrapped")] #[doc(alias = "gst_memory_new_wrapped")]
@ -200,7 +206,7 @@ impl Memory {
ffi::gst_memory_init( ffi::gst_memory_init(
mem as *mut ffi::GstMemory, mem as *mut ffi::GstMemory,
ffi::GST_MINI_OBJECT_FLAG_LOCK_READONLY, ffi::GST_MINI_OBJECT_FLAG_LOCK_READONLY,
RUST_ALLOCATOR.to_glib_none().0, rust_allocator().to_glib_none().0,
ptr::null_mut(), ptr::null_mut(),
len, len,
0, 0,
@ -242,7 +248,7 @@ impl Memory {
ffi::gst_memory_init( ffi::gst_memory_init(
mem as *mut ffi::GstMemory, mem as *mut ffi::GstMemory,
0, 0,
RUST_ALLOCATOR.to_glib_none().0, rust_allocator().to_glib_none().0,
ptr::null_mut(), ptr::null_mut(),
len, len,
0, 0,

View file

@ -237,9 +237,9 @@ impl<'a, T> MetaRef<'a, T> {
where where
T: MetaAPI, T: MetaAPI,
{ {
use glib::once_cell::sync::Lazy; static TRANSFORM_COPY: std::sync::OnceLock<glib::Quark> = std::sync::OnceLock::new();
static TRANSFORM_COPY: Lazy<glib::Quark> = Lazy::new(|| glib::Quark::from_str("gst-copy")); let transform_copy = TRANSFORM_COPY.get_or_init(|| glib::Quark::from_str("gst-copy"));
let (offset, size) = self.buffer.byte_range_into_offset_len(range)?; let (offset, size) = self.buffer.byte_range_into_offset_len(range)?;
@ -262,7 +262,7 @@ impl<'a, T> MetaRef<'a, T> {
buffer.as_mut_ptr(), buffer.as_mut_ptr(),
mut_override(self.upcast_ref().as_ptr()), mut_override(self.upcast_ref().as_ptr()),
mut_override(self.buffer.as_ptr()), mut_override(self.buffer.as_ptr()),
TRANSFORM_COPY.into_glib(), transform_copy.into_glib(),
&mut copy_data as *mut _ as *mut _, &mut copy_data as *mut _ as *mut _,
), ),
"Failed to copy meta" "Failed to copy meta"

View file

@ -43,12 +43,12 @@ macro_rules! bitflags_serialize_impl {
where where
S: serde::Serializer, S: serde::Serializer,
{ {
use glib::once_cell::sync::Lazy;
let mut handled = Self::empty(); let mut handled = Self::empty();
let mut res = String::new(); let mut res = String::new();
static SORTED_VALUES: Lazy<Vec<(u32, String)>> = Lazy::new(|| { static SORTED_VALUES: std::sync::OnceLock<Vec<(u32, String)>> = std::sync::OnceLock::new();
let sorted_values = SORTED_VALUES.get_or_init(|| {
let class = FlagsClass::with_type(<$type>::static_type()).unwrap(); let class = FlagsClass::with_type(<$type>::static_type()).unwrap();
let mut sorted_values: Vec<(u32, String)> = let mut sorted_values: Vec<(u32, String)> =
class.values().iter() class.values().iter()
@ -62,7 +62,7 @@ macro_rules! bitflags_serialize_impl {
sorted_values sorted_values
}); });
for (bits, nick) in SORTED_VALUES.iter() { for (bits, nick) in sorted_values.iter() {
// not all values defined in the class are always also defined // not all values defined in the class are always also defined
// in the bitflags struct, see RTPBufferFlags for example // in the bitflags struct, see RTPBufferFlags for example
if let Some(value) = Self::from_bits(*bits) { if let Some(value) = Self::from_bits(*bits) {

View file

@ -666,22 +666,24 @@ mod tests {
impl ElementImpl for TestElement { impl ElementImpl for TestElement {
fn metadata() -> Option<&'static ElementMetadata> { fn metadata() -> Option<&'static ElementMetadata> {
use glib::once_cell::sync::Lazy; static ELEMENT_METADATA: std::sync::OnceLock<ElementMetadata> =
static ELEMENT_METADATA: Lazy<ElementMetadata> = Lazy::new(|| { std::sync::OnceLock::new();
Some(ELEMENT_METADATA.get_or_init(|| {
ElementMetadata::new( ElementMetadata::new(
"Test Element", "Test Element",
"Generic", "Generic",
"Does nothing", "Does nothing",
"Sebastian Dröge <sebastian@centricular.com>", "Sebastian Dröge <sebastian@centricular.com>",
) )
}); }))
Some(&*ELEMENT_METADATA)
} }
fn pad_templates() -> &'static [PadTemplate] { fn pad_templates() -> &'static [PadTemplate] {
use glib::once_cell::sync::Lazy; static PAD_TEMPLATES: std::sync::OnceLock<Vec<PadTemplate>> =
static PAD_TEMPLATES: Lazy<Vec<PadTemplate>> = Lazy::new(|| { std::sync::OnceLock::new();
PAD_TEMPLATES.get_or_init(|| {
let caps = crate::Caps::new_any(); let caps = crate::Caps::new_any();
vec![ vec![
PadTemplate::new( PadTemplate::new(
@ -699,9 +701,7 @@ mod tests {
) )
.unwrap(), .unwrap(),
] ]
}); })
PAD_TEMPLATES.as_ref()
} }
fn change_state( fn change_state(

View file

@ -4,9 +4,9 @@
use std::{fmt, mem}; use std::{fmt, mem};
use glib::once_cell::sync::Lazy;
use glib::{Date, StaticType, ToValue}; use glib::{Date, StaticType, ToValue};
use num_rational::Rational32; use num_rational::Rational32;
use once_cell::sync::Lazy;
use serde::{ use serde::{
de, de,
de::{Deserialize, Deserializer, SeqAccess, Visitor}, de::{Deserialize, Deserializer, SeqAccess, Visitor},