1use std::{mem, panic, ptr};
4
5#[cfg(not(panic = "abort"))]
6use std::sync::atomic::{AtomicBool, Ordering};
7
8use glib::{ffi::gpointer, prelude::*, translate::*};
9
10use crate::{AppSink, ffi};
11
12#[cfg(feature = "futures")]
13pub use crate::app_sink_futures::AppSinkStream;
14
15#[allow(clippy::type_complexity)]
16pub struct AppSinkCallbacks {
17 eos: Option<Box<dyn FnMut(&AppSink) + Send + 'static>>,
18 new_preroll: Option<
19 Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
20 >,
21 new_sample: Option<
22 Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
23 >,
24 new_event: Option<Box<dyn FnMut(&AppSink) -> bool + Send + 'static>>,
25 propose_allocation:
26 Option<Box<dyn FnMut(&AppSink, &mut gst::query::Allocation) -> bool + Send + 'static>>,
27 #[cfg(not(panic = "abort"))]
28 panicked: AtomicBool,
29 callbacks: ffi::GstAppSinkCallbacks,
30}
31
32unsafe impl Send for AppSinkCallbacks {}
33unsafe impl Sync for AppSinkCallbacks {}
34
35impl AppSinkCallbacks {
36 pub fn builder() -> AppSinkCallbacksBuilder {
37 skip_assert_initialized!();
38 AppSinkCallbacksBuilder {
39 eos: None,
40 new_preroll: None,
41 new_sample: None,
42 new_event: None,
43 propose_allocation: None,
44 }
45 }
46}
47
48#[allow(clippy::type_complexity)]
49#[must_use = "The builder must be built to be used"]
50pub struct AppSinkCallbacksBuilder {
51 eos: Option<Box<dyn FnMut(&AppSink) + Send + 'static>>,
52 new_preroll: Option<
53 Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
54 >,
55 new_sample: Option<
56 Box<dyn FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static>,
57 >,
58 new_event: Option<Box<dyn FnMut(&AppSink) -> bool + Send + 'static>>,
59 propose_allocation:
60 Option<Box<dyn FnMut(&AppSink, &mut gst::query::Allocation) -> bool + Send + 'static>>,
61}
62
63impl AppSinkCallbacksBuilder {
64 pub fn eos<F: FnMut(&AppSink) + Send + 'static>(self, eos: F) -> Self {
65 Self {
66 eos: Some(Box::new(eos)),
67 ..self
68 }
69 }
70
71 pub fn eos_if<F: FnMut(&AppSink) + Send + 'static>(self, eos: F, predicate: bool) -> Self {
72 if predicate { self.eos(eos) } else { self }
73 }
74
75 pub fn eos_if_some<F: FnMut(&AppSink) + Send + 'static>(self, eos: Option<F>) -> Self {
76 if let Some(eos) = eos {
77 self.eos(eos)
78 } else {
79 self
80 }
81 }
82
83 pub fn new_preroll<
84 F: FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static,
85 >(
86 self,
87 new_preroll: F,
88 ) -> Self {
89 Self {
90 new_preroll: Some(Box::new(new_preroll)),
91 ..self
92 }
93 }
94
95 pub fn new_preroll_if<
96 F: FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static,
97 >(
98 self,
99 new_preroll: F,
100 predicate: bool,
101 ) -> Self {
102 if predicate {
103 self.new_preroll(new_preroll)
104 } else {
105 self
106 }
107 }
108
109 pub fn new_preroll_if_some<
110 F: FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static,
111 >(
112 self,
113 new_preroll: Option<F>,
114 ) -> Self {
115 if let Some(new_preroll) = new_preroll {
116 self.new_preroll(new_preroll)
117 } else {
118 self
119 }
120 }
121
122 pub fn new_sample<
123 F: FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static,
124 >(
125 self,
126 new_sample: F,
127 ) -> Self {
128 Self {
129 new_sample: Some(Box::new(new_sample)),
130 ..self
131 }
132 }
133
134 pub fn new_sample_if<
135 F: FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static,
136 >(
137 self,
138 new_sample: F,
139 predicate: bool,
140 ) -> Self {
141 if predicate {
142 self.new_sample(new_sample)
143 } else {
144 self
145 }
146 }
147
148 pub fn new_sample_if_some<
149 F: FnMut(&AppSink) -> Result<gst::FlowSuccess, gst::FlowError> + Send + 'static,
150 >(
151 self,
152 new_sample: Option<F>,
153 ) -> Self {
154 if let Some(new_sample) = new_sample {
155 self.new_sample(new_sample)
156 } else {
157 self
158 }
159 }
160
161 #[cfg(feature = "v1_20")]
162 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
163 pub fn new_event<F: FnMut(&AppSink) -> bool + Send + 'static>(self, new_event: F) -> Self {
164 Self {
165 new_event: Some(Box::new(new_event)),
166 ..self
167 }
168 }
169
170 #[cfg(feature = "v1_20")]
171 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
172 pub fn new_event_if<F: FnMut(&AppSink) -> bool + Send + 'static>(
173 self,
174 new_event: F,
175 predicate: bool,
176 ) -> Self {
177 if predicate {
178 self.new_event(new_event)
179 } else {
180 self
181 }
182 }
183
184 #[cfg(feature = "v1_20")]
185 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
186 pub fn new_event_if_some<F: FnMut(&AppSink) -> bool + Send + 'static>(
187 self,
188 new_event: Option<F>,
189 ) -> Self {
190 if let Some(new_event) = new_event {
191 self.new_event(new_event)
192 } else {
193 self
194 }
195 }
196
197 #[cfg(feature = "v1_24")]
198 #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
199 pub fn propose_allocation<
200 F: FnMut(&AppSink, &mut gst::query::Allocation) -> bool + Send + 'static,
201 >(
202 self,
203 propose_allocation: F,
204 ) -> Self {
205 Self {
206 propose_allocation: Some(Box::new(propose_allocation)),
207 ..self
208 }
209 }
210
211 #[cfg(feature = "v1_24")]
212 #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
213 pub fn propose_allocation_if<
214 F: FnMut(&AppSink, &mut gst::query::Allocation) -> bool + Send + 'static,
215 >(
216 self,
217 propose_allocation: F,
218 predicate: bool,
219 ) -> Self {
220 if predicate {
221 self.propose_allocation(propose_allocation)
222 } else {
223 self
224 }
225 }
226
227 #[cfg(feature = "v1_24")]
228 #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
229 pub fn propose_allocation_if_some<
230 F: FnMut(&AppSink, &mut gst::query::Allocation) -> bool + Send + 'static,
231 >(
232 self,
233 propose_allocation: Option<F>,
234 ) -> Self {
235 if let Some(propose_allocation) = propose_allocation {
236 self.propose_allocation(propose_allocation)
237 } else {
238 self
239 }
240 }
241
242 #[must_use = "Building the callbacks without using them has no effect"]
243 pub fn build(self) -> AppSinkCallbacks {
244 let have_eos = self.eos.is_some();
245 let have_new_preroll = self.new_preroll.is_some();
246 let have_new_sample = self.new_sample.is_some();
247 let have_new_event = self.new_event.is_some();
248 let have_propose_allocation = self.propose_allocation.is_some();
249
250 AppSinkCallbacks {
251 eos: self.eos,
252 new_preroll: self.new_preroll,
253 new_sample: self.new_sample,
254 new_event: self.new_event,
255 propose_allocation: self.propose_allocation,
256 #[cfg(not(panic = "abort"))]
257 panicked: AtomicBool::new(false),
258 callbacks: ffi::GstAppSinkCallbacks {
259 eos: if have_eos { Some(trampoline_eos) } else { None },
260 new_preroll: if have_new_preroll {
261 Some(trampoline_new_preroll)
262 } else {
263 None
264 },
265 new_sample: if have_new_sample {
266 Some(trampoline_new_sample)
267 } else {
268 None
269 },
270 new_event: if have_new_event {
271 Some(trampoline_new_event)
272 } else {
273 None
274 },
275 propose_allocation: if have_propose_allocation {
276 Some(trampoline_propose_allocation)
277 } else {
278 None
279 },
280 _gst_reserved: [ptr::null_mut(), ptr::null_mut()],
281 },
282 }
283 }
284}
285
286unsafe extern "C" fn trampoline_eos(appsink: *mut ffi::GstAppSink, callbacks: gpointer) {
287 unsafe {
288 let callbacks = callbacks as *mut AppSinkCallbacks;
289 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
290
291 #[cfg(not(panic = "abort"))]
292 if (*callbacks).panicked.load(Ordering::Relaxed) {
293 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
294 gst::subclass::post_panic_error_message(
295 element.upcast_ref(),
296 element.upcast_ref(),
297 None,
298 );
299 return;
300 }
301
302 if let Some(ref mut eos) = (*callbacks).eos {
303 let result = panic::catch_unwind(panic::AssertUnwindSafe(|| eos(&element)));
304 match result {
305 Ok(result) => result,
306 Err(err) => {
307 #[cfg(panic = "abort")]
308 {
309 unreachable!("{err:?}");
310 }
311 #[cfg(not(panic = "abort"))]
312 {
313 (*callbacks).panicked.store(true, Ordering::Relaxed);
314 gst::subclass::post_panic_error_message(
315 element.upcast_ref(),
316 element.upcast_ref(),
317 Some(err),
318 );
319 }
320 }
321 }
322 }
323 }
324}
325
326unsafe extern "C" fn trampoline_new_preroll(
327 appsink: *mut ffi::GstAppSink,
328 callbacks: gpointer,
329) -> gst::ffi::GstFlowReturn {
330 unsafe {
331 let callbacks = callbacks as *mut AppSinkCallbacks;
332 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
333
334 #[cfg(not(panic = "abort"))]
335 if (*callbacks).panicked.load(Ordering::Relaxed) {
336 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
337 gst::subclass::post_panic_error_message(
338 element.upcast_ref(),
339 element.upcast_ref(),
340 None,
341 );
342 return gst::FlowReturn::Error.into_glib();
343 }
344
345 let ret = if let Some(ref mut new_preroll) = (*callbacks).new_preroll {
346 let result =
347 panic::catch_unwind(panic::AssertUnwindSafe(|| new_preroll(&element).into()));
348 match result {
349 Ok(result) => result,
350 Err(err) => {
351 #[cfg(panic = "abort")]
352 {
353 unreachable!("{err:?}");
354 }
355 #[cfg(not(panic = "abort"))]
356 {
357 (*callbacks).panicked.store(true, Ordering::Relaxed);
358 gst::subclass::post_panic_error_message(
359 element.upcast_ref(),
360 element.upcast_ref(),
361 Some(err),
362 );
363
364 gst::FlowReturn::Error
365 }
366 }
367 }
368 } else {
369 gst::FlowReturn::Error
370 };
371
372 ret.into_glib()
373 }
374}
375
376unsafe extern "C" fn trampoline_new_sample(
377 appsink: *mut ffi::GstAppSink,
378 callbacks: gpointer,
379) -> gst::ffi::GstFlowReturn {
380 unsafe {
381 let callbacks = callbacks as *mut AppSinkCallbacks;
382 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
383
384 #[cfg(not(panic = "abort"))]
385 if (*callbacks).panicked.load(Ordering::Relaxed) {
386 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
387 gst::subclass::post_panic_error_message(
388 element.upcast_ref(),
389 element.upcast_ref(),
390 None,
391 );
392 return gst::FlowReturn::Error.into_glib();
393 }
394
395 let ret = if let Some(ref mut new_sample) = (*callbacks).new_sample {
396 let result =
397 panic::catch_unwind(panic::AssertUnwindSafe(|| new_sample(&element).into()));
398 match result {
399 Ok(result) => result,
400 Err(err) => {
401 #[cfg(panic = "abort")]
402 {
403 unreachable!("{err:?}");
404 }
405 #[cfg(not(panic = "abort"))]
406 {
407 (*callbacks).panicked.store(true, Ordering::Relaxed);
408 gst::subclass::post_panic_error_message(
409 element.upcast_ref(),
410 element.upcast_ref(),
411 Some(err),
412 );
413
414 gst::FlowReturn::Error
415 }
416 }
417 }
418 } else {
419 gst::FlowReturn::Error
420 };
421
422 ret.into_glib()
423 }
424}
425
426unsafe extern "C" fn trampoline_new_event(
427 appsink: *mut ffi::GstAppSink,
428 callbacks: gpointer,
429) -> glib::ffi::gboolean {
430 unsafe {
431 let callbacks = callbacks as *mut AppSinkCallbacks;
432 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
433
434 #[cfg(not(panic = "abort"))]
435 if (*callbacks).panicked.load(Ordering::Relaxed) {
436 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
437 gst::subclass::post_panic_error_message(
438 element.upcast_ref(),
439 element.upcast_ref(),
440 None,
441 );
442 return false.into_glib();
443 }
444
445 let ret = if let Some(ref mut new_event) = (*callbacks).new_event {
446 let result = panic::catch_unwind(panic::AssertUnwindSafe(|| new_event(&element)));
447 match result {
448 Ok(result) => result,
449 Err(err) => {
450 #[cfg(panic = "abort")]
451 {
452 unreachable!("{err:?}");
453 }
454 #[cfg(not(panic = "abort"))]
455 {
456 (*callbacks).panicked.store(true, Ordering::Relaxed);
457 gst::subclass::post_panic_error_message(
458 element.upcast_ref(),
459 element.upcast_ref(),
460 Some(err),
461 );
462
463 false
464 }
465 }
466 }
467 } else {
468 false
469 };
470
471 ret.into_glib()
472 }
473}
474
475unsafe extern "C" fn trampoline_propose_allocation(
476 appsink: *mut ffi::GstAppSink,
477 query: *mut gst::ffi::GstQuery,
478 callbacks: gpointer,
479) -> glib::ffi::gboolean {
480 unsafe {
481 let callbacks = callbacks as *mut AppSinkCallbacks;
482 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
483
484 #[cfg(not(panic = "abort"))]
485 if (*callbacks).panicked.load(Ordering::Relaxed) {
486 let element: Borrowed<AppSink> = from_glib_borrow(appsink);
487 gst::subclass::post_panic_error_message(
488 element.upcast_ref(),
489 element.upcast_ref(),
490 None,
491 );
492 return false.into_glib();
493 }
494
495 let ret = if let Some(ref mut propose_allocation) = (*callbacks).propose_allocation {
496 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
497 gst::QueryViewMut::Allocation(allocation) => allocation,
498 _ => unreachable!(),
499 };
500 let result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
501 propose_allocation(&element, query)
502 }));
503 match result {
504 Ok(result) => result,
505 Err(err) => {
506 #[cfg(panic = "abort")]
507 {
508 unreachable!("{err:?}");
509 }
510 #[cfg(not(panic = "abort"))]
511 {
512 (*callbacks).panicked.store(true, Ordering::Relaxed);
513 gst::subclass::post_panic_error_message(
514 element.upcast_ref(),
515 element.upcast_ref(),
516 Some(err),
517 );
518 false
519 }
520 }
521 }
522 } else {
523 false
524 };
525
526 ret.into_glib()
527 }
528}
529
530unsafe extern "C" fn destroy_callbacks(ptr: gpointer) {
531 unsafe {
532 let _ = Box::<AppSinkCallbacks>::from_raw(ptr as *mut _);
533 }
534}
535
536impl AppSink {
537 pub fn builder<'a>() -> AppSinkBuilder<'a> {
542 assert_initialized_main_thread!();
543 AppSinkBuilder {
544 builder: gst::Object::builder(),
545 callbacks: None,
546 drop_out_of_segment: None,
547 }
548 }
549
550 #[doc(alias = "gst_app_sink_set_callbacks")]
570 pub fn set_callbacks(&self, callbacks: AppSinkCallbacks) {
571 unsafe {
572 let sink = self.to_glib_none().0;
573
574 #[allow(clippy::manual_dangling_ptr)]
575 #[cfg(not(feature = "v1_18"))]
576 {
577 static SET_ONCE_QUARK: std::sync::OnceLock<glib::Quark> =
578 std::sync::OnceLock::new();
579
580 let set_once_quark = SET_ONCE_QUARK
581 .get_or_init(|| glib::Quark::from_str("gstreamer-rs-app-sink-callbacks"));
582
583 if gst::version() < (1, 16, 3, 0) {
586 if !glib::gobject_ffi::g_object_get_qdata(
587 sink as *mut _,
588 set_once_quark.into_glib(),
589 )
590 .is_null()
591 {
592 panic!("AppSink callbacks can only be set once");
593 }
594
595 glib::gobject_ffi::g_object_set_qdata(
596 sink as *mut _,
597 set_once_quark.into_glib(),
598 1 as *mut _,
599 );
600 }
601 }
602
603 ffi::gst_app_sink_set_callbacks(
604 sink,
605 mut_override(&callbacks.callbacks),
606 Box::into_raw(Box::new(callbacks)) as *mut _,
607 Some(destroy_callbacks),
608 );
609 }
610 }
611
612 #[doc(alias = "drop-out-of-segment")]
613 pub fn drops_out_of_segment(&self) -> bool {
614 unsafe {
615 from_glib(gst_base::ffi::gst_base_sink_get_drop_out_of_segment(
616 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
617 ))
618 }
619 }
620
621 #[doc(alias = "max-bitrate")]
622 #[doc(alias = "gst_base_sink_get_max_bitrate")]
623 pub fn max_bitrate(&self) -> u64 {
624 unsafe {
625 gst_base::ffi::gst_base_sink_get_max_bitrate(
626 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
627 )
628 }
629 }
630
631 #[doc(alias = "max-lateness")]
632 #[doc(alias = "gst_base_sink_get_max_lateness")]
633 pub fn max_lateness(&self) -> i64 {
634 unsafe {
635 gst_base::ffi::gst_base_sink_get_max_lateness(
636 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
637 )
638 }
639 }
640
641 #[doc(alias = "processing-deadline")]
642 #[cfg(feature = "v1_16")]
643 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
644 #[doc(alias = "gst_base_sink_get_processing_deadline")]
645 pub fn processing_deadline(&self) -> gst::ClockTime {
646 unsafe {
647 try_from_glib(gst_base::ffi::gst_base_sink_get_processing_deadline(
648 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
649 ))
650 .expect("undefined processing_deadline")
651 }
652 }
653
654 #[doc(alias = "render-delay")]
655 #[doc(alias = "gst_base_sink_get_render_delay")]
656 pub fn render_delay(&self) -> gst::ClockTime {
657 unsafe {
658 try_from_glib(gst_base::ffi::gst_base_sink_get_render_delay(
659 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
660 ))
661 .expect("undefined render_delay")
662 }
663 }
664
665 #[cfg(feature = "v1_18")]
666 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
667 #[doc(alias = "gst_base_sink_get_stats")]
668 pub fn stats(&self) -> gst::Structure {
669 unsafe {
670 from_glib_full(gst_base::ffi::gst_base_sink_get_stats(
671 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
672 ))
673 }
674 }
675
676 #[doc(alias = "sync")]
677 pub fn is_sync(&self) -> bool {
678 unsafe {
679 from_glib(gst_base::ffi::gst_base_sink_get_sync(
680 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
681 ))
682 }
683 }
684
685 #[doc(alias = "throttle-time")]
686 #[doc(alias = "gst_base_sink_get_throttle_time")]
687 pub fn throttle_time(&self) -> u64 {
688 unsafe {
689 gst_base::ffi::gst_base_sink_get_throttle_time(
690 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
691 )
692 }
693 }
694
695 #[doc(alias = "ts-offset")]
696 #[doc(alias = "gst_base_sink_get_ts_offset")]
697 pub fn ts_offset(&self) -> gst::ClockTimeDiff {
698 unsafe {
699 gst_base::ffi::gst_base_sink_get_ts_offset(
700 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
701 )
702 }
703 }
704
705 #[doc(alias = "async")]
706 #[doc(alias = "gst_base_sink_is_async_enabled")]
707 pub fn is_async(&self) -> bool {
708 unsafe {
709 from_glib(gst_base::ffi::gst_base_sink_is_async_enabled(
710 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
711 ))
712 }
713 }
714
715 #[doc(alias = "last-sample")]
716 pub fn enables_last_sample(&self) -> bool {
717 unsafe {
718 from_glib(gst_base::ffi::gst_base_sink_is_last_sample_enabled(
719 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
720 ))
721 }
722 }
723
724 #[doc(alias = "qos")]
725 #[doc(alias = "gst_base_sink_is_qos_enabled")]
726 pub fn is_qos(&self) -> bool {
727 unsafe {
728 from_glib(gst_base::ffi::gst_base_sink_is_qos_enabled(
729 self.as_ptr() as *mut gst_base::ffi::GstBaseSink
730 ))
731 }
732 }
733
734 #[doc(alias = "async")]
735 #[doc(alias = "gst_base_sink_set_async_enabled")]
736 pub fn set_async(&self, enabled: bool) {
737 unsafe {
738 gst_base::ffi::gst_base_sink_set_async_enabled(
739 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
740 enabled.into_glib(),
741 );
742 }
743 }
744
745 #[doc(alias = "drop-out-of-segment")]
746 #[doc(alias = "gst_base_sink_set_drop_out_of_segment")]
747 pub fn set_drop_out_of_segment(&self, drop_out_of_segment: bool) {
748 unsafe {
749 gst_base::ffi::gst_base_sink_set_drop_out_of_segment(
750 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
751 drop_out_of_segment.into_glib(),
752 );
753 }
754 }
755
756 #[doc(alias = "last-sample")]
757 pub fn set_enable_last_sample(&self, enabled: bool) {
758 unsafe {
759 gst_base::ffi::gst_base_sink_set_last_sample_enabled(
760 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
761 enabled.into_glib(),
762 );
763 }
764 }
765
766 #[doc(alias = "max-bitrate")]
767 #[doc(alias = "gst_base_sink_set_max_bitrate")]
768 pub fn set_max_bitrate(&self, max_bitrate: u64) {
769 unsafe {
770 gst_base::ffi::gst_base_sink_set_max_bitrate(
771 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
772 max_bitrate,
773 );
774 }
775 }
776
777 #[doc(alias = "max-lateness")]
778 #[doc(alias = "gst_base_sink_set_max_lateness")]
779 pub fn set_max_lateness(&self, max_lateness: i64) {
780 unsafe {
781 gst_base::ffi::gst_base_sink_set_max_lateness(
782 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
783 max_lateness,
784 );
785 }
786 }
787
788 #[doc(alias = "processing-deadline")]
789 #[cfg(feature = "v1_16")]
790 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
791 #[doc(alias = "gst_base_sink_set_processing_deadline")]
792 pub fn set_processing_deadline(&self, processing_deadline: gst::ClockTime) {
793 unsafe {
794 gst_base::ffi::gst_base_sink_set_processing_deadline(
795 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
796 processing_deadline.into_glib(),
797 );
798 }
799 }
800
801 #[doc(alias = "qos")]
802 #[doc(alias = "gst_base_sink_set_qos_enabled")]
803 pub fn set_qos(&self, enabled: bool) {
804 unsafe {
805 gst_base::ffi::gst_base_sink_set_qos_enabled(
806 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
807 enabled.into_glib(),
808 );
809 }
810 }
811
812 #[doc(alias = "render-delay")]
813 #[doc(alias = "gst_base_sink_set_render_delay")]
814 pub fn set_render_delay(&self, delay: gst::ClockTime) {
815 unsafe {
816 gst_base::ffi::gst_base_sink_set_render_delay(
817 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
818 delay.into_glib(),
819 );
820 }
821 }
822
823 #[doc(alias = "sync")]
824 #[doc(alias = "gst_base_sink_set_sync")]
825 pub fn set_sync(&self, sync: bool) {
826 unsafe {
827 gst_base::ffi::gst_base_sink_set_sync(
828 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
829 sync.into_glib(),
830 );
831 }
832 }
833
834 #[doc(alias = "throttle-time")]
835 #[doc(alias = "gst_base_sink_set_throttle_time")]
836 pub fn set_throttle_time(&self, throttle: u64) {
837 unsafe {
838 gst_base::ffi::gst_base_sink_set_throttle_time(
839 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
840 throttle,
841 );
842 }
843 }
844
845 #[doc(alias = "ts-offset")]
846 #[doc(alias = "gst_base_sink_set_ts_offset")]
847 pub fn set_ts_offset(&self, offset: gst::ClockTimeDiff) {
848 unsafe {
849 gst_base::ffi::gst_base_sink_set_ts_offset(
850 self.as_ptr() as *mut gst_base::ffi::GstBaseSink,
851 offset,
852 );
853 }
854 }
855
856 #[doc(alias = "async")]
857 pub fn connect_async_notify<F: Fn(&Self) + Send + Sync + 'static>(
858 &self,
859 f: F,
860 ) -> glib::SignalHandlerId {
861 unsafe extern "C" fn notify_async_trampoline<F: Fn(&AppSink) + Send + Sync + 'static>(
862 this: *mut ffi::GstAppSink,
863 _param_spec: glib::ffi::gpointer,
864 f: glib::ffi::gpointer,
865 ) {
866 unsafe {
867 let f: &F = &*(f as *const F);
868 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
869 }
870 }
871 unsafe {
872 let f: Box<F> = Box::new(f);
873 glib::signal::connect_raw(
874 self.as_ptr() as *mut _,
875 b"notify::async\0".as_ptr() as *const _,
876 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
877 notify_async_trampoline::<F> as *const (),
878 )),
879 Box::into_raw(f),
880 )
881 }
882 }
883
884 #[doc(alias = "blocksize")]
885 pub fn connect_blocksize_notify<F: Fn(&Self) + Send + Sync + 'static>(
886 &self,
887 f: F,
888 ) -> glib::SignalHandlerId {
889 unsafe extern "C" fn notify_blocksize_trampoline<
890 F: Fn(&AppSink) + Send + Sync + 'static,
891 >(
892 this: *mut ffi::GstAppSink,
893 _param_spec: glib::ffi::gpointer,
894 f: glib::ffi::gpointer,
895 ) {
896 unsafe {
897 let f: &F = &*(f as *const F);
898 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
899 }
900 }
901 unsafe {
902 let f: Box<F> = Box::new(f);
903 glib::signal::connect_raw(
904 self.as_ptr() as *mut _,
905 b"notify::blocksize\0".as_ptr() as *const _,
906 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
907 notify_blocksize_trampoline::<F> as *const (),
908 )),
909 Box::into_raw(f),
910 )
911 }
912 }
913
914 #[doc(alias = "enable-last-sample")]
915 pub fn connect_enable_last_sample_notify<F: Fn(&Self) + Send + Sync + 'static>(
916 &self,
917 f: F,
918 ) -> glib::SignalHandlerId {
919 unsafe extern "C" fn notify_enable_last_sample_trampoline<
920 F: Fn(&AppSink) + Send + Sync + 'static,
921 >(
922 this: *mut ffi::GstAppSink,
923 _param_spec: glib::ffi::gpointer,
924 f: glib::ffi::gpointer,
925 ) {
926 unsafe {
927 let f: &F = &*(f as *const F);
928 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
929 }
930 }
931 unsafe {
932 let f: Box<F> = Box::new(f);
933 glib::signal::connect_raw(
934 self.as_ptr() as *mut _,
935 b"notify::enable-last-sample\0".as_ptr() as *const _,
936 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
937 notify_enable_last_sample_trampoline::<F> as *const (),
938 )),
939 Box::into_raw(f),
940 )
941 }
942 }
943
944 #[doc(alias = "last-sample")]
945 pub fn connect_last_sample_notify<F: Fn(&Self) + Send + Sync + 'static>(
946 &self,
947 f: F,
948 ) -> glib::SignalHandlerId {
949 unsafe extern "C" fn notify_last_sample_trampoline<
950 F: Fn(&AppSink) + Send + Sync + 'static,
951 >(
952 this: *mut ffi::GstAppSink,
953 _param_spec: glib::ffi::gpointer,
954 f: glib::ffi::gpointer,
955 ) {
956 unsafe {
957 let f: &F = &*(f as *const F);
958 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
959 }
960 }
961 unsafe {
962 let f: Box<F> = Box::new(f);
963 glib::signal::connect_raw(
964 self.as_ptr() as *mut _,
965 b"notify::last-sample\0".as_ptr() as *const _,
966 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
967 notify_last_sample_trampoline::<F> as *const (),
968 )),
969 Box::into_raw(f),
970 )
971 }
972 }
973
974 #[doc(alias = "max-bitrate")]
975 pub fn connect_max_bitrate_notify<F: Fn(&Self) + Send + Sync + 'static>(
976 &self,
977 f: F,
978 ) -> glib::SignalHandlerId {
979 unsafe extern "C" fn notify_max_bitrate_trampoline<
980 F: Fn(&AppSink) + Send + Sync + 'static,
981 >(
982 this: *mut ffi::GstAppSink,
983 _param_spec: glib::ffi::gpointer,
984 f: glib::ffi::gpointer,
985 ) {
986 unsafe {
987 let f: &F = &*(f as *const F);
988 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
989 }
990 }
991 unsafe {
992 let f: Box<F> = Box::new(f);
993 glib::signal::connect_raw(
994 self.as_ptr() as *mut _,
995 b"notify::max-bitrate\0".as_ptr() as *const _,
996 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
997 notify_max_bitrate_trampoline::<F> as *const (),
998 )),
999 Box::into_raw(f),
1000 )
1001 }
1002 }
1003
1004 #[doc(alias = "max-lateness")]
1005 pub fn connect_max_lateness_notify<F: Fn(&Self) + Send + Sync + 'static>(
1006 &self,
1007 f: F,
1008 ) -> glib::SignalHandlerId {
1009 unsafe extern "C" fn notify_max_lateness_trampoline<
1010 F: Fn(&AppSink) + Send + Sync + 'static,
1011 >(
1012 this: *mut ffi::GstAppSink,
1013 _param_spec: glib::ffi::gpointer,
1014 f: glib::ffi::gpointer,
1015 ) {
1016 unsafe {
1017 let f: &F = &*(f as *const F);
1018 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1019 }
1020 }
1021 unsafe {
1022 let f: Box<F> = Box::new(f);
1023 glib::signal::connect_raw(
1024 self.as_ptr() as *mut _,
1025 b"notify::max-lateness\0".as_ptr() as *const _,
1026 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1027 notify_max_lateness_trampoline::<F> as *const (),
1028 )),
1029 Box::into_raw(f),
1030 )
1031 }
1032 }
1033
1034 #[cfg(feature = "v1_16")]
1035 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1036 #[doc(alias = "processing-deadline")]
1037 pub fn connect_processing_deadline_notify<F: Fn(&Self) + Send + Sync + 'static>(
1038 &self,
1039 f: F,
1040 ) -> glib::SignalHandlerId {
1041 unsafe extern "C" fn notify_processing_deadline_trampoline<
1042 F: Fn(&AppSink) + Send + Sync + 'static,
1043 >(
1044 this: *mut ffi::GstAppSink,
1045 _param_spec: glib::ffi::gpointer,
1046 f: glib::ffi::gpointer,
1047 ) {
1048 unsafe {
1049 let f: &F = &*(f as *const F);
1050 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1051 }
1052 }
1053 unsafe {
1054 let f: Box<F> = Box::new(f);
1055 glib::signal::connect_raw(
1056 self.as_ptr() as *mut _,
1057 b"notify::processing-deadline\0".as_ptr() as *const _,
1058 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1059 notify_processing_deadline_trampoline::<F> as *const (),
1060 )),
1061 Box::into_raw(f),
1062 )
1063 }
1064 }
1065
1066 #[doc(alias = "qos")]
1067 pub fn connect_qos_notify<F: Fn(&Self) + Send + Sync + 'static>(
1068 &self,
1069 f: F,
1070 ) -> glib::SignalHandlerId {
1071 unsafe extern "C" fn notify_qos_trampoline<F: Fn(&AppSink) + Send + Sync + 'static>(
1072 this: *mut ffi::GstAppSink,
1073 _param_spec: glib::ffi::gpointer,
1074 f: glib::ffi::gpointer,
1075 ) {
1076 unsafe {
1077 let f: &F = &*(f as *const F);
1078 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1079 }
1080 }
1081 unsafe {
1082 let f: Box<F> = Box::new(f);
1083 glib::signal::connect_raw(
1084 self.as_ptr() as *mut _,
1085 b"notify::qos\0".as_ptr() as *const _,
1086 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1087 notify_qos_trampoline::<F> as *const (),
1088 )),
1089 Box::into_raw(f),
1090 )
1091 }
1092 }
1093
1094 #[doc(alias = "render-delay")]
1095 pub fn connect_render_delay_notify<F: Fn(&Self) + Send + Sync + 'static>(
1096 &self,
1097 f: F,
1098 ) -> glib::SignalHandlerId {
1099 unsafe extern "C" fn notify_render_delay_trampoline<
1100 F: Fn(&AppSink) + Send + Sync + 'static,
1101 >(
1102 this: *mut ffi::GstAppSink,
1103 _param_spec: glib::ffi::gpointer,
1104 f: glib::ffi::gpointer,
1105 ) {
1106 unsafe {
1107 let f: &F = &*(f as *const F);
1108 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1109 }
1110 }
1111 unsafe {
1112 let f: Box<F> = Box::new(f);
1113 glib::signal::connect_raw(
1114 self.as_ptr() as *mut _,
1115 b"notify::render-delay\0".as_ptr() as *const _,
1116 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1117 notify_render_delay_trampoline::<F> as *const (),
1118 )),
1119 Box::into_raw(f),
1120 )
1121 }
1122 }
1123
1124 #[cfg(feature = "v1_18")]
1125 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1126 #[doc(alias = "stats")]
1127 pub fn connect_stats_notify<F: Fn(&Self) + Send + Sync + 'static>(
1128 &self,
1129 f: F,
1130 ) -> glib::SignalHandlerId {
1131 unsafe extern "C" fn notify_stats_trampoline<F: Fn(&AppSink) + Send + Sync + 'static>(
1132 this: *mut ffi::GstAppSink,
1133 _param_spec: glib::ffi::gpointer,
1134 f: glib::ffi::gpointer,
1135 ) {
1136 unsafe {
1137 let f: &F = &*(f as *const F);
1138 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1139 }
1140 }
1141 unsafe {
1142 let f: Box<F> = Box::new(f);
1143 glib::signal::connect_raw(
1144 self.as_ptr() as *mut _,
1145 b"notify::stats\0".as_ptr() as *const _,
1146 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1147 notify_stats_trampoline::<F> as *const (),
1148 )),
1149 Box::into_raw(f),
1150 )
1151 }
1152 }
1153
1154 #[doc(alias = "sync")]
1155 pub fn connect_sync_notify<F: Fn(&Self) + Send + Sync + 'static>(
1156 &self,
1157 f: F,
1158 ) -> glib::SignalHandlerId {
1159 unsafe extern "C" fn notify_sync_trampoline<F: Fn(&AppSink) + Send + Sync + 'static>(
1160 this: *mut ffi::GstAppSink,
1161 _param_spec: glib::ffi::gpointer,
1162 f: glib::ffi::gpointer,
1163 ) {
1164 unsafe {
1165 let f: &F = &*(f as *const F);
1166 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1167 }
1168 }
1169 unsafe {
1170 let f: Box<F> = Box::new(f);
1171 glib::signal::connect_raw(
1172 self.as_ptr() as *mut _,
1173 b"notify::sync\0".as_ptr() as *const _,
1174 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1175 notify_sync_trampoline::<F> as *const (),
1176 )),
1177 Box::into_raw(f),
1178 )
1179 }
1180 }
1181
1182 #[doc(alias = "throttle-time")]
1183 pub fn connect_throttle_time_notify<F: Fn(&Self) + Send + Sync + 'static>(
1184 &self,
1185 f: F,
1186 ) -> glib::SignalHandlerId {
1187 unsafe extern "C" fn notify_throttle_time_trampoline<
1188 F: Fn(&AppSink) + Send + Sync + 'static,
1189 >(
1190 this: *mut ffi::GstAppSink,
1191 _param_spec: glib::ffi::gpointer,
1192 f: glib::ffi::gpointer,
1193 ) {
1194 unsafe {
1195 let f: &F = &*(f as *const F);
1196 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1197 }
1198 }
1199 unsafe {
1200 let f: Box<F> = Box::new(f);
1201 glib::signal::connect_raw(
1202 self.as_ptr() as *mut _,
1203 b"notify::throttle-time\0".as_ptr() as *const _,
1204 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1205 notify_throttle_time_trampoline::<F> as *const (),
1206 )),
1207 Box::into_raw(f),
1208 )
1209 }
1210 }
1211
1212 #[doc(alias = "ts-offset")]
1213 pub fn connect_ts_offset_notify<F: Fn(&Self) + Send + Sync + 'static>(
1214 &self,
1215 f: F,
1216 ) -> glib::SignalHandlerId {
1217 unsafe extern "C" fn notify_ts_offset_trampoline<
1218 F: Fn(&AppSink) + Send + Sync + 'static,
1219 >(
1220 this: *mut ffi::GstAppSink,
1221 _param_spec: glib::ffi::gpointer,
1222 f: glib::ffi::gpointer,
1223 ) {
1224 unsafe {
1225 let f: &F = &*(f as *const F);
1226 f(AppSink::from_glib_borrow(this).unsafe_cast_ref())
1227 }
1228 }
1229 unsafe {
1230 let f: Box<F> = Box::new(f);
1231 glib::signal::connect_raw(
1232 self.as_ptr() as *mut _,
1233 b"notify::ts-offset\0".as_ptr() as *const _,
1234 Some(mem::transmute::<*const (), unsafe extern "C" fn()>(
1235 notify_ts_offset_trampoline::<F> as *const (),
1236 )),
1237 Box::into_raw(f),
1238 )
1239 }
1240 }
1241
1242 #[cfg(feature = "futures")]
1243 pub fn stream(&self) -> AppSinkStream {
1244 AppSinkStream::new(self)
1245 }
1246}
1247
1248#[must_use = "The builder must be built to be used"]
1253pub struct AppSinkBuilder<'a> {
1254 builder: gst::gobject::GObjectBuilder<'a, AppSink>,
1255 callbacks: Option<AppSinkCallbacks>,
1256 drop_out_of_segment: Option<bool>,
1257}
1258
1259impl<'a> AppSinkBuilder<'a> {
1260 #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
1268 pub fn build(self) -> AppSink {
1269 let appsink = self.builder.build().unwrap();
1270
1271 if let Some(callbacks) = self.callbacks {
1272 appsink.set_callbacks(callbacks);
1273 }
1274
1275 if let Some(drop_out_of_segment) = self.drop_out_of_segment {
1276 appsink.set_drop_out_of_segment(drop_out_of_segment);
1277 }
1278
1279 appsink
1280 }
1281
1282 pub fn async_(self, async_: bool) -> Self {
1283 Self {
1284 builder: self.builder.property("async", async_),
1285 ..self
1286 }
1287 }
1288
1289 pub fn buffer_list(self, buffer_list: bool) -> Self {
1290 Self {
1291 builder: self.builder.property("buffer-list", buffer_list),
1292 ..self
1293 }
1294 }
1295
1296 pub fn callbacks(self, callbacks: AppSinkCallbacks) -> Self {
1297 Self {
1298 callbacks: Some(callbacks),
1299 ..self
1300 }
1301 }
1302
1303 pub fn caps(self, caps: &'a gst::Caps) -> Self {
1304 Self {
1305 builder: self.builder.property("caps", caps),
1306 ..self
1307 }
1308 }
1309
1310 #[cfg_attr(feature = "v1_28", deprecated = "Since 1.28")]
1311 #[allow(deprecated)]
1312 pub fn drop(self, drop: bool) -> Self {
1313 Self {
1314 builder: self.builder.property("drop", drop),
1315 ..self
1316 }
1317 }
1318
1319 pub fn drop_out_of_segment(self, drop_out_of_segment: bool) -> Self {
1320 Self {
1321 drop_out_of_segment: Some(drop_out_of_segment),
1322 ..self
1323 }
1324 }
1325
1326 pub fn enable_last_sample(self, enable_last_sample: bool) -> Self {
1327 Self {
1328 builder: self
1329 .builder
1330 .property("enable-last-sample", enable_last_sample),
1331 ..self
1332 }
1333 }
1334
1335 pub fn max_bitrate(self, max_bitrate: u64) -> Self {
1336 Self {
1337 builder: self.builder.property("max-bitrate", max_bitrate),
1338 ..self
1339 }
1340 }
1341
1342 pub fn max_buffers(self, max_buffers: u32) -> Self {
1343 Self {
1344 builder: self.builder.property("max-buffers", max_buffers),
1345 ..self
1346 }
1347 }
1348
1349 pub fn max_lateness(self, max_lateness: i64) -> Self {
1350 Self {
1351 builder: self.builder.property("max-lateness", max_lateness),
1352 ..self
1353 }
1354 }
1355
1356 #[cfg(feature = "v1_16")]
1357 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1358 pub fn processing_deadline(self, processing_deadline: gst::ClockTime) -> Self {
1359 Self {
1360 builder: self
1361 .builder
1362 .property("processing-deadline", processing_deadline),
1363 ..self
1364 }
1365 }
1366
1367 pub fn qos(self, qos: bool) -> Self {
1368 Self {
1369 builder: self.builder.property("qos", qos),
1370 ..self
1371 }
1372 }
1373
1374 pub fn render_delay(self, render_delay: Option<gst::ClockTime>) -> Self {
1375 Self {
1376 builder: self.builder.property("render-delay", render_delay),
1377 ..self
1378 }
1379 }
1380
1381 pub fn sync(self, sync: bool) -> Self {
1382 Self {
1383 builder: self.builder.property("sync", sync),
1384 ..self
1385 }
1386 }
1387
1388 pub fn throttle_time(self, throttle_time: u64) -> Self {
1389 Self {
1390 builder: self.builder.property("throttle-time", throttle_time),
1391 ..self
1392 }
1393 }
1394
1395 pub fn ts_offset(self, ts_offset: gst::ClockTimeDiff) -> Self {
1396 Self {
1397 builder: self.builder.property("ts-offset", ts_offset),
1398 ..self
1399 }
1400 }
1401
1402 pub fn wait_on_eos(self, wait_on_eos: bool) -> Self {
1403 Self {
1404 builder: self.builder.property("wait-on-eos", wait_on_eos),
1405 ..self
1406 }
1407 }
1408
1409 #[cfg(feature = "v1_24")]
1410 #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
1411 pub fn max_time(self, max_time: Option<gst::ClockTime>) -> Self {
1412 Self {
1413 builder: self.builder.property("max-time", max_time),
1414 ..self
1415 }
1416 }
1417
1418 #[cfg(feature = "v1_24")]
1419 #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))]
1420 pub fn max_bytes(self, max_bytes: u64) -> Self {
1421 Self {
1422 builder: self.builder.property("max-bytes", max_bytes),
1423 ..self
1424 }
1425 }
1426
1427 #[cfg(feature = "v1_28")]
1428 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
1429 pub fn leaky_type(self, leaky_type: crate::AppLeakyType) -> Self {
1430 Self {
1431 builder: self.builder.property("leaky-type", leaky_type),
1432 ..self
1433 }
1434 }
1435
1436 #[cfg(feature = "v1_28")]
1437 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
1438 pub fn silent(self, silent: bool) -> Self {
1439 Self {
1440 builder: self.builder.property("silent", silent),
1441 ..self
1442 }
1443 }
1444
1445 #[inline]
1450 pub fn property(self, name: &'a str, value: impl Into<glib::Value> + 'a) -> Self {
1451 Self {
1452 builder: self.builder.property(name, value),
1453 ..self
1454 }
1455 }
1456
1457 #[inline]
1460 pub fn property_from_str(self, name: &'a str, value: &'a str) -> Self {
1461 Self {
1462 builder: self.builder.property_from_str(name, value),
1463 ..self
1464 }
1465 }
1466
1467 gst::impl_builder_gvalue_extra_setters!(property_and_name);
1468}