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