@@ -30,7 +30,8 @@ const PLAYBACK_RESOLUTION: XY<u32> = XY::new(1920, 1080);
3030const MAX_PLAYBACK_FAILURE_RATE : f64 = 5.0 ;
3131const MAX_OPEN_TIME_SECS : f64 = 30.0 ;
3232const 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
3536pub 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
444448async 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