From 8dcf3fec2035ed3c440ecc285f6648d769ef35f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 22 Oct 2019 23:32:39 +0300 Subject: [PATCH] gstreamer: Change Sample constructor to the builder pattern Simplifies construction of Samples considerably. --- gstreamer-video/src/functions.rs | 7 +- gstreamer/src/sample.rs | 110 +++++++++++++++++++++---------- gstreamer/src/sample_serde.rs | 63 ++++++++++-------- gstreamer/src/tags_serde.rs | 5 +- 4 files changed, 115 insertions(+), 70 deletions(-) diff --git a/gstreamer-video/src/functions.rs b/gstreamer-video/src/functions.rs index 189c5fcd7..fa17bb0fd 100644 --- a/gstreamer-video/src/functions.rs +++ b/gstreamer-video/src/functions.rs @@ -137,12 +137,7 @@ mod tests { .unwrap() .to_caps() .unwrap(); - let sample = gst::Sample::new( - Some(&in_buffer), - Some(&in_caps), - None::<&gst::Segment>, - None, - ); + let sample = gst::Sample::new().buffer(&in_buffer).caps(&in_caps).build(); let out_caps = ::VideoInfo::new(::VideoFormat::Abgr, 320, 240) .build() diff --git a/gstreamer/src/sample.rs b/gstreamer/src/sample.rs index cd104ec24..a1bd02719 100644 --- a/gstreamer/src/sample.rs +++ b/gstreamer/src/sample.rs @@ -31,41 +31,87 @@ gst_define_mini_object_wrapper!(Sample, SampleRef, gst_sys::GstSample, [Debug,], gst_sys::gst_sample_get_type() }); -impl Sample { - pub fn new( - buffer: Option<&Buffer>, - caps: Option<&Caps>, - segment: Option<&FormattedSegment>, - info: Option, - ) -> Self { - assert_initialized_main_thread!(); - unsafe { - let info = info.map(|i| i.into_ptr()).unwrap_or(ptr::null_mut()); +#[derive(Debug, Clone)] +pub struct SampleBuilder<'a> { + buffer: Option<&'a Buffer>, + buffer_list: Option<&'a BufferList>, + caps: Option<&'a Caps>, + segment: Option<&'a Segment>, + info: Option, +} - from_glib_full(gst_sys::gst_sample_new( - buffer.to_glib_none().0, - caps.to_glib_none().0, - segment.to_glib_none().0, - mut_override(info), - )) +impl<'a> SampleBuilder<'a> { + pub fn buffer(self, buffer: &'a Buffer) -> Self { + Self { + buffer: Some(buffer), + buffer_list: None, + ..self } } - pub fn with_buffer_list( - buffer_list: Option<&BufferList>, - caps: Option<&Caps>, - segment: Option<&FormattedSegment>, - info: Option, - ) -> Self { - assert_initialized_main_thread!(); - let sample = Self::new(None, caps, segment, info); - unsafe { - gst_sys::gst_sample_set_buffer_list( - sample.to_glib_none().0, - buffer_list.to_glib_none().0, - ); + pub fn buffer_list(self, buffer_list: &'a BufferList) -> Self { + Self { + buffer: None, + buffer_list: Some(buffer_list), + ..self + } + } + + pub fn caps(self, caps: &'a Caps) -> Self { + Self { + caps: Some(caps), + ..self + } + } + + pub fn segment(self, segment: &'a FormattedSegment) -> Self { + Self { + segment: Some(segment.upcast_ref()), + ..self + } + } + + pub fn info(self, info: Structure) -> Self { + Self { + info: Some(info), + ..self + } + } + + pub fn build(self) -> Sample { + assert_initialized_main_thread!(); + + unsafe { + let info = self.info.map(|i| i.into_ptr()).unwrap_or(ptr::null_mut()); + + let sample: Sample = from_glib_full(gst_sys::gst_sample_new( + self.buffer.to_glib_none().0, + self.caps.to_glib_none().0, + self.segment.to_glib_none().0, + mut_override(info), + )); + + if let Some(buffer_list) = self.buffer_list { + gst_sys::gst_sample_set_buffer_list( + sample.to_glib_none().0, + buffer_list.to_glib_none().0, + ); + } + + sample + } + } +} + +impl Sample { + pub fn new<'a>() -> SampleBuilder<'a> { + SampleBuilder { + buffer: None, + buffer_list: None, + caps: None, + segment: None, + info: None, } - sample } } @@ -182,10 +228,8 @@ impl fmt::Debug for SampleRef { #[cfg(test)] mod tests { - #[test] fn test_sample_new_with_info() { - use GenericFormattedValue; use Sample; use Structure; @@ -194,7 +238,7 @@ mod tests { let info = Structure::builder("sample.info") .field("f3", &123i32) .build(); - let sample = Sample::new::(None, None, None, Some(info)); + let sample = Sample::new().info(info).build(); assert!(sample.get_info().is_some()); } diff --git a/gstreamer/src/sample_serde.rs b/gstreamer/src/sample_serde.rs index 1fe5953ef..9ffa0a611 100644 --- a/gstreamer/src/sample_serde.rs +++ b/gstreamer/src/sample_serde.rs @@ -12,7 +12,6 @@ use serde::ser::{Serialize, SerializeStruct, Serializer}; use Buffer; use BufferList; use Caps; -use GenericFormattedValue; use Sample; use SampleRef; use Segment; @@ -47,21 +46,29 @@ struct SampleDe { impl From for Sample { fn from(mut buf_de: SampleDe) -> Self { - if buf_de.buffer.is_some() { - Sample::new::( - buf_de.buffer.as_ref(), - buf_de.caps.as_ref(), - buf_de.segment.as_ref(), - buf_de.info.take(), - ) - } else { - Sample::with_buffer_list::( - buf_de.buffer_list.as_ref(), - buf_de.caps.as_ref(), - buf_de.segment.as_ref(), - buf_de.info.take(), - ) + let mut builder = Sample::new(); + + if let Some(buffer) = buf_de.buffer.as_ref() { + builder = builder.buffer(buffer); } + + if let Some(buffer_list) = buf_de.buffer_list.as_ref() { + builder = builder.buffer_list(buffer_list); + } + + if let Some(caps) = buf_de.caps.as_ref() { + builder = builder.caps(caps); + } + + if let Some(segment) = buf_de.segment.as_ref() { + builder = builder.segment(segment); + } + + if let Some(info) = buf_de.info { + builder = builder.info(info); + } + + builder.build() } } @@ -124,12 +131,12 @@ mod tests { .field("f3", &123i32) .build(); - Sample::new::( - Some(&buffer), - Some(&caps), - Some(&segment), - Some(info), - ) + Sample::new() + .buffer(&buffer) + .caps(&caps) + .segment(&segment) + .info(info) + .build() }; let res = ron::ser::to_string_pretty(&sample, pretty_config.clone()); @@ -187,7 +194,7 @@ mod tests { buffer.set_offset_end(4); buffer.set_duration(4.into()); } - Sample::new::(Some(&buffer), None, None, None) + Sample::new().buffer(&buffer).build() }; // `Sample`'s `Segment` is allocated in GStreamer 1.x, should be fixed in version 2.0 @@ -354,12 +361,12 @@ mod tests { .field("f3", &123i32) .build(); - Sample::new::( - Some(&buffer), - Some(&caps), - Some(&segment), - Some(info), - ) + Sample::new() + .buffer(&buffer) + .caps(&caps) + .segment(&segment) + .info(info) + .build() }; let sample_ser = ron::ser::to_string(&sample).unwrap(); let sample_de: Sample = ron::de::from_str(sample_ser.as_str()).unwrap(); diff --git a/gstreamer/src/tags_serde.rs b/gstreamer/src/tags_serde.rs index 076672cf1..3510a27c1 100644 --- a/gstreamer/src/tags_serde.rs +++ b/gstreamer/src/tags_serde.rs @@ -323,7 +323,6 @@ mod tests { use tags::*; use Buffer; - use GenericFormattedValue; use Sample; use TagMergeMode; use TagScope; @@ -354,7 +353,7 @@ mod tests { buffer.set_offset(0); buffer.set_offset_end(0); } - Sample::new::(Some(&buffer), None, None, None) + Sample::new().buffer(&buffer).build() }; tags.add::(&sample, TagMergeMode::Append); // Sample } @@ -569,7 +568,7 @@ mod tests { buffer.set_offset(0); buffer.set_offset_end(0); } - Sample::new::(Some(&buffer), None, None, None) + Sample::new().buffer(&buffer).build() }; tags.add::(&sample, TagMergeMode::Append); // Sample }