mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 21:11:00 +00:00
9b96cfc452
Contrary to the existing Task Sink, the Async and Sync Mutex Sinks handle buffers in the `PadSinkHandler` directly. The Async Mutex Sink uses an async Mutex for the `PadSinkHandlerInner` while the Sync Mutex Sink uses... a sync Mutex. All Sinks share the same settings and stats manager. Use the `--sink` command line option to select the sink (default is `sync-mutex` since it allows evaluating the framework with as little overhead as possible. Also apply various fixes: - Only keep the segment start instead of the full `Segment`. This helps with cache locality (`Segment` is a plain struct with many fields) and avoids downcasting the generic `Segment` upon each buffer handling. - Box the `Stat`s. This should improve cache locality a bit. - Fix EOS handling which took ages for no benefits in this particular use case. - Use a macro to raise log level in the main element. - Move error handling during item processing in `handle_loop_error`. This function was precisely designed for this and it should reduce the `handle_item`'s Future size.
115 lines
4.1 KiB
Rust
115 lines
4.1 KiB
Rust
use gst::glib;
|
|
use gst::prelude::*;
|
|
|
|
use std::time::Duration;
|
|
|
|
const DEFAULT_CONTEXT: &str = "";
|
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_millis(20);
|
|
const DEFAULT_PUSH_PERIOD: Duration = Duration::from_millis(20);
|
|
const DEFAULT_MAX_BUFFERS: i32 = 50 * (100 - 25);
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Settings {
|
|
pub context: String,
|
|
pub context_wait: Duration,
|
|
pub is_main_elem: bool,
|
|
pub logs_stats: bool,
|
|
pub push_period: Duration,
|
|
pub max_buffers: Option<u32>,
|
|
}
|
|
|
|
impl Default for Settings {
|
|
fn default() -> Self {
|
|
Settings {
|
|
context: DEFAULT_CONTEXT.into(),
|
|
context_wait: DEFAULT_CONTEXT_WAIT,
|
|
is_main_elem: false,
|
|
logs_stats: false,
|
|
push_period: DEFAULT_PUSH_PERIOD,
|
|
max_buffers: Some(DEFAULT_MAX_BUFFERS as u32),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Settings {
|
|
pub fn properties() -> Vec<glib::ParamSpec> {
|
|
vec![
|
|
glib::ParamSpecString::builder("context")
|
|
.nick("Context")
|
|
.blurb("Context name to share threads with")
|
|
.default_value(Some(DEFAULT_CONTEXT))
|
|
.build(),
|
|
glib::ParamSpecUInt::builder("context-wait")
|
|
.nick("Context Wait")
|
|
.blurb("Throttle poll loop to run at most once every this many ms")
|
|
.maximum(1000)
|
|
.default_value(DEFAULT_CONTEXT_WAIT.as_millis() as u32)
|
|
.build(),
|
|
glib::ParamSpecBoolean::builder("main-elem")
|
|
.nick("Main Element")
|
|
.blurb("Declare this element as the main one")
|
|
.write_only()
|
|
.build(),
|
|
glib::ParamSpecBoolean::builder("logs-stats")
|
|
.nick("Logs Stats")
|
|
.blurb("Whether statistics should be logged")
|
|
.write_only()
|
|
.build(),
|
|
glib::ParamSpecUInt::builder("push-period")
|
|
.nick("Src buffer Push Period")
|
|
.blurb("Push period used by `src` element (used for stats warnings)")
|
|
.default_value(DEFAULT_PUSH_PERIOD.as_millis() as u32)
|
|
.build(),
|
|
glib::ParamSpecInt::builder("max-buffers")
|
|
.nick("Max Buffers")
|
|
.blurb("Number of buffers to count before stopping stats (-1 = unlimited)")
|
|
.minimum(-1i32)
|
|
.default_value(DEFAULT_MAX_BUFFERS)
|
|
.build(),
|
|
]
|
|
}
|
|
|
|
pub fn set_property(&mut self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
|
match pspec.name() {
|
|
"context" => {
|
|
self.context = value
|
|
.get::<Option<String>>()
|
|
.unwrap()
|
|
.unwrap_or_else(|| DEFAULT_CONTEXT.into());
|
|
}
|
|
"context-wait" => {
|
|
self.context_wait = Duration::from_millis(value.get::<u32>().unwrap().into());
|
|
}
|
|
"main-elem" => {
|
|
self.is_main_elem = value.get::<bool>().unwrap();
|
|
}
|
|
"logs-stats" => {
|
|
let logs_stats = value.get().unwrap();
|
|
self.logs_stats = logs_stats;
|
|
}
|
|
"push-period" => {
|
|
self.push_period = Duration::from_millis(value.get::<u32>().unwrap().into());
|
|
}
|
|
"max-buffers" => {
|
|
let value = value.get::<i32>().unwrap();
|
|
self.max_buffers = if value > 0 { Some(value as u32) } else { None };
|
|
}
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
|
|
pub fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
|
match pspec.name() {
|
|
"context" => self.context.to_value(),
|
|
"context-wait" => (self.context_wait.as_millis() as u32).to_value(),
|
|
"main-elem" => self.is_main_elem.to_value(),
|
|
"push-period" => (self.push_period.as_millis() as u32).to_value(),
|
|
"max-buffers" => self
|
|
.max_buffers
|
|
.and_then(|val| val.try_into().ok())
|
|
.unwrap_or(-1i32)
|
|
.to_value(),
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
}
|