gstreamer_rtsp_server/subclass/
rtsp_media_factory.rs1use 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> {
13 self.parent_gen_key(url)
14 }
15
16 fn create_element(&self, url: &gst_rtsp::RTSPUrl) -> Option<gst::Element> {
17 self.parent_create_element(url)
18 }
19
20 fn construct(&self, url: &gst_rtsp::RTSPUrl) -> Option<crate::RTSPMedia> {
21 self.parent_construct(url)
22 }
23
24 fn create_pipeline(&self, media: &crate::RTSPMedia) -> Option<gst::Pipeline> {
25 self.parent_create_pipeline(media)
26 }
27
28 fn configure(&self, media: &crate::RTSPMedia) {
29 self.parent_configure(media)
30 }
31
32 fn media_constructed(&self, media: &crate::RTSPMedia) {
33 self.parent_media_constructed(media)
34 }
35
36 fn media_configure(&self, media: &crate::RTSPMedia) {
37 self.parent_media_configure(media)
38 }
39}
40
41pub trait RTSPMediaFactoryImplExt: RTSPMediaFactoryImpl {
42 fn parent_gen_key(&self, url: &gst_rtsp::RTSPUrl) -> Option<glib::GString> {
43 unsafe {
44 let data = Self::type_data();
45 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
46 (*parent_class)
47 .gen_key
48 .map(|f| {
49 from_glib_full(f(
50 self.obj()
51 .unsafe_cast_ref::<RTSPMediaFactory>()
52 .to_glib_none()
53 .0,
54 url.to_glib_none().0,
55 ))
56 })
57 .unwrap_or(None)
58 }
59 }
60
61 fn parent_create_element(&self, url: &gst_rtsp::RTSPUrl) -> Option<gst::Element> {
62 unsafe {
63 let data = Self::type_data();
64 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
65 (*parent_class)
66 .create_element
67 .map(|f| {
68 from_glib_none(f(
69 self.obj()
70 .unsafe_cast_ref::<RTSPMediaFactory>()
71 .to_glib_none()
72 .0,
73 url.to_glib_none().0,
74 ))
75 })
76 .unwrap_or(None)
77 }
78 }
79
80 fn parent_construct(&self, url: &gst_rtsp::RTSPUrl) -> Option<crate::RTSPMedia> {
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 .construct
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_pipeline(&self, media: &crate::RTSPMedia) -> Option<gst::Pipeline> {
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_pipeline
105 .map(|f| {
106 let ptr = f(
107 self.obj()
108 .unsafe_cast_ref::<RTSPMediaFactory>()
109 .to_glib_none()
110 .0,
111 media.to_glib_none().0,
112 ) as *mut gst::ffi::GstPipeline;
113
114 if glib::gobject_ffi::g_object_is_floating(ptr as *mut _) != glib::ffi::GFALSE {
116 glib::gobject_ffi::g_object_ref_sink(ptr as *mut _);
117 }
118 from_glib_none(ptr)
119 })
120 .unwrap_or(None)
121 }
122 }
123
124 fn parent_configure(&self, media: &crate::RTSPMedia) {
125 unsafe {
126 let data = Self::type_data();
127 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
128 if let Some(f) = (*parent_class).configure {
129 f(
130 self.obj()
131 .unsafe_cast_ref::<RTSPMediaFactory>()
132 .to_glib_none()
133 .0,
134 media.to_glib_none().0,
135 );
136 }
137 }
138 }
139
140 fn parent_media_constructed(&self, media: &crate::RTSPMedia) {
141 unsafe {
142 let data = Self::type_data();
143 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
144 if let Some(f) = (*parent_class).media_constructed {
145 f(
146 self.obj()
147 .unsafe_cast_ref::<RTSPMediaFactory>()
148 .to_glib_none()
149 .0,
150 media.to_glib_none().0,
151 );
152 }
153 }
154 }
155
156 fn parent_media_configure(&self, media: &crate::RTSPMedia) {
157 unsafe {
158 let data = Self::type_data();
159 let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTSPMediaFactoryClass;
160 if let Some(f) = (*parent_class).media_configure {
161 f(
162 self.obj()
163 .unsafe_cast_ref::<RTSPMediaFactory>()
164 .to_glib_none()
165 .0,
166 media.to_glib_none().0,
167 );
168 }
169 }
170 }
171}
172
173impl<T: RTSPMediaFactoryImpl> RTSPMediaFactoryImplExt for T {}
174unsafe impl<T: RTSPMediaFactoryImpl> IsSubclassable<T> for RTSPMediaFactory {
175 fn class_init(klass: &mut glib::Class<Self>) {
176 Self::parent_class_init::<T>(klass);
177 let klass = klass.as_mut();
178 klass.gen_key = Some(factory_gen_key::<T>);
179 klass.create_element = Some(factory_create_element::<T>);
180 klass.construct = Some(factory_construct::<T>);
181 klass.create_pipeline = Some(factory_create_pipeline::<T>);
182 klass.configure = Some(factory_configure::<T>);
183 klass.media_constructed = Some(factory_media_constructed::<T>);
184 klass.media_configure = Some(factory_media_configure::<T>);
185 }
186}
187
188unsafe extern "C" fn factory_gen_key<T: RTSPMediaFactoryImpl>(
189 ptr: *mut ffi::GstRTSPMediaFactory,
190 url: *const gst_rtsp::ffi::GstRTSPUrl,
191) -> *mut std::os::raw::c_char {
192 let instance = &*(ptr as *mut T::Instance);
193 let imp = instance.imp();
194
195 imp.gen_key(&from_glib_borrow(url)).into_glib_ptr()
196}
197
198unsafe extern "C" fn factory_create_element<T: RTSPMediaFactoryImpl>(
199 ptr: *mut ffi::GstRTSPMediaFactory,
200 url: *const gst_rtsp::ffi::GstRTSPUrl,
201) -> *mut gst::ffi::GstElement {
202 let instance = &*(ptr as *mut T::Instance);
203 let imp = instance.imp();
204
205 let element = imp.create_element(&from_glib_borrow(url)).into_glib_ptr();
206 glib::gobject_ffi::g_object_force_floating(element as *mut _);
207 element
208}
209
210unsafe extern "C" fn factory_construct<T: RTSPMediaFactoryImpl>(
211 ptr: *mut ffi::GstRTSPMediaFactory,
212 url: *const gst_rtsp::ffi::GstRTSPUrl,
213) -> *mut ffi::GstRTSPMedia {
214 let instance = &*(ptr as *mut T::Instance);
215 let imp = instance.imp();
216
217 imp.construct(&from_glib_borrow(url)).into_glib_ptr()
218}
219
220unsafe extern "C" fn factory_create_pipeline<T: RTSPMediaFactoryImpl>(
221 ptr: *mut ffi::GstRTSPMediaFactory,
222 media: *mut ffi::GstRTSPMedia,
223) -> *mut gst::ffi::GstElement {
224 static PIPELINE_QUARK: std::sync::OnceLock<glib::Quark> = std::sync::OnceLock::new();
225
226 let pipeline_quark =
227 PIPELINE_QUARK.get_or_init(|| glib::Quark::from_str("gstreamer-rs-rtsp-media-pipeline"));
228
229 let instance = &*(ptr as *mut T::Instance);
230 let imp = instance.imp();
231
232 let pipeline: *mut gst::ffi::GstPipeline = imp
233 .create_pipeline(&from_glib_borrow(media))
234 .into_glib_ptr();
235
236 glib::gobject_ffi::g_object_set_qdata_full(
238 media as *mut _,
239 pipeline_quark.into_glib(),
240 pipeline as *mut _,
241 Some(transmute::<
242 *const (),
243 unsafe extern "C" fn(glib::ffi::gpointer),
244 >(glib::gobject_ffi::g_object_unref as *const ())),
245 );
246
247 pipeline as *mut _
248}
249
250unsafe extern "C" fn factory_configure<T: RTSPMediaFactoryImpl>(
251 ptr: *mut ffi::GstRTSPMediaFactory,
252 media: *mut ffi::GstRTSPMedia,
253) {
254 let instance = &*(ptr as *mut T::Instance);
255 let imp = instance.imp();
256
257 imp.configure(&from_glib_borrow(media));
258}
259
260unsafe extern "C" fn factory_media_constructed<T: RTSPMediaFactoryImpl>(
261 ptr: *mut ffi::GstRTSPMediaFactory,
262 media: *mut ffi::GstRTSPMedia,
263) {
264 let instance = &*(ptr as *mut T::Instance);
265 let imp = instance.imp();
266
267 imp.media_constructed(&from_glib_borrow(media));
268}
269
270unsafe extern "C" fn factory_media_configure<T: RTSPMediaFactoryImpl>(
271 ptr: *mut ffi::GstRTSPMediaFactory,
272 media: *mut ffi::GstRTSPMedia,
273) {
274 let instance = &*(ptr as *mut T::Instance);
275 let imp = instance.imp();
276
277 imp.media_configure(&from_glib_borrow(media));
278}