1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use glib::translate::{from_glib, from_glib_full, IntoGlib};
4 use glib::ToSendValue;
5 use std::mem;
6 
7 // FIXME: Copy from gstreamer/src/event.rs
8 macro_rules! event_builder_generic_impl {
9     ($new_fn:expr) => {
10         pub fn seqnum(self, seqnum: gst::Seqnum) -> Self {
11             Self {
12                 seqnum: Some(seqnum),
13                 ..self
14             }
15         }
16 
17         pub fn running_time_offset(self, running_time_offset: i64) -> Self {
18             Self {
19                 running_time_offset: Some(running_time_offset),
20                 ..self
21             }
22         }
23 
24         pub fn other_fields(
25             self,
26             other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))],
27         ) -> Self {
28             Self {
29                 other_fields: self
30                     .other_fields
31                     .iter()
32                     .cloned()
33                     .chain(other_fields.iter().cloned())
34                     .collect(),
35                 ..self
36             }
37         }
38 
39         pub fn build(mut self) -> gst::Event {
40             assert_initialized_main_thread!();
41             unsafe {
42                 let event = $new_fn(&mut self);
43                 if let Some(seqnum) = self.seqnum {
44                     gst::ffi::gst_event_set_seqnum(event, seqnum.into_glib());
45                 }
46 
47                 if let Some(running_time_offset) = self.running_time_offset {
48                     gst::ffi::gst_event_set_running_time_offset(event, running_time_offset);
49                 }
50 
51                 {
52                     let s = gst::StructureRef::from_glib_borrow_mut(
53                         gst::ffi::gst_event_writable_structure(event),
54                     );
55 
56                     for (k, v) in self.other_fields {
57                         s.set_value(k, v.to_send_value());
58                     }
59                 }
60 
61                 from_glib_full(event)
62             }
63         }
64     };
65 }
66 
67 pub struct DownstreamForceKeyUnitEventBuilder<'a> {
68     seqnum: Option<gst::Seqnum>,
69     running_time_offset: Option<i64>,
70     other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>,
71     timestamp: Option<gst::ClockTime>,
72     stream_time: Option<gst::ClockTime>,
73     running_time: Option<gst::ClockTime>,
74     all_headers: bool,
75     count: u32,
76 }
77 
78 impl<'a> DownstreamForceKeyUnitEventBuilder<'a> {
new() -> Self79     fn new() -> Self {
80         skip_assert_initialized!();
81         Self {
82             seqnum: None,
83             running_time_offset: None,
84             other_fields: Vec::new(),
85             timestamp: gst::ClockTime::NONE,
86             stream_time: gst::ClockTime::NONE,
87             running_time: gst::ClockTime::NONE,
88             all_headers: true,
89             count: 0,
90         }
91     }
92 
timestamp(self, timestamp: impl Into<Option<gst::ClockTime>>) -> Self93     pub fn timestamp(self, timestamp: impl Into<Option<gst::ClockTime>>) -> Self {
94         Self {
95             timestamp: timestamp.into(),
96             ..self
97         }
98     }
99 
stream_time(self, stream_time: impl Into<Option<gst::ClockTime>>) -> Self100     pub fn stream_time(self, stream_time: impl Into<Option<gst::ClockTime>>) -> Self {
101         Self {
102             stream_time: stream_time.into(),
103             ..self
104         }
105     }
106 
running_time(self, running_time: impl Into<Option<gst::ClockTime>>) -> Self107     pub fn running_time(self, running_time: impl Into<Option<gst::ClockTime>>) -> Self {
108         Self {
109             running_time: running_time.into(),
110             ..self
111         }
112     }
113 
all_headers(self, all_headers: bool) -> Self114     pub fn all_headers(self, all_headers: bool) -> Self {
115         Self {
116             all_headers,
117             ..self
118         }
119     }
120 
count(self, count: u32) -> Self121     pub fn count(self, count: u32) -> Self {
122         Self { count, ..self }
123     }
124 
125     event_builder_generic_impl!(|s: &mut Self| {
126         ffi::gst_video_event_new_downstream_force_key_unit(
127             s.timestamp.into_glib(),
128             s.stream_time.into_glib(),
129             s.running_time.into_glib(),
130             s.all_headers.into_glib(),
131             s.count,
132         )
133     });
134 }
135 
136 #[derive(Clone, PartialEq, Eq, Debug)]
137 pub struct DownstreamForceKeyUnitEvent {
138     pub timestamp: Option<gst::ClockTime>,
139     pub stream_time: Option<gst::ClockTime>,
140     pub running_time: Option<gst::ClockTime>,
141     pub all_headers: bool,
142     pub count: u32,
143 }
144 
145 impl DownstreamForceKeyUnitEvent {
builder<'a>() -> DownstreamForceKeyUnitEventBuilder<'a>146     pub fn builder<'a>() -> DownstreamForceKeyUnitEventBuilder<'a> {
147         DownstreamForceKeyUnitEventBuilder::new()
148     }
149 
150     #[doc(alias = "gst_video_event_parse_downstream_force_key_unit")]
parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError>151     pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
152         skip_assert_initialized!();
153         unsafe {
154             let mut timestamp = mem::MaybeUninit::uninit();
155             let mut stream_time = mem::MaybeUninit::uninit();
156             let mut running_time = mem::MaybeUninit::uninit();
157             let mut all_headers = mem::MaybeUninit::uninit();
158             let mut count = mem::MaybeUninit::uninit();
159 
160             let res: bool = from_glib(ffi::gst_video_event_parse_downstream_force_key_unit(
161                 event.as_mut_ptr(),
162                 timestamp.as_mut_ptr(),
163                 stream_time.as_mut_ptr(),
164                 running_time.as_mut_ptr(),
165                 all_headers.as_mut_ptr(),
166                 count.as_mut_ptr(),
167             ));
168             if res {
169                 Ok(Self {
170                     timestamp: from_glib(timestamp.assume_init()),
171                     stream_time: from_glib(stream_time.assume_init()),
172                     running_time: from_glib(running_time.assume_init()),
173                     all_headers: from_glib(all_headers.assume_init()),
174                     count: count.assume_init(),
175                 })
176             } else {
177                 Err(glib::bool_error!("Failed to parse GstEvent"))
178             }
179         }
180     }
181 }
182 
183 pub struct UpstreamForceKeyUnitEventBuilder<'a> {
184     seqnum: Option<gst::Seqnum>,
185     running_time_offset: Option<i64>,
186     other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>,
187     running_time: Option<gst::ClockTime>,
188     all_headers: bool,
189     count: u32,
190 }
191 
192 impl<'a> UpstreamForceKeyUnitEventBuilder<'a> {
new() -> Self193     fn new() -> Self {
194         skip_assert_initialized!();
195         Self {
196             seqnum: None,
197             running_time_offset: None,
198             other_fields: Vec::new(),
199             running_time: gst::ClockTime::NONE,
200             all_headers: true,
201             count: 0,
202         }
203     }
204 
running_time(self, running_time: impl Into<Option<gst::ClockTime>>) -> Self205     pub fn running_time(self, running_time: impl Into<Option<gst::ClockTime>>) -> Self {
206         Self {
207             running_time: running_time.into(),
208             ..self
209         }
210     }
211 
all_headers(self, all_headers: bool) -> Self212     pub fn all_headers(self, all_headers: bool) -> Self {
213         Self {
214             all_headers,
215             ..self
216         }
217     }
218 
count(self, count: u32) -> Self219     pub fn count(self, count: u32) -> Self {
220         Self { count, ..self }
221     }
222 
223     event_builder_generic_impl!(|s: &mut Self| {
224         ffi::gst_video_event_new_upstream_force_key_unit(
225             s.running_time.into_glib(),
226             s.all_headers.into_glib(),
227             s.count,
228         )
229     });
230 }
231 
232 #[derive(Clone, PartialEq, Eq, Debug)]
233 pub struct UpstreamForceKeyUnitEvent {
234     pub running_time: Option<gst::ClockTime>,
235     pub all_headers: bool,
236     pub count: u32,
237 }
238 
239 impl UpstreamForceKeyUnitEvent {
builder<'a>() -> UpstreamForceKeyUnitEventBuilder<'a>240     pub fn builder<'a>() -> UpstreamForceKeyUnitEventBuilder<'a> {
241         UpstreamForceKeyUnitEventBuilder::new()
242     }
243 
244     #[doc(alias = "gst_video_event_parse_upstream_force_key_unit")]
parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError>245     pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
246         skip_assert_initialized!();
247         unsafe {
248             let mut running_time = mem::MaybeUninit::uninit();
249             let mut all_headers = mem::MaybeUninit::uninit();
250             let mut count = mem::MaybeUninit::uninit();
251 
252             let res: bool = from_glib(ffi::gst_video_event_parse_upstream_force_key_unit(
253                 event.as_mut_ptr(),
254                 running_time.as_mut_ptr(),
255                 all_headers.as_mut_ptr(),
256                 count.as_mut_ptr(),
257             ));
258             if res {
259                 Ok(Self {
260                     running_time: from_glib(running_time.assume_init()),
261                     all_headers: from_glib(all_headers.assume_init()),
262                     count: count.assume_init(),
263                 })
264             } else {
265                 Err(glib::bool_error!("Failed to parse GstEvent"))
266             }
267         }
268     }
269 }
270 
271 #[derive(Clone, PartialEq, Eq, Debug)]
272 pub enum ForceKeyUnitEvent {
273     Downstream(DownstreamForceKeyUnitEvent),
274     Upstream(UpstreamForceKeyUnitEvent),
275 }
276 
277 impl ForceKeyUnitEvent {
278     #[doc(alias = "gst_video_event_is_force_key_unit")]
is(event: &gst::EventRef) -> bool279     pub fn is(event: &gst::EventRef) -> bool {
280         skip_assert_initialized!();
281         unsafe { from_glib(ffi::gst_video_event_is_force_key_unit(event.as_mut_ptr())) }
282     }
283 
parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError>284     pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
285         skip_assert_initialized!();
286         if event.is_upstream() {
287             UpstreamForceKeyUnitEvent::parse(event).map(Self::Upstream)
288         } else {
289             DownstreamForceKeyUnitEvent::parse(event).map(Self::Downstream)
290         }
291     }
292 }
293 
294 pub struct StillFrameEventBuilder<'a> {
295     seqnum: Option<gst::Seqnum>,
296     running_time_offset: Option<i64>,
297     other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>,
298     in_still: bool,
299 }
300 
301 impl<'a> StillFrameEventBuilder<'a> {
new(in_still: bool) -> Self302     fn new(in_still: bool) -> Self {
303         skip_assert_initialized!();
304         Self {
305             seqnum: None,
306             running_time_offset: None,
307             other_fields: Vec::new(),
308             in_still,
309         }
310     }
311 
312     event_builder_generic_impl!(|s: &mut Self| ffi::gst_video_event_new_still_frame(
313         s.in_still.into_glib()
314     ));
315 }
316 
317 #[derive(Clone, PartialEq, Eq, Debug)]
318 pub struct StillFrameEvent {
319     pub in_still: bool,
320 }
321 
322 impl StillFrameEvent {
builder<'a>(in_still: bool) -> StillFrameEventBuilder<'a>323     pub fn builder<'a>(in_still: bool) -> StillFrameEventBuilder<'a> {
324         assert_initialized_main_thread!();
325         StillFrameEventBuilder::new(in_still)
326     }
327 
328     #[doc(alias = "gst_video_event_parse_still_frame")]
parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError>329     pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
330         skip_assert_initialized!();
331         unsafe {
332             let mut in_still = mem::MaybeUninit::uninit();
333 
334             let res: bool = from_glib(ffi::gst_video_event_parse_still_frame(
335                 event.as_mut_ptr(),
336                 in_still.as_mut_ptr(),
337             ));
338             if res {
339                 Ok(Self {
340                     in_still: from_glib(in_still.assume_init()),
341                 })
342             } else {
343                 Err(glib::bool_error!("Invalid still-frame event"))
344             }
345         }
346     }
347 }
348