mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-25 19:11:06 +00:00
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:
parent
ce5dca918d
commit
193bcbf055
38 changed files with 229 additions and 212 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -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",
|
||||||
]
|
]
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,7 +156,10 @@ 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();
|
||||||
|
|
||||||
|
META_INFO
|
||||||
|
.get_or_init(|| unsafe {
|
||||||
MetaInfo(
|
MetaInfo(
|
||||||
ptr::NonNull::new(gst::ffi::gst_meta_register(
|
ptr::NonNull::new(gst::ffi::gst_meta_register(
|
||||||
custom_meta_api_get_type().into_glib(),
|
custom_meta_api_get_type().into_glib(),
|
||||||
|
@ -169,9 +171,9 @@ mod custom_meta {
|
||||||
) as *mut gst::ffi::GstMetaInfo)
|
) as *mut gst::ffi::GstMetaInfo)
|
||||||
.expect("Failed to register meta API"),
|
.expect("Failed to register meta API"),
|
||||||
)
|
)
|
||||||
});
|
})
|
||||||
|
.0
|
||||||
META_INFO.0.as_ptr()
|
.as_ptr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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]));
|
||||||
|
|
|
@ -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 _,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 _,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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]));
|
||||||
|
|
|
@ -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),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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 (),
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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(|| {
|
||||||
|
|
|
@ -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),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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")))]
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 _,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,7 +141,10 @@ 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 {
|
||||||
|
static RUST_ALLOCATOR: std::sync::OnceLock<crate::Allocator> = std::sync::OnceLock::new();
|
||||||
|
|
||||||
|
RUST_ALLOCATOR.get_or_init(|| unsafe {
|
||||||
struct TypeInfoWrap(glib::gobject_ffi::GTypeInfo);
|
struct TypeInfoWrap(glib::gobject_ffi::GTypeInfo);
|
||||||
unsafe impl Send for TypeInfoWrap {}
|
unsafe impl Send for TypeInfoWrap {}
|
||||||
unsafe impl Sync for TypeInfoWrap {}
|
unsafe impl Sync for TypeInfoWrap {}
|
||||||
|
@ -182,8 +185,11 @@ static RUST_ALLOCATOR: Lazy<crate::Allocator> = Lazy::new(|| unsafe {
|
||||||
|
|
||||||
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,
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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},
|
||||||
|
|
Loading…
Reference in a new issue