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::{ffi, BaseParse, BaseParseFrame};
12
13mod sealed {
14 pub trait Sealed {}
15 impl<T: super::IsA<super::BaseParse>> Sealed for T {}
16}
17
18pub trait BaseParseExtManual: sealed::Sealed + IsA<BaseParse> + 'static {
19 #[doc(alias = "get_sink_pad")]
20 fn sink_pad(&self) -> &gst::Pad {
21 unsafe {
22 let elt = &*(self.as_ptr() as *const ffi::GstBaseParse);
23 &*(&elt.sinkpad as *const *mut gst::ffi::GstPad as *const gst::Pad)
24 }
25 }
26
27 #[doc(alias = "get_src_pad")]
28 fn src_pad(&self) -> &gst::Pad {
29 unsafe {
30 let elt = &*(self.as_ptr() as *const ffi::GstBaseParse);
31 &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const gst::Pad)
32 }
33 }
34
35 fn segment(&self) -> gst::Segment {
36 unsafe {
37 let ptr: &ffi::GstBaseParse = &*(self.as_ptr() as *const _);
38 let sinkpad = self.sink_pad();
39 let _guard = sinkpad.stream_lock();
40 from_glib_none(&ptr.segment as *const gst::ffi::GstSegment)
41 }
42 }
43
44 fn lost_sync(&self) -> bool {
45 unsafe {
46 let ptr: &ffi::GstBaseParse = &*(self.as_ptr() as *const _);
47 let sinkpad = self.sink_pad();
48 let _guard = sinkpad.stream_lock();
49 ptr.flags & ffi::GST_BASE_PARSE_FLAG_LOST_SYNC as u32 != 0
50 }
51 }
52
53 fn is_draining(&self) -> bool {
54 unsafe {
55 let ptr: &ffi::GstBaseParse = &*(self.as_ptr() as *const _);
56 let sinkpad = self.sink_pad();
57 let _guard = sinkpad.stream_lock();
58 ptr.flags & ffi::GST_BASE_PARSE_FLAG_DRAINING as u32 != 0
59 }
60 }
61
62 #[doc(alias = "gst_base_parse_set_duration")]
63 fn set_duration(&self, duration: impl FormattedValue, interval: u32) {
64 unsafe {
65 ffi::gst_base_parse_set_duration(
66 self.as_ref().to_glib_none().0,
67 duration.format().into_glib(),
68 duration.into_raw_value(),
69 interval as i32,
70 );
71 }
72 }
73
74 #[doc(alias = "gst_base_parse_set_frame_rate")]
75 fn set_frame_rate(&self, fps: gst::Fraction, lead_in: u32, lead_out: u32) {
76 let (fps_num, fps_den) = fps.into();
77 unsafe {
78 ffi::gst_base_parse_set_frame_rate(
79 self.as_ref().to_glib_none().0,
80 fps_num as u32,
81 fps_den as u32,
82 lead_in,
83 lead_out,
84 );
85 }
86 }
87
88 #[doc(alias = "gst_base_parse_convert_default")]
89 fn convert_default<U: SpecificFormattedValueFullRange>(
90 &self,
91 src_val: impl FormattedValue,
92 ) -> Option<U> {
93 unsafe {
94 let mut dest_val = mem::MaybeUninit::uninit();
95 let ret = from_glib(ffi::gst_base_parse_convert_default(
96 self.as_ref().to_glib_none().0,
97 src_val.format().into_glib(),
98 src_val.into_raw_value(),
99 U::default_format().into_glib(),
100 dest_val.as_mut_ptr(),
101 ));
102 if ret {
103 Some(U::from_raw(U::default_format(), dest_val.assume_init()))
104 } else {
105 None
106 }
107 }
108 }
109
110 fn convert_default_generic(
111 &self,
112 src_val: impl FormattedValue,
113 dest_format: gst::Format,
114 ) -> Option<gst::GenericFormattedValue> {
115 unsafe {
116 let mut dest_val = mem::MaybeUninit::uninit();
117 let ret = from_glib(ffi::gst_base_parse_convert_default(
118 self.as_ref().to_glib_none().0,
119 src_val.format().into_glib(),
120 src_val.into_raw_value(),
121 dest_format.into_glib(),
122 dest_val.as_mut_ptr(),
123 ));
124 if ret {
125 Some(gst::GenericFormattedValue::new(
126 dest_format,
127 dest_val.assume_init(),
128 ))
129 } else {
130 None
131 }
132 }
133 }
134
135 #[doc(alias = "gst_base_parse_finish_frame")]
136 fn finish_frame(
137 &self,
138 frame: BaseParseFrame,
139 size: u32,
140 ) -> Result<gst::FlowSuccess, gst::FlowError> {
141 unsafe {
142 try_from_glib(ffi::gst_base_parse_finish_frame(
143 self.as_ref().to_glib_none().0,
144 frame.to_glib_none().0,
145 i32::try_from(size).expect("size higher than i32::MAX"),
146 ))
147 }
148 }
149}
150
151impl<O: IsA<BaseParse>> BaseParseExtManual for O {}
152