Skip to content

Commit

Permalink
Use of localhost and catching error if stat listener does not connect (
Browse files Browse the repository at this point in the history
  • Loading branch information
Proryanator authored Mar 11, 2023
1 parent 6f602a5 commit 4d6fe47
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 22 deletions.
4 changes: 2 additions & 2 deletions engine/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ fn log_header(index: usize, permutations: &Vec<Permutation>, calc_time: Option<D
pub fn spawn_ffmpeg_child(ffmpeg_args: &FfmpegArgs, verbose: bool, log_error_output: Option<bool>) -> Child {
// log the full ffmpeg command to be spawned
if verbose {
println!("V: ffmpeg args: {:?}", ffmpeg_args.encoder_args);
println!("V: ffmpeg args: [{}]", ffmpeg_args.to_string());
let mut cloned = ffmpeg_args.clone();
cloned.set_no_output_for_error();
println!("V: ffmpeg args no network calls (copy this and run locally, minus the quotes): {:?}", cloned.encoder_args);
println!("V: ffmpeg args no network calls (copy this and run locally, minus the quotes): [{}]", cloned.to_string());
}

let mut effective_ffmpeg_args = ffmpeg_args.clone();
Expand Down
2 changes: 1 addition & 1 deletion engine/src/permutation_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::progressbar::draw_yellow_bar;
use crate::result::{log_results_to_file, PermutationResult};
use crate::threads::setup_ctrl_channel;

pub static TCP_OUTPUT: &str = "-f {} tcp://127.0.0.1:2000";
pub static TCP_OUTPUT: &str = "-f {} tcp://localhost:2000";

// the hard-coded vmaf quality we want to shoot for when doing bitrate permutations
const TARGET_QUALITY: c_float = 95.0;
Expand Down
20 changes: 20 additions & 0 deletions engine/src/progressbar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ impl Default for TrialResult {
}

pub fn watch_encode_progress(total_frames: u64, detect_overload: bool, target_fps: u32, verbose: bool, stats_period: c_float, ctrl_channel: &Result<Receiver<()>, Error>) -> TrialResult {
// set this flag every second to see real-time fps statistics and other information
let mut can_log_verbose = true;
let verbose_log_interval = time::Duration::from_secs(1);
let mut log_verbose_timer = SystemTime::now();

static FRAME: AtomicUsize = AtomicUsize::new(0);
static PREVIOUS_FRAME: AtomicUsize = AtomicUsize::new(0);

Expand All @@ -53,13 +58,23 @@ pub fn watch_encode_progress(total_frames: u64, detect_overload: bool, target_fp
let stat_listener = start_listening_to_ffmpeg_stats(verbose, &FRAME, &PREVIOUS_FRAME);

let mut last_frame = 0;

loop {
if log_verbose_timer.elapsed().unwrap() > verbose_log_interval {
log_verbose_timer = SystemTime::now();
can_log_verbose = true;
}

// important to not get stuck in this thread
exit_on_ctrl_c(&ctrl_channel);

// takes into account the stat update period to properly adjust the calculated FPS
let calculated_fps = ((FRAME.load(Ordering::Relaxed) - PREVIOUS_FRAME.load(Ordering::Relaxed)) * interval_adjustment) as u16;

if verbose && can_log_verbose {
println!("V: Calculated fps: {}", calculated_fps);
}

// only record fps counts that are close to 1/4 of the target; any lower is noise
if calculated_fps >= (target_fps / 4) as u16 {
trial_result.all_fps.push(calculated_fps);
Expand Down Expand Up @@ -104,6 +119,11 @@ pub fn watch_encode_progress(total_frames: u64, detect_overload: bool, target_fp
break;
}
}

// always toggle off the verbose logger
if can_log_verbose {
can_log_verbose = false;
}
}

// change bar style as read
Expand Down
48 changes: 34 additions & 14 deletions engine/src/stat_tcp_listener.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,56 @@
use std::io::{BufRead, BufReader};
use std::net::{TcpListener, TcpStream};
use std::num::ParseIntError;
use std::process;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread::sleep;
use std::time::{Duration, SystemTime};

use stoppable_thread::StoppableHandle;

use cli::cli_util::error_with_ack;
use ffmpeg::report_files::capture_group;

static LOCALHOST: &str = "127.0.0.1";
static LOCALHOST: &str = "localhost";
static PORT: &str = "1234";

pub fn start_listening_to_ffmpeg_stats(verbose: bool, frame: &'static AtomicUsize, previous_frame: &'static AtomicUsize) -> StoppableHandle<()> {
let stat_listener = TcpListener::bind(format!("{}:{}", LOCALHOST, PORT)).unwrap();
// important so that this thread doesn't just hang here
stat_listener.set_nonblocking(true).expect("Unable to set non-blocking for tcp listener, listener might block...");

let tcp_reading_thread;
match stat_listener.accept() {
Ok(client) => {
if verbose {
println!("Connected to ffmpeg's -progress output via TCP...");
}

tcp_reading_thread = spawn_tcp_reading_thread(client.0, frame, previous_frame);
let listen_start_time = SystemTime::now();
let allowed_elapsed_time = Duration::from_secs(10);

loop {
if listen_start_time.elapsed().unwrap() > allowed_elapsed_time {
println!("Unable to connect to ffmpeg output for {} seconds, either ffmpeg didn't start correctly or the tcp connection: {}:{} could not be created...", allowed_elapsed_time.as_secs(), LOCALHOST, PORT);
error_with_ack(true);
}
// probably log this error eventually
Err(_e) => {
println!("Not able to connect to client for reading stats, cannot proceed");
process::exit(1);

// will try to connect for 10 seconds
match stat_listener.accept() {
Ok(client) => {
if verbose {
println!("Connected to ffmpeg's -progress output via TCP...");
}

// making received client non-blocking, otherwise it dies pretty quick
client.0.set_nonblocking(false).unwrap();
tcp_reading_thread = spawn_tcp_reading_thread(client.0, frame, previous_frame);
break;
}
// probably log this error eventually
Err(_e) => {
if verbose {
println!("Not able to connect to ffmpeg stat output, will try again...");
sleep(Duration::from_secs(1));
}
}
}
}

// eventually we'll want to add code where we kill the listener here

return tcp_reading_thread;
}

Expand Down
10 changes: 5 additions & 5 deletions ffmpeg/src/args.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::ffi::c_float;

pub static TCP_LISTEN: &str = "tcp://127.0.0.1:2000?listen";
pub static TCP_LISTEN: &str = "tcp://localhost:2000?listen";
pub static NO_OUTPUT: &str = "-f null -";

#[derive(Clone)]
Expand Down Expand Up @@ -72,7 +72,7 @@ impl FfmpegArgs {

// not all will want to send progress
if self.send_progress {
output.push_str(format!("-progress tcp://127.0.0.1:1234 -stats_period {} ", self.stats_period).as_str());
output.push_str(format!("-progress tcp://localhost:1234 -stats_period {} ", self.stats_period).as_str());
}

if self.report {
Expand Down Expand Up @@ -198,14 +198,14 @@ mod tests {
#[test]
fn to_string_one_input_test() {
assert_eq!(get_one_input_args().to_string(),
"-progress tcp://127.0.0.1:1234 -stats_period 0.5 -i 1080-60.y4m -b:v 6M -c:v h264_nvenc -preset hq -tune hq -profile:v high -rc cbr -multipass qres -rc-lookahead 8 -f null -"
"-progress tcp://localhost:1234 -stats_period 0.5 -i 1080-60.y4m -b:v 6M -c:v h264_nvenc -preset hq -tune hq -profile:v high -rc cbr -multipass qres -rc-lookahead 8 -f null -"
);
}

#[test]
fn to_string_two_input_test() {
assert_eq!(get_two_input_args().to_string(),
"-progress tcp://127.0.0.1:1234 -stats_period 0.5 -i 1080-60.y4m -i 1080-60-2.y4m -b:v 6M -c:v h264_nvenc -preset hq -tune hq -profile:v high -rc cbr -multipass qres -rc-lookahead 8 -f null -"
"-progress tcp://localhost:1234 -stats_period 0.5 -i 1080-60.y4m -i 1080-60-2.y4m -b:v 6M -c:v h264_nvenc -preset hq -tune hq -profile:v high -rc cbr -multipass qres -rc-lookahead 8 -f null -"
);
}

Expand All @@ -227,7 +227,7 @@ mod tests {
fn map_to_vmaf_to_string_test() {
let vmaf_args = get_two_input_args().map_to_vmaf(FPS_LIMIT);
assert_eq!(vmaf_args.to_string(),
format!("-report -r {} -i tcp://127.0.0.1:2000?listen -r {} -i 1080-60.y4m -filter_complex libvmaf='n_threads={}:n_subsample=5' -f null -", FPS_LIMIT, FPS_LIMIT, num_cpus::get().to_string())
format!("-report -r {} -i tcp://localhost:2000?listen -r {} -i 1080-60.y4m -filter_complex libvmaf='n_threads={}:n_subsample=5' -f null -", FPS_LIMIT, FPS_LIMIT, num_cpus::get().to_string())
);
}

Expand Down

0 comments on commit 4d6fe47

Please sign in to comment.