]> git.nihav.org Git - nihav.git/commitdiff
Introduce muxer quirks
authorKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 13 Mar 2025 17:28:33 +0000 (18:28 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 13 Mar 2025 17:28:33 +0000 (18:28 +0100)
This will allow nihav-encoder to deal better with certain peculiarities
of some formats in more generic way (e.g. make sure Bink muxer gets
the number of output frames or enforce fixed frame rate on transcoding
to AVI).

nihav-commonfmt/src/muxers/avi.rs
nihav-commonfmt/src/muxers/gif.rs
nihav-commonfmt/src/muxers/wav.rs
nihav-commonfmt/src/muxers/y4m.rs
nihav-core/src/muxers/mod.rs
nihav-flash/src/muxers/flv.rs
nihav-game/src/muxers/ea.rs
nihav-llaudio/src/muxers/flac.rs
nihav-rad/src/muxers/bink.rs
nihav-realmedia/src/muxers/rmvb/mod.rs

index 136d255493b0eb342d76ef0ebec86f223ef380be..972a7ca0f6bf3944397316f72ad065141552882e 100644 (file)
@@ -356,6 +356,7 @@ impl MuxerCreator for AVIMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "avi" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::Universal }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks(MUX_QUIRK_FIXED_RATE) }
 }
 
 #[cfg(test)]
index 435d1b887fa2618a723018db8d75a35ba7cd1404..13ca8180d37e0002be6a4ae10e61ecde2b75507e 100644 (file)
@@ -195,6 +195,7 @@ impl MuxerCreator for GIFMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "gif" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleVideo("gif") }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks(MUX_QUIRK_FIXED_RATE) }
 }
 
 #[cfg(test)]
index 1317b95e3e65d57630fa3bfa62c8a619e49d0dc9..5b20677b4c65acc38c887c33c9624bb6f5421a7a 100644 (file)
@@ -112,6 +112,7 @@ impl MuxerCreator for WAVMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "wav" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleAudio("any") }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks::new() }
 }
 
 #[cfg(test)]
index 600f78e8a16863adbfc42ef195855aaccc896e60..1d0ad38c7e0a709616e161c4155002aceaaac517 100644 (file)
@@ -83,6 +83,7 @@ impl MuxerCreator for Y4MMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "yuv4mpeg" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleVideo("rawvideo") }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks(MUX_QUIRK_FIXED_RATE) }
 }
 
 #[cfg(test)]
index eb71df5ec36b2f7e57ee10f013ed5470bc2b112c..4df7c4a0964a904243e255a34e0a5bd896a8ef33 100644 (file)
@@ -54,6 +54,45 @@ impl From<ByteIOError> for MuxerError {
     fn from(_: ByteIOError) -> Self { MuxerError::IOError }
 }
 
