1#![allow(deprecated)]
6
7use crate::{
8 ffi, Bus, Caps, Clock, ClockTime, Context, ElementFactory, Message, Object, Pad, PadTemplate,
9 State, StateChange, StateChangeError, StateChangeReturn, StateChangeSuccess, URIType,
10};
11use glib::{
12 object::ObjectType as _,
13 prelude::*,
14 signal::{connect_raw, SignalHandlerId},
15 translate::*,
16};
17use std::boxed::Box as Box_;
18
19glib::wrapper! {
20 #[doc(alias = "GstElement")]
21 pub struct Element(Object<ffi::GstElement, ffi::GstElementClass>) @extends Object;
22
23 match fn {
24 type_ => || ffi::gst_element_get_type(),
25 }
26}
27
28impl Element {
29 pub const NONE: Option<&'static Element> = None;
30
31 #[doc(alias = "gst_element_make_from_uri")]
32 pub fn make_from_uri(
33 type_: URIType,
34 uri: &str,
35 elementname: Option<&str>,
36 ) -> Result<Element, glib::Error> {
37 assert_initialized_main_thread!();
38 unsafe {
39 let mut error = std::ptr::null_mut();
40 let ret = ffi::gst_element_make_from_uri(
41 type_.into_glib(),
42 uri.to_glib_none().0,
43 elementname.to_glib_none().0,
44 &mut error,
45 );
46 if error.is_null() {
47 Ok(from_glib_none(ret))
48 } else {
49 Err(from_glib_full(error))
50 }
51 }
52 }
53}
54
55unsafe impl Send for Element {}
56unsafe impl Sync for Element {}
57
58pub trait ElementExt: IsA<Element> + 'static {
59 #[doc(alias = "gst_element_abort_state")]
60 fn abort_state(&self) {
61 unsafe {
62 ffi::gst_element_abort_state(self.as_ref().to_glib_none().0);
63 }
64 }
65
66 #[doc(alias = "gst_element_add_pad")]
67 fn add_pad(&self, pad: &impl IsA<Pad>) -> Result<(), glib::error::BoolError> {
68 unsafe {
69 glib::result_from_gboolean!(
70 ffi::gst_element_add_pad(
71 self.as_ref().to_glib_none().0,
72 pad.as_ref().to_glib_none().0
73 ),
74 "Failed to add pad"
75 )
76 }
77 }
78
79 #[doc(alias = "gst_element_change_state")]
80 fn change_state(
81 &self,
82 transition: StateChange,
83 ) -> Result<StateChangeSuccess, StateChangeError> {
84 unsafe {
85 try_from_glib(ffi::gst_element_change_state(
86 self.as_ref().to_glib_none().0,
87 transition.into_glib(),
88 ))
89 }
90 }
91
92 #[doc(alias = "gst_element_continue_state")]
93 fn continue_state(
94 &self,
95 ret: impl Into<StateChangeReturn>,
96 ) -> Result<StateChangeSuccess, StateChangeError> {
97 unsafe {
98 try_from_glib(ffi::gst_element_continue_state(
99 self.as_ref().to_glib_none().0,
100 ret.into().into_glib(),
101 ))
102 }
103 }
104
105 #[doc(alias = "gst_element_create_all_pads")]
106 fn create_all_pads(&self) {
107 unsafe {
108 ffi::gst_element_create_all_pads(self.as_ref().to_glib_none().0);
109 }
110 }
111
112 #[cfg(feature = "v1_24")]
113 #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
114 #[doc(alias = "gst_element_decorate_stream_id")]
115 fn decorate_stream_id(&self, stream_id: &str) -> glib::GString {
116 unsafe {
117 from_glib_full(ffi::gst_element_decorate_stream_id(
118 self.as_ref().to_glib_none().0,
119 stream_id.to_glib_none().0,
120 ))
121 }
122 }
123
124 #[doc(alias = "gst_element_get_base_time")]
125 #[doc(alias = "get_base_time")]
126 fn base_time(&self) -> Option<ClockTime> {
127 unsafe {
128 from_glib(ffi::gst_element_get_base_time(
129 self.as_ref().to_glib_none().0,
130 ))
131 }
132 }
133
134 #[doc(alias = "gst_element_get_bus")]
135 #[doc(alias = "get_bus")]
136 fn bus(&self) -> Option<Bus> {
137 unsafe { from_glib_full(ffi::gst_element_get_bus(self.as_ref().to_glib_none().0)) }
138 }
139
140 #[doc(alias = "gst_element_get_clock")]
141 #[doc(alias = "get_clock")]
142 fn clock(&self) -> Option<Clock> {
143 unsafe { from_glib_full(ffi::gst_element_get_clock(self.as_ref().to_glib_none().0)) }
144 }
145
146 #[doc(alias = "gst_element_get_compatible_pad")]
147 #[doc(alias = "get_compatible_pad")]
148 fn compatible_pad(&self, pad: &impl IsA<Pad>, caps: Option<&Caps>) -> Option<Pad> {
149 unsafe {
150 from_glib_full(ffi::gst_element_get_compatible_pad(
151 self.as_ref().to_glib_none().0,
152 pad.as_ref().to_glib_none().0,
153 caps.to_glib_none().0,
154 ))
155 }
156 }
157
158 #[doc(alias = "gst_element_get_compatible_pad_template")]
159 #[doc(alias = "get_compatible_pad_template")]
160 fn compatible_pad_template(&self, compattempl: &PadTemplate) -> Option<PadTemplate> {
161 unsafe {
162 from_glib_none(ffi::gst_element_get_compatible_pad_template(
163 self.as_ref().to_glib_none().0,
164 compattempl.to_glib_none().0,
165 ))
166 }
167 }
168
169 #[doc(alias = "gst_element_get_context")]
170 #[doc(alias = "get_context")]
171 fn context(&self, context_type: &str) -> Option<Context> {
172 unsafe {
173 from_glib_full(ffi::gst_element_get_context(
174 self.as_ref().to_glib_none().0,
175 context_type.to_glib_none().0,
176 ))
177 }
178 }
179
180 #[doc(alias = "gst_element_get_contexts")]
181 #[doc(alias = "get_contexts")]
182 fn contexts(&self) -> Vec<Context> {
183 unsafe {
184 FromGlibPtrContainer::from_glib_full(ffi::gst_element_get_contexts(
185 self.as_ref().to_glib_none().0,
186 ))
187 }
188 }
189
190 #[doc(alias = "gst_element_get_factory")]
191 #[doc(alias = "get_factory")]
192 fn factory(&self) -> Option<ElementFactory> {
193 unsafe { from_glib_none(ffi::gst_element_get_factory(self.as_ref().to_glib_none().0)) }
194 }
195
196 #[doc(alias = "gst_element_get_start_time")]
197 #[doc(alias = "get_start_time")]
198 fn start_time(&self) -> Option<ClockTime> {
199 unsafe {
200 from_glib(ffi::gst_element_get_start_time(
201 self.as_ref().to_glib_none().0,
202 ))
203 }
204 }
205
206 #[doc(alias = "gst_element_get_state")]
207 #[doc(alias = "get_state")]
208 fn state(
209 &self,
210 timeout: impl Into<Option<ClockTime>>,
211 ) -> (Result<StateChangeSuccess, StateChangeError>, State, State) {
212 unsafe {
213 let mut state = std::mem::MaybeUninit::uninit();
214 let mut pending = std::mem::MaybeUninit::uninit();
215 let ret = try_from_glib(ffi::gst_element_get_state(
216 self.as_ref().to_glib_none().0,
217 state.as_mut_ptr(),
218 pending.as_mut_ptr(),
219 timeout.into().into_glib(),
220 ));
221 (
222 ret,
223 from_glib(state.assume_init()),
224 from_glib(pending.assume_init()),
225 )
226 }
227 }
228
229 #[doc(alias = "gst_element_get_static_pad")]
230 #[doc(alias = "get_static_pad")]
231 fn static_pad(&self, name: &str) -> Option<Pad> {
232 unsafe {
233 from_glib_full(ffi::gst_element_get_static_pad(
234 self.as_ref().to_glib_none().0,
235 name.to_glib_none().0,
236 ))
237 }
238 }
239
240 #[doc(alias = "gst_element_is_locked_state")]
241 fn is_locked_state(&self) -> bool {
242 unsafe {
243 from_glib(ffi::gst_element_is_locked_state(
244 self.as_ref().to_glib_none().0,
245 ))
246 }
247 }
248
249 #[doc(alias = "gst_element_lost_state")]
250 fn lost_state(&self) {
251 unsafe {
252 ffi::gst_element_lost_state(self.as_ref().to_glib_none().0);
253 }
254 }
255
256 #[doc(alias = "gst_element_no_more_pads")]
257 fn no_more_pads(&self) {
258 unsafe {
259 ffi::gst_element_no_more_pads(self.as_ref().to_glib_none().0);
260 }
261 }
262
263 #[doc(alias = "gst_element_post_message")]
264 fn post_message(&self, message: Message) -> Result<(), glib::error::BoolError> {
265 unsafe {
266 glib::result_from_gboolean!(
267 ffi::gst_element_post_message(
268 self.as_ref().to_glib_none().0,
269 message.into_glib_ptr()
270 ),
271 "Failed to post message"
272 )
273 }
274 }
275
276 #[doc(alias = "gst_element_provide_clock")]
277 fn provide_clock(&self) -> Option<Clock> {
278 unsafe {
279 from_glib_full(ffi::gst_element_provide_clock(
280 self.as_ref().to_glib_none().0,
281 ))
282 }
283 }
284
285 #[doc(alias = "gst_element_release_request_pad")]
286 fn release_request_pad(&self, pad: &impl IsA<Pad>) {
287 unsafe {
288 ffi::gst_element_release_request_pad(
289 self.as_ref().to_glib_none().0,
290 pad.as_ref().to_glib_none().0,
291 );
292 }
293 }
294
295 #[doc(alias = "gst_element_remove_pad")]
296 fn remove_pad(&self, pad: &impl IsA<Pad>) -> Result<(), glib::error::BoolError> {
297 unsafe {
298 glib::result_from_gboolean!(
299 ffi::gst_element_remove_pad(
300 self.as_ref().to_glib_none().0,
301 pad.as_ref().to_glib_none().0
302 ),
303 "Failed to remove pad"
304 )
305 }
306 }
307
308 #[doc(alias = "gst_element_request_pad")]
309 fn request_pad(
310 &self,
311 templ: &PadTemplate,
312 name: Option<&str>,
313 caps: Option<&Caps>,
314 ) -> Option<Pad> {
315 unsafe {
316 from_glib_full(ffi::gst_element_request_pad(
317 self.as_ref().to_glib_none().0,
318 templ.to_glib_none().0,
319 name.to_glib_none().0,
320 caps.to_glib_none().0,
321 ))
322 }
323 }
324
325 #[doc(alias = "gst_element_set_base_time")]
326 fn set_base_time(&self, time: ClockTime) {
327 unsafe {
328 ffi::gst_element_set_base_time(self.as_ref().to_glib_none().0, time.into_glib());
329 }
330 }
331
332 #[doc(alias = "gst_element_set_bus")]
333 fn set_bus(&self, bus: Option<&Bus>) {
334 unsafe {
335 ffi::gst_element_set_bus(self.as_ref().to_glib_none().0, bus.to_glib_none().0);
336 }
337 }
338
339 #[doc(alias = "gst_element_set_clock")]
340 fn set_clock(&self, clock: Option<&impl IsA<Clock>>) -> Result<(), glib::error::BoolError> {
341 unsafe {
342 glib::result_from_gboolean!(
343 ffi::gst_element_set_clock(
344 self.as_ref().to_glib_none().0,
345 clock.map(|p| p.as_ref()).to_glib_none().0
346 ),
347 "Failed to set clock"
348 )
349 }
350 }
351
352 #[doc(alias = "gst_element_set_context")]
353 fn set_context(&self, context: &Context) {
354 unsafe {
355 ffi::gst_element_set_context(self.as_ref().to_glib_none().0, context.to_glib_none().0);
356 }
357 }
358
359 #[doc(alias = "gst_element_set_locked_state")]
360 fn set_locked_state(&self, locked_state: bool) -> bool {
361 unsafe {
362 from_glib(ffi::gst_element_set_locked_state(
363 self.as_ref().to_glib_none().0,
364 locked_state.into_glib(),
365 ))
366 }
367 }
368
369 #[doc(alias = "gst_element_set_start_time")]
370 fn set_start_time(&self, time: impl Into<Option<ClockTime>>) {
371 unsafe {
372 ffi::gst_element_set_start_time(
373 self.as_ref().to_glib_none().0,
374 time.into().into_glib(),
375 );
376 }
377 }
378
379 #[doc(alias = "gst_element_set_state")]
380 fn set_state(&self, state: State) -> Result<StateChangeSuccess, StateChangeError> {
381 unsafe {
382 try_from_glib(ffi::gst_element_set_state(
383 self.as_ref().to_glib_none().0,
384 state.into_glib(),
385 ))
386 }
387 }
388
389 #[doc(alias = "gst_element_sync_state_with_parent")]
390 fn sync_state_with_parent(&self) -> Result<(), glib::error::BoolError> {
391 unsafe {
392 glib::result_from_gboolean!(
393 ffi::gst_element_sync_state_with_parent(self.as_ref().to_glib_none().0),
394 "Failed to sync state with parent"
395 )
396 }
397 }
398
399 #[doc(alias = "gst_element_unlink")]
400 fn unlink(&self, dest: &impl IsA<Element>) {
401 unsafe {
402 ffi::gst_element_unlink(
403 self.as_ref().to_glib_none().0,
404 dest.as_ref().to_glib_none().0,
405 );
406 }
407 }
408
409 #[doc(alias = "gst_element_unlink_pads")]
410 fn unlink_pads(&self, srcpadname: &str, dest: &impl IsA<Element>, destpadname: &str) {
411 unsafe {
412 ffi::gst_element_unlink_pads(
413 self.as_ref().to_glib_none().0,
414 srcpadname.to_glib_none().0,
415 dest.as_ref().to_glib_none().0,
416 destpadname.to_glib_none().0,
417 );
418 }
419 }
420
421 #[doc(alias = "no-more-pads")]
422 fn connect_no_more_pads<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
423 unsafe extern "C" fn no_more_pads_trampoline<
424 P: IsA<Element>,
425 F: Fn(&P) + Send + Sync + 'static,
426 >(
427 this: *mut ffi::GstElement,
428 f: glib::ffi::gpointer,
429 ) {
430 let f: &F = &*(f as *const F);
431 f(Element::from_glib_borrow(this).unsafe_cast_ref())
432 }
433 unsafe {
434 let f: Box_<F> = Box_::new(f);
435 connect_raw(
436 self.as_ptr() as *mut _,
437 c"no-more-pads".as_ptr() as *const _,
438 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
439 no_more_pads_trampoline::<Self, F> as *const (),
440 )),
441 Box_::into_raw(f),
442 )
443 }
444 }
445
446 #[doc(alias = "pad-added")]
447 fn connect_pad_added<F: Fn(&Self, &Pad) + Send + Sync + 'static>(
448 &self,
449 f: F,
450 ) -> SignalHandlerId {
451 unsafe extern "C" fn pad_added_trampoline<
452 P: IsA<Element>,
453 F: Fn(&P, &Pad) + Send + Sync + 'static,
454 >(
455 this: *mut ffi::GstElement,
456 new_pad: *mut ffi::GstPad,
457 f: glib::ffi::gpointer,
458 ) {
459 let f: &F = &*(f as *const F);
460 f(
461 Element::from_glib_borrow(this).unsafe_cast_ref(),
462 &from_glib_borrow(new_pad),
463 )
464 }
465 unsafe {
466 let f: Box_<F> = Box_::new(f);
467 connect_raw(
468 self.as_ptr() as *mut _,
469 c"pad-added".as_ptr() as *const _,
470 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
471 pad_added_trampoline::<Self, F> as *const (),
472 )),
473 Box_::into_raw(f),
474 )
475 }
476 }
477
478 #[doc(alias = "pad-removed")]
479 fn connect_pad_removed<F: Fn(&Self, &Pad) + Send + Sync + 'static>(
480 &self,
481 f: F,
482 ) -> SignalHandlerId {
483 unsafe extern "C" fn pad_removed_trampoline<
484 P: IsA<Element>,
485 F: Fn(&P, &Pad) + Send + Sync + 'static,
486 >(
487 this: *mut ffi::GstElement,
488 old_pad: *mut ffi::GstPad,
489 f: glib::ffi::gpointer,
490 ) {
491 let f: &F = &*(f as *const F);
492 f(
493 Element::from_glib_borrow(this).unsafe_cast_ref(),
494 &from_glib_borrow(old_pad),
495 )
496 }
497 unsafe {
498 let f: Box_<F> = Box_::new(f);
499 connect_raw(
500 self.as_ptr() as *mut _,
501 c"pad-removed".as_ptr() as *const _,
502 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
503 pad_removed_trampoline::<Self, F> as *const (),
504 )),
505 Box_::into_raw(f),
506 )
507 }
508 }
509}
510
511impl<O: IsA<Element>> ElementExt for O {}