From 38db96859bde9958efb0d10c7556a6309da285f3 Mon Sep 17 00:00:00 2001 From: Guillaume Desmottes Date: Wed, 8 Jan 2020 12:41:33 +0530 Subject: [PATCH] gstreamer: add Caps::builder_full() API to create a caps containing multiple structures. Fix #231 --- gstreamer/src/caps.rs | 165 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/gstreamer/src/caps.rs b/gstreamer/src/caps.rs index f861fda46..c5000d89a 100644 --- a/gstreamer/src/caps.rs +++ b/gstreamer/src/caps.rs @@ -34,6 +34,21 @@ impl Caps { Builder::new(name) } + pub fn builder_full() -> BuilderFull { + assert_initialized_main_thread!(); + BuilderFull::new() + } + + pub fn builder_full_with_features(features: CapsFeatures) -> BuilderFull { + assert_initialized_main_thread!(); + BuilderFull::new_with_features(features) + } + + pub fn builder_full_with_any_features() -> BuilderFull { + assert_initialized_main_thread!(); + BuilderFull::new_with_any_features() + } + pub fn new_empty() -> Self { assert_initialized_main_thread!(); unsafe { from_glib_full(gst_sys::gst_caps_new_empty()) } @@ -563,6 +578,83 @@ impl<'a> Builder<'a> { } } +#[derive(Debug)] +pub struct BuilderFull { + caps: ::Caps, + features: Option, + any_features: bool, +} + +impl BuilderFull { + fn new() -> Self { + BuilderFull { + caps: Caps::new_empty(), + features: None, + any_features: false, + } + } + + fn new_with_features(features: CapsFeatures) -> Self { + BuilderFull { + caps: Caps::new_empty(), + features: Some(features), + any_features: false, + } + } + + fn new_with_any_features() -> Self { + BuilderFull { + caps: Caps::new_empty(), + features: None, + any_features: true, + } + } + + fn append_structure(mut self, structure: Structure, features: Option) -> Self { + let features = { + if self.any_features { + Some(CapsFeatures::new_any()) + } else { + match self.features { + None => features, + Some(ref result) => { + let mut result = result.clone(); + match features { + None => Some(result), + Some(features) => { + features.iter().for_each(|feat| result.add(feat)); + Some(result) + } + } + } + } + } + }; + + self.caps + .get_mut() + .unwrap() + .append_structure_full(structure, features); + self + } + + pub fn structure(self, structure: Structure) -> Self { + self.append_structure(structure, None) + } + + pub fn structure_with_features(self, structure: Structure, features: CapsFeatures) -> Self { + self.append_structure(structure, Some(features)) + } + + pub fn structure_with_any_features(self, structure: Structure) -> Self { + self.append_structure(structure, Some(CapsFeatures::new_any())) + } + + pub fn build(self) -> Caps { + self.caps + } +} + #[cfg(test)] mod tests { use super::*; @@ -656,4 +748,77 @@ mod tests { let caps = Caps::new_simple("foo/bar", &[]); format!("{}", caps); } + + #[test] + fn test_builder_full() { + ::init().unwrap(); + + let caps = Caps::builder_full() + .structure(Structure::builder("audio/x-raw").build()) + .structure(Structure::builder("video/x-raw").build()) + .build(); + assert_eq!(caps.to_string(), "audio/x-raw; video/x-raw"); + + let caps = Caps::builder_full() + .structure( + Structure::builder("audio/x-raw") + .field("format", &"S16LE") + .build(), + ) + .structure(Structure::builder("video/x-raw").build()) + .build(); + assert_eq!( + caps.to_string(), + "audio/x-raw, format=(string)S16LE; video/x-raw" + ); + + let caps = Caps::builder_full() + .structure_with_any_features(Structure::builder("audio/x-raw").build()) + .structure_with_features( + Structure::builder("video/x-raw").build(), + CapsFeatures::new(&["foo:bla", "foo:baz"]), + ) + .build(); + assert_eq!( + caps.to_string(), + "audio/x-raw(ANY); video/x-raw(foo:bla, foo:baz)" + ); + } + + #[test] + fn test_builder_full_with_features() { + ::init().unwrap(); + + let caps = Caps::builder_full_with_features(CapsFeatures::new(&["foo:bla"])) + .structure(Structure::builder("audio/x-raw").build()) + .structure_with_features( + Structure::builder("video/x-raw").build(), + CapsFeatures::new(&["foo:baz"]), + ) + .build(); + assert_eq!( + caps.to_string(), + "audio/x-raw(foo:bla); video/x-raw(foo:bla, foo:baz)" + ); + } + + #[test] + fn test_builder_full_with_any_features() { + ::init().unwrap(); + + let caps = Caps::builder_full_with_any_features() + .structure(Structure::builder("audio/x-raw").build()) + .structure(Structure::builder("video/x-raw").build()) + .build(); + assert_eq!(caps.to_string(), "audio/x-raw(ANY); video/x-raw(ANY)"); + + let caps = Caps::builder_full_with_any_features() + .structure(Structure::builder("audio/x-raw").build()) + .structure_with_features( + Structure::builder("video/x-raw").build(), + CapsFeatures::new(&["foo:bla", "foo:baz"]), + ) + .build(); + assert_eq!(caps.to_string(), "audio/x-raw(ANY); video/x-raw(ANY)"); + } }