handle invalid framerate, check for av-offset property

This commit is contained in:
jazzfool 2024-10-07 19:23:21 +11:00
parent cd978e34e5
commit b4fceafe1f
2 changed files with 18 additions and 2 deletions

View file

@ -71,4 +71,6 @@ pub enum Error {
Sync,
#[error("failed to lock internal sync primitive")]
Lock,
#[error("invalid framerate: {0}")]
Framerate(f64),
}

View file

@ -53,6 +53,7 @@ pub(crate) struct Internal {
pub(crate) framerate: f64,
pub(crate) duration: std::time::Duration,
pub(crate) speed: f64,
pub(crate) sync_av: bool,
pub(crate) frame: Arc<Mutex<Vec<u8>>>,
pub(crate) upload_frame: Arc<AtomicBool>,
@ -141,10 +142,12 @@ impl Internal {
/// Syncs audio with video when there is (inevitably) latency presenting the frame.
pub(crate) fn set_av_offset(&mut self, offset: Duration) {
if self.sync_av {
self.source
.set_property("av-offset", -(offset.as_nanos() as i64));
}
}
}
/// A multimedia video loaded from a URI (e.g., a local file path or HTTP stream).
pub struct Video(pub(crate) RefCell<Internal>);
@ -220,6 +223,14 @@ impl Video {
.map_err(|_| Error::Caps)?;
let framerate = framerate.numer() as f64 / framerate.denom() as f64;
if framerate.is_nan()
|| framerate.is_infinite()
|| framerate < 0.0
|| framerate.abs() < f64::EPSILON
{
return Err(Error::Framerate(framerate));
}
let duration = std::time::Duration::from_nanos(
pipeline
.query_duration::<gst::ClockTime>()
@ -227,6 +238,8 @@ impl Video {
.unwrap_or(0),
);
let sync_av = pipeline.has_property("av-offset", None);
// NV12 = 12bpp
let frame = Arc::new(Mutex::new(vec![
0u8;
@ -293,6 +306,7 @@ impl Video {
framerate,
duration,
speed: 1.0,
sync_av,
frame,
upload_frame,