tutorial: Port to once_cell::Lazy

This commit is contained in:
Sebastian Dröge 2020-01-26 10:37:05 +02:00 committed by Sebastian Dröge
parent 1e778e9827
commit c25a3e13e3
8 changed files with 43 additions and 33 deletions

View file

@ -15,7 +15,7 @@ gstreamer-video = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs
gstreamer-audio = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } gstreamer-audio = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
byte-slice-cast = "0.3" byte-slice-cast = "0.3"
num-traits = "0.2" num-traits = "0.2"
lazy_static = "1.0" once_cell = "1.0"
[lib] [lib]
name = "gstrstutorial" name = "gstrstutorial"

View file

@ -14,19 +14,21 @@ use gst;
use gst::prelude::*; use gst::prelude::*;
use gst::subclass::prelude::*; use gst::subclass::prelude::*;
use once_cell::sync::Lazy;
// Struct containing all the element data // Struct containing all the element data
struct Identity { struct Identity {
srcpad: gst::Pad, srcpad: gst::Pad,
sinkpad: gst::Pad, sinkpad: gst::Pad,
} }
lazy_static! { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
static ref CAT: gst::DebugCategory = gst::DebugCategory::new( gst::DebugCategory::new(
"rsidentity", "rsidentity",
gst::DebugColorFlags::empty(), gst::DebugColorFlags::empty(),
Some("Identity Element"), Some("Identity Element"),
); )
} });
impl Identity { impl Identity {
// After creating of our two pads set all the functions on them // After creating of our two pads set all the functions on them

View file

@ -16,8 +16,7 @@ extern crate gstreamer_video as gst_video;
extern crate byte_slice_cast; extern crate byte_slice_cast;
extern crate num_traits; extern crate num_traits;
#[macro_use] extern crate once_cell;
extern crate lazy_static;
mod identity; mod identity;
mod progressbin; mod progressbin;

View file

@ -16,6 +16,8 @@ use gst::prelude::*;
use gst::subclass::prelude::*; use gst::subclass::prelude::*;
use std::sync::Mutex; use std::sync::Mutex;
use once_cell::sync::Lazy;
// This enum may be used to control what type of output the progressbin should produce. // This enum may be used to control what type of output the progressbin should produce.
// It also serves the secondary purpose of illustrating how to add enum-type properties // It also serves the secondary purpose of illustrating how to add enum-type properties
// to a plugin written in rust. // to a plugin written in rust.
@ -37,13 +39,13 @@ pub(crate) enum ProgressBinOutput {
const DEFAULT_OUTPUT_TYPE: ProgressBinOutput = ProgressBinOutput::Println; const DEFAULT_OUTPUT_TYPE: ProgressBinOutput = ProgressBinOutput::Println;
lazy_static! { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
static ref CAT: gst::DebugCategory = gst::DebugCategory::new( gst::DebugCategory::new(
"progressbin", "progressbin",
gst::DebugColorFlags::empty(), gst::DebugColorFlags::empty(),
Some("Rust Progress Reporter"), Some("Rust Progress Reporter"),
); )
} });
// Struct containing all the element data // Struct containing all the element data
struct ProgressBin { struct ProgressBin {

View file

@ -19,6 +19,8 @@ use gst_video;
use std::i32; use std::i32;
use std::sync::Mutex; use std::sync::Mutex;
use once_cell::sync::Lazy;
// Default values of properties // Default values of properties
const DEFAULT_INVERT: bool = false; const DEFAULT_INVERT: bool = false;
const DEFAULT_SHIFT: u32 = 0; const DEFAULT_SHIFT: u32 = 0;
@ -75,13 +77,13 @@ struct Rgb2Gray {
state: Mutex<Option<State>>, state: Mutex<Option<State>>,
} }
lazy_static! { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
static ref CAT: gst::DebugCategory = gst::DebugCategory::new( gst::DebugCategory::new(
"rsrgb2gray", "rsrgb2gray",
gst::DebugColorFlags::empty(), gst::DebugColorFlags::empty(),
Some("Rust RGB-GRAY converter"), Some("Rust RGB-GRAY converter"),
); )
} });
impl Rgb2Gray { impl Rgb2Gray {
// Converts one pixel of BGRx to a grayscale value, shifting and/or // Converts one pixel of BGRx to a grayscale value, shifting and/or

View file

@ -26,6 +26,8 @@ use std::{i32, u32};
use num_traits::cast::NumCast; use num_traits::cast::NumCast;
use num_traits::float::Float; use num_traits::float::Float;
use once_cell::sync::Lazy;
// Default values of properties // Default values of properties
const DEFAULT_SAMPLES_PER_BUFFER: u32 = 1024; const DEFAULT_SAMPLES_PER_BUFFER: u32 = 1024;
const DEFAULT_FREQ: u32 = 440; const DEFAULT_FREQ: u32 = 440;
@ -142,13 +144,13 @@ struct SineSrc {
clock_wait: Mutex<ClockWait>, clock_wait: Mutex<ClockWait>,
} }
lazy_static! { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
static ref CAT: gst::DebugCategory = gst::DebugCategory::new( gst::DebugCategory::new(
"rssinesrc", "rssinesrc",
gst::DebugColorFlags::empty(), gst::DebugColorFlags::empty(),
Some("Rust Sine Wave Source"), Some("Rust Sine Wave Source"),
); )
} });
impl SineSrc { impl SineSrc {
fn process<F: Float + FromByteSlice>( fn process<F: Float + FromByteSlice>(

View file

@ -45,7 +45,7 @@ glib = { git = "https://github.com/gtk-rs/glib" }
gstreamer = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } gstreamer = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
gstreamer-base = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } gstreamer-base = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
gstreamer-video = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } gstreamer-video = { git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
lazy_static = "1.0" once_cell = "1.0"
[lib] [lib]
name = "gstrstutorial" name = "gstrstutorial"
@ -56,7 +56,7 @@ path = "src/lib.rs"
gst-plugin-version-helper = { git = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs" } gst-plugin-version-helper = { git = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs" }
``` ```
We depend on the `gstreamer`, `gstreamer-base` and `gstreamer-video` crates for various GStreamer APIs that will be used later, and the `glib` crate to be able to use some GLib API that well need. GStreamer is building upon GLib, and this leaks through in various places. We also have one build dependency on the `gst-plugin-version-helper` crate, which helps to get some information about the plugin for the `gst_plugin_define!` macro automatically, and the `lazy_static` crate, which allows to declare lazily initialized global variables. We depend on the `gstreamer`, `gstreamer-base` and `gstreamer-video` crates for various GStreamer APIs that will be used later, and the `glib` crate to be able to use some GLib API that well need. GStreamer is building upon GLib, and this leaks through in various places. We also have one build dependency on the `gst-plugin-version-helper` crate, which helps to get some information about the plugin for the `gst_plugin_define!` macro automatically, and the `once_cell` crate, which allows to declare lazily initialized global variables.
With the basic project structure being set-up, we should be able to compile the project with `cargo build` now, which will download and build all dependencies and then creates a file called `target/debug/libgstrstutorial.so` (or .dll on Windows, .dylib on macOS). This is going to be our GStreamer plugin. With the basic project structure being set-up, we should be able to compile the project with `cargo build` now, which will download and build all dependencies and then creates a file called `target/debug/libgstrstutorial.so` (or .dll on Windows, .dylib on macOS). This is going to be our GStreamer plugin.
@ -79,8 +79,7 @@ extern crate glib;
extern crate gstreamer as gst; extern crate gstreamer as gst;
extern crate gstreamer_base as gst_base; extern crate gstreamer_base as gst_base;
extern crate gstreamer_video as gst_video; extern crate gstreamer_video as gst_video;
#[macro_use] extern crate once_cell;
extern crate lazy_static;
``` ```
Next we make use of the `gst_plugin_define!` `macro` from the `gstreamer` crate to set-up the static metadata of the plugin (and make the shared library recognizeable by GStreamer to be a valid plugin), and to define the name of our entry point function (`plugin_init`) where we will register all the elements that this plugin provides. Next we make use of the `gst_plugin_define!` `macro` from the `gstreamer` crate to set-up the static metadata of the plugin (and make the shared library recognizeable by GStreamer to be a valid plugin), and to define the name of our entry point function (`plugin_init`) where we will register all the elements that this plugin provides.
@ -170,6 +169,8 @@ use gst_video;
use std::i32; use std::i32;
use std::sync::Mutex; use std::sync::Mutex;
use once_cell::sync::Lazy;
``` ```
GStreamer is based on the GLib object system ([GObject](https://developer.gnome.org/gobject/stable/)). C (just like Rust) does not have built-in support for object orientated programming, inheritance, virtual methods and related concepts, and GObject makes these features available in C as a library. Without language support this is a quite verbose endeavour in C, and the `glib` crate tries to expose all this in a (as much as possible) Rust-style API while hiding all the details that do not really matter. GStreamer is based on the GLib object system ([GObject](https://developer.gnome.org/gobject/stable/)). C (just like Rust) does not have built-in support for object orientated programming, inheritance, virtual methods and related concepts, and GObject makes these features available in C as a library. Without language support this is a quite verbose endeavour in C, and the `glib` crate tries to expose all this in a (as much as possible) Rust-style API while hiding all the details that do not really matter.
@ -307,19 +308,19 @@ pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
## Debug Category ## Debug Category
To be able to later have a debug category available for our new element that To be able to later have a debug category available for our new element that
can be used for logging, we make use of the `lazy_static!` macro from the can be used for logging, we make use of the `once_cell::sync::Lazy` type from the
crate with the same name. This crate allows to declare lazily initialized `once_cell` crate. This type allows to declare lazily initialized
global variables, i.e. on the very first use the provided code will be global variables, i.e. on the very first use the provided code will be
executed and the result will be stored for all later uses. executed and the result will be stored for all later uses.
```rust ```rust
lazy_static! { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
static ref CAT: gst::DebugCategory = gst::DebugCategory::new( gst::DebugCategory::new(
"rsrgb2gray", "rsrgb2gray",
gst::DebugColorFlags::empty(), gst::DebugColorFlags::empty(),
Some("Rust RGB-GRAY converter"), Some("Rust RGB-GRAY converter"),
); )
} });
``` ```
We give the debug category the same name as our element, which generally is We give the debug category the same name as our element, which generally is

View file

@ -41,6 +41,8 @@ use std::ops::Rem;
use num_traits::float::Float; use num_traits::float::Float;
use num_traits::cast::NumCast; use num_traits::cast::NumCast;
use once_cell::sync::Lazy;
// Default values of properties // Default values of properties
const DEFAULT_SAMPLES_PER_BUFFER: u32 = 1024; const DEFAULT_SAMPLES_PER_BUFFER: u32 = 1024;
const DEFAULT_FREQ: u32 = 440; const DEFAULT_FREQ: u32 = 440;
@ -138,13 +140,13 @@ struct SineSrc {
state: Mutex<State>, state: Mutex<State>,
} }
lazy_static! { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
static ref CAT: gst::DebugCategory = gst::DebugCategory::new( gst::DebugCategory::new(
"rssinesrc", "rssinesrc",
gst::DebugColorFlags::empty(), gst::DebugColorFlags::empty(),
Some("Rust Sine Wave Source"), Some("Rust Sine Wave Source"),
); )
} });
impl SineSrc { impl SineSrc {
// Called when a new instance is to be created // Called when a new instance is to be created