Skip to content

Commit 2a21cad

Browse files
committed
examples: add glcontext
1 parent 6f24989 commit 2a21cad

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

examples/glcontext.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright (C) 2025 Guillaume Desmottes <[email protected]>
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
use std::{collections::HashMap, fs::File};
10+
11+
use gst_log_parser::parse;
12+
use gstreamer as gst;
13+
use structopt::StructOpt;
14+
15+
#[derive(StructOpt)]
16+
#[structopt(
17+
name = "glcontext",
18+
about = "Check for how long it takes for functions to be scheduled in the GL thread"
19+
)]
20+
struct Opt {
21+
#[structopt(help = "Input file")]
22+
input: String,
23+
}
24+
25+
fn print_stats(times: Vec<gst::ClockTime>) {
26+
let n = times.len();
27+
println!("{n} function calls. Schedule times:");
28+
if n == 0 {
29+
return;
30+
}
31+
let (min_idx, min) = times
32+
.iter()
33+
.enumerate()
34+
.min_by(|(_a_idx, a), (_b_idx, b)| a.cmp(b))
35+
.unwrap();
36+
let (max_idx, max) = times
37+
.iter()
38+
.enumerate()
39+
.max_by(|(_a_idx, a), (_b_idx, b)| a.cmp(b))
40+
.unwrap();
41+
println!(" min: {min} (call {min_idx})");
42+
println!(" max: {max} (call {max_idx})");
43+
let sum: gst::ClockTime = times.into_iter().sum();
44+
let avg = sum.nseconds() / n as u64;
45+
let avg = gst::ClockTime::from_nseconds(avg);
46+
println!(" avg: {avg}");
47+
}
48+
49+
fn main() -> anyhow::Result<()> {
50+
let opt = Opt::from_args();
51+
let f = File::open(opt.input)?;
52+
53+
let add_re = regex::Regex::new(r"schedule function:(?<function>.*) data:(?<data>.*)")?;
54+
let run_re = regex::Regex::new(r"running function:(?<function>.*) data:(?<data>.*)")?;
55+
let mut pendings = HashMap::new();
56+
let mut times = vec![];
57+
58+
let parsed = parse(f);
59+
for entry in parsed
60+
.filter(|entry| entry.category == "glcontext" && entry.level == gst::DebugLevel::Trace)
61+
{
62+
match entry.function.as_str() {
63+
"gst_gl_context_thread_add" => {
64+
let Some(capture) = add_re.captures(&entry.message) else {
65+
continue;
66+
};
67+
pendings.insert(
68+
(
69+
(capture["function"]).to_string(),
70+
(capture["data"]).to_string(),
71+
),
72+
entry.ts,
73+
);
74+
}
75+
"_gst_gl_context_thread_run_generic" => {
76+
let Some(capture) = run_re.captures(&entry.message) else {
77+
continue;
78+
};
79+
if let Some(pending) = pendings.remove(&(
80+
(capture["function"]).to_string(),
81+
(capture["data"]).to_string(),
82+
)) {
83+
times.push(entry.ts - pending);
84+
}
85+
}
86+
_ => {}
87+
}
88+
}
89+
90+
print_stats(times);
91+
92+
Ok(())
93+
}

0 commit comments

Comments
 (0)