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