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> {
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 unsafe {
231 let instance = &*(ptr as *mut T::Instance);
232 let imp = instance.imp();
233
234 imp.gen_key(&from_glib_borrow(url)).into_glib_ptr()
235 }
236}
237
238unsafe extern "C" fn factory_create_element<T: RTSPMediaFactoryImpl>(
239 ptr: *mut ffi::GstRTSPMediaFactory,
240 url: *const gst_rtsp::ffi::GstRTSPUrl,
241) -> *mut gst::ffi::GstElement {
242 unsafe {
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}
251
252unsafe extern "C" fn factory_construct<T: RTSPMediaFactoryImpl>(
253 ptr: *mut ffi::GstRTSPMediaFactory,
254 url: *const gst_rtsp::ffi::GstRTSPUrl,
255) -> *mut ffi::GstRTSPMedia {
256 unsafe {
257 let instance = &*(ptr as *mut T::Instance);
258 let imp = instance.imp();
259
260 imp.construct(&from_glib_borrow(url)).into_glib_ptr()
261 }
262}
263
264unsafe extern "C" fn factory_create_pipeline<T: RTSPMediaFactoryImpl>(
265 ptr: *mut ffi::GstRTSPMediaFactory,
266 media: *mut ffi::GstRTSPMedia,
267) -> *mut gst::ffi::GstElement {
268 unsafe {
269 static PIPELINE_QUARK: std::sync::OnceLock<glib::Quark> = std::sync::OnceLock::new();
270
271 let pipeline_quark = PIPELINE_QUARK
272 .get_or_init(|| glib::Quark::from_str("gstreamer-rs-rtsp-media-pipeline"));
273
274 let instance = &*(ptr as *mut T::Instance);
275 let imp = instance.imp();
276
277 let pipeline: *mut gst::ffi::GstPipeline = imp
278 .create_pipeline(&from_glib_borrow(media))
279 .into_glib_ptr();
280
281 glib::gobject_ffi::g_object_set_qdata_full(
283 media as *mut _,
284 pipeline_quark.into_glib(),
285 pipeline as *mut _,
286 Some(transmute::<
287 *const (),
288 unsafe extern "C" fn(glib::ffi::gpointer),
289 >(glib::gobject_ffi::g_object_unref as *const ())),
290 );
291
292 pipeline as *mut _
293 }
294}
295
296unsafe extern "C" fn factory_configure<T: RTSPMediaFactoryImpl>(
297 ptr: *mut ffi::GstRTSPMediaFactory,
298 media: *mut ffi::GstRTSPMedia,
299) {
300 unsafe {
301 let instance = &*(ptr as *mut T::Instance);
302 let imp = instance.imp();
303
304 imp.configure(&from_glib_borrow(media));
305 }
306}
307
308unsafe extern "C" fn factory_media_constructed<T: RTSPMediaFactoryImpl>(
309 ptr: *mut ffi::GstRTSPMediaFactory,
310 media: *mut ffi::GstRTSPMedia,
311) {
312 unsafe {
313 let instance = &*(ptr as *mut T::Instance);
314 let imp = instance.imp();
315
316 imp.media_constructed(&from_glib_borrow(media));
317 }
318}
319
320unsafe extern "C" fn factory_media_configure<T: RTSPMediaFactoryImpl>(
321 ptr: *mut ffi::GstRTSPMediaFactory,
322 media: *mut ffi::GstRTSPMedia,
323) {
324 unsafe {
325 let instance = &*(ptr as *mut T::Instance);
326 let imp = instance.imp();
327
328 imp.media_configure(&from_glib_borrow(media));
329 }
330}