diff --git a/Gir_GstAudio.toml b/Gir_GstAudio.toml index b71999fea..6cb73be93 100644 --- a/Gir_GstAudio.toml +++ b/Gir_GstAudio.toml @@ -65,6 +65,9 @@ conversion_type = "scalar" name = "GstAudio.AudioFormat" status = "generate" + [[object.derive]] + name = "Debug, Eq, PartialEq, Hash" + [[object.member]] name = "s16" # Platform dependant diff --git a/gstreamer-audio/src/audio_format.rs b/gstreamer-audio/src/audio_format.rs index cb8cc05e8..cd4ba5d58 100644 --- a/gstreamer-audio/src/audio_format.rs +++ b/gstreamer-audio/src/audio_format.rs @@ -124,6 +124,18 @@ impl fmt::Display for ::AudioFormat { } } +impl PartialOrd for ::AudioFormat { + fn partial_cmp(&self, other: &::AudioFormat) -> Option { + ::AudioFormatInfo::from_format(*self).partial_cmp(&::AudioFormatInfo::from_format(*other)) + } +} + +impl Ord for ::AudioFormat { + fn cmp(&self, other: &::AudioFormat) -> std::cmp::Ordering { + ::AudioFormatInfo::from_format(*self).cmp(&::AudioFormatInfo::from_format(*other)) + } +} + pub const AUDIO_FORMAT_UNKNOWN: ::AudioFormat = ::AudioFormat::Unknown; pub const AUDIO_FORMAT_ENCODED: ::AudioFormat = ::AudioFormat::Encoded; pub const AUDIO_FORMAT_S8: ::AudioFormat = ::AudioFormat::S8; @@ -341,4 +353,15 @@ mod tests { .build(); assert_eq!(caps.to_string(), "audio/x-raw, format=(string){ S16LE, S16BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string)interleaved"); } + + #[test] + fn sort() { + gst::init().unwrap(); + + assert!( + ::AudioFormatInfo::from_format(::AudioFormat::F64be) + > ::AudioFormatInfo::from_format(::AudioFormat::U8) + ); + assert!(::AudioFormat::S20be > ::AudioFormat::S18be); + } } diff --git a/gstreamer-audio/src/audio_format_info.rs b/gstreamer-audio/src/audio_format_info.rs index d66f2349c..b1fe6a06f 100644 --- a/gstreamer-audio/src/audio_format_info.rs +++ b/gstreamer-audio/src/audio_format_info.rs @@ -10,6 +10,7 @@ use glib_sys; use gobject_sys; use gst_audio_sys; +use std::cmp::Ordering; use std::ffi::CStr; use std::fmt; use std::str; @@ -218,6 +219,64 @@ impl PartialEq for AudioFormatInfo { impl Eq for AudioFormatInfo {} +impl PartialOrd for AudioFormatInfo { + fn partial_cmp(&self, other: &AudioFormatInfo) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for AudioFormatInfo { + // See GST_AUDIO_FORMATS_ALL for the sorting algorithm + fn cmp(&self, other: &AudioFormatInfo) -> Ordering { + self.depth() + .cmp(&other.depth()) + .then_with(|| self.width().cmp(&other.width())) + .then_with(|| { + match ( + self.flags().contains(::AudioFormatFlags::FLOAT), + other.flags().contains(::AudioFormatFlags::FLOAT), + ) { + (true, false) => Ordering::Greater, + (false, true) => Ordering::Less, + _ => Ordering::Equal, + } + }) + .then_with(|| { + match ( + self.flags().contains(::AudioFormatFlags::SIGNED), + other.flags().contains(::AudioFormatFlags::SIGNED), + ) { + (true, false) => Ordering::Greater, + (false, true) => Ordering::Less, + _ => Ordering::Equal, + } + }) + .then_with(|| match (self.endianness(), other.endianness()) { + (::AudioEndianness::LittleEndian, ::AudioEndianness::BigEndian) => { + #[cfg(target_endian = "little")] + { + Ordering::Greater + } + #[cfg(target_endian = "big")] + { + Ordering::Less + } + } + (::AudioEndianness::BigEndian, ::AudioEndianness::LittleEndian) => { + #[cfg(target_endian = "little")] + { + Ordering::Less + } + #[cfg(target_endian = "big")] + { + Ordering::Greater + } + } + _ => Ordering::Equal, + }) + } +} + impl fmt::Debug for AudioFormatInfo { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { f.debug_struct("AudioFormatInfo") diff --git a/gstreamer-audio/src/auto/enums.rs b/gstreamer-audio/src/auto/enums.rs index 637692516..648ba0432 100644 --- a/gstreamer-audio/src/auto/enums.rs +++ b/gstreamer-audio/src/auto/enums.rs @@ -193,7 +193,7 @@ impl SetValue for AudioChannelPosition { } } -#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)] #[non_exhaustive] pub enum AudioFormat { Unknown,