gstreamer_base/
flow_combiner.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::ffi;
4use glib::{prelude::*, translate::*};
5
6glib::wrapper! {
7    /// Utility struct to help handling [`gst::FlowReturn`][crate::gst::FlowReturn] combination. Useful for
8    /// [`gst::Element`][crate::gst::Element]<!-- -->s that have multiple source pads and need to combine
9    /// the different [`gst::FlowReturn`][crate::gst::FlowReturn] for those pads.
10    ///
11    /// [`FlowCombiner`][crate::FlowCombiner] works by using the last [`gst::FlowReturn`][crate::gst::FlowReturn] for all [`gst::Pad`][crate::gst::Pad]
12    /// it has in its list and computes the combined return value and provides
13    /// it to the caller.
14    ///
15    /// To add a new pad to the [`FlowCombiner`][crate::FlowCombiner] use [`add_pad()`][Self::add_pad()].
16    /// The new [`gst::Pad`][crate::gst::Pad] is stored with a default value of [`gst::FlowReturn::Ok`][crate::gst::FlowReturn::Ok].
17    ///
18    /// In case you want a [`gst::Pad`][crate::gst::Pad] to be removed, use [`remove_pad()`][Self::remove_pad()].
19    ///
20    /// Please be aware that this struct isn't thread safe as its designed to be
21    ///  used by demuxers, those usually will have a single thread operating it.
22    ///
23    /// These functions will take refs on the passed [`gst::Pad`][crate::gst::Pad]<!-- -->s.
24    ///
25    /// Aside from reducing the user's code size, the main advantage of using this
26    /// helper struct is to follow the standard rules for [`gst::FlowReturn`][crate::gst::FlowReturn] combination.
27    /// These rules are:
28    ///
29    /// * [`gst::FlowReturn::Eos`][crate::gst::FlowReturn::Eos]: only if all returns are EOS too
30    /// * [`gst::FlowReturn::NotLinked`][crate::gst::FlowReturn::NotLinked]: only if all returns are NOT_LINKED too
31    /// * [`gst::FlowReturn::Error`][crate::gst::FlowReturn::Error] or below: if at least one returns an error return
32    /// * [`gst::FlowReturn::NotNegotiated`][crate::gst::FlowReturn::NotNegotiated]: if at least one returns a not-negotiated return
33    /// * [`gst::FlowReturn::Flushing`][crate::gst::FlowReturn::Flushing]: if at least one returns flushing
34    /// * [`gst::FlowReturn::Ok`][crate::gst::FlowReturn::Ok]: otherwise
35    ///
36    /// [`gst::FlowReturn::Error`][crate::gst::FlowReturn::Error] or below, GST_FLOW_NOT_NEGOTIATED and GST_FLOW_FLUSHING are
37    /// returned immediately from the [`update_flow()`][Self::update_flow()] function.
38    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
39    #[doc(alias = "GstFlowCombiner")]
40    pub struct FlowCombiner(Shared<ffi::GstFlowCombiner>);
41
42    match fn {
43        ref => |ptr| ffi::gst_flow_combiner_ref(ptr),
44        unref => |ptr| ffi::gst_flow_combiner_unref(ptr),
45        type_ => || ffi::gst_flow_combiner_get_type(),
46    }
47}
48
49impl FlowCombiner {
50    /// Creates a new [`FlowCombiner`][crate::FlowCombiner], use `gst_flow_combiner_free()` to free it.
51    ///
52    /// # Returns
53    ///
54    /// A new [`FlowCombiner`][crate::FlowCombiner]
55    #[doc(alias = "gst_flow_combiner_new")]
56    pub fn new() -> Self {
57        assert_initialized_main_thread!();
58        unsafe { from_glib_full(ffi::gst_flow_combiner_new()) }
59    }
60
61    /// Adds a new [`gst::Pad`][crate::gst::Pad] to the [`FlowCombiner`][crate::FlowCombiner].
62    /// ## `pad`
63    /// the [`gst::Pad`][crate::gst::Pad] that is being added
64    #[doc(alias = "gst_flow_combiner_add_pad")]
65    pub fn add_pad<P: IsA<gst::Pad>>(&self, pad: &P) {
66        unsafe {
67            ffi::gst_flow_combiner_add_pad(self.to_glib_none().0, pad.as_ref().to_glib_none().0);
68        }
69    }
70
71    /// Removes all pads from a [`FlowCombiner`][crate::FlowCombiner] and resets it to its initial state.
72    #[doc(alias = "gst_flow_combiner_clear")]
73    pub fn clear(&self) {
74        unsafe {
75            ffi::gst_flow_combiner_clear(self.to_glib_none().0);
76        }
77    }
78
79    /// Removes a [`gst::Pad`][crate::gst::Pad] from the [`FlowCombiner`][crate::FlowCombiner].
80    /// ## `pad`
81    /// the [`gst::Pad`][crate::gst::Pad] to remove
82    #[doc(alias = "gst_flow_combiner_remove_pad")]
83    pub fn remove_pad<P: IsA<gst::Pad>>(&self, pad: &P) {
84        unsafe {
85            ffi::gst_flow_combiner_remove_pad(self.to_glib_none().0, pad.as_ref().to_glib_none().0);
86        }
87    }
88
89    /// Reset flow combiner and all pads to their initial state without removing pads.
90    #[doc(alias = "gst_flow_combiner_reset")]
91    pub fn reset(&self) {
92        unsafe {
93            ffi::gst_flow_combiner_reset(self.to_glib_none().0);
94        }
95    }
96
97    /// Computes the combined flow return for the pads in it.
98    ///
99    /// The [`gst::FlowReturn`][crate::gst::FlowReturn] parameter should be the last flow return update for a pad
100    /// in this [`FlowCombiner`][crate::FlowCombiner]. It will use this value to be able to shortcut some
101    /// combinations and avoid looking over all pads again. e.g. The last combined
102    /// return is the same as the latest obtained [`gst::FlowReturn`][crate::gst::FlowReturn].
103    /// ## `fret`
104    /// the latest [`gst::FlowReturn`][crate::gst::FlowReturn] received for a pad in this [`FlowCombiner`][crate::FlowCombiner]
105    ///
106    /// # Returns
107    ///
108    /// The combined [`gst::FlowReturn`][crate::gst::FlowReturn]
109    #[doc(alias = "gst_flow_combiner_update_flow")]
110    pub fn update_flow<FRet: Into<gst::FlowReturn>>(
111        &self,
112        fret: FRet,
113    ) -> Result<gst::FlowSuccess, gst::FlowError> {
114        let fret: gst::FlowReturn = fret.into();
115        unsafe {
116            try_from_glib(ffi::gst_flow_combiner_update_flow(
117                self.to_glib_none().0,
118                fret.into_glib(),
119            ))
120        }
121    }
122
123    /// Sets the provided pad's last flow return to provided value and computes
124    /// the combined flow return for the pads in it.
125    ///
126    /// The [`gst::FlowReturn`][crate::gst::FlowReturn] parameter should be the last flow return update for a pad
127    /// in this [`FlowCombiner`][crate::FlowCombiner]. It will use this value to be able to shortcut some
128    /// combinations and avoid looking over all pads again. e.g. The last combined
129    /// return is the same as the latest obtained [`gst::FlowReturn`][crate::gst::FlowReturn].
130    /// ## `pad`
131    /// the [`gst::Pad`][crate::gst::Pad] whose [`gst::FlowReturn`][crate::gst::FlowReturn] to update
132    /// ## `fret`
133    /// the latest [`gst::FlowReturn`][crate::gst::FlowReturn] received for a pad in this [`FlowCombiner`][crate::FlowCombiner]
134    ///
135    /// # Returns
136    ///
137    /// The combined [`gst::FlowReturn`][crate::gst::FlowReturn]
138    #[doc(alias = "gst_flow_combiner_update_pad_flow")]
139    pub fn update_pad_flow<P: IsA<gst::Pad>, FRet: Into<gst::FlowReturn>>(
140        &self,
141        pad: &P,
142        fret: FRet,
143    ) -> Result<gst::FlowSuccess, gst::FlowError> {
144        let fret: gst::FlowReturn = fret.into();
145        unsafe {
146            try_from_glib(ffi::gst_flow_combiner_update_pad_flow(
147                self.to_glib_none().0,
148                pad.as_ref().to_glib_none().0,
149                fret.into_glib(),
150            ))
151        }
152    }
153}
154
155impl Default for FlowCombiner {
156    fn default() -> Self {
157        Self::new()
158    }
159}
160
161#[derive(Debug)]
162pub struct UniqueFlowCombiner(FlowCombiner);
163
164unsafe impl Sync for UniqueFlowCombiner {}
165unsafe impl Send for UniqueFlowCombiner {}
166
167impl UniqueFlowCombiner {
168    pub fn new() -> Self {
169        Self(FlowCombiner::new())
170    }
171
172    pub fn add_pad<P: IsA<gst::Pad>>(&mut self, pad: &P) {
173        self.0.add_pad(pad);
174    }
175
176    pub fn clear(&mut self) {
177        self.0.clear();
178    }
179
180    pub fn remove_pad<P: IsA<gst::Pad>>(&mut self, pad: &P) {
181        self.0.remove_pad(pad);
182    }
183
184    pub fn reset(&mut self) {
185        self.0.reset();
186    }
187
188    pub fn update_flow(
189        &mut self,
190        fret: Result<gst::FlowSuccess, gst::FlowError>,
191    ) -> Result<gst::FlowSuccess, gst::FlowError> {
192        self.0.update_flow(fret)
193    }
194
195    pub fn update_pad_flow<P: IsA<gst::Pad>>(
196        &mut self,
197        pad: &P,
198        fret: Result<gst::FlowSuccess, gst::FlowError>,
199    ) -> Result<gst::FlowSuccess, gst::FlowError> {
200        self.0.update_pad_flow(pad, fret)
201    }
202}
203
204impl Default for UniqueFlowCombiner {
205    fn default() -> Self {
206        Self::new()
207    }
208}