frame_hook_plan/
frame_hook_plan.rs1use cumulus3d_cli::declare::{Plan, Recon};
37use cumulus3d_cli::events::Frame;
38use std::collections::BTreeMap;
39use std::sync::{Arc, Mutex};
40use std::time::Instant;
41
42#[derive(Default)]
43struct Seen {
44 per_camera: BTreeMap<String, usize>,
45 bad: usize,
46 bytes: usize,
47 sizes: BTreeMap<(u32, u32), usize>,
48 first_s: Option<f64>,
49 last_s: f64,
50 positions: usize,
51}
52
53fn main() -> Result<(), String> {
54 let path = std::env::args().nth(1).ok_or("usage: frame_hook_plan <plan.toml>")?;
55 let plan = Plan::load(&path)?;
56 let seen = Arc::new(Mutex::new(Seen::default()));
57 let refined = Arc::new(Mutex::new(Vec::new()));
58 let t0 = Instant::now();
59 let (s, r) = (seen.clone(), refined.clone());
60 let recon = Recon::from_plan(plan)
61 .on_frame(move |f: &Arc<Frame>| {
62 let mut s = s.lock().unwrap();
63 let t = t0.elapsed().as_secs_f64();
64 s.first_s.get_or_insert(t);
65 s.last_s = t;
66 *s.per_camera.entry(f.camera.clone()).or_default() += 1;
67 *s.sizes.entry((f.width, f.height)).or_default() += 1;
68 s.bytes += f.rgb.len();
69 s.positions = s.positions.max(f.position + 1);
70 if f.rgb.len() != (f.width * f.height * 3) as usize || f.width == 0 {
71 s.bad += 1;
72 }
73 })
74 .on_zone_refined(move |z, cloud| r.lock().unwrap().push((z.zone, cloud.len())))
75 .build()
76 .map_err(|e| e.to_string())?;
77 let summary = recon.run()?;
78 let s = seen.lock().unwrap();
79 let total: usize = s.per_camera.values().sum();
80 println!(
81 "frame hook: {total} frames over {} positions, per camera {:?}, sizes {:?}, {:.1} MB RGB, bad {}",
82 s.positions,
83 s.per_camera,
84 s.sizes,
85 s.bytes as f64 / 1e6,
86 s.bad
87 );
88 println!(
89 "frame hook: first frame at {:.2}s, last at {:.2}s; run total {:.1}s",
90 s.first_s.unwrap_or(0.0),
91 s.last_s,
92 t0.elapsed().as_secs_f64()
93 );
94 println!("refined zones (zone, dense points): {:?}", refined.lock().unwrap());
95 println!("events {}, hook calls {}, hook panics {}", summary.events, summary.hook_calls, summary.hook_panics);
96 if total == 0 || s.bad > 0 || summary.hook_panics > 0 {
97 return Err("frame hook check failed".into());
98 }
99 Ok(())
100}