From 580fc603e0be785daf542d86029ed960aaaff17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 10 Dec 2017 12:26:16 +0200 Subject: [PATCH] Use builders for the key-unit and still-frame events too --- gstreamer-video/src/video_event.rs | 185 +++++++++++++++++++++++++---- 1 file changed, 165 insertions(+), 20 deletions(-) diff --git a/gstreamer-video/src/video_event.rs b/gstreamer-video/src/video_event.rs index d27d3fdeb..1e9137e77 100644 --- a/gstreamer-video/src/video_event.rs +++ b/gstreamer-video/src/video_event.rs @@ -7,31 +7,128 @@ // except according to those terms. use ffi; +use gst_ffi; use gst; use gst::MiniObject; use glib::translate::{from_glib, from_glib_full, ToGlib}; +use glib::ToSendValue; pub fn is_force_key_unit_event(event: &gst::EventRef) -> bool { unsafe { from_glib(ffi::gst_video_event_is_force_key_unit(event.as_mut_ptr())) } } -pub fn new_downstream_force_key_unit_event( +// FIXME: Copy from gstreamer/src/event.rs +macro_rules! event_builder_generic_impl { + ($new_fn:expr) => { + pub fn seqnum(self, seqnum: gst::Seqnum) -> Self { + Self { + seqnum: Some(seqnum), + .. self + } + } + + pub fn running_time_offset(self, running_time_offset: i64) -> Self { + Self { + running_time_offset: Some(running_time_offset), + .. self + } + } + + pub fn other_fields(self, other_fields: &[(&'a str, &'a ToSendValue)]) -> Self { + Self { + other_fields: self.other_fields.iter().cloned() + .chain(other_fields.iter().cloned()) + .collect(), + .. self + } + } + + pub fn build(mut self) -> gst::Event { + assert_initialized_main_thread!(); + unsafe { + let event = $new_fn(&mut self); + if let Some(seqnum) = self.seqnum { + gst_ffi::gst_event_set_seqnum(event, seqnum.to_glib()); + } + + if let Some(running_time_offset) = self.running_time_offset { + gst_ffi::gst_event_set_running_time_offset(event, running_time_offset); + } + + { + let s = gst::StructureRef::from_glib_borrow_mut( + gst_ffi::gst_event_writable_structure(event) + ); + + for (k, v) in self.other_fields { + s.set_value(k, v.to_send_value()); + } + } + + from_glib_full(event) + } + } + } +} + +pub fn new_downstream_force_key_unit_event<'a>( timestamp: gst::ClockTime, stream_time: gst::ClockTime, running_time: gst::ClockTime, all_headers: bool, count: u32, -) -> gst::Event { - unsafe { - from_glib_full(ffi::gst_video_event_new_downstream_force_key_unit( - timestamp.to_glib(), - stream_time.to_glib(), - running_time.to_glib(), - all_headers.to_glib(), - count, - )) +) -> DownstreamForceKeyUnitEventBuilder<'a> { + DownstreamForceKeyUnitEventBuilder::new( + timestamp, + stream_time, + running_time, + all_headers, + count, + ) +} + +pub struct DownstreamForceKeyUnitEventBuilder<'a> { + seqnum: Option, + running_time_offset: Option, + other_fields: Vec<(&'a str, &'a ToSendValue)>, + timestamp: gst::ClockTime, + stream_time: gst::ClockTime, + running_time: gst::ClockTime, + all_headers: bool, + count: u32, +} + +impl<'a> DownstreamForceKeyUnitEventBuilder<'a> { + fn new( + timestamp: gst::ClockTime, + stream_time: gst::ClockTime, + running_time: gst::ClockTime, + all_headers: bool, + count: u32, + ) -> Self { + skip_assert_initialized!(); + Self { + seqnum: None, + running_time_offset: None, + other_fields: Vec::new(), + timestamp: timestamp, + stream_time: stream_time, + running_time: running_time, + all_headers: all_headers, + count: count, + } } + + event_builder_generic_impl!(|s: &mut Self| { + ffi::gst_video_event_new_downstream_force_key_unit( + s.timestamp.to_glib(), + s.stream_time.to_glib(), + s.running_time.to_glib(), + s.all_headers.to_glib(), + s.count, + ) + }); } #[derive(Clone, PartialEq, Eq, Debug)] @@ -75,18 +172,43 @@ pub fn parse_downstream_force_key_unit_event( } } -pub fn new_upstream_force_key_unit_event( +pub fn new_upstream_force_key_unit_event<'a>( running_time: gst::ClockTime, all_headers: bool, count: u32, -) -> gst::Event { - unsafe { - from_glib_full(ffi::gst_video_event_new_upstream_force_key_unit( - running_time.to_glib(), - all_headers.to_glib(), - count, - )) +) -> UpstreamForceKeyUnitEventBuilder<'a> { + UpstreamForceKeyUnitEventBuilder::new(running_time, all_headers, count) +} + +pub struct UpstreamForceKeyUnitEventBuilder<'a> { + seqnum: Option, + running_time_offset: Option, + other_fields: Vec<(&'a str, &'a ToSendValue)>, + running_time: gst::ClockTime, + all_headers: bool, + count: u32, +} + +impl<'a> UpstreamForceKeyUnitEventBuilder<'a> { + fn new(running_time: gst::ClockTime, all_headers: bool, count: u32) -> Self { + skip_assert_initialized!(); + Self { + seqnum: None, + running_time_offset: None, + other_fields: Vec::new(), + running_time: running_time, + all_headers: all_headers, + count: count, + } } + + event_builder_generic_impl!(|s: &mut Self| { + ffi::gst_video_event_new_upstream_force_key_unit( + s.running_time.to_glib(), + s.all_headers.to_glib(), + s.count, + ) + }); } #[derive(Clone, PartialEq, Eq, Debug)] @@ -136,8 +258,31 @@ pub fn parse_force_key_unit_event(event: &gst::EventRef) -> Option gst::Event { - unsafe { from_glib_full(ffi::gst_video_event_new_still_frame(in_still.to_glib())) } +pub fn new_still_frame_event<'a>(in_still: bool) -> StillFrameEventBuilder<'a> { + StillFrameEventBuilder::new(in_still) +} + +pub struct StillFrameEventBuilder<'a> { + seqnum: Option, + running_time_offset: Option, + other_fields: Vec<(&'a str, &'a ToSendValue)>, + in_still: bool, +} + +impl<'a> StillFrameEventBuilder<'a> { + fn new(in_still: bool) -> Self { + skip_assert_initialized!(); + Self { + seqnum: None, + running_time_offset: None, + other_fields: Vec::new(), + in_still: in_still, + } + } + + event_builder_generic_impl!(|s: &mut Self| { + ffi::gst_video_event_new_still_frame(s.in_still.to_glib()) + }); } #[derive(Clone, PartialEq, Eq, Debug)]