gstreamer_rtsp_server/subclass/
rtsp_media_factory.rs
1use std::mem::transmute;
4
5use glib::{prelude::*, subclass::prelude::*, translate::*};
6
7use crate::{ffi, RTSPMediaFactory};
8
9pub trait RTSPMediaFactoryImpl:
10 ObjectImpl + ObjectSubclass<Type: IsA<RTSPMediaFactory>> + Send + Sync
11{
12 fn gen_key(&self, url: &gst_rtsp::RTSPUrl) -> Option<glib::GString> {
16 self.parent_gen_key(url)
17 }
18
19 fn create_element(&self, url: &gst_rtsp::RTSPUrl) -> Option<gst::Element> {
32 self.parent_create_element(url)
33 }
34
35 fn construct(&self, url: &gst_rtsp::RTSPUrl) -> Option<crate::RTSPMedia> {
53 self.parent_construct(url)
54 }
55
56 fn create_pipeline(&self, media: &crate::RTSPMedia) -> Option<gst::Pipeline> {
59 self.parent_create_pipeline(media)
60 }
61
62 fn configure(&self, media: &crate::RTSPMedia) {
65 self.parent_configure(media)
66 }
67
68 fn media_constructed(&self, media: &crate::RTSPMedia) {
70 self.parent_media_constructed(media)
71 }
72
73 fn media_configure(&self, media: &crate::RTSPMedia) {
75 self.parent_media_configure(media)
76 }
77}
78
79pub trait RTSPMediaFactoryImplExt: RTSPMediaFactoryImpl {
80 fn parent_gen_key(&self, url: &gst_rtsp::RTSPUrl) -> Option<glib::GString> {
81 unsafe {
82 let data = Self::type_data();
83 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
84 (*parent_class)
85 .gen_key
86 .map(|f| {
87 from_glib_full(f(
88 self.obj()
89 .unsafe_cast_ref::<RTSPMediaFactory>()
90 .to_glib_none()
91 .0,
92 url.to_glib_none().0,
93 ))
94 })
95 .unwrap_or(None)
96 }
97 }
98
99 fn parent_create_element(&self, url: &gst_rtsp::RTSPUrl) -> Option<gst::Element> {
100 unsafe {
101 let data = Self::type_data();
102 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
103 (*parent_class)
104 .create_element
105 .map(|f| {
106 from_glib_none(f(
107 self.obj()
108 .unsafe_cast_ref::<RTSPMediaFactory>()
109 .to_glib_none()
110 .0,
111 url.to_glib_none().0,
112 ))
113 })
114 .unwrap_or(None)
115 }
116 }
117
118 fn parent_construct(&self, url: &gst_rtsp::RTSPUrl) -> Option<crate::RTSPMedia> {
119 unsafe {
120 let data = Self::type_data();
121 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
122 (*parent_class)
123 .construct
124 .map(|f| {
125 from_glib_full(f(
126 self.obj()
127 .unsafe_cast_ref::<RTSPMediaFactory>()
128 .to_glib_none()
129 .0,
130 url.to_glib_none().0,
131 ))
132 })
133 .unwrap_or(None)
134 }
135 }
136
137 fn parent_create_pipeline(&self, media: &crate::RTSPMedia) -> Option<gst::Pipeline> {
138 unsafe {
139 let data = Self::type_data();
140 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
141 (*parent_class)
142 .create_pipeline
143 .map(|f| {
144 let ptr = f(
145 self.obj()
146 .unsafe_cast_ref::<RTSPMediaFactory>()
147 .to_glib_none()
148 .0,
149 media.to_glib_none().0,
150 ) as *mut gst::ffi::GstPipeline;
151
152 if glib::gobject_ffi::g_object_is_floating(ptr as *mut _) != glib::ffi::GFALSE {
154 glib::gobject_ffi::g_object_ref_sink(ptr as *mut _);
155 }
156 from_glib_none(ptr)
157 })
158 .unwrap_or(None)
159 }
160 }
161
162 fn parent_configure(&self, media: &crate::RTSPMedia) {
163 unsafe {
164 let data = Self::type_data();
165 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
166 if let Some(f) = (*parent_class).configure {
167 f(
168 self.obj()
169 .unsafe_cast_ref::<RTSPMediaFactory>()
170 .to_glib_none()
171 .0,
172 media.to_glib_none().0,
173 );
174 }
175 }
176 }
177
178 fn parent_media_constructed(&self, media: &crate::RTSPMedia) {
179 unsafe {
180 let data = Self::type_data();
181 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
182 if let Some(f) = (*parent_class).media_constructed {
183 f(
184 self.obj()
185 .unsafe_cast_ref::<RTSPMediaFactory>()
186 .to_glib_none()
187 .0,
188 media.to_glib_none().0,
189 );
190 }
191 }
192 }
193
194 fn parent_media_configure(&self, media: &crate::RTSPMedia) {
195 unsafe {
196 let data = Self::type_data();
197 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
198 if let Some(f) = (*parent_class).media_configure {
199 f(
200 self.obj()
201 .unsafe_cast_ref::<RTSPMediaFactory>()
202 .to_glib_none()
203 .0,
204 media.to_glib_none().0,
205 );
206 }
207 }
208 }
209}
210
211impl<T: RTSPMediaFactoryImpl> RTSPMediaFactoryImplExt for T {}
212unsafe impl<T: RTSPMediaFactoryImpl> IsSubclassable<T> for RTSPMediaFactory {
213 fn class_init(klass: &mut glib::Class<Self>) {
214 Self::parent_class_init::<T>(klass);
215 let klass = klass.as_mut();
216 klass.gen_key = Some(factory_gen_key::<T>);
217 klass.create_element = Some(factory_create_element::<T>);
218 klass.construct = Some(factory_construct::<T>);
219 klass.create_pipeline = Some(factory_create_pipeline::<T>);
220 klass.configure = Some(factory_configure::<T>);
221 klass.media_constructed = Some(factory_media_constructed::<T>);
222 klass.media_configure = Some(factory_media_configure::<T>);
223 }
224}
225
226unsafe extern "C" fn factory_gen_key<T: RTSPMediaFactoryImpl>(
227 ptr: *mut ffi::GstRTSPMediaFactory,
228 url: *const gst_rtsp::ffi::GstRTSPUrl,
229) -> *mut std::os::raw::c_char {
230 let instance = &*(ptr as *mut T::Instance);
231 let imp = instance.imp();
232
233 imp.gen_key(&from_glib_borrow(url)).into_glib_ptr()
234}
235
236unsafe extern "C" fn factory_create_element<T: RTSPMediaFactoryImpl>(
237 ptr: *mut ffi::GstRTSPMediaFactory,
238 url: *const gst_rtsp::ffi::GstRTSPUrl,
239) -> *mut gst::ffi::GstElement {
240 let instance = &*(ptr as *mut T::Instance);
241 let imp = instance.imp();
242
243 let element = imp.create_element(&from_glib_borrow(url)).into_glib_ptr();
244 glib::gobject_ffi::g_object_force_floating(element as *mut _);
245 element
246}
247
248unsafe extern "C" fn factory_construct<T: RTSPMediaFactoryImpl>(
249 ptr: *mut ffi::GstRTSPMediaFactory,
250 url: *const gst_rtsp::ffi::GstRTSPUrl,
251) -> *mut ffi::GstRTSPMedia {
252 let instance = &*(ptr as *mut T::Instance);
253 let imp = instance.imp();
254
255 imp.construct(&from_glib_borrow(url)).into_glib_ptr()
256}
257
258unsafe extern "C" fn factory_create_pipeline<T: RTSPMediaFactoryImpl>(
259 ptr: *mut ffi::GstRTSPMediaFactory,
260 media: *mut ffi::GstRTSPMedia,
261) -> *mut gst::ffi::GstElement {
262 static PIPELINE_QUARK: std::sync::OnceLock<glib::Quark> = std::sync::OnceLock::new();
263
264 let pipeline_quark =
265 PIPELINE_QUARK.get_or_init(|| glib::Quark::from_str("gstreamer-rs-rtsp-media-pipeline"));
266
267 let instance = &*(ptr as *mut T::Instance);
268 let imp = instance.imp();
269
270 let pipeline: *mut gst::ffi::GstPipeline = imp
271 .create_pipeline(&from_glib_borrow(media))
272 .into_glib_ptr();
273
274 glib::gobject_ffi::g_object_set_qdata_full(
276 media as *mut _,
277 pipeline_quark.into_glib(),
278 pipeline as *mut _,
279 Some(transmute::<
280 *const (),
281 unsafe extern "C" fn(glib::ffi::gpointer),
282 >(glib::gobject_ffi::g_object_unref as *const ())),
283 );
284
285 pipeline as *mut _
286}
287
288unsafe extern "C" fn factory_configure<T: RTSPMediaFactoryImpl>(
289 ptr: *mut ffi::GstRTSPMediaFactory,
290 media: *mut ffi::GstRTSPMedia,
291) {
292 let instance = &*(ptr as *mut T::Instance);
293 let imp = instance.imp();
294
295 imp.configure(&from_glib_borrow(media));
296}
297
298unsafe extern "C" fn factory_media_constructed<T: RTSPMediaFactoryImpl>(
299 ptr: *mut ffi::GstRTSPMediaFactory,
300 media: *mut ffi::GstRTSPMedia,
301) {
302 let instance = &*(ptr as *mut T::Instance);
303 let imp = instance.imp();
304
305 imp.media_constructed(&from_glib_borrow(media));
306}
307
308unsafe extern "C" fn factory_media_configure<T: RTSPMediaFactoryImpl>(
309 ptr: *mut ffi::GstRTSPMediaFactory,
310 media: *mut ffi::GstRTSPMedia,
311) {
312 let instance = &*(ptr as *mut T::Instance);
313 let imp = instance.imp();
314
315 imp.media_configure(&from_glib_borrow(media));
316}