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