Skip to content

Commit d3f6d48

Browse files
committed
Stop export after sample frames and shorten timeout
1 parent 3c44d4c commit d3f6d48

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

crates/cap-test/src/suites/performance.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ const PLAYBACK_RESOLUTION: XY<u32> = XY::new(1920, 1080);
3030
const MAX_PLAYBACK_FAILURE_RATE: f64 = 5.0;
3131
const MAX_OPEN_TIME_SECS: f64 = 30.0;
3232
const MAX_EXPORT_START_SECS: f64 = 60.0;
33-
const MAX_EXPORT_WALL_TIME_SECS: u64 = 600;
33+
const MAX_EXPORT_SAMPLE_FRAMES: u32 = 120;
34+
const MAX_EXPORT_WALL_TIME_SECS: u64 = 180;
3435

3536
pub async fn run_suite(
3637
hardware: &DiscoveredHardware,
@@ -284,6 +285,9 @@ async fn run_export_test(recording_path: &Path) -> TestResult {
284285
result
285286
.notes
286287
.push(format!("total_frames={}", metrics.total_frames));
288+
result
289+
.notes
290+
.push(format!("rendered_frames={}", metrics.rendered_frames));
287291

288292
let min_export_fps = 3.0;
289293

@@ -443,9 +447,9 @@ async fn benchmark_playback(
443447

444448
async fn benchmark_export(recording_path: &Path) -> Result<ExportMetrics> {
445449
let output_dir = TempDir::new().context("failed to create export tempdir")?;
446-
let output_path = output_dir.path().join("performance-export.mp4");
450+
let planned_output_path = output_dir.path().join("performance-export.mp4");
447451
let exporter_base = ExporterBase::builder(recording_path.to_path_buf())
448-
.with_output_path(output_path.clone())
452+
.with_output_path(planned_output_path.clone())
449453
.build()
450454
.await
451455
.map_err(|error| anyhow::anyhow!("failed to build exporter base: {error}"))?;
@@ -459,33 +463,44 @@ async fn benchmark_export(recording_path: &Path) -> Result<ExportMetrics> {
459463
};
460464

461465
let total_frames = exporter_base.total_frames(settings.fps);
466+
let sample_frames = total_frames.clamp(1, MAX_EXPORT_SAMPLE_FRAMES);
462467
let started_at = Instant::now();
463468
let last_frame = Arc::new(AtomicU32::new(0));
464469
let first_progress = Arc::new(Mutex::new(None));
465470
let progress_started_at = started_at;
466471
let progress_frame = Arc::clone(&last_frame);
467472
let progress_first = Arc::clone(&first_progress);
473+
let stop_after_frame = sample_frames;
468474

469-
let output_path = tokio::time::timeout(
475+
let export_result = tokio::time::timeout(
470476
Duration::from_secs(MAX_EXPORT_WALL_TIME_SECS),
471477
settings.export(exporter_base, move |frame| {
472478
progress_frame.store(frame, Ordering::Relaxed);
473479
let mut first = progress_first.lock().unwrap_or_else(|err| err.into_inner());
474480
if first.is_none() {
475481
*first = Some(progress_started_at.elapsed().as_secs_f64());
476482
}
477-
true
483+
frame.saturating_add(1) < stop_after_frame
478484
}),
479485
)
480486
.await
481-
.context("export timed out")?
482-
.map_err(anyhow::Error::msg)?;
487+
.context("export timed out")?;
483488

484489
let elapsed = started_at.elapsed();
485-
let rendered_frames = last_frame.load(Ordering::Relaxed).saturating_add(1);
490+
let rendered_frames = last_frame
491+
.load(Ordering::Relaxed)
492+
.saturating_add(1)
493+
.min(sample_frames);
486494
let first_progress_secs = *first_progress.lock().unwrap_or_else(|err| err.into_inner());
495+
let sampled_enough = rendered_frames >= sample_frames && first_progress_secs.is_some();
496+
497+
let output_path = match export_result {
498+
Ok(path) => path,
499+
Err(_error) if sampled_enough => planned_output_path.clone(),
500+
Err(error) => return Err(anyhow::Error::msg(error)),
501+
};
487502

488-
if !output_path.exists() {
503+
if !sampled_enough && !output_path.exists() {
489504
bail!(
490505
"Export completed but output is missing at {}",
491506
output_path.display()
@@ -496,7 +511,7 @@ async fn benchmark_export(recording_path: &Path) -> Result<ExportMetrics> {
496511
elapsed,
497512
first_progress_secs,
498513
output_path,
499-
total_frames,
514+
total_frames: sample_frames,
500515
rendered_frames,
501516
effective_fps: rendered_frames as f64 / elapsed.as_secs_f64().max(0.001),
502517
})

0 commit comments

Comments
 (0)