Skip to content

Commit 4d6fe47

Browse files
authored
Use of localhost and catching error if stat listener does not connect (#10)
1 parent 6f602a5 commit 4d6fe47

5 files changed

Lines changed: 62 additions & 22 deletions

File tree

engine/src/engine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ fn log_header(index: usize, permutations: &Vec<Permutation>, calc_time: Option<D
7777
pub fn spawn_ffmpeg_child(ffmpeg_args: &FfmpegArgs, verbose: bool, log_error_output: Option<bool>) -> Child {
7878
// log the full ffmpeg command to be spawned
7979
if verbose {
80-
println!("V: ffmpeg args: {:?}", ffmpeg_args.encoder_args);
80+
println!("V: ffmpeg args: [{}]", ffmpeg_args.to_string());
8181
let mut cloned = ffmpeg_args.clone();
8282
cloned.set_no_output_for_error();
83-
println!("V: ffmpeg args no network calls (copy this and run locally, minus the quotes): {:?}", cloned.encoder_args);
83+
println!("V: ffmpeg args no network calls (copy this and run locally, minus the quotes): [{}]", cloned.to_string());
8484
}
8585

8686
let mut effective_ffmpeg_args = ffmpeg_args.clone();

engine/src/permutation_engine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::progressbar::draw_yellow_bar;
1717
use crate::result::{log_results_to_file, PermutationResult};
1818
use crate::threads::setup_ctrl_channel;
1919

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

2222
// the hard-coded vmaf quality we want to shoot for when doing bitrate permutations
2323
const TARGET_QUALITY: c_float = 95.0;

engine/src/progressbar.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ impl Default for TrialResult {
2828
}
2929

3030
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 {
31+
// set this flag every second to see real-time fps statistics and other information
32+
let mut can_log_verbose = true;
33+
let verbose_log_interval = time::Duration::from_secs(1);
34+
let mut log_verbose_timer = SystemTime::now();
35+
3136
static FRAME: AtomicUsize = AtomicUsize::new(0);
3237
static PREVIOUS_FRAME: AtomicUsize = AtomicUsize::new(0);
3338

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

5560
let mut last_frame = 0;
61+
5662
loop {
63+
if log_verbose_timer.elapsed().unwrap() > verbose_log_interval {
64+
log_verbose_timer = SystemTime::now();
65+
can_log_verbose = true;
66+
}
67+
5768
// important to not get stuck in this thread
5869
exit_on_ctrl_c(&ctrl_channel);
5970

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

74+
if verbose && can_log_verbose {
75+
println!("V: Calculated fps: {}", calculated_fps);
76+
}
77+
6378
// only record fps counts that are close to 1/4 of the target; any lower is noise
6479
if calculated_fps >= (target_fps / 4) as u16 {
6580
trial_result.all_fps.push(calculated_fps);
@@ -104,6 +119,11 @@ pub fn watch_encode_progress(total_frames: u64, detect_overload: bool, target_fp
104119
break;
105120
}
106121
}
122+
123+
// always toggle off the verbose logger
124+
if can_log_verbose {
125+
can_log_verbose = false;
126+
}
107127
}
108128

109129
// change bar style as read

engine/src/stat_tcp_listener.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,56 @@
11
use std::io::{BufRead, BufReader};
22
use std::net::{TcpListener, TcpStream};
33
use std::num::ParseIntError;
4-
use std::process;
54
use std::sync::atomic::{AtomicUsize, Ordering};
5+
use std::thread::sleep;
6+
use std::time::{Duration, SystemTime};
67

78
use stoppable_thread::StoppableHandle;
9+
10+
use cli::cli_util::error_with_ack;
811
use ffmpeg::report_files::capture_group;
912

10-
static LOCALHOST: &str = "127.0.0.1";
13+
static LOCALHOST: &str = "localhost";
1114
static PORT: &str = "1234";
1215

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

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

23-
tcp_reading_thread = spawn_tcp_reading_thread(client.0, frame, previous_frame);
23+
let listen_start_time = SystemTime::now();
24+
let allowed_elapsed_time = Duration::from_secs(10);
25+
26+
loop {
27+
if listen_start_time.elapsed().unwrap() > allowed_elapsed_time {
28+
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);
29+
error_with_ack(true);
2430
}
25-
// probably log this error eventually
26-
Err(_e) => {
27-
println!("Not able to connect to client for reading stats, cannot proceed");
28-
process::exit(1);
31+
32+
// will try to connect for 10 seconds
33+
match stat_listener.accept() {
34+
Ok(client) => {
35+
if verbose {
36+
println!("Connected to ffmpeg's -progress output via TCP...");
37+
}
38+
39+
// making received client non-blocking, otherwise it dies pretty quick
40+
client.0.set_nonblocking(false).unwrap();
41+
tcp_reading_thread = spawn_tcp_reading_thread(client.0, frame, previous_frame);
42+
break;
43+
}
44+
// probably log this error eventually
45+
Err(_e) => {
46+
if verbose {
47+
println!("Not able to connect to ffmpeg stat output, will try again...");
48+
sleep(Duration::from_secs(1));
49+
}
50+
}
2951
}
3052
}
3153

32-
// eventually we'll want to add code where we kill the listener here
33-
3454
return tcp_reading_thread;
3555
}
3656

ffmpeg/src/args.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::ffi::c_float;
22

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

66
#[derive(Clone)]
@@ -72,7 +72,7 @@ impl FfmpegArgs {
7272

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

7878
if self.report {
@@ -198,14 +198,14 @@ mod tests {
198198
#[test]
199199
fn to_string_one_input_test() {
200200
assert_eq!(get_one_input_args().to_string(),
201-
"-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 -"
201+
"-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 -"
202202
);
203203
}
204204

205205
#[test]
206206
fn to_string_two_input_test() {
207207
assert_eq!(get_two_input_args().to_string(),
208-
"-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 -"
208+
"-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 -"
209209
);
210210
}
211211

@@ -227,7 +227,7 @@ mod tests {
227227
fn map_to_vmaf_to_string_test() {
228228
let vmaf_args = get_two_input_args().map_to_vmaf(FPS_LIMIT);
229229
assert_eq!(vmaf_args.to_string(),
230-
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())
230+
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())
231231
);
232232
}
233233

0 commit comments

Comments
 (0)