gstreamer_rtp/subclass/
rtp_base_payload.rs
1use glib::translate::*;
4use gst::subclass::prelude::*;
5
6use crate::{ffi, prelude::*, RTPBasePayload};
7
8pub trait RTPBasePayloadImpl: ElementImpl + ObjectSubclass<Type: IsA<RTPBasePayload>> {
9 fn caps(&self, pad: &gst::Pad, filter: Option<&gst::Caps>) -> gst::Caps {
11 self.parent_caps(pad, filter)
12 }
13
14 fn set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
16 self.parent_set_caps(caps)
17 }
18
19 fn handle_buffer(&self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
21 self.parent_handle_buffer(buffer)
22 }
23
24 fn query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
26 RTPBasePayloadImplExt::parent_query(self, pad, query)
27 }
28
29 fn sink_event(&self, event: gst::Event) -> bool {
31 self.parent_sink_event(event)
32 }
33
34 fn src_event(&self, event: gst::Event) -> bool {
36 self.parent_src_event(event)
37 }
38}
39
40pub trait RTPBasePayloadImplExt: RTPBasePayloadImpl {
41 fn parent_caps(&self, pad: &gst::Pad, filter: Option<&gst::Caps>) -> gst::Caps {
42 unsafe {
43 let data = Self::type_data();
44 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
45 let f = (*parent_class)
46 .get_caps
47 .expect("Missing parent function `get_caps`");
48 from_glib_full(f(
49 self.obj()
50 .unsafe_cast_ref::<RTPBasePayload>()
51 .to_glib_none()
52 .0,
53 pad.to_glib_none().0,
54 filter.to_glib_none().0,
55 ))
56 }
57 }
58
59 fn parent_set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
60 unsafe {
61 let data = Self::type_data();
62 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
63 (*parent_class)
64 .set_caps
65 .map(|f| {
66 gst::result_from_gboolean!(
67 f(
68 self.obj()
69 .unsafe_cast_ref::<RTPBasePayload>()
70 .to_glib_none()
71 .0,
72 caps.to_glib_none().0
73 ),
74 gst::CAT_RUST,
75 "Parent function `set_caps` failed"
76 )
77 })
78 .unwrap_or_else(|| {
79 self.obj()
81 .unsafe_cast_ref::<RTPBasePayload>()
82 .set_outcaps(None)
83 .map_err(|_| gst::loggable_error!(gst::CAT_RUST, "Failed to negotiate"))
84 })
85 }
86 }
87
88 fn parent_handle_buffer(
89 &self,
90 buffer: gst::Buffer,
91 ) -> Result<gst::FlowSuccess, gst::FlowError> {
92 unsafe {
93 let data = Self::type_data();
94 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
95 (*parent_class)
96 .handle_buffer
97 .map(|f| {
98 try_from_glib(f(
99 self.obj()
100 .unsafe_cast_ref::<RTPBasePayload>()
101 .to_glib_none()
102 .0,
103 buffer.into_glib_ptr(),
104 ))
105 })
106 .unwrap_or(Err(gst::FlowError::Error))
107 }
108 }
109
110 fn parent_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
111 unsafe {
112 let data = Self::type_data();
113 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
114 (*parent_class)
115 .query
116 .map(|f| {
117 from_glib(f(
118 self.obj()
119 .unsafe_cast_ref::<RTPBasePayload>()
120 .to_glib_none()
121 .0,
122 pad.to_glib_none().0,
123 query.as_mut_ptr(),
124 ))
125 })
126 .unwrap_or(false)
127 }
128 }
129
130 fn parent_sink_event(&self, event: gst::Event) -> bool {
131 unsafe {
132 let data = Self::type_data();
133 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
134 (*parent_class)
135 .sink_event
136 .map(|f| {
137 from_glib(f(
138 self.obj()
139 .unsafe_cast_ref::<RTPBasePayload>()
140 .to_glib_none()
141 .0,
142 event.into_glib_ptr(),
143 ))
144 })
145 .unwrap_or(false)
146 }
147 }
148
149 fn parent_src_event(&self, event: gst::Event) -> bool {
150 unsafe {
151 let data = Self::type_data();
152 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass;
153 (*parent_class)
154 .src_event
155 .map(|f| {
156 from_glib(f(
157 self.obj()
158 .unsafe_cast_ref::<RTPBasePayload>()
159 .to_glib_none()
160 .0,
161 event.into_glib_ptr(),
162 ))
163 })
164 .unwrap_or(false)
165 }
166 }
167}
168
169impl<T: RTPBasePayloadImpl> RTPBasePayloadImplExt for T {}
170
171unsafe impl<T: RTPBasePayloadImpl> IsSubclassable<T> for RTPBasePayload {
172 fn class_init(klass: &mut glib::Class<Self>) {
173 Self::parent_class_init::<T>(klass);
174 let klass = klass.as_mut();
175 klass.get_caps = Some(rtp_base_payload_get_caps::<T>);
176 klass.set_caps = Some(rtp_base_payload_set_caps::<T>);
177 klass.handle_buffer = Some(rtp_base_payload_handle_buffer::<T>);
178 klass.query = Some(rtp_base_payload_query::<T>);
179 klass.sink_event = Some(rtp_base_payload_sink_event::<T>);
180 klass.src_event = Some(rtp_base_payload_src_event::<T>);
181 }
182}
183
184unsafe extern "C" fn rtp_base_payload_get_caps<T: RTPBasePayloadImpl>(
185 ptr: *mut ffi::GstRTPBasePayload,
186 pad: *mut gst::ffi::GstPad,
187 filter: *mut gst::ffi::GstCaps,
188) -> *mut gst::ffi::GstCaps {
189 let instance = &*(ptr as *mut T::Instance);
190 let imp = instance.imp();
191
192 gst::panic_to_error!(imp, gst::Caps::new_empty(), {
193 RTPBasePayloadImpl::caps(
194 imp,
195 &from_glib_borrow(pad),
196 Option::<gst::Caps>::from_glib_borrow(filter)
197 .as_ref()
198 .as_ref(),
199 )
200 })
201 .into_glib_ptr()
202}
203
204unsafe extern "C" fn rtp_base_payload_set_caps<T: RTPBasePayloadImpl>(
205 ptr: *mut ffi::GstRTPBasePayload,
206 caps: *mut gst::ffi::GstCaps,
207) -> glib::ffi::gboolean {
208 let instance = &*(ptr as *mut T::Instance);
209 let imp = instance.imp();
210 let caps = from_glib_borrow(caps);
211
212 gst::panic_to_error!(imp, false, {
213 match imp.set_caps(&caps) {
214 Ok(()) => true,
215 Err(err) => {
216 err.log_with_imp(imp);
217 false
218 }
219 }
220 })
221 .into_glib()
222}
223
224unsafe extern "C" fn rtp_base_payload_handle_buffer<T: RTPBasePayloadImpl>(
225 ptr: *mut ffi::GstRTPBasePayload,
226 buffer: *mut gst::ffi::GstBuffer,
227) -> gst::ffi::GstFlowReturn {
228 let instance = &*(ptr as *mut T::Instance);
229 let imp = instance.imp();
230
231 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
232 imp.handle_buffer(from_glib_full(buffer)).into()
233 })
234 .into_glib()
235}
236
237unsafe extern "C" fn rtp_base_payload_query<T: RTPBasePayloadImpl>(
238 ptr: *mut ffi::GstRTPBasePayload,
239 pad: *mut gst::ffi::GstPad,
240 query: *mut gst::ffi::GstQuery,
241) -> glib::ffi::gboolean {
242 let instance = &*(ptr as *mut T::Instance);
243 let imp = instance.imp();
244
245 gst::panic_to_error!(imp, false, {
246 RTPBasePayloadImpl::query(
247 imp,
248 &from_glib_borrow(pad),
249 gst::QueryRef::from_mut_ptr(query),
250 )
251 })
252 .into_glib()
253}
254
255unsafe extern "C" fn rtp_base_payload_sink_event<T: RTPBasePayloadImpl>(
256 ptr: *mut ffi::GstRTPBasePayload,
257 event: *mut gst::ffi::GstEvent,
258) -> glib::ffi::gboolean {
259 let instance = &*(ptr as *mut T::Instance);
260 let imp = instance.imp();
261
262 gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib()
263}
264
265unsafe extern "C" fn rtp_base_payload_src_event<T: RTPBasePayloadImpl>(
266 ptr: *mut ffi::GstRTPBasePayload,
267 event: *mut gst::ffi::GstEvent,
268) -> glib::ffi::gboolean {
269 let instance = &*(ptr as *mut T::Instance);
270 let imp = instance.imp();
271
272 gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
273}