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
58mod sealed {
59 pub trait Sealed {}
60 impl<T: super::IsA<super::Element>> Sealed for T {}
61}
62
63pub trait ElementExt: IsA<Element> + sealed::Sealed + 'static {
64 #[doc(alias = "gst_element_abort_state")]
65 fn abort_state(&self) {
66 unsafe {
67 ffi::gst_element_abort_state(self.as_ref().to_glib_none().0);
68 }
69 }
70
71 #[doc(alias = "gst_element_add_pad")]
72 fn add_pad(&self, pad: &impl IsA<Pad>) -> Result<(), glib::error::BoolError> {
73 unsafe {
74 glib::result_from_gboolean!(
75 ffi::gst_element_add_pad(
76 self.as_ref().to_glib_none().0,
77 pad.as_ref().to_glib_none().0
78 ),
79 "Failed to add pad"
80 )
81 }
82 }
83
84 #[doc(alias = "gst_element_change_state")]
85 fn change_state(
86 &self,
87 transition: StateChange,
88 ) -> Result<StateChangeSuccess, StateChangeError> {
89 unsafe {
90 try_from_glib(ffi::gst_element_change_state(
91 self.as_ref().to_glib_none().0,
92 transition.into_glib(),
93 ))
94 }
95 }
96
97 #[doc(alias = "gst_element_continue_state")]
98 fn continue_state(
99 &self,
100 ret: impl Into<StateChangeReturn>,
101 ) -> Result<StateChangeSuccess, StateChangeError> {
102 unsafe {
103 try_from_glib(ffi::gst_element_continue_state(
104 self.as_ref().to_glib_none().0,
105 ret.into().into_glib(),
106 ))
107 }
108 }
109
110 #[doc(alias = "gst_element_create_all_pads")]
111 fn create_all_pads(&self) {
112 unsafe {
113 ffi::gst_element_create_all_pads(self.as_ref().to_glib_none().0);
114 }
115 }
116
117 #[cfg(feature = "v1_24")]
118 #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
119 #[doc(alias = "gst_element_decorate_stream_id")]
120 fn decorate_stream_id(&self, stream_id: &str) -> glib::GString {
121 unsafe {
122 from_glib_full(ffi::gst_element_decorate_stream_id(
123 self.as_ref().to_glib_none().0,
124 stream_id.to_glib_none().0,
125 ))
126 }
127 }
128
129 #[doc(alias = "gst_element_foreach_pad")]
130 fn foreach_pad<P: FnMut(&Element, &Pad) -> bool>(&self, func: P) -> bool {
131 let mut func_data: P = func;
132 unsafe extern "C" fn func_func<P: FnMut(&Element, &Pad) -> bool>(
133 element: *mut ffi::GstElement,
134 pad: *mut ffi::GstPad,
135 user_data: glib::ffi::gpointer,
136 ) -> glib::ffi::gboolean {
137 let element = from_glib_borrow(element);
138 let pad = from_glib_borrow(pad);
139 let callback = user_data as *mut P;
140 (*callback)(&element, &pad).into_glib()
141 }
142 let func = Some(func_func::<P> as _);
143 let super_callback0: &mut P = &mut func_data;
144 unsafe {
145 from_glib(ffi::gst_element_foreach_pad(
146 self.as_ref().to_glib_none().0,
147 func,
148 super_callback0 as *mut _ as *mut _,
149 ))
150 }
151 }
152
153 #[doc(alias = "gst_element_foreach_sink_pad")]
154 fn foreach_sink_pad<P: FnMut(&Element, &Pad) -> bool>(&self, func: P) -> bool {
155 let mut func_data: P = func;
156 unsafe extern "C" fn func_func<P: FnMut(&Element, &Pad) -> bool>(
157 element: *mut ffi::GstElement,
158 pad: *mut ffi::GstPad,
159 user_data: glib::ffi::gpointer,
160 ) -> glib::ffi::gboolean {
161 let element = from_glib_borrow(element);
162 let pad = from_glib_borrow(pad);
163 let callback = user_data as *mut P;
164 (*callback)(&element, &pad).into_glib()
165 }
166 let func = Some(func_func::<P> as _);
167 let super_callback0: &mut P = &mut func_data;
168 unsafe {
169 from_glib(ffi::gst_element_foreach_sink_pad(
170 self.as_ref().to_glib_none().0,
171 func,
172 super_callback0 as *mut _ as *mut _,
173 ))
174 }
175 }
176
177 #[doc(alias = "gst_element_foreach_src_pad")]
178 fn foreach_src_pad<P: FnMut(&Element, &Pad) -> bool>(&self, func: P) -> bool {
179 let mut func_data: P = func;
180 unsafe extern "C" fn func_func<P: FnMut(&Element, &Pad) -> bool>(
181 element: *mut ffi::GstElement,
182 pad: *mut ffi::GstPad,
183 user_data: glib::ffi::gpointer,
184 ) -> glib::ffi::gboolean {
185 let element = from_glib_borrow(element);
186 let pad = from_glib_borrow(pad);
187 let callback = user_data as *mut P;
188 (*callback)(&element, &pad).into_glib()
189 }
190 let func = Some(func_func::<P> as _);
191 let super_callback0: &mut P = &mut func_data;
192 unsafe {
193 from_glib(ffi::gst_element_foreach_src_pad(
194 self.as_ref().to_glib_none().0,
195 func,
196 super_callback0 as *mut _ as *mut _,
197 ))
198 }
199 }
200
201 #[doc(alias = "gst_element_get_base_time")]
202 #[doc(alias = "get_base_time")]
203 fn base_time(&self) -> Option<ClockTime> {
204 unsafe {
205 from_glib(ffi::gst_element_get_base_time(
206 self.as_ref().to_glib_none().0,
207 ))
208 }
209 }
210
211 #[doc(alias = "gst_element_get_bus")]
212 #[doc(alias = "get_bus")]
213 fn bus(&self) -> Option<Bus> {
214 unsafe { from_glib_full(ffi::gst_element_get_bus(self.as_ref().to_glib_none().0)) }
215 }
216
217 #[doc(alias = "gst_element_get_clock")]
218 #[doc(alias = "get_clock")]
219 fn clock(&self) -> Option<Clock> {
220 unsafe { from_glib_full(ffi::gst_element_get_clock(self.as_ref().to_glib_none().0)) }
221 }
222
223 #[doc(alias = "gst_element_get_compatible_pad")]
224 #[doc(alias = "get_compatible_pad")]
225 fn compatible_pad(&self, pad: &impl IsA<Pad>, caps: Option<&Caps>) -> Option<Pad> {
226 unsafe {
227 from_glib_full(ffi::gst_element_get_compatible_pad(
228 self.as_ref().to_glib_none().0,
229 pad.as_ref().to_glib_none().0,
230 caps.to_glib_none().0,
231 ))
232 }
233 }
234
235 #[doc(alias = "gst_element_get_compatible_pad_template")]
236 #[doc(alias = "get_compatible_pad_template")]
237 fn compatible_pad_template(&self, compattempl: &PadTemplate) -> Option<PadTemplate> {
238 unsafe {
239 from_glib_none(ffi::gst_element_get_compatible_pad_template(
240 self.as_ref().to_glib_none().0,
241 compattempl.to_glib_none().0,
242 ))
243 }
244 }
245
246 #[doc(alias = "gst_element_get_context")]
247 #[doc(alias = "get_context")]
248 fn context(&self, context_type: &str) -> Option<Context> {
249 unsafe {
250 from_glib_full(ffi::gst_element_get_context(
251 self.as_ref().to_glib_none().0,
252 context_type.to_glib_none().0,
253 ))
254 }
255 }
256
257 #[doc(alias = "gst_element_get_contexts")]
258 #[doc(alias = "get_contexts")]
259 fn contexts(&self) -> Vec<Context> {
260 unsafe {
261 FromGlibPtrContainer::from_glib_full(ffi::gst_element_get_contexts(
262 self.as_ref().to_glib_none().0,
263 ))
264 }
265 }
266
267 #[doc(alias = "gst_element_get_factory")]
268 #[doc(alias = "get_factory")]
269 fn factory(&self) -> Option<ElementFactory> {
270 unsafe { from_glib_none(ffi::gst_element_get_factory(self.as_ref().to_glib_none().0)) }
271 }
272
273 #[doc(alias = "gst_element_get_start_time")]
274 #[doc(alias = "get_start_time")]
275 fn start_time(&self) -> Option<ClockTime> {
276 unsafe {
277 from_glib(ffi::gst_element_get_start_time(
278 self.as_ref().to_glib_none().0,
279 ))
280 }
281 }
282
283 #[doc(alias = "gst_element_get_state")]
284 #[doc(alias = "get_state")]
285 fn state(
286 &self,
287 timeout: impl Into<Option<ClockTime>>,
288 ) -> (Result<StateChangeSuccess, StateChangeError>, State, State) {
289 unsafe {
290 let mut state = std::mem::MaybeUninit::uninit();
291 let mut pending = std::mem::MaybeUninit::uninit();
292 let ret = try_from_glib(ffi::gst_element_get_state(
293 self.as_ref().to_glib_none().0,
294 state.as_mut_ptr(),
295 pending.as_mut_ptr(),
296 timeout.into().into_glib(),
297 ));
298 (
299 ret,
300 from_glib(state.assume_init()),
301 from_glib(pending.assume_init()),
302 )
303 }
304 }
305
306 #[doc(alias = "gst_element_get_static_pad")]
307 #[doc(alias = "get_static_pad")]
308 fn static_pad(&self, name: &str) -> Option<Pad> {
309 unsafe {
310 from_glib_full(ffi::gst_element_get_static_pad(
311 self.as_ref().to_glib_none().0,
312 name.to_glib_none().0,
313 ))
314 }
315 }
316
317 #[doc(alias = "gst_element_is_locked_state")]
318 fn is_locked_state(&self) -> bool {
319 unsafe {
320 from_glib(ffi::gst_element_is_locked_state(
321 self.as_ref().to_glib_none().0,
322 ))
323 }
324 }
325
326 #[doc(alias = "gst_element_lost_state")]
327 fn lost_state(&self) {
328 unsafe {
329 ffi::gst_element_lost_state(self.as_ref().to_glib_none().0);
330 }
331 }
332
333 #[doc(alias = "gst_element_no_more_pads")]
334 fn no_more_pads(&self) {
335 unsafe {
336 ffi::gst_element_no_more_pads(self.as_ref().to_glib_none().0);
337 }
338 }
339
340 #[doc(alias = "gst_element_post_message")]
341 fn post_message(&self, message: Message) -> Result<(), glib::error::BoolError> {
342 unsafe {
343 glib::result_from_gboolean!(
344 ffi::gst_element_post_message(
345 self.as_ref().to_glib_none().0,
346 message.into_glib_ptr()
347 ),
348 "Failed to post message"
349 )
350 }
351 }
352
353 #[doc(alias = "gst_element_provide_clock")]
354 fn provide_clock(&self) -> Option<Clock> {
355 unsafe {
356 from_glib_full(ffi::gst_element_provide_clock(
357 self.as_ref().to_glib_none().0,
358 ))
359 }
360 }
361
362 #[doc(alias = "gst_element_release_request_pad")]
363 fn release_request_pad(&self, pad: &impl IsA<Pad>) {
364 unsafe {
365 ffi::gst_element_release_request_pad(
366 self.as_ref().to_glib_none().0,
367 pad.as_ref().to_glib_none().0,
368 );
369 }
370 }
371
372 #[doc(alias = "gst_element_remove_pad")]
373 fn remove_pad(&self, pad: &impl IsA<Pad>) -> Result<(), glib::error::BoolError> {
374 unsafe {
375 glib::result_from_gboolean!(
376 ffi::gst_element_remove_pad(
377 self.as_ref().to_glib_none().0,
378 pad.as_ref().to_glib_none().0
379 ),
380 "Failed to remove pad"
381 )
382 }
383 }
384
385 #[doc(alias = "gst_element_request_pad")]
386 fn request_pad(
387 &self,
388 templ: &PadTemplate,
389 name: Option<&str>,
390 caps: Option<&Caps>,
391 ) -> Option<Pad> {
392 unsafe {
393 from_glib_full(ffi::gst_element_request_pad(
394 self.as_ref().to_glib_none().0,
395 templ.to_glib_none().0,
396 name.to_glib_none().0,
397 caps.to_glib_none().0,
398 ))
399 }
400 }
401
402 #[doc(alias = "gst_element_set_base_time")]
403 fn set_base_time(&self, time: ClockTime) {
404 unsafe {
405 ffi::gst_element_set_base_time(self.as_ref().to_glib_none().0, time.into_glib());
406 }
407 }
408
409 #[doc(alias = "gst_element_set_bus")]
410 fn set_bus(&self, bus: Option<&Bus>) {
411 unsafe {
412 ffi::gst_element_set_bus(self.as_ref().to_glib_none().0, bus.to_glib_none().0);
413 }
414 }
415
416 #[doc(alias = "gst_element_set_clock")]
417 fn set_clock(&self, clock: Option<&impl IsA<Clock>>) -> Result<(), glib::error::BoolError> {
418 unsafe {
419 glib::result_from_gboolean!(
420 ffi::gst_element_set_clock(
421 self.as_ref().to_glib_none().0,
422 clock.map(|p| p.as_ref()).to_glib_none().0
423 ),
424 "Failed to set clock"
425 )
426 }
427 }
428
429 #[doc(alias = "gst_element_set_context")]
430 fn set_context(&self, context: &Context) {
431 unsafe {
432 ffi::gst_element_set_context(self.as_ref().to_glib_none().0, context.to_glib_none().0);
433 }
434 }
435
436 #[doc(alias = "gst_element_set_locked_state")]
437 fn set_locked_state(&self, locked_state: bool) -> bool {
438 unsafe {
439 from_glib(ffi::gst_element_set_locked_state(
440 self.as_ref().to_glib_none().0,
441 locked_state.into_glib(),
442 ))
443 }
444 }
445
446 #[doc(alias = "gst_element_set_start_time")]
447 fn set_start_time(&self, time: impl Into<Option<ClockTime>>) {
448 unsafe {
449 ffi::gst_element_set_start_time(
450 self.as_ref().to_glib_none().0,
451 time.into().into_glib(),
452 );
453 }
454 }
455
456 #[doc(alias = "gst_element_set_state")]
457 fn set_state(&self, state: State) -> Result<StateChangeSuccess, StateChangeError> {
458 unsafe {
459 try_from_glib(ffi::gst_element_set_state(
460 self.as_ref().to_glib_none().0,
461 state.into_glib(),
462 ))
463 }
464 }
465
466 #[doc(alias = "gst_element_sync_state_with_parent")]
467 fn sync_state_with_parent(&self) -> Result<(), glib::error::BoolError> {
468 unsafe {
469 glib::result_from_gboolean!(
470 ffi::gst_element_sync_state_with_parent(self.as_ref().to_glib_none().0),
471 "Failed to sync state with parent"
472 )
473 }
474 }
475
476 #[doc(alias = "gst_element_unlink")]
477 fn unlink(&self, dest: &impl IsA<Element>) {
478 unsafe {
479 ffi::gst_element_unlink(
480 self.as_ref().to_glib_none().0,
481 dest.as_ref().to_glib_none().0,
482 );
483 }
484 }
485
486 #[doc(alias = "gst_element_unlink_pads")]
487 fn unlink_pads(&self, srcpadname: &str, dest: &impl IsA<Element>, destpadname: &str) {
488 unsafe {
489 ffi::gst_element_unlink_pads(
490 self.as_ref().to_glib_none().0,
491 srcpadname.to_glib_none().0,
492 dest.as_ref().to_glib_none().0,
493 destpadname.to_glib_none().0,
494 );
495 }
496 }
497
498 #[doc(alias = "no-more-pads")]
499 fn connect_no_more_pads<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
500 unsafe extern "C" fn no_more_pads_trampoline<
501 P: IsA<Element>,
502 F: Fn(&P) + Send + Sync + 'static,
503 >(
504 this: *mut ffi::GstElement,
505 f: glib::ffi::gpointer,
506 ) {
507 let f: &F = &*(f as *const F);
508 f(Element::from_glib_borrow(this).unsafe_cast_ref())
509 }
510 unsafe {
511 let f: Box_<F> = Box_::new(f);
512 connect_raw(
513 self.as_ptr() as *mut _,
514 b"no-more-pads\0".as_ptr() as *const _,
515 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
516 no_more_pads_trampoline::<Self, F> as *const (),
517 )),
518 Box_::into_raw(f),
519 )
520 }
521 }
522
523 #[doc(alias = "pad-added")]
524 fn connect_pad_added<F: Fn(&Self, &Pad) + Send + Sync + 'static>(
525 &self,
526 f: F,
527 ) -> SignalHandlerId {
528 unsafe extern "C" fn pad_added_trampoline<
529 P: IsA<Element>,
530 F: Fn(&P, &Pad) + Send + Sync + 'static,
531 >(
532 this: *mut ffi::GstElement,
533 new_pad: *mut ffi::GstPad,
534 f: glib::ffi::gpointer,
535 ) {
536 let f: &F = &*(f as *const F);
537 f(
538 Element::from_glib_borrow(this).unsafe_cast_ref(),
539 &from_glib_borrow(new_pad),
540 )
541 }
542 unsafe {
543 let f: Box_<F> = Box_::new(f);
544 connect_raw(
545 self.as_ptr() as *mut _,
546 b"pad-added\0".as_ptr() as *const _,
547 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
548 pad_added_trampoline::<Self, F> as *const (),
549 )),
550 Box_::into_raw(f),
551 )
552 }
553 }
554
555 #[doc(alias = "pad-removed")]
556 fn connect_pad_removed<F: Fn(&Self, &Pad) + Send + Sync + 'static>(
557 &self,
558 f: F,
559 ) -> SignalHandlerId {
560 unsafe extern "C" fn pad_removed_trampoline<
561 P: IsA<Element>,
562 F: Fn(&P, &Pad) + Send + Sync + 'static,
563 >(
564 this: *mut ffi::GstElement,
565 old_pad: *mut ffi::GstPad,
566 f: glib::ffi::gpointer,
567 ) {
568 let f: &F = &*(f as *const F);
569 f(
570 Element::from_glib_borrow(this).unsafe_cast_ref(),
571 &from_glib_borrow(old_pad),
572 )
573 }
574 unsafe {
575 let f: Box_<F> = Box_::new(f);
576 connect_raw(
577 self.as_ptr() as *mut _,
578 b"pad-removed\0".as_ptr() as *const _,
579 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
580 pad_removed_trampoline::<Self, F> as *const (),
581 )),
582 Box_::into_raw(f),
583 )
584 }
585 }
586}
587
588impl<O: IsA<Element>> ElementExt for O {}