Skip to main content

gstreamer_base/
base_parse.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::mem;
4
5use glib::{prelude::*, translate::*};
6use gst::{
7    format::{FormattedValue, SpecificFormattedValueFullRange},
8    prelude::*,
9};
10
11use crate::{BaseParse, BaseParseFrame, ffi};
12
13pub trait BaseParseExtManual: IsA<BaseParse> + 'static {
14    #[doc(alias = "get_sink_pad")]
15    fn sink_pad(&self) -> &gst::Pad {
16        unsafe {
17            let elt = &*(self.as_ptr() as *const ffi::GstBaseParse);
18            &*(&elt.sinkpad as *const *mut gst::ffi::GstPad as *const gst::Pad)
19        }
20    }
21
22    #[doc(alias = "get_src_pad")]
23    fn src_pad(&self) -> &gst::Pad {
24        unsafe {
25            let elt = &*(self.as_ptr() as *const ffi::GstBaseParse);
26            &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const gst::Pad)
27        }
28    }
29
30    fn segment(&self) -> gst::Segment {
31        unsafe {
32            let ptr: &ffi::GstBaseParse = &*(self.as_ptr() as *const _);
33            let sinkpad = self.sink_pad();
34            let _guard = sinkpad.stream_lock();
35            from_glib_none(&ptr.segment as *const gst::ffi::GstSegment)
36        }
37    }
38
39    fn lost_sync(&self) -> bool {
40        unsafe {
41            let ptr: &ffi::GstBaseParse = &*(self.as_ptr() as *const _);
42            let sinkpad = self.sink_pad();
43            let _guard = sinkpad.stream_lock();
44            ptr.flags & ffi::GST_BASE_PARSE_FLAG_LOST_SYNC as u32 != 0
45        }
46    }
47
48    fn is_draining(&self) -> bool {
49        unsafe {
50            let ptr: &ffi::GstBaseParse = &*(self.as_ptr() as *const _);
51            let sinkpad = self.sink_pad();
52            let _guard = sinkpad.stream_lock();
53            ptr.flags & ffi::GST_BASE_PARSE_FLAG_DRAINING as u32 != 0
54        }
55    }
56
57    /// Sets the duration of the currently playing media. Subclass can use this
58    /// when it is able to determine duration and/or notices a change in the media
59    /// duration. Alternatively, if `interval` is non-zero (default), then stream
60    /// duration is determined based on estimated bitrate, and updated every `interval`
61    /// frames.
62    ///
63    /// This value is reset during PAUSED->READY state changes. Subclasses must
64    /// call this function from `GstBaseParseClass::start` if they want to set a static value.
65    /// ## `fmt`
66    /// [`gst::Format`][crate::gst::Format].
67    /// ## `duration`
68    /// duration value.
69    /// ## `interval`
70    /// how often to update the duration estimate based on bitrate, or 0.
71    #[doc(alias = "gst_base_parse_set_duration")]
72    fn set_duration(&self, duration: impl FormattedValue, interval: u32) {
73        unsafe {
74            ffi::gst_base_parse_set_duration(
75                self.as_ref().to_glib_none().0,
76                duration.format().into_glib(),
77                duration.into_raw_value(),
78                interval as i32,
79            );
80        }
81    }
82
83    /// If frames per second is configured, parser can take care of buffer duration
84    /// and timestamping. When performing segment clipping, or seeking to a specific
85    /// location, a corresponding decoder might need an initial `lead_in` and a
86    /// following `lead_out` number of frames to ensure the desired segment is
87    /// entirely filled upon decoding.
88    ///
89    /// This value is reset during PAUSED->READY state changes. Subclasses must
90    /// call this function from `GstBaseParseClass::start` if they want to set a static value.
91    /// ## `fps_num`
92    /// frames per second (numerator).
93    /// ## `fps_den`
94    /// frames per second (denominator).
95    /// ## `lead_in`
96    /// frames needed before a segment for subsequent decode
97    /// ## `lead_out`
98    /// frames needed after a segment
99    #[doc(alias = "gst_base_parse_set_frame_rate")]
100    fn set_frame_rate(&self, fps: gst::Fraction, lead_in: u32, lead_out: u32) {
101        let (fps_num, fps_den) = fps.into();
102        unsafe {
103            ffi::gst_base_parse_set_frame_rate(
104                self.as_ref().to_glib_none().0,
105                fps_num as u32,
106                fps_den as u32,
107                lead_in,
108                lead_out,
109            );
110        }
111    }
112
113    /// Default implementation of `GstBaseParseClass::convert`.
114    /// ## `src_format`
115    /// [`gst::Format`][crate::gst::Format] describing the source format.
116    /// ## `src_value`
117    /// Source value to be converted.
118    /// ## `dest_format`
119    /// [`gst::Format`][crate::gst::Format] defining the converted format.
120    ///
121    /// # Returns
122    ///
123    /// [`true`] if conversion was successful.
124    ///
125    /// ## `dest_value`
126    /// Pointer where the conversion result will be put.
127    #[doc(alias = "gst_base_parse_convert_default")]
128    fn convert_default<U: SpecificFormattedValueFullRange>(
129        &self,
130        src_val: impl FormattedValue,
131    ) -> Option<U> {
132        unsafe {
133            let mut dest_val = mem::MaybeUninit::uninit();
134            let ret = from_glib(ffi::gst_base_parse_convert_default(
135                self.as_ref().to_glib_none().0,
136                src_val.format().into_glib(),
137                src_val.into_raw_value(),
138                U::default_format().into_glib(),
139                dest_val.as_mut_ptr(),
140            ));
141            if ret {
142                Some(U::from_raw(U::default_format(), dest_val.assume_init()))
143            } else {
144                None
145            }
146        }
147    }
148
149    fn convert_default_generic(
150        &self,
151        src_val: impl FormattedValue,
152        dest_format: gst::Format,
153    ) -> Option<gst::GenericFormattedValue> {
154        unsafe {
155            let mut dest_val = mem::MaybeUninit::uninit();
156            let ret = from_glib(ffi::gst_base_parse_convert_default(
157                self.as_ref().to_glib_none().0,
158                src_val.format().into_glib(),
159                src_val.into_raw_value(),
160                dest_format.into_glib(),
161                dest_val.as_mut_ptr(),
162            ));
163            if ret {
164                Some(gst::GenericFormattedValue::new(
165                    dest_format,
166                    dest_val.assume_init(),
167                ))
168            } else {
169                None
170            }
171        }
172    }
173
174    /// Collects parsed data and pushes it downstream.
175    /// Source pad caps must be set when this is called.
176    ///
177    /// If `frame`'s out_buffer is set, that will be used as subsequent frame data,
178    /// and `size` amount will be flushed from the input data. The output_buffer size
179    /// can differ from the consumed size indicated by `size`.
180    ///
181    /// Otherwise, `size` samples will be taken from the input and used for output,
182    /// and the output's metadata (timestamps etc) will be taken as (optionally)
183    /// set by the subclass on `frame`'s (input) buffer (which is otherwise
184    /// ignored for any but the above purpose/information).
185    ///
186    /// Note that the latter buffer is invalidated by this call, whereas the
187    /// caller retains ownership of `frame`.
188    /// ## `frame`
189    /// a [`BaseParseFrame`][crate::BaseParseFrame]
190    /// ## `size`
191    /// consumed input data represented by frame
192    ///
193    /// # Returns
194    ///
195    /// a [`gst::FlowReturn`][crate::gst::FlowReturn] that should be escalated to caller (of caller)
196    #[doc(alias = "gst_base_parse_finish_frame")]
197    fn finish_frame(
198        &self,
199        frame: BaseParseFrame,
200        size: u32,
201    ) -> Result<gst::FlowSuccess, gst::FlowError> {
202        unsafe {
203            try_from_glib(ffi::gst_base_parse_finish_frame(
204                self.as_ref().to_glib_none().0,
205                frame.to_glib_none().0,
206                i32::try_from(size).expect("size higher than i32::MAX"),
207            ))
208        }
209    }
210}
211
212impl<O: IsA<BaseParse>> BaseParseExtManual for O {}