Run video decoder on thread, fixing sync issues

This commit is contained in:
Jeremy Soller 2024-01-24 20:13:55 -07:00
parent a79f21329d
commit 48ba7e7278
No known key found for this signature in database
GPG key ID: DCFCA852D3906975

View file

@ -205,15 +205,27 @@ fn ffmpeg_thread<P: AsRef<Path>>(
} }
}); });
let mut receive_and_process_decoded_video_frames = let (video_packet_tx, video_packet_rx) = mpsc::channel();
|decoder: &mut ffmpeg::decoder::Video| -> Result<(), ffmpeg::Error> { thread::spawn(move || -> Result<(), ffmpeg::Error> {
let mut eof = false;
while !eof {
let start = Instant::now(); let start = Instant::now();
match video_packet_rx.recv() {
Ok(packet) => {
video_decoder.send_packet(&packet)?;
}
Err(_err) => {
video_decoder.send_eof()?;
eof = true;
}
}
let mut pts = None; let mut pts = None;
let mut video_frames = 0; let mut video_frames = 0;
loop { loop {
let mut raw_frame = Video::empty(); let mut raw_frame = Video::empty();
if decoder.receive_frame(&mut raw_frame).is_ok() { if video_decoder.receive_frame(&mut raw_frame).is_ok() {
pts = raw_frame.pts(); pts = raw_frame.pts();
raw_frame_tx.send(raw_frame).unwrap(); raw_frame_tx.send(raw_frame).unwrap();
video_frames += 1; video_frames += 1;
@ -231,9 +243,9 @@ fn ffmpeg_thread<P: AsRef<Path>>(
duration duration
); );
} }
}
Ok(()) Ok(())
}; });
let audio_stream = ictx let audio_stream = ictx
.streams() .streams()
@ -303,7 +315,7 @@ fn ffmpeg_thread<P: AsRef<Path>>(
if expected > actual { if expected > actual {
let sleep = expected - actual; let sleep = expected - actual;
if sleep > min_sleep { if sleep > min_sleep {
// We leave 1ms of buffer room // We leave min_sleep of buffer room
thread::sleep(sleep - min_sleep); thread::sleep(sleep - min_sleep);
} }
} else { } else {
@ -318,18 +330,15 @@ fn ffmpeg_thread<P: AsRef<Path>>(
}; };
for (stream, packet) in ictx.packets() { for (stream, packet) in ictx.packets() {
let start = Instant::now();
if stream.index() == video_stream_index { if stream.index() == video_stream_index {
video_decoder.send_packet(&packet)?; video_packet_tx.send(packet).unwrap();
receive_and_process_decoded_video_frames(&mut video_decoder)?;
} else if stream.index() == audio_stream_index { } else if stream.index() == audio_stream_index {
audio_decoder.send_packet(&packet)?; audio_decoder.send_packet(&packet)?;
receive_and_process_decoded_audio_frames(&mut audio_decoder)?; receive_and_process_decoded_audio_frames(&mut audio_decoder)?;
} }
} }
video_decoder.send_eof()?;
receive_and_process_decoded_video_frames(&mut video_decoder)?;
audio_decoder.send_eof()?; audio_decoder.send_eof()?;
receive_and_process_decoded_audio_frames(&mut audio_decoder)?; receive_and_process_decoded_audio_frames(&mut audio_decoder)?;