Improve audio sync
This commit is contained in:
parent
09fc0d1cb8
commit
e2bb8cf5e1
1 changed files with 24 additions and 13 deletions
|
|
@ -264,8 +264,8 @@ fn ffmpeg_thread<P: AsRef<Path>>(
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut start_time_opt = None;
|
let mut start_time_opt = None;
|
||||||
let mut start_pts = 0;
|
let mut start_sample = 0;
|
||||||
let mut end_pts = 0;
|
let mut end_sample = 0;
|
||||||
let mut receive_and_process_decoded_audio_frames =
|
let mut receive_and_process_decoded_audio_frames =
|
||||||
|decoder: &mut ffmpeg::decoder::Audio| -> Result<(), ffmpeg::Error> {
|
|decoder: &mut ffmpeg::decoder::Audio| -> Result<(), ffmpeg::Error> {
|
||||||
let mut decoded = Audio::empty();
|
let mut decoded = Audio::empty();
|
||||||
|
|
@ -273,9 +273,9 @@ fn ffmpeg_thread<P: AsRef<Path>>(
|
||||||
while decoder.receive_frame(&mut decoded).is_ok() {
|
while decoder.receive_frame(&mut decoded).is_ok() {
|
||||||
if start_time_opt.is_none() {
|
if start_time_opt.is_none() {
|
||||||
start_time_opt = Some(Instant::now());
|
start_time_opt = Some(Instant::now());
|
||||||
start_pts = decoded.pts().unwrap_or(0);
|
start_sample = end_sample;
|
||||||
}
|
}
|
||||||
end_pts = decoded.pts().unwrap_or(start_pts);
|
end_sample += decoded.samples();
|
||||||
|
|
||||||
audio_resampler.run(&decoded, &mut resampled)?;
|
audio_resampler.run(&decoded, &mut resampled)?;
|
||||||
{
|
{
|
||||||
|
|
@ -295,25 +295,36 @@ fn ffmpeg_thread<P: AsRef<Path>>(
|
||||||
|
|
||||||
// Sync with audio
|
// Sync with audio
|
||||||
if let Some(start_time) = &start_time_opt {
|
if let Some(start_time) = &start_time_opt {
|
||||||
let pts_diff = end_pts - start_pts;
|
let samples = end_sample - start_sample;
|
||||||
let expected_rational = Rational::new(pts_diff as i32, 1) * decoder.time_base();
|
let expected_float = samples as f64 * f64::from(decoder.time_base());
|
||||||
let expected_float = f64::from(expected_rational);
|
|
||||||
let expected = Duration::from_secs_f64(expected_float);
|
let expected = Duration::from_secs_f64(expected_float);
|
||||||
|
println!(
|
||||||
|
"PTS {}..{} => {} * {:?} => {}",
|
||||||
|
start_sample,
|
||||||
|
end_sample,
|
||||||
|
samples,
|
||||||
|
decoder.time_base(),
|
||||||
|
expected_float
|
||||||
|
);
|
||||||
let actual = start_time.elapsed();
|
let actual = start_time.elapsed();
|
||||||
if expected > actual {
|
if expected > actual {
|
||||||
let sleep = expected - actual;
|
let sleep = expected - actual;
|
||||||
println!(
|
let min_sleep = Duration::from_millis(1);
|
||||||
"expected {:?} - actual {:?} = sleep {:?}",
|
if sleep > min_sleep {
|
||||||
actual, expected, sleep
|
println!(
|
||||||
);
|
"expected {:?} - actual {:?} = sleep {:?}",
|
||||||
thread::sleep(sleep);
|
actual, expected, sleep
|
||||||
|
);
|
||||||
|
// We leave 1s of buffer room
|
||||||
|
thread::sleep(sleep - min_sleep);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let skip = actual - expected;
|
let skip = actual - expected;
|
||||||
println!(
|
println!(
|
||||||
"actual {:?} - expected {:?} = skip {:?}",
|
"actual {:?} - expected {:?} = skip {:?}",
|
||||||
actual, expected, skip
|
actual, expected, skip
|
||||||
);
|
);
|
||||||
//TODO: skip frames?
|
//TODO: handle skipping
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue