mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2025-09-02 01:43:49 +00:00
gstreamer: caps_features: implement Hash
Will be used to implement Hash on Caps. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1639>
This commit is contained in:
parent
f9f85ae75e
commit
68280c1dae
1 changed files with 62 additions and 0 deletions
|
@ -882,6 +882,34 @@ impl ToOwned for CapsFeaturesRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::hash::Hash for CapsFeaturesRef {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
use std::hash::{DefaultHasher, Hasher};
|
||||||
|
|
||||||
|
// re-implement gst_hash_caps_features so the hashing is not depending on the features order.
|
||||||
|
if self.is_any() {
|
||||||
|
"ANY".hash(state);
|
||||||
|
} else if self.is_empty() {
|
||||||
|
"EMPTY".hash(state);
|
||||||
|
} else {
|
||||||
|
let mut features_hash = 0;
|
||||||
|
for f in self.iter() {
|
||||||
|
let mut field_hasher = DefaultHasher::new();
|
||||||
|
f.hash(&mut field_hasher);
|
||||||
|
|
||||||
|
features_hash ^= field_hasher.finish();
|
||||||
|
}
|
||||||
|
features_hash.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::hash::Hash for CapsFeatures {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.as_ref().hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl Sync for CapsFeaturesRef {}
|
unsafe impl Sync for CapsFeaturesRef {}
|
||||||
unsafe impl Send for CapsFeaturesRef {}
|
unsafe impl Send for CapsFeaturesRef {}
|
||||||
|
|
||||||
|
@ -1009,4 +1037,38 @@ mod tests {
|
||||||
assert!(cf.contains_by_id(overlay_comp));
|
assert!(cf.contains_by_id(overlay_comp));
|
||||||
assert!(!cf.contains("memory:GLMemory"));
|
assert!(!cf.contains("memory:GLMemory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_hash() {
|
||||||
|
crate::init().unwrap();
|
||||||
|
|
||||||
|
use std::hash::BuildHasher;
|
||||||
|
let bh = std::hash::RandomState::new();
|
||||||
|
|
||||||
|
let any = CapsFeatures::new_any();
|
||||||
|
let empty = CapsFeatures::new_empty();
|
||||||
|
assert_eq!(bh.hash_one(&any), bh.hash_one(&any));
|
||||||
|
assert_eq!(bh.hash_one(&empty), bh.hash_one(&empty));
|
||||||
|
assert_ne!(bh.hash_one(&any), bh.hash_one(&empty));
|
||||||
|
|
||||||
|
// Different names
|
||||||
|
let cf1 = CapsFeatures::from(gstr!("memory:DMABuf"));
|
||||||
|
let cf2 = CapsFeatures::from(gstr!("memory:GLMemory"));
|
||||||
|
assert_eq!(bh.hash_one(&cf1), bh.hash_one(&cf1));
|
||||||
|
assert_eq!(bh.hash_one(&cf2), bh.hash_one(&cf2));
|
||||||
|
assert_ne!(bh.hash_one(&cf1), bh.hash_one(&cf2));
|
||||||
|
|
||||||
|
// Same features, different order
|
||||||
|
let cf1 = CapsFeatures::from([
|
||||||
|
gstr!("memory:DMABuf"),
|
||||||
|
gstr!("meta:GstVideoOverlayComposition"),
|
||||||
|
]);
|
||||||
|
let cf2 = CapsFeatures::from([
|
||||||
|
gstr!("meta:GstVideoOverlayComposition"),
|
||||||
|
gstr!("memory:DMABuf"),
|
||||||
|
]);
|
||||||
|
assert_eq!(bh.hash_one(&cf1), bh.hash_one(&cf1));
|
||||||
|
assert_eq!(bh.hash_one(&cf2), bh.hash_one(&cf2));
|
||||||
|
assert_eq!(bh.hash_one(&cf1), bh.hash_one(&cf2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue