Run video decoder on thread, fixing sync issues
This commit is contained in:
parent
a79f21329d
commit
48ba7e7278
1 changed files with 21 additions and 12 deletions
|
|
@ -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)?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue