diff --git a/av1an-core/src/progress_bar.rs b/av1an-core/src/progress_bar.rs index f15414a1..005daea1 100644 --- a/av1an-core/src/progress_bar.rs +++ b/av1an-core/src/progress_bar.rs @@ -1,7 +1,9 @@ use std::fmt::Write; +use std::time::Duration; use indicatif::{ - HumanBytes, MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, ProgressStyle, + HumanBytes, HumanDuration, MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, + ProgressStyle, }; use once_cell::sync::OnceCell; @@ -13,9 +15,9 @@ const PROGRESS_CHARS: &str = "█▉▊▋▌▍▎▏ "; const INDICATIF_PROGRESS_TEMPLATE: &str = if cfg!(windows) { // Do not use a spinner on Windows since the default console cannot display // the characters used for the spinner - "{elapsed_precise:.bold} ▕{wide_bar:.blue/white.dim}▏ {percent:.bold} {pos} ({fps:.bold}, eta {eta}{msg})" + "{elapsed_precise:.bold} ▕{wide_bar:.blue/white.dim}▏ {percent:.bold} {pos} ({fps:.bold}, eta {fixed_eta}{msg})" } else { - "{spinner:.green.bold} {elapsed_precise:.bold} ▕{wide_bar:.blue/white.dim}▏ {percent:.bold} {pos} ({fps:.bold}, eta {eta}{msg})" + "{spinner:.green.bold} {elapsed_precise:.bold} ▕{wide_bar:.blue/white.dim}▏ {percent:.bold} {pos} ({fps:.bold}, eta {fixed_eta}{msg})" }; const INDICATIF_SPINNER_TEMPLATE: &str = if cfg!(windows) { @@ -36,14 +38,32 @@ fn pretty_progress_style() -> ProgressStyle { ProgressStyle::default_bar() .template(INDICATIF_PROGRESS_TEMPLATE) .unwrap() - .with_key( - "fps", - |state: &ProgressState, w: &mut dyn Write| match state.per_sec() { - fps if fps.abs() < f64::EPSILON => write!(w, "0 fps").unwrap(), - fps if fps < 1.0 => write!(w, "{:.2} s/fr", 1.0 / fps).unwrap(), - fps => write!(w, "{:.2} fps", fps).unwrap(), - }, - ) + .with_key("fps", |state: &ProgressState, w: &mut dyn Write| { + if state.pos() == 0 || state.elapsed().as_secs_f32() < f32::EPSILON { + write!(w, "0 fps").unwrap(); + } else { + let fps = state.pos() as f32 / state.elapsed().as_secs_f32(); + if fps < 1.0 { + write!(w, "{:.2} s/fr", 1.0 / fps).unwrap(); + } else { + write!(w, "{:.2} fps", fps).unwrap(); + } + } + }) + .with_key("fixed_eta", |state: &ProgressState, w: &mut dyn Write| { + if state.pos() == 0 || state.elapsed().as_secs_f32() < f32::EPSILON { + write!(w, "unknown").unwrap(); + } else { + let spf = state.elapsed().as_secs_f32() / state.pos() as f32; + let remaining = state.len().unwrap_or(0) - state.pos(); + write!( + w, + "{:#}", + HumanDuration(Duration::from_secs_f32(spf * remaining as f32)) + ) + .unwrap(); + } + }) .with_key("pos", |state: &ProgressState, w: &mut dyn Write| { write!(w, "{}/{}", state.pos(), state.len().unwrap_or(0)).unwrap(); }) @@ -57,14 +77,18 @@ fn spinner_style() -> ProgressStyle { ProgressStyle::default_spinner() .template(INDICATIF_SPINNER_TEMPLATE) .unwrap() - .with_key( - "fps", - |state: &ProgressState, w: &mut dyn Write| match state.per_sec() { - fps if fps.abs() < f64::EPSILON => write!(w, "0 fps").unwrap(), - fps if fps < 1.0 => write!(w, "{:.2} s/fr", 1.0 / fps).unwrap(), - fps => write!(w, "{:.2} fps", fps).unwrap(), - }, - ) + .with_key("fps", |state: &ProgressState, w: &mut dyn Write| { + if state.pos() == 0 || state.elapsed().as_secs_f32() < f32::EPSILON { + write!(w, "0 fps").unwrap(); + } else { + let fps = state.pos() as f32 / state.elapsed().as_secs_f32(); + if fps < 1.0 { + write!(w, "{:.2} s/fr", 1.0 / fps).unwrap(); + } else { + write!(w, "{:.2} fps", fps).unwrap(); + } + } + }) .with_key("pos", |state: &ProgressState, w: &mut dyn Write| { write!(w, "{}", state.pos()).unwrap(); }) @@ -81,8 +105,8 @@ pub fn init_progress_bar(len: u64) { // Affects scenechange progress. PROGRESS_BAR.get_or_init(|| ProgressBar::new(len).with_style(spinner_style())) }; - pb.set_draw_target(ProgressDrawTarget::stderr_with_hz(60)); - // pb.enable_steady_tick(Duration::from_millis(100)); + pb.set_draw_target(ProgressDrawTarget::stderr()); + pb.enable_steady_tick(Duration::from_millis(100)); pb.reset(); pb.reset_eta(); pb.reset_elapsed(); @@ -186,7 +210,7 @@ pub fn init_multi_progress_bar(len: u64, workers: usize, total_chunks: usize) { let pb = ProgressBar::hidden(); pb.set_style(pretty_progress_style()); - // pb.enable_steady_tick(Duration::from_millis(100)); + pb.enable_steady_tick(Duration::from_millis(100)); pb.reset_elapsed(); pb.reset_eta(); pb.set_position(0); @@ -194,7 +218,7 @@ pub fn init_multi_progress_bar(len: u64, workers: usize, total_chunks: usize) { pb.reset(); pbs.push(mpb.add(pb)); - mpb.set_draw_target(ProgressDrawTarget::stderr_with_hz(60)); + mpb.set_draw_target(ProgressDrawTarget::stderr()); (mpb, pbs) });