improve av-offset accuracy

This commit is contained in:
jazzfool 2024-10-17 15:45:46 +11:00
parent b0b092d9e2
commit 2c55d14dbe

View file

@ -62,6 +62,8 @@ pub(crate) struct Internal {
pub(crate) looping: bool, pub(crate) looping: bool,
pub(crate) is_eos: bool, pub(crate) is_eos: bool,
pub(crate) restart_stream: bool, pub(crate) restart_stream: bool,
pub(crate) sync_av_avg: u64,
pub(crate) sync_av_counter: u64,
} }
impl Internal { impl Internal {
@ -143,8 +145,13 @@ impl Internal {
/// Syncs audio with video when there is (inevitably) latency presenting the frame. /// Syncs audio with video when there is (inevitably) latency presenting the frame.
pub(crate) fn set_av_offset(&mut self, offset: Duration) { pub(crate) fn set_av_offset(&mut self, offset: Duration) {
if self.sync_av { if self.sync_av {
self.sync_av_counter += 1;
self.sync_av_avg = self.sync_av_avg * (self.sync_av_counter - 1) / self.sync_av_counter
+ offset.as_nanos() as u64 / self.sync_av_counter;
if self.sync_av_counter % 128 == 0 {
self.source self.source
.set_property("av-offset", -(offset.as_nanos() as i64)); .set_property("av-offset", -(self.sync_av_avg as i64));
}
} }
} }
} }
@ -273,6 +280,10 @@ impl Video {
.ok_or(gst::FlowError::Eos)? .ok_or(gst::FlowError::Eos)?
}; };
*last_frame_time_ref
.lock()
.map_err(|_| gst::FlowError::Error)? = Instant::now();
let buffer = sample.buffer().ok_or(gst::FlowError::Error)?; let buffer = sample.buffer().ok_or(gst::FlowError::Error)?;
let map = buffer.map_readable().map_err(|_| gst::FlowError::Error)?; let map = buffer.map_readable().map_err(|_| gst::FlowError::Error)?;
@ -280,9 +291,6 @@ impl Video {
let frame_len = frame.len(); let frame_len = frame.len();
frame.copy_from_slice(&map.as_slice()[..frame_len]); frame.copy_from_slice(&map.as_slice()[..frame_len]);
*last_frame_time_ref
.lock()
.map_err(|_| gst::FlowError::Error)? = Instant::now();
upload_frame_ref.swap(true, Ordering::SeqCst); upload_frame_ref.swap(true, Ordering::SeqCst);
Ok(()) Ok(())
@ -314,6 +322,8 @@ impl Video {
looping: false, looping: false,
is_eos: false, is_eos: false,
restart_stream: false, restart_stream: false,
sync_av_avg: 0,
sync_av_counter: 0,
}))) })))
} }