+/// Muxer quirks (i.e. peculiarities in muxer behaviour like accepting only frames of fixed duration)
+#[derive(Clone,Copy,Default)]
+pub struct MuxerQuirks(pub u32);
+
+/// Muxer expects all packets of one stream to have the same duration.
+pub const MUX_QUIRK_FIXED_RATE: u32         = 1 <<  0;
+/// Muxer expects to know full duration in advance.
+pub const MUX_QUIRK_FIXED_DURATION: u32     = 1 <<  1;
+/// Muxer does not care about synchronisation of the stream.
+pub const MUX_QUIRK_UNSYNC: u32            = 1 <<  2;
+
+impl MuxerQuirks {
+    /// Creates a new instance of `MuxerQuirks`
+    pub fn new() -> Self { Self::default() }
+
+    /// Queries if the muxer expects all packets of one stream to have the same duration.
+    pub fn is_fixed_rate(self) -> bool { (self.0 & MUX_QUIRK_FIXED_RATE) != 0 }
+    /// Tells that muxer expects all packets of one stream to have the same duration.
+    pub fn set_fixed_rate(&mut self) { self.0 |= MUX_QUIRK_FIXED_RATE; }
+    /// Tells that muxer does not expect all packets of one stream to have the same duration.
+    pub fn clear_fixed_rate(&mut self) { self.0 &= !MUX_QUIRK_FIXED_RATE; }
+
+    /// Queries if the muxer expects to know full duration in advance.
+    pub fn is_fixed_duration(self) -> bool { (self.0 & MUX_QUIRK_FIXED_DURATION) != 0 }
+    /// Tells that muxer expects to know full duration in advance.
+    pub fn set_fixed_duration(&mut self) { self.0 |= MUX_QUIRK_FIXED_DURATION; }
+    /// Tells that muxer does not expect to know full duration in advance.
+    pub fn clear_fixed_duration(&mut self) { self.0 &= !MUX_QUIRK_FIXED_DURATION; }
+
+
+    /// Queries if the muxer does not care about stream synchronisation.
+    pub fn is_unsync(self) -> bool { (self.0 & MUX_QUIRK_UNSYNC) != 0 }
+    /// Tells that muxer does not care about stream synchronisation.
+    pub fn set_unsync(&mut self) { self.0 |= MUX_QUIRK_UNSYNC; }
+    /// Tells that muxer actually cares about streams being synchronised.
+    pub fn clear_unsync(&mut self) { self.0 &= !MUX_QUIRK_UNSYNC; }
+}
+
+
 /// A trait for muxing operations.
 pub trait MuxCore<'a>: NAOptionHandler {
     /// Prepares everything for packet muxing.
@@ -131,6 +170,8 @@ pub trait MuxerCreator {
     fn get_name(&self) -> &'static str;
     /// Returns muxer capabilities for the current muxer.
     fn get_capabilities(&self) -> MuxerCapabilities;
+    /// Returns current muxer quirks.
+    fn get_quirks(&self) -> MuxerQuirks;
 }
 
 /// Creates muxer for a provided bytestream writer.
index 3ff9bee5a39ea093596f326c969a3ba4a50b827a..2ab2c5b9073a60077f9df3e61f6b9cfd98fe4db2 100644 (file)
@@ -287,6 +287,7 @@ impl MuxerCreator for FLVMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "flv" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleVideoAndAudio("any", "any") }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks::new() }
 }
 
 #[cfg(test)]
index 8a4816531bc6ccb0eb1cdd1cdb6f8d3d2ce51122..3aa42125e8b1a6a205c836bc0abc344bbf598fee 100644 (file)
@@ -123,6 +123,7 @@ impl MuxerCreator for EAMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "ea" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::OnlyVideo }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks(MUX_QUIRK_FIXED_RATE) }
 }
 
 #[cfg(test)]
index fb54a8976e07381043a901370393b12161d46eff..130aaeb60570bbbb06735c6d27ac18401e5e6c6e 100644 (file)
@@ -94,6 +94,7 @@ impl MuxerCreator for FLACMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "flac" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleAudio("flac") }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks::new() }
 }
 
 #[cfg(test)]
index 3a7240dac9c2ef62eb69afd403a07579d244ddc8..adf8af7feb3e4e21708a04dffab8a52a38fdbb22 100644 (file)
@@ -236,6 +236,7 @@ impl MuxerCreator for BinkMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "bink" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::Universal }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks(MUX_QUIRK_FIXED_RATE | MUX_QUIRK_FIXED_DURATION) }
 }
 
 #[cfg(test)]
index 1d08f4d0b83854f3562b3d53bd261d6b623a95c4..f8bdaa287c0e58cebdcd56547397c608064fc525 100644 (file)
@@ -406,6 +406,7 @@ impl MuxerCreator for RealMediaMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "realmedia" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::Universal }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks::new() }
 }
 
 struct RAMuxer<'a> {
@@ -473,6 +474,7 @@ impl MuxerCreator for RealAudioMuxerCreator {
     }
     fn get_name(&self) -> &'static str { "realaudio" }
     fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleAudio("any") }
+    fn get_quirks(&self) -> MuxerQuirks { MuxerQuirks::new() }
 }
 
 #[cfg(test)]