From 832bc1b53b7b03a847d6901e713d0bd96b6fece8 Mon Sep 17 00:00:00 2001 From: Andrew Straw Date: Sat, 11 Jan 2025 17:58:43 +0100 Subject: [PATCH 1/2] braid-process-video: fix braidz output --- braid-process-video/src/lib.rs | 15 ++++--- braid-process-video/src/output_braidz.rs | 52 +++++++++++++++--------- braid-process-video/src/output_types.rs | 12 ++++++ braid-process-video/src/output_video.rs | 19 ++++++--- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/braid-process-video/src/lib.rs b/braid-process-video/src/lib.rs index 02d740e15..62db09f45 100644 --- a/braid-process-video/src/lib.rs +++ b/braid-process-video/src/lib.rs @@ -777,7 +777,7 @@ pub async fn run_config(cfg: &Valid) -> Result { - let (braidz_storage, coord_proc_fut) = output_braidz::BraidStorage::new( + let braidz_storage = output_braidz::BraidStorage::new( cfg, &b, tracking_parameters.clone(), @@ -788,8 +788,6 @@ pub async fn run_config(cfg: &Valid) -> Result) -> Result( diff --git a/braid-process-video/src/output_braidz.rs b/braid-process-video/src/output_braidz.rs index 7ed213d04..49004c4a8 100644 --- a/braid-process-video/src/output_braidz.rs +++ b/braid-process-video/src/output_braidz.rs @@ -1,8 +1,5 @@ use eyre::{self as anyhow, Result}; -use std::{ - collections::{BTreeMap, BTreeSet}, - future::Future, -}; +use std::collections::{BTreeMap, BTreeSet}; use flydra_types::{PerCamSaveData, RawCamName}; @@ -15,6 +12,7 @@ pub(crate) struct BraidStorage { pub(crate) cam_manager: flydra2::ConnectedCamerasManager, pub(crate) frame_data_tx: tokio::sync::mpsc::Sender, pub(crate) output_braidz_path: std::path::PathBuf, + pub(crate) coord_proc_jh: tokio::task::JoinHandle>, } impl BraidStorage { @@ -26,12 +24,7 @@ impl BraidStorage { all_expected_cameras: BTreeSet, expected_framerate: Option, braidz_calibration: Option, - ) -> Result<( - Self, - impl Future< - Output = Result>, flydra2::Error>, - >, - )> { + ) -> Result { let output_braidz_path = std::path::PathBuf::from(&b.filename); let output_dirname = if output_braidz_path.extension() == Some(std::ffi::OsStr::new("braidz")) { @@ -141,17 +134,20 @@ impl BraidStorage { .await .unwrap(); - let coord_proc_fut = coord_processor.consume_stream(frame_data_rx, expected_framerate); - - Ok(( - Self { - cam_manager, - frame_data_tx, - output_braidz_path, - }, - coord_proc_fut, - )) + let coord_proc_jh = tokio::spawn(async move { + let coord_proc_fut = coord_processor.consume_stream(frame_data_rx, expected_framerate); + coord_proc_fut.await?.await??; + Ok(()) + }); + + Ok(Self { + cam_manager, + frame_data_tx, + output_braidz_path, + coord_proc_jh, + }) } + pub(crate) async fn render_frame( &mut self, out_fno: usize, @@ -211,4 +207,20 @@ impl BraidStorage { } Ok(()) } + + pub(crate) async fn close(self) -> Result<()> { + let BraidStorage { + cam_manager: _, + frame_data_tx, + output_braidz_path: _, + coord_proc_jh, + } = self; + + // Stop transmitting frames, which causes coord processor to end. + std::mem::drop(frame_data_tx); + + // Wait for coord processor to finish. + coord_proc_jh.await??; + Ok(()) + } } diff --git a/braid-process-video/src/output_types.rs b/braid-process-video/src/output_types.rs index 108dd7cfa..4c76f18eb 100644 --- a/braid-process-video/src/output_types.rs +++ b/braid-process-video/src/output_types.rs @@ -40,6 +40,14 @@ impl<'lib> OutputStorage<'lib> { OutputStorage::Video(v) => &v.path, } } + + pub(crate) async fn close(self) -> Result<()> { + match self { + OutputStorage::Debug(d) => d.close().await, + OutputStorage::Braid(b) => b.close().await, + OutputStorage::Video(v) => v.close().await, + } + } } pub(crate) struct DebugStorage { @@ -100,4 +108,8 @@ impl DebugStorage { } Ok(()) } + + pub(crate) async fn close(self) -> Result<()> { + Ok(()) + } } diff --git a/braid-process-video/src/output_video.rs b/braid-process-video/src/output_video.rs index c2aa56172..79bcdd6a0 100644 --- a/braid-process-video/src/output_video.rs +++ b/braid-process-video/src/output_video.rs @@ -76,25 +76,30 @@ impl<'lib> VideoStorage<'lib> { let feature_radius = v .video_options - .feature_radius.clone() + .feature_radius + .clone() .unwrap_or_else(|| crate::DEFAULT_FEATURE_RADIUS.to_string()); let feature_style = v .video_options - .feature_style.clone() + .feature_style + .clone() .unwrap_or_else(|| crate::DEFAULT_FEATURE_STYLE.to_string()); let reprojected_radius = v .video_options - .reprojected_radius.clone() + .reprojected_radius + .clone() .unwrap_or_else(|| crate::DEFAULT_REPROJECTED_RADIUS.to_string()); let reprojected_style = v .video_options - .reprojected_style.clone() + .reprojected_style + .clone() .unwrap_or_else(|| crate::DEFAULT_REPROJECTED_STYLE.to_string()); let cam_text_style = v .video_options - .cam_text_style.clone() + .cam_text_style + .clone() .unwrap_or_else(|| crate::DEFAULT_CAMERA_TEXT_STYLE.to_string()); let mut usvg_opt = usvg::Options::default(); @@ -309,4 +314,8 @@ impl<'lib> VideoStorage<'lib> { Ok(()) } + + pub(crate) async fn close(self) -> Result<()> { + Ok(()) + } } From b54ca457c3f0bfb14065f1bd32b3c08b476e78ca Mon Sep 17 00:00:00 2001 From: Andrew Straw Date: Sat, 11 Jan 2025 16:14:54 +0100 Subject: [PATCH 2/2] braidz-process-video: test braidz output Until the previous commit 832bc1b53b7b03a847d6901e713d0bd96b6fece8, no braidz file was created and the tests here would block forever. --- braid-process-video/src/lib.rs | 3 ++- braid-process-video/tests/test-montage.rs | 26 +++++++++++++++-------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/braid-process-video/src/lib.rs b/braid-process-video/src/lib.rs index 62db09f45..e84d25a88 100644 --- a/braid-process-video/src/lib.rs +++ b/braid-process-video/src/lib.rs @@ -25,7 +25,8 @@ mod synced_iter; mod config; pub(crate) use config::FeatureDetectionMethod; pub use config::{ - BraidRetrackVideoConfig, OutputConfig, Valid, Validate, VideoOutputConfig, VideoSourceConfig, + BraidRetrackVideoConfig, BraidzOutputConfig, OutputConfig, Valid, Validate, VideoOutputConfig, + VideoSourceConfig, }; mod auto_config_generator; diff --git a/braid-process-video/tests/test-montage.rs b/braid-process-video/tests/test-montage.rs index 9581338fb..edddc5c15 100644 --- a/braid-process-video/tests/test-montage.rs +++ b/braid-process-video/tests/test-montage.rs @@ -1,7 +1,8 @@ use eyre::{self as anyhow}; use braid_process_video::{ - BraidRetrackVideoConfig, OutputConfig, Valid, Validate, VideoOutputConfig, VideoSourceConfig, + BraidRetrackVideoConfig, BraidzOutputConfig, OutputConfig, Valid, Validate, VideoOutputConfig, + VideoSourceConfig, }; const BASE_URL: &str = "https://strawlab-cdn.com/assets/flycube6-videos"; @@ -10,14 +11,16 @@ const SOURCE_JSON: &str = include_str!("source.json"); async fn do_config(cfg: &Valid) -> anyhow::Result<()> { // generate the output let output_fnames = braid_process_video::run_config(cfg).await?; - assert_eq!(output_fnames.len(), 1); - let output_fname = output_fnames[0].clone(); + assert_eq!(output_fnames.len(), 2); + let output_mp4 = output_fnames[0].clone(); // start parsing output let do_decode_h264 = false; - let _src = frame_source::from_path(&output_fname, do_decode_h264)?; + let _src = frame_source::from_path(&output_mp4, do_decode_h264)?; - // TODO: check output. How? + // TODO: check output mp4. How? + + // TODO: check output braidz Ok(()) } @@ -71,10 +74,15 @@ fn get_files( } let input_braidz = input_braidz.map(Into::into); - let output = vec![OutputConfig::Video(VideoOutputConfig { - filename: format!("tests/rendered/{}.mp4", dirname), - video_options: Default::default(), - })]; + let output = vec![ + OutputConfig::Video(VideoOutputConfig { + filename: format!("tests/rendered/{}.mp4", dirname), + video_options: Default::default(), + }), + OutputConfig::Braidz(BraidzOutputConfig { + filename: format!("tests/rendered/{dirname}.braidz"), + }), + ]; let cfg = BraidRetrackVideoConfig { input_braidz,