mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-21 19:11:02 +00:00
tracers: buffers-lateness: Add a signal to force writing log file
This way applications can write the queue levels info whenever it wants and does not need to wait for the application to quite. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1912>
This commit is contained in:
parent
153d4c7ac5
commit
1dcf0943db
1 changed files with 66 additions and 36 deletions
|
@ -44,7 +44,7 @@
|
||||||
*
|
*
|
||||||
* By default this is not set.
|
* By default this is not set.
|
||||||
*/
|
*/
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
@ -139,6 +139,7 @@ struct State {
|
||||||
pads: HashMap<usize, Pad>,
|
pads: HashMap<usize, Pad>,
|
||||||
log: Vec<LogLine>,
|
log: Vec<LogLine>,
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
|
logs_written: HashSet<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Pad {
|
struct Pad {
|
||||||
|
@ -163,6 +164,51 @@ pub struct BufferLateness {
|
||||||
state: Mutex<State>,
|
state: Mutex<State>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BufferLateness {
|
||||||
|
fn write_log(&self, file_path: Option<&str>) {
|
||||||
|
use std::io::prelude::*;
|
||||||
|
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
let path = file_path.map_or_else(|| state.settings.file.clone(), PathBuf::from);
|
||||||
|
let first_write = state.logs_written.contains(&path);
|
||||||
|
|
||||||
|
let mut file = match std::fs::OpenOptions::new()
|
||||||
|
.append(!first_write)
|
||||||
|
.create(true)
|
||||||
|
.open(path.clone())
|
||||||
|
{
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(err) => {
|
||||||
|
gst::error!(CAT, imp = self, "Failed to create file: {err}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let log = std::mem::take(&mut state.log);
|
||||||
|
state.logs_written.insert(path);
|
||||||
|
drop(state);
|
||||||
|
|
||||||
|
gst::debug!(CAT, imp = self, "Writing file {:?}", file);
|
||||||
|
|
||||||
|
for LogLine {
|
||||||
|
timestamp,
|
||||||
|
element_name,
|
||||||
|
pad_name,
|
||||||
|
ptr,
|
||||||
|
buffer_clock_time,
|
||||||
|
pipeline_clock_time,
|
||||||
|
lateness,
|
||||||
|
min_latency,
|
||||||
|
} in &log
|
||||||
|
{
|
||||||
|
if let Err(err) = writeln!(&mut file, "{timestamp},{element_name}:{pad_name},0x{ptr:08x},{buffer_clock_time},{pipeline_clock_time},{lateness},{min_latency}") {
|
||||||
|
gst::error!(CAT, imp = self, "Failed to write to file: {err}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[glib::object_subclass]
|
#[glib::object_subclass]
|
||||||
impl ObjectSubclass for BufferLateness {
|
impl ObjectSubclass for BufferLateness {
|
||||||
const NAME: &'static str = "GstBufferLateness";
|
const NAME: &'static str = "GstBufferLateness";
|
||||||
|
@ -186,42 +232,26 @@ impl ObjectImpl for BufferLateness {
|
||||||
self.register_hook(TracerHook::PadQueryPost);
|
self.register_hook(TracerHook::PadQueryPost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn signals() -> &'static [glib::subclass::Signal] {
|
||||||
|
static SIGNALS: LazyLock<Vec<glib::subclass::Signal>> = LazyLock::new(|| {
|
||||||
|
vec![glib::subclass::Signal::builder("write-log")
|
||||||
|
.action()
|
||||||
|
.param_types([Option::<String>::static_type()])
|
||||||
|
.class_handler(|_, args| {
|
||||||
|
let obj = args[0].get::<super::BufferLateness>().unwrap();
|
||||||
|
|
||||||
|
obj.imp().write_log(args[1].get::<Option<&str>>().unwrap());
|
||||||
|
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.build()]
|
||||||
|
});
|
||||||
|
|
||||||
|
SIGNALS.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
fn dispose(&self) {
|
fn dispose(&self) {
|
||||||
use std::io::prelude::*;
|
self.write_log(None);
|
||||||
|
|
||||||
let state = self.state.lock().unwrap();
|
|
||||||
|
|
||||||
let mut file = match std::fs::File::create(&state.settings.file) {
|
|
||||||
Ok(file) => file,
|
|
||||||
Err(err) => {
|
|
||||||
gst::error!(CAT, imp = self, "Failed to create file: {err}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
gst::debug!(
|
|
||||||
CAT,
|
|
||||||
imp = self,
|
|
||||||
"Writing file {}",
|
|
||||||
state.settings.file.display()
|
|
||||||
);
|
|
||||||
|
|
||||||
for LogLine {
|
|
||||||
timestamp,
|
|
||||||
element_name,
|
|
||||||
pad_name,
|
|
||||||
ptr,
|
|
||||||
buffer_clock_time,
|
|
||||||
pipeline_clock_time,
|
|
||||||
lateness,
|
|
||||||
min_latency,
|
|
||||||
} in &state.log
|
|
||||||
{
|
|
||||||
if let Err(err) = writeln!(&mut file, "{timestamp},{element_name}:{pad_name},0x{ptr:08x},{buffer_clock_time},{pipeline_clock_time},{lateness},{min_latency}") {
|
|
||||||
gst::error!(CAT, imp = self, "Failed to write to file: {err}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue