1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use std::{ffi::CStr, future::Future, mem, num::NonZeroU64, pin::Pin}; |
4 | |
5 | use glib::translate::*; |
6 | use itertools::Itertools; |
7 | |
8 | use crate::{ |
9 | format::{ |
10 | CompatibleFormattedValue, FormattedValue, SpecificFormattedValueFullRange, |
11 | SpecificFormattedValueIntrinsic, |
12 | }, |
13 | prelude::*, |
14 | ClockTime, Element, ElementFlags, Event, Format, GenericFormattedValue, Pad, PadTemplate, |
15 | Plugin, QueryRef, Rank, State, |
16 | }; |
17 | |
18 | impl Element { |
19 | #[doc (alias = "gst_element_link_many" )] |
20 | pub fn link_many( |
21 | elements: impl IntoIterator<Item = impl AsRef<Element> + Clone>, |
22 | ) -> Result<(), glib::BoolError> { |
23 | skip_assert_initialized!(); |
24 | for (src, dest) in elements.into_iter().tuple_windows() { |
25 | unsafe { |
26 | glib::result_from_gboolean!( |
27 | ffi::gst_element_link( |
28 | src.as_ref().to_glib_none().0, |
29 | dest.as_ref().to_glib_none().0, |
30 | ), |
31 | "Failed to link elements ' {}' and ' {}'" , |
32 | src.as_ref().name(), |
33 | dest.as_ref().name(), |
34 | )?; |
35 | } |
36 | } |
37 | |
38 | Ok(()) |
39 | } |
40 | |
41 | #[doc (alias = "gst_element_unlink_many" )] |
42 | pub fn unlink_many(elements: impl IntoIterator<Item = impl AsRef<Element> + Clone>) { |
43 | skip_assert_initialized!(); |
44 | for (src, dest) in elements.into_iter().tuple_windows() { |
45 | unsafe { |
46 | ffi::gst_element_unlink( |
47 | src.as_ref().to_glib_none().0, |
48 | dest.as_ref().to_glib_none().0, |
49 | ); |
50 | } |
51 | } |
52 | } |
53 | |
54 | #[doc (alias = "gst_element_register" )] |
55 | pub fn register( |
56 | plugin: Option<&Plugin>, |
57 | name: &str, |
58 | rank: Rank, |
59 | type_: glib::types::Type, |
60 | ) -> Result<(), glib::error::BoolError> { |
61 | skip_assert_initialized!(); |
62 | unsafe { |
63 | glib::result_from_gboolean!( |
64 | ffi::gst_element_register( |
65 | plugin.to_glib_none().0, |
66 | name.to_glib_none().0, |
67 | rank.into_glib() as u32, |
68 | type_.into_glib() |
69 | ), |
70 | "Failed to register element factory" |
71 | ) |
72 | } |
73 | } |
74 | } |
75 | |
76 | #[derive (PartialEq, Eq, Copy, Clone, Debug, Hash)] |
77 | pub enum ElementMessageType { |
78 | Error, |
79 | Warning, |
80 | Info, |
81 | } |
82 | |
83 | #[derive (Debug, PartialEq, Eq)] |
84 | pub struct NotifyWatchId(NonZeroU64); |
85 | |
86 | impl IntoGlib for NotifyWatchId { |
87 | type GlibType = libc::c_ulong; |
88 | |
89 | #[inline ] |
90 | fn into_glib(self) -> libc::c_ulong { |
91 | self.0.get() as libc::c_ulong |
92 | } |
93 | } |
94 | |
95 | impl FromGlib<libc::c_ulong> for NotifyWatchId { |
96 | #[inline ] |
97 | unsafe fn from_glib(val: libc::c_ulong) -> NotifyWatchId { |
98 | skip_assert_initialized!(); |
99 | debug_assert_ne!(val, 0); |
100 | NotifyWatchId(NonZeroU64::new_unchecked(val as _)) |
101 | } |
102 | } |
103 | |
104 | mod sealed { |
105 | pub trait Sealed {} |
106 | impl<T: super::IsA<super::Element>> Sealed for T {} |
107 | } |
108 | |
109 | pub trait ElementExtManual: sealed::Sealed + IsA<Element> + 'static { |
110 | #[doc (alias = "get_element_class" )] |
111 | #[inline ] |
112 | fn element_class(&self) -> &glib::Class<Element> { |
113 | unsafe { self.unsafe_cast_ref::<Element>().class() } |
114 | } |
115 | |
116 | #[doc (alias = "get_current_state" )] |
117 | fn current_state(&self) -> State { |
118 | self.state(Some(ClockTime::ZERO)).1 |
119 | } |
120 | |
121 | #[doc (alias = "get_pending_state" )] |
122 | fn pending_state(&self) -> State { |
123 | self.state(Some(ClockTime::ZERO)).2 |
124 | } |
125 | |
126 | #[doc (alias = "gst_element_query" )] |
127 | fn query(&self, query: &mut QueryRef) -> bool { |
128 | unsafe { |
129 | from_glib(ffi::gst_element_query( |
130 | self.as_ref().to_glib_none().0, |
131 | query.as_mut_ptr(), |
132 | )) |
133 | } |
134 | } |
135 | |
136 | #[doc (alias = "gst_element_send_event" )] |
137 | fn send_event(&self, event: impl Into<Event>) -> bool { |
138 | unsafe { |
139 | from_glib(ffi::gst_element_send_event( |
140 | self.as_ref().to_glib_none().0, |
141 | event.into().into_glib_ptr(), |
142 | )) |
143 | } |
144 | } |
145 | |
146 | #[doc (alias = "get_metadata" )] |
147 | #[doc (alias = "gst_element_class_get_metadata" )] |
148 | fn metadata<'a>(&self, key: &str) -> Option<&'a str> { |
149 | self.element_class().metadata(key) |
150 | } |
151 | |
152 | #[doc (alias = "get_pad_template" )] |
153 | #[doc (alias = "gst_element_class_get_pad_template" )] |
154 | fn pad_template(&self, name: &str) -> Option<PadTemplate> { |
155 | self.element_class().pad_template(name) |
156 | } |
157 | |
158 | #[doc (alias = "get_pad_template_list" )] |
159 | #[doc (alias = "gst_element_class_get_pad_template_list" )] |
160 | fn pad_template_list(&self) -> glib::List<PadTemplate> { |
161 | self.element_class().pad_template_list() |
162 | } |
163 | |
164 | #[allow (clippy::too_many_arguments)] |
165 | #[doc (alias = "gst_element_message_full" )] |
166 | fn message_full<T: crate::MessageErrorDomain>( |
167 | &self, |
168 | type_: ElementMessageType, |
169 | code: T, |
170 | message: Option<&str>, |
171 | debug: Option<&str>, |
172 | file: &str, |
173 | function: &str, |
174 | line: u32, |
175 | ) { |
176 | unsafe { |
177 | let type_ = match type_ { |
178 | ElementMessageType::Error => ffi::GST_MESSAGE_ERROR, |
179 | ElementMessageType::Warning => ffi::GST_MESSAGE_WARNING, |
180 | ElementMessageType::Info => ffi::GST_MESSAGE_INFO, |
181 | }; |
182 | |
183 | ffi::gst_element_message_full( |
184 | self.as_ref().to_glib_none().0, |
185 | type_, |
186 | T::domain().into_glib(), |
187 | code.code(), |
188 | message.to_glib_full(), |
189 | debug.to_glib_full(), |
190 | file.to_glib_none().0, |
191 | function.to_glib_none().0, |
192 | line as i32, |
193 | ); |
194 | } |
195 | } |
196 | |
197 | fn set_element_flags(&self, flags: ElementFlags) { |
198 | unsafe { |
199 | let ptr: *mut ffi::GstObject = self.as_ptr() as *mut _; |
200 | let _guard = self.as_ref().object_lock(); |
201 | (*ptr).flags |= flags.into_glib(); |
202 | } |
203 | } |
204 | |
205 | fn unset_element_flags(&self, flags: ElementFlags) { |
206 | unsafe { |
207 | let ptr: *mut ffi::GstObject = self.as_ptr() as *mut _; |
208 | let _guard = self.as_ref().object_lock(); |
209 | (*ptr).flags &= !flags.into_glib(); |
210 | } |
211 | } |
212 | |
213 | #[doc (alias = "get_element_flags" )] |
214 | fn element_flags(&self) -> ElementFlags { |
215 | unsafe { |
216 | let ptr: *mut ffi::GstObject = self.as_ptr() as *mut _; |
217 | let _guard = self.as_ref().object_lock(); |
218 | from_glib((*ptr).flags) |
219 | } |
220 | } |
221 | |
222 | #[allow (clippy::too_many_arguments)] |
223 | #[doc (alias = "gst_element_message_full_with_details" )] |
224 | fn message_full_with_details<T: crate::MessageErrorDomain>( |
225 | &self, |
226 | type_: ElementMessageType, |
227 | code: T, |
228 | message: Option<&str>, |
229 | debug: Option<&str>, |
230 | file: &str, |
231 | function: &str, |
232 | line: u32, |
233 | structure: crate::Structure, |
234 | ) { |
235 | unsafe { |
236 | let type_ = match type_ { |
237 | ElementMessageType::Error => ffi::GST_MESSAGE_ERROR, |
238 | ElementMessageType::Warning => ffi::GST_MESSAGE_WARNING, |
239 | ElementMessageType::Info => ffi::GST_MESSAGE_INFO, |
240 | }; |
241 | |
242 | ffi::gst_element_message_full_with_details( |
243 | self.as_ref().to_glib_none().0, |
244 | type_, |
245 | T::domain().into_glib(), |
246 | code.code(), |
247 | message.to_glib_full(), |
248 | debug.to_glib_full(), |
249 | file.to_glib_none().0, |
250 | function.to_glib_none().0, |
251 | line as i32, |
252 | structure.into_glib_ptr(), |
253 | ); |
254 | } |
255 | } |
256 | |
257 | fn post_error_message(&self, msg: crate::ErrorMessage) { |
258 | let crate::ErrorMessage { |
259 | error_domain, |
260 | error_code, |
261 | ref message, |
262 | ref debug, |
263 | filename, |
264 | function, |
265 | line, |
266 | } = msg; |
267 | |
268 | unsafe { |
269 | ffi::gst_element_message_full( |
270 | self.as_ref().to_glib_none().0, |
271 | ffi::GST_MESSAGE_ERROR, |
272 | error_domain.into_glib(), |
273 | error_code, |
274 | message.to_glib_full(), |
275 | debug.to_glib_full(), |
276 | filename.to_glib_none().0, |
277 | function.to_glib_none().0, |
278 | line as i32, |
279 | ); |
280 | } |
281 | } |
282 | |
283 | #[doc (alias = "gst_element_iterate_pads" )] |
284 | fn iterate_pads(&self) -> crate::Iterator<Pad> { |
285 | unsafe { |
286 | from_glib_full(ffi::gst_element_iterate_pads( |
287 | self.as_ref().to_glib_none().0, |
288 | )) |
289 | } |
290 | } |
291 | |
292 | #[doc (alias = "gst_element_iterate_sink_pads" )] |
293 | fn iterate_sink_pads(&self) -> crate::Iterator<Pad> { |
294 | unsafe { |
295 | from_glib_full(ffi::gst_element_iterate_sink_pads( |
296 | self.as_ref().to_glib_none().0, |
297 | )) |
298 | } |
299 | } |
300 | |
301 | #[doc (alias = "gst_element_iterate_src_pads" )] |
302 | fn iterate_src_pads(&self) -> crate::Iterator<Pad> { |
303 | unsafe { |
304 | from_glib_full(ffi::gst_element_iterate_src_pads( |
305 | self.as_ref().to_glib_none().0, |
306 | )) |
307 | } |
308 | } |
309 | |
310 | #[doc (alias = "get_pads" )] |
311 | #[doc (alias = "gst_element_foreach_pad" )] |
312 | fn pads(&self) -> Vec<Pad> { |
313 | unsafe { |
314 | let elt: &ffi::GstElement = &*(self.as_ptr() as *const _); |
315 | let _guard = self.as_ref().object_lock(); |
316 | FromGlibPtrContainer::from_glib_none(elt.pads) |
317 | } |
318 | } |
319 | |
320 | #[doc (alias = "get_sink_pads" )] |
321 | #[doc (alias = "gst_element_foreach_sink_pad" )] |
322 | fn sink_pads(&self) -> Vec<Pad> { |
323 | unsafe { |
324 | let elt: &ffi::GstElement = &*(self.as_ptr() as *const _); |
325 | let _guard = self.as_ref().object_lock(); |
326 | FromGlibPtrContainer::from_glib_none(elt.sinkpads) |
327 | } |
328 | } |
329 | |
330 | #[doc (alias = "get_src_pads" )] |
331 | #[doc (alias = "gst_element_foreach_src_pad" )] |
332 | fn src_pads(&self) -> Vec<Pad> { |
333 | unsafe { |
334 | let elt: &ffi::GstElement = &*(self.as_ptr() as *const _); |
335 | let _guard = self.as_ref().object_lock(); |
336 | FromGlibPtrContainer::from_glib_none(elt.srcpads) |
337 | } |
338 | } |
339 | |
340 | fn num_pads(&self) -> u16 { |
341 | unsafe { |
342 | let elt: &ffi::GstElement = &*(self.as_ptr() as *const _); |
343 | let _guard = self.as_ref().object_lock(); |
344 | elt.numpads |
345 | } |
346 | } |
347 | |
348 | fn num_sink_pads(&self) -> u16 { |
349 | unsafe { |
350 | let elt: &ffi::GstElement = &*(self.as_ptr() as *const _); |
351 | let _guard = self.as_ref().object_lock(); |
352 | elt.numsinkpads |
353 | } |
354 | } |
355 | |
356 | fn num_src_pads(&self) -> u16 { |
357 | unsafe { |
358 | let elt: &ffi::GstElement = &*(self.as_ptr() as *const _); |
359 | let _guard = self.as_ref().object_lock(); |
360 | elt.numsrcpads |
361 | } |
362 | } |
363 | |
364 | #[doc (alias = "gst_element_add_property_deep_notify_watch" )] |
365 | fn add_property_deep_notify_watch( |
366 | &self, |
367 | property_name: Option<&str>, |
368 | include_value: bool, |
369 | ) -> NotifyWatchId { |
370 | let property_name = property_name.to_glib_none(); |
371 | unsafe { |
372 | from_glib(ffi::gst_element_add_property_deep_notify_watch( |
373 | self.as_ref().to_glib_none().0, |
374 | property_name.0, |
375 | include_value.into_glib(), |
376 | )) |
377 | } |
378 | } |
379 | |
380 | #[doc (alias = "gst_element_add_property_notify_watch" )] |
381 | fn add_property_notify_watch( |
382 | &self, |
383 | property_name: Option<&str>, |
384 | include_value: bool, |
385 | ) -> NotifyWatchId { |
386 | let property_name = property_name.to_glib_none(); |
387 | unsafe { |
388 | from_glib(ffi::gst_element_add_property_notify_watch( |
389 | self.as_ref().to_glib_none().0, |
390 | property_name.0, |
391 | include_value.into_glib(), |
392 | )) |
393 | } |
394 | } |
395 | |
396 | #[doc (alias = "gst_element_remove_property_notify_watch" )] |
397 | fn remove_property_notify_watch(&self, watch_id: NotifyWatchId) { |
398 | unsafe { |
399 | ffi::gst_element_remove_property_notify_watch( |
400 | self.as_ref().to_glib_none().0, |
401 | watch_id.into_glib(), |
402 | ); |
403 | } |
404 | } |
405 | |
406 | #[doc (alias = "gst_element_query_convert" )] |
407 | fn query_convert<U: SpecificFormattedValueFullRange>( |
408 | &self, |
409 | src_val: impl FormattedValue, |
410 | ) -> Option<U> { |
411 | unsafe { |
412 | let mut dest_val = mem::MaybeUninit::uninit(); |
413 | let ret = from_glib(ffi::gst_element_query_convert( |
414 | self.as_ref().to_glib_none().0, |
415 | src_val.format().into_glib(), |
416 | src_val.into_raw_value(), |
417 | U::default_format().into_glib(), |
418 | dest_val.as_mut_ptr(), |
419 | )); |
420 | if ret { |
421 | Some(U::from_raw(U::default_format(), dest_val.assume_init())) |
422 | } else { |
423 | None |
424 | } |
425 | } |
426 | } |
427 | |
428 | #[doc (alias = "gst_element_query_convert" )] |
429 | fn query_convert_generic( |
430 | &self, |
431 | src_val: impl FormattedValue, |
432 | dest_format: Format, |
433 | ) -> Option<GenericFormattedValue> { |
434 | unsafe { |
435 | let mut dest_val = mem::MaybeUninit::uninit(); |
436 | let ret = from_glib(ffi::gst_element_query_convert( |
437 | self.as_ref().to_glib_none().0, |
438 | src_val.format().into_glib(), |
439 | src_val.into_raw_value(), |
440 | dest_format.into_glib(), |
441 | dest_val.as_mut_ptr(), |
442 | )); |
443 | if ret { |
444 | Some(GenericFormattedValue::new( |
445 | dest_format, |
446 | dest_val.assume_init(), |
447 | )) |
448 | } else { |
449 | None |
450 | } |
451 | } |
452 | } |
453 | |
454 | #[doc (alias = "gst_element_query_duration" )] |
455 | fn query_duration<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> { |
456 | unsafe { |
457 | let mut duration = mem::MaybeUninit::uninit(); |
458 | let ret = from_glib(ffi::gst_element_query_duration( |
459 | self.as_ref().to_glib_none().0, |
460 | T::default_format().into_glib(), |
461 | duration.as_mut_ptr(), |
462 | )); |
463 | if ret { |
464 | try_from_glib(duration.assume_init()).ok() |
465 | } else { |
466 | None |
467 | } |
468 | } |
469 | } |
470 | |
471 | #[doc (alias = "gst_element_query_duration" )] |
472 | fn query_duration_generic(&self, format: Format) -> Option<GenericFormattedValue> { |
473 | unsafe { |
474 | let mut duration = mem::MaybeUninit::uninit(); |
475 | let ret = from_glib(ffi::gst_element_query_duration( |
476 | self.as_ref().to_glib_none().0, |
477 | format.into_glib(), |
478 | duration.as_mut_ptr(), |
479 | )); |
480 | if ret { |
481 | Some(GenericFormattedValue::new(format, duration.assume_init())) |
482 | } else { |
483 | None |
484 | } |
485 | } |
486 | } |
487 | |
488 | #[doc (alias = "gst_element_query_position" )] |
489 | fn query_position<T: SpecificFormattedValueIntrinsic>(&self) -> Option<T> { |
490 | unsafe { |
491 | let mut cur = mem::MaybeUninit::uninit(); |
492 | let ret = from_glib(ffi::gst_element_query_position( |
493 | self.as_ref().to_glib_none().0, |
494 | T::default_format().into_glib(), |
495 | cur.as_mut_ptr(), |
496 | )); |
497 | if ret { |
498 | try_from_glib(cur.assume_init()).ok() |
499 | } else { |
500 | None |
501 | } |
502 | } |
503 | } |
504 | |
505 | #[doc (alias = "gst_element_query_position" )] |
506 | fn query_position_generic(&self, format: Format) -> Option<GenericFormattedValue> { |
507 | unsafe { |
508 | let mut cur = mem::MaybeUninit::uninit(); |
509 | let ret = from_glib(ffi::gst_element_query_position( |
510 | self.as_ref().to_glib_none().0, |
511 | format.into_glib(), |
512 | cur.as_mut_ptr(), |
513 | )); |
514 | if ret { |
515 | Some(GenericFormattedValue::new(format, cur.assume_init())) |
516 | } else { |
517 | None |
518 | } |
519 | } |
520 | } |
521 | |
522 | #[doc (alias = "gst_element_seek" )] |
523 | fn seek<V: FormattedValue>( |
524 | &self, |
525 | rate: f64, |
526 | flags: crate::SeekFlags, |
527 | start_type: crate::SeekType, |
528 | start: V, |
529 | stop_type: crate::SeekType, |
530 | stop: impl CompatibleFormattedValue<V>, |
531 | ) -> Result<(), glib::error::BoolError> { |
532 | let stop = stop.try_into_checked(start).unwrap(); |
533 | |
534 | unsafe { |
535 | glib::result_from_gboolean!( |
536 | ffi::gst_element_seek( |
537 | self.as_ref().to_glib_none().0, |
538 | rate, |
539 | start.format().into_glib(), |
540 | flags.into_glib(), |
541 | start_type.into_glib(), |
542 | start.into_raw_value(), |
543 | stop_type.into_glib(), |
544 | stop.into_raw_value(), |
545 | ), |
546 | "Failed to seek" , |
547 | ) |
548 | } |
549 | } |
550 | |
551 | #[doc (alias = "gst_element_seek_simple" )] |
552 | fn seek_simple( |
553 | &self, |
554 | seek_flags: crate::SeekFlags, |
555 | seek_pos: impl FormattedValue, |
556 | ) -> Result<(), glib::error::BoolError> { |
557 | unsafe { |
558 | glib::result_from_gboolean!( |
559 | ffi::gst_element_seek_simple( |
560 | self.as_ref().to_glib_none().0, |
561 | seek_pos.format().into_glib(), |
562 | seek_flags.into_glib(), |
563 | seek_pos.into_raw_value(), |
564 | ), |
565 | "Failed to seek" , |
566 | ) |
567 | } |
568 | } |
569 | |
570 | #[doc (alias = "gst_element_call_async" )] |
571 | fn call_async<F>(&self, func: F) |
572 | where |
573 | F: FnOnce(&Self) + Send + 'static, |
574 | { |
575 | let user_data: Box<Option<F>> = Box::new(Some(func)); |
576 | |
577 | unsafe extern "C" fn trampoline<O: IsA<Element>, F: FnOnce(&O) + Send + 'static>( |
578 | element: *mut ffi::GstElement, |
579 | user_data: glib::ffi::gpointer, |
580 | ) { |
581 | let user_data: &mut Option<F> = &mut *(user_data as *mut _); |
582 | let callback = user_data.take().unwrap(); |
583 | |
584 | callback(Element::from_glib_borrow(element).unsafe_cast_ref()); |
585 | } |
586 | |
587 | unsafe extern "C" fn free_user_data<O: IsA<Element>, F: FnOnce(&O) + Send + 'static>( |
588 | user_data: glib::ffi::gpointer, |
589 | ) { |
590 | let _: Box<Option<F>> = Box::from_raw(user_data as *mut _); |
591 | } |
592 | |
593 | unsafe { |
594 | ffi::gst_element_call_async( |
595 | self.as_ref().to_glib_none().0, |
596 | Some(trampoline::<Self, F>), |
597 | Box::into_raw(user_data) as *mut _, |
598 | Some(free_user_data::<Self, F>), |
599 | ); |
600 | } |
601 | } |
602 | |
603 | fn call_async_future<F, T>(&self, func: F) -> Pin<Box<dyn Future<Output = T> + Send + 'static>> |
604 | where |
605 | F: FnOnce(&Self) -> T + Send + 'static, |
606 | T: Send + 'static, |
607 | { |
608 | use futures_channel::oneshot; |
609 | |
610 | let (sender, receiver) = oneshot::channel(); |
611 | |
612 | self.call_async(move |element| { |
613 | let _ = sender.send(func(element)); |
614 | }); |
615 | |
616 | Box::pin(async move { receiver.await.expect("sender dropped" ) }) |
617 | } |
618 | |
619 | #[doc (alias = "get_current_running_time" )] |
620 | #[doc (alias = "gst_element_get_current_running_time" )] |
621 | fn current_running_time(&self) -> Option<crate::ClockTime> { |
622 | let base_time = self.base_time(); |
623 | let clock_time = self.current_clock_time(); |
624 | |
625 | clock_time |
626 | .zip(base_time) |
627 | .and_then(|(ct, bt)| ct.checked_sub(bt)) |
628 | } |
629 | |
630 | #[doc (alias = "get_current_clock_time" )] |
631 | #[doc (alias = "gst_element_get_current_clock_time" )] |
632 | fn current_clock_time(&self) -> Option<crate::ClockTime> { |
633 | if let Some(clock) = self.clock() { |
634 | clock.time() |
635 | } else { |
636 | crate::ClockTime::NONE |
637 | } |
638 | } |
639 | |
640 | #[doc (alias = "gst_element_get_request_pad" )] |
641 | #[doc (alias = "get_request_pad" )] |
642 | #[doc (alias = "gst_element_request_pad_simple" )] |
643 | fn request_pad_simple(&self, name: &str) -> Option<Pad> { |
644 | unsafe { |
645 | #[cfg (feature = "v1_20" )] |
646 | { |
647 | from_glib_full(ffi::gst_element_request_pad_simple( |
648 | self.as_ref().to_glib_none().0, |
649 | name.to_glib_none().0, |
650 | )) |
651 | } |
652 | #[cfg (not(feature = "v1_20" ))] |
653 | { |
654 | from_glib_full(ffi::gst_element_get_request_pad( |
655 | self.as_ref().to_glib_none().0, |
656 | name.to_glib_none().0, |
657 | )) |
658 | } |
659 | } |
660 | } |
661 | |
662 | #[doc (alias = "gst_element_link" )] |
663 | fn link(&self, dest: &impl IsA<Element>) -> Result<(), glib::error::BoolError> { |
664 | unsafe { |
665 | glib::result_from_gboolean!( |
666 | ffi::gst_element_link( |
667 | self.as_ref().to_glib_none().0, |
668 | dest.as_ref().to_glib_none().0 |
669 | ), |
670 | "Failed to link elements ' {}' and ' {}'" , |
671 | self.as_ref().name(), |
672 | dest.as_ref().name(), |
673 | ) |
674 | } |
675 | } |
676 | |
677 | #[doc (alias = "gst_element_link_filtered" )] |
678 | fn link_filtered( |
679 | &self, |
680 | dest: &impl IsA<Element>, |
681 | filter: &crate::Caps, |
682 | ) -> Result<(), glib::error::BoolError> { |
683 | unsafe { |
684 | glib::result_from_gboolean!( |
685 | ffi::gst_element_link_filtered( |
686 | self.as_ref().to_glib_none().0, |
687 | dest.as_ref().to_glib_none().0, |
688 | filter.to_glib_none().0 |
689 | ), |
690 | "Failed to link elements ' {}' and ' {}' with filter ' {:?}'" , |
691 | self.as_ref().name(), |
692 | dest.as_ref().name(), |
693 | filter, |
694 | ) |
695 | } |
696 | } |
697 | |
698 | #[doc (alias = "gst_element_link_pads" )] |
699 | fn link_pads( |
700 | &self, |
701 | srcpadname: Option<&str>, |
702 | dest: &impl IsA<Element>, |
703 | destpadname: Option<&str>, |
704 | ) -> Result<(), glib::error::BoolError> { |
705 | unsafe { |
706 | glib::result_from_gboolean!( |
707 | ffi::gst_element_link_pads( |
708 | self.as_ref().to_glib_none().0, |
709 | srcpadname.to_glib_none().0, |
710 | dest.as_ref().to_glib_none().0, |
711 | destpadname.to_glib_none().0 |
712 | ), |
713 | "Failed to link pads ' {}' and ' {}'" , |
714 | if let Some(srcpadname) = srcpadname { |
715 | format!(" {}: {}" , self.as_ref().name(), srcpadname) |
716 | } else { |
717 | format!(" {}:*" , self.as_ref().name()) |
718 | }, |
719 | if let Some(destpadname) = destpadname { |
720 | format!(" {}: {}" , dest.as_ref().name(), destpadname) |
721 | } else { |
722 | format!(" {}:*" , dest.as_ref().name()) |
723 | }, |
724 | ) |
725 | } |
726 | } |
727 | |
728 | #[doc (alias = "gst_element_link_pads_filtered" )] |
729 | fn link_pads_filtered( |
730 | &self, |
731 | srcpadname: Option<&str>, |
732 | dest: &impl IsA<Element>, |
733 | destpadname: Option<&str>, |
734 | filter: &crate::Caps, |
735 | ) -> Result<(), glib::error::BoolError> { |
736 | unsafe { |
737 | glib::result_from_gboolean!( |
738 | ffi::gst_element_link_pads_filtered( |
739 | self.as_ref().to_glib_none().0, |
740 | srcpadname.to_glib_none().0, |
741 | dest.as_ref().to_glib_none().0, |
742 | destpadname.to_glib_none().0, |
743 | filter.to_glib_none().0 |
744 | ), |
745 | "Failed to link pads ' {}' and ' {}' with filter ' {:?}'" , |
746 | if let Some(srcpadname) = srcpadname { |
747 | format!(" {}: {}" , self.as_ref().name(), srcpadname) |
748 | } else { |
749 | format!(" {}:*" , self.as_ref().name()) |
750 | }, |
751 | if let Some(destpadname) = destpadname { |
752 | format!(" {}: {}" , dest.as_ref().name(), destpadname) |
753 | } else { |
754 | format!(" {}:*" , dest.as_ref().name()) |
755 | }, |
756 | filter, |
757 | ) |
758 | } |
759 | } |
760 | |
761 | #[doc (alias = "gst_element_link_pads_full" )] |
762 | fn link_pads_full( |
763 | &self, |
764 | srcpadname: Option<&str>, |
765 | dest: &impl IsA<Element>, |
766 | destpadname: Option<&str>, |
767 | flags: crate::PadLinkCheck, |
768 | ) -> Result<(), glib::error::BoolError> { |
769 | unsafe { |
770 | glib::result_from_gboolean!( |
771 | ffi::gst_element_link_pads_full( |
772 | self.as_ref().to_glib_none().0, |
773 | srcpadname.to_glib_none().0, |
774 | dest.as_ref().to_glib_none().0, |
775 | destpadname.to_glib_none().0, |
776 | flags.into_glib() |
777 | ), |
778 | "Failed to link pads ' {}' and ' {}' with flags ' {:?}'" , |
779 | if let Some(srcpadname) = srcpadname { |
780 | format!(" {}: {}" , self.as_ref().name(), srcpadname) |
781 | } else { |
782 | format!(" {}:*" , self.as_ref().name()) |
783 | }, |
784 | if let Some(destpadname) = destpadname { |
785 | format!(" {}: {}" , dest.as_ref().name(), destpadname) |
786 | } else { |
787 | format!(" {}:*" , dest.as_ref().name()) |
788 | }, |
789 | flags, |
790 | ) |
791 | } |
792 | } |
793 | } |
794 | |
795 | impl<O: IsA<Element>> ElementExtManual for O {} |
796 | |
797 | pub unsafe trait ElementClassExt { |
798 | #[doc (alias = "get_metadata" )] |
799 | #[doc (alias = "gst_element_class_get_metadata" )] |
800 | fn metadata<'a>(&self, key: &str) -> Option<&'a str> { |
801 | unsafe { |
802 | let klass = self as *const _ as *const ffi::GstElementClass; |
803 | |
804 | let ptr = ffi::gst_element_class_get_metadata(klass as *mut _, key.to_glib_none().0); |
805 | |
806 | if ptr.is_null() { |
807 | None |
808 | } else { |
809 | Some(CStr::from_ptr(ptr).to_str().unwrap()) |
810 | } |
811 | } |
812 | } |
813 | |
814 | #[doc (alias = "get_pad_template" )] |
815 | #[doc (alias = "gst_element_class_get_pad_template" )] |
816 | fn pad_template(&self, name: &str) -> Option<PadTemplate> { |
817 | unsafe { |
818 | let klass = self as *const _ as *const ffi::GstElementClass; |
819 | |
820 | from_glib_none(ffi::gst_element_class_get_pad_template( |
821 | klass as *mut _, |
822 | name.to_glib_none().0, |
823 | )) |
824 | } |
825 | } |
826 | |
827 | #[doc (alias = "get_pad_template_list" )] |
828 | #[doc (alias = "gst_element_class_get_pad_template_list" )] |
829 | fn pad_template_list(&self) -> glib::List<PadTemplate> { |
830 | unsafe { |
831 | let klass = self as *const _ as *const ffi::GstElementClass; |
832 | |
833 | glib::List::from_glib_none(ffi::gst_element_class_get_pad_template_list( |
834 | klass as *mut _, |
835 | )) |
836 | } |
837 | } |
838 | } |
839 | |
840 | unsafe impl<T: IsA<Element> + glib::object::IsClass> ElementClassExt for glib::object::Class<T> {} |
841 | |
842 | #[doc (alias = "GST_ELEMENT_METADATA_AUTHOR" )] |
843 | pub static ELEMENT_METADATA_AUTHOR: &glib::GStr = |
844 | unsafe { glib::GStr::from_utf8_with_nul_unchecked(bytes:ffi::GST_ELEMENT_METADATA_AUTHOR) }; |
845 | #[doc (alias = "GST_ELEMENT_METADATA_DESCRIPTION" )] |
846 | pub static ELEMENT_METADATA_DESCRIPTION: &glib::GStr = |
847 | unsafe { glib::GStr::from_utf8_with_nul_unchecked(bytes:ffi::GST_ELEMENT_METADATA_DESCRIPTION) }; |
848 | #[doc (alias = "GST_ELEMENT_METADATA_DOC_URI" )] |
849 | pub static ELEMENT_METADATA_DOC_URI: &glib::GStr = |
850 | unsafe { glib::GStr::from_utf8_with_nul_unchecked(bytes:ffi::GST_ELEMENT_METADATA_DOC_URI) }; |
851 | #[doc (alias = "GST_ELEMENT_METADATA_ICON_NAME" )] |
852 | pub static ELEMENT_METADATA_ICON_NAME: &glib::GStr = |
853 | unsafe { glib::GStr::from_utf8_with_nul_unchecked(bytes:ffi::GST_ELEMENT_METADATA_ICON_NAME) }; |
854 | #[doc (alias = "GST_ELEMENT_METADATA_KLASS" )] |
855 | pub static ELEMENT_METADATA_KLASS: &glib::GStr = |
856 | unsafe { glib::GStr::from_utf8_with_nul_unchecked(bytes:ffi::GST_ELEMENT_METADATA_KLASS) }; |
857 | #[doc (alias = "GST_ELEMENT_METADATA_LONGNAME" )] |
858 | pub static ELEMENT_METADATA_LONGNAME: &glib::GStr = |
859 | unsafe { glib::GStr::from_utf8_with_nul_unchecked(bytes:ffi::GST_ELEMENT_METADATA_LONGNAME) }; |
860 | |
861 | #[doc (alias = "GST_ELEMENT_ERROR" )] |
862 | #[doc (alias = "GST_ELEMENT_ERROR_WITH_DETAILS" )] |
863 | #[macro_export ] |
864 | macro_rules! element_error( |
865 | ($obj:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*]) => { { |
866 | use $crate::prelude::ElementExtManual; |
867 | $obj.message_full( |
868 | $crate::ElementMessageType::Error, |
869 | $err, |
870 | Some(&format!($($msg)*)), |
871 | Some(&format!($($debug)*)), |
872 | file!(), |
873 | $crate::glib::function_name!(), |
874 | line!(), |
875 | ); |
876 | }}; |
877 | ($obj:expr, $err:expr, ($($msg:tt)*)) => { { |
878 | use $crate::prelude::ElementExtManual; |
879 | $obj.message_full( |
880 | $crate::ElementMessageType::Error, |
881 | $err, |
882 | Some(&format!($($msg)*)), |
883 | None, |
884 | file!(), |
885 | $crate::glib::function_name!(), |
886 | line!(), |
887 | ); |
888 | }}; |
889 | ($obj:expr, $err:expr, [$($debug:tt)*]) => { { |
890 | use $crate::prelude::ElementExtManual; |
891 | $obj.message_full( |
892 | $crate::ElementMessageType::Error, |
893 | $err, |
894 | None, |
895 | Some(&format!($($debug)*)), |
896 | file!(), |
897 | $crate::glib::function_name!(), |
898 | line!(), |
899 | ); |
900 | }}; |
901 | |
902 | ($obj:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*], details: $details:expr) => { { |
903 | use $crate::prelude::ElementExtManual; |
904 | $obj.message_full_with_details( |
905 | $crate::ElementMessageType::Error, |
906 | $err, |
907 | Some(&format!($($msg)*)), |
908 | Some(&format!($($debug)*)), |
909 | file!(), |
910 | $crate::glib::function_name!(), |
911 | line!(), |
912 | $details, |
913 | ); |
914 | }}; |
915 | ($obj:expr, $err:expr, ($($msg:tt)*), details: $details:expr) => { { |
916 | use $crate::prelude::ElementExtManual; |
917 | $obj.message_full_with_details( |
918 | $crate::ElementMessageType::Error, |
919 | $err, |
920 | Some(&format!($($msg)*)), |
921 | None, |
922 | file!(), |
923 | $crate::glib::function_name!(), |
924 | line!(), |
925 | $details, |
926 | ); |
927 | }}; |
928 | ($obj:expr, $err:expr, [$($debug:tt)*], details: $details:expr) => { { |
929 | use $crate::prelude::ElementExtManual; |
930 | $obj.message_full_with_details( |
931 | $crate::ElementMessageType::Error, |
932 | $err, |
933 | None, |
934 | Some(&format!($($debug)*)), |
935 | file!(), |
936 | $crate::glib::function_name!(), |
937 | line!(), |
938 | $details, |
939 | ); |
940 | }}; |
941 | ); |
942 | |
943 | #[doc (alias = "GST_ELEMENT_WARNING" )] |
944 | #[doc (alias = "GST_ELEMENT_WARNING_WITH_DETAILS" )] |
945 | #[macro_export ] |
946 | macro_rules! element_warning( |
947 | ($obj:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*]) => { { |
948 | use $crate::prelude::ElementExtManual; |
949 | $obj.message_full( |
950 | $crate::ElementMessageType::Warning, |
951 | $err, |
952 | Some(&format!($($msg)*)), |
953 | Some(&format!($($debug)*)), |
954 | file!(), |
955 | $crate::glib::function_name!(), |
956 | line!(), |
957 | ); |
958 | }}; |
959 | ($obj:expr, $err:expr, ($($msg:tt)*)) => { { |
960 | use $crate::prelude::ElementExtManual; |
961 | $obj.message_full( |
962 | $crate::ElementMessageType::Warning, |
963 | $err, |
964 | Some(&format!($($msg)*)), |
965 | None, |
966 | file!(), |
967 | $crate::glib::function_name!(), |
968 | line!(), |
969 | ); |
970 | }}; |
971 | ($obj:expr, $err:expr, [$($debug:tt)*]) => { { |
972 | use $crate::prelude::ElementExtManual; |
973 | $obj.message_full( |
974 | $crate::ElementMessageType::Warning, |
975 | $err, |
976 | None, |
977 | Some(&format!($($debug)*)), |
978 | file!(), |
979 | $crate::glib::function_name!(), |
980 | line!(), |
981 | ); |
982 | }}; |
983 | |
984 | ($obj:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*], details: $details:expr) => { { |
985 | use $crate::prelude::ElementExtManual; |
986 | $obj.message_full_with_details( |
987 | $crate::ElementMessageType::Warning, |
988 | $err, |
989 | Some(&format!($($msg)*)), |
990 | Some(&format!($($debug)*)), |
991 | file!(), |
992 | $crate::glib::function_name!(), |
993 | line!(), |
994 | $details, |
995 | ); |
996 | }}; |
997 | ($obj:expr, $err:expr, ($($msg:tt)*), details: $details:expr) => { { |
998 | use $crate::prelude::ElementExtManual; |
999 | $obj.message_full_with_details( |
1000 | $crate::ElementMessageType::Warning, |
1001 | $err, |
1002 | Some(&format!($($msg)*)), |
1003 | None, |
1004 | file!(), |
1005 | $crate::glib::function_name!(), |
1006 | line!(), |
1007 | $details, |
1008 | ); |
1009 | }}; |
1010 | ($obj:expr, $err:expr, [$($debug:tt)*], details: $details:expr) => { { |
1011 | use $crate::prelude::ElementExtManual; |
1012 | $obj.message_full_with_details( |
1013 | $crate::ElementMessageType::Warning, |
1014 | $err, |
1015 | None, |
1016 | Some(&format!($($debug)*)), |
1017 | file!(), |
1018 | $crate::glib::function_name!(), |
1019 | line!(), |
1020 | $details, |
1021 | ); |
1022 | }}; |
1023 | ); |
1024 | |
1025 | #[doc (alias = "GST_ELEMENT_INFO" )] |
1026 | #[doc (alias = "GST_ELEMENT_INFO_WITH_DETAILS" )] |
1027 | #[macro_export ] |
1028 | macro_rules! element_info( |
1029 | ($obj:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*]) => { { |
1030 | use $crate::prelude::ElementExtManual; |
1031 | $obj.message_full( |
1032 | $crate::ElementMessageType::Info, |
1033 | $err, |
1034 | Some(&format!($($msg)*)), |
1035 | Some(&format!($($debug)*)), |
1036 | file!(), |
1037 | $crate::glib::function_name!(), |
1038 | line!(), |
1039 | ); |
1040 | }}; |
1041 | ($obj:expr, $err:expr, ($($msg:tt)*)) => { { |
1042 | use $crate::prelude::ElementExtManual; |
1043 | $obj.message_full( |
1044 | $crate::ElementMessageType::Info, |
1045 | $err, |
1046 | Some(&format!($($msg)*)), |
1047 | None, |
1048 | file!(), |
1049 | $crate::glib::function_name!(), |
1050 | line!(), |
1051 | ); |
1052 | }}; |
1053 | ($obj:expr, $err:expr, [$($debug:tt)*]) => { { |
1054 | use $crate::prelude::ElementExtManual; |
1055 | $obj.message_full( |
1056 | $crate::ElementMessageType::Info, |
1057 | $err, |
1058 | None, |
1059 | Some(&format!($($debug)*)), |
1060 | file!(), |
1061 | $crate::glib::function_name!(), |
1062 | line!(), |
1063 | ); |
1064 | }}; |
1065 | |
1066 | ($obj:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*], details: $details:expr) => { { |
1067 | use $crate::prelude::ElementExtManual; |
1068 | $obj.message_full_with_details( |
1069 | $crate::ElementMessageType::Info, |
1070 | $err, |
1071 | Some(&format!($($msg)*)), |
1072 | Some(&format!($($debug)*)), |
1073 | file!(), |
1074 | $crate::glib::function_name!(), |
1075 | line!(), |
1076 | $details, |
1077 | ); |
1078 | }}; |
1079 | ($obj:expr, $err:expr, ($($msg:tt)*), details: $details:expr) => { { |
1080 | use $crate::prelude::ElementExtManual; |
1081 | $obj.message_full_with_details( |
1082 | $crate::ElementMessageType::Info, |
1083 | $err, |
1084 | Some(&format!($($msg)*)), |
1085 | None, |
1086 | file!(), |
1087 | $crate::glib::function_name!(), |
1088 | line!(), |
1089 | $details, |
1090 | ); |
1091 | }}; |
1092 | ($obj:expr, $err:expr, [$($debug:tt)*], details: $details:expr) => { { |
1093 | use $crate::prelude::ElementExtManual; |
1094 | $obj.message_full_with_details( |
1095 | $crate::ElementMessageType::Info, |
1096 | $err, |
1097 | None, |
1098 | Some(&format!($($debug)*)), |
1099 | file!(), |
1100 | $crate::glib::function_name!(), |
1101 | line!(), |
1102 | $details, |
1103 | ); |
1104 | }}; |
1105 | ); |
1106 | |
1107 | #[doc (alias = "GST_ELEMENT_ERROR" )] |
1108 | #[doc (alias = "GST_ELEMENT_ERROR_WITH_DETAILS" )] |
1109 | #[macro_export ] |
1110 | macro_rules! element_imp_error( |
1111 | ($imp:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*]) => { { |
1112 | let obj = $imp.obj(); |
1113 | $crate::element_error!(obj, $err, ($($msg)*), [$($debug)*]); |
1114 | }}; |
1115 | ($imp:expr, $err:expr, ($($msg:tt)*)) => { { |
1116 | let obj = $imp.obj(); |
1117 | $crate::element_error!(obj, $err, ($($msg)*)); |
1118 | }}; |
1119 | ($imp:expr, $err:expr, [$($debug:tt)*]) => { { |
1120 | let obj = $imp.obj(); |
1121 | $crate::element_error!(obj, $err, [$($debug)*]); |
1122 | }}; |
1123 | |
1124 | ($imp:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*], details: $details:expr) => { { |
1125 | let obj = $imp.obj(); |
1126 | $crate::element_error!(obj, $err, ($($msg)*), [$($debug)*], details: $details); |
1127 | }}; |
1128 | ($imp:expr, $err:expr, ($($msg:tt)*), details: $details:expr) => { { |
1129 | let obj = $imp.obj(); |
1130 | $crate::element_error!(obj, $err, ($($msg)*), details: $details); |
1131 | }}; |
1132 | ($imp:expr, $err:expr, [$($debug:tt)*], details: $details:expr) => { { |
1133 | let obj = $imp.obj(); |
1134 | $crate::element_error!(obj, $err, [$($debug)*], details: $details); |
1135 | }}; |
1136 | ); |
1137 | |
1138 | #[doc (alias = "GST_ELEMENT_WARNING" )] |
1139 | #[doc (alias = "GST_ELEMENT_WARNING_WITH_DETAILS" )] |
1140 | #[macro_export ] |
1141 | macro_rules! element_imp_warning( |
1142 | ($imp:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*]) => { { |
1143 | let obj = $imp.obj(); |
1144 | $crate::element_warning!(obj, $err, ($($msg)*), [$($debug)*]); |
1145 | }}; |
1146 | ($imp:expr, $err:expr, ($($msg:tt)*)) => { { |
1147 | let obj = $imp.obj(); |
1148 | $crate::element_warning!(obj, $err, ($($msg)*)); |
1149 | }}; |
1150 | ($imp:expr, $err:expr, [$($debug:tt)*]) => { { |
1151 | let obj = $imp.obj(); |
1152 | $crate::element_warning!(obj, $err, [$($debug)*]); |
1153 | }}; |
1154 | |
1155 | ($imp:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*], details: $details:expr) => { { |
1156 | let obj = $imp.obj(); |
1157 | $crate::element_warning!(obj, $err, ($($msg)*), [$($debug)*], details: $details); |
1158 | }}; |
1159 | ($imp:expr, $err:expr, ($($msg:tt)*), details: $details:expr) => { { |
1160 | let obj = $imp.obj(); |
1161 | $crate::element_warning!(obj, $err, ($($msg)*), details: $details); |
1162 | }}; |
1163 | ($imp:expr, $err:expr, [$($debug:tt)*], details: $details:expr) => { { |
1164 | let obj = $imp.obj(); |
1165 | $crate::element_warning!(obj, $err, [$($debug)*], details: $details); |
1166 | }}; |
1167 | ); |
1168 | |
1169 | #[doc (alias = "GST_ELEMENT_INFO" )] |
1170 | #[doc (alias = "GST_ELEMENT_INFO_WITH_DETAILS" )] |
1171 | #[macro_export ] |
1172 | macro_rules! element_imp_info( |
1173 | ($imp:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*]) => { { |
1174 | let obj = $imp.obj(); |
1175 | $crate::element_info!(obj, $err, ($($msg)*), [$($debug)*]); |
1176 | }}; |
1177 | ($imp:expr, $err:expr, ($($msg:tt)*)) => { { |
1178 | let obj = $imp.obj(); |
1179 | $crate::element_info!(obj, $err, ($($msg)*)); |
1180 | }}; |
1181 | ($imp:expr, $err:expr, [$($debug:tt)*]) => { { |
1182 | let obj = $imp.obj(); |
1183 | $crate::element_info!(obj, $err, [$($debug)*]); |
1184 | }}; |
1185 | |
1186 | ($imp:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*], details: $details:expr) => { { |
1187 | let obj = $imp.obj(); |
1188 | $crate::element_info!(obj, $err, ($($msg)*), [$($debug)*], details: $details); |
1189 | }}; |
1190 | ($imp:expr, $err:expr, ($($msg:tt)*), details: $details:expr) => { { |
1191 | let obj = $imp.obj(); |
1192 | $crate::element_info!(obj, $err, ($($msg)*), details: $details); |
1193 | }}; |
1194 | ($imp:expr, $err:expr, [$($debug:tt)*], details: $details:expr) => { { |
1195 | let obj = $imp.obj(); |
1196 | $crate::element_info!(obj, $err, [$($debug)*], details: $details); |
1197 | }}; |
1198 | ); |
1199 | |
1200 | #[cfg (test)] |
1201 | mod tests { |
1202 | use std::sync::mpsc::channel; |
1203 | |
1204 | use glib::GString; |
1205 | |
1206 | use super::*; |
1207 | |
1208 | #[test ] |
1209 | fn test_get_pads() { |
1210 | crate::init().unwrap(); |
1211 | |
1212 | let identity = crate::ElementFactory::make("identity" ).build().unwrap(); |
1213 | |
1214 | let mut pad_names = identity |
1215 | .pads() |
1216 | .iter() |
1217 | .map(|p| p.name()) |
1218 | .collect::<Vec<GString>>(); |
1219 | pad_names.sort(); |
1220 | assert_eq!(pad_names, vec![String::from("sink" ), String::from("src" )]); |
1221 | |
1222 | let mut pad_names = identity |
1223 | .sink_pads() |
1224 | .iter() |
1225 | .map(|p| p.name()) |
1226 | .collect::<Vec<GString>>(); |
1227 | pad_names.sort(); |
1228 | assert_eq!(pad_names, vec![String::from("sink" )]); |
1229 | |
1230 | let mut pad_names = identity |
1231 | .src_pads() |
1232 | .iter() |
1233 | .map(|p| p.name()) |
1234 | .collect::<Vec<GString>>(); |
1235 | pad_names.sort(); |
1236 | assert_eq!(pad_names, vec![String::from("src" )]); |
1237 | } |
1238 | |
1239 | #[test ] |
1240 | fn test_foreach_pad() { |
1241 | crate::init().unwrap(); |
1242 | |
1243 | let identity = crate::ElementFactory::make("identity" ).build().unwrap(); |
1244 | |
1245 | let mut pad_names = Vec::new(); |
1246 | identity.foreach_pad(|_element, pad| { |
1247 | pad_names.push(pad.name()); |
1248 | |
1249 | true |
1250 | }); |
1251 | pad_names.sort(); |
1252 | assert_eq!(pad_names, vec![String::from("sink" ), String::from("src" )]); |
1253 | } |
1254 | |
1255 | #[test ] |
1256 | fn test_call_async() { |
1257 | crate::init().unwrap(); |
1258 | |
1259 | let identity = crate::ElementFactory::make("identity" ).build().unwrap(); |
1260 | let (sender, receiver) = channel(); |
1261 | |
1262 | identity.call_async(move |_| { |
1263 | sender.send(()).unwrap(); |
1264 | }); |
1265 | |
1266 | assert_eq!(receiver.recv(), Ok(())); |
1267 | } |
1268 | |
1269 | #[test ] |
1270 | fn test_element_error() { |
1271 | crate::init().unwrap(); |
1272 | |
1273 | let identity = crate::ElementFactory::make("identity" ).build().unwrap(); |
1274 | |
1275 | crate::element_error!(identity, crate::CoreError::Failed, ("msg" ), ["debug" ]); |
1276 | crate::element_error!(identity, crate::CoreError::Failed, ["debug" ]); |
1277 | crate::element_error!(identity, crate::CoreError::Failed, ("msg" )); |
1278 | |
1279 | // We define a new variable for each call so there would be a compiler warning if the |
1280 | // string formatting did not actually use it. |
1281 | let x = 123i32; |
1282 | crate::element_error!(identity, crate::CoreError::Failed, ("msg {x}" ), ["debug" ]); |
1283 | let x = 123i32; |
1284 | crate::element_error!(identity, crate::CoreError::Failed, ["debug {x}" ]); |
1285 | let x = 123i32; |
1286 | crate::element_error!(identity, crate::CoreError::Failed, ("msg {}" , x)); |
1287 | } |
1288 | } |
1289 | |