Skip to main content

gstreamer_base/auto/
base_sink.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6use crate::ffi;
7use glib::{
8    prelude::*,
9    signal::{SignalHandlerId, connect_raw},
10    translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15    /// [`BaseSink`][crate::BaseSink] is the base class for sink elements in GStreamer, such as
16    /// xvimagesink or filesink. It is a layer on top of [`gst::Element`][crate::gst::Element] that provides a
17    /// simplified interface to plugin writers. [`BaseSink`][crate::BaseSink] handles many details
18    /// for you, for example: preroll, clock synchronization, state changes,
19    /// activation in push or pull mode, and queries.
20    ///
21    /// In most cases, when writing sink elements, there is no need to implement
22    /// class methods from [`gst::Element`][crate::gst::Element] or to set functions on pads, because the
23    /// [`BaseSink`][crate::BaseSink] infrastructure should be sufficient.
24    ///
25    /// [`BaseSink`][crate::BaseSink] provides support for exactly one sink pad, which should be
26    /// named "sink". A sink implementation (subclass of [`BaseSink`][crate::BaseSink]) should
27    /// install a pad template in its class_init function, like so:
28    ///
29    ///
30    /// **⚠️ The following code is in C ⚠️**
31    ///
32    /// ```C
33    /// static void
34    /// my_element_class_init (GstMyElementClass *klass)
35    /// {
36    ///   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
37    ///
38    ///   // sinktemplate should be a #GstStaticPadTemplate with direction
39    ///   // %GST_PAD_SINK and name "sink"
40    ///   gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
41    ///
42    ///   gst_element_class_set_static_metadata (gstelement_class,
43    ///       "Sink name",
44    ///       "Sink",
45    ///       "My Sink element",
46    ///       "The author <my.sink@my.email>");
47    /// }
48    /// ```
49    ///
50    /// [`BaseSink`][crate::BaseSink] will handle the prerolling correctly. This means that it will
51    /// return [`gst::StateChangeReturn::Async`][crate::gst::StateChangeReturn::Async] from a state change to PAUSED until the first
52    /// buffer arrives in this element. The base class will call the
53    /// `GstBaseSinkClass::preroll` vmethod with this preroll buffer and will then
54    /// commit the state change to the next asynchronously pending state.
55    ///
56    /// When the element is set to PLAYING, [`BaseSink`][crate::BaseSink] will synchronise on the
57    /// clock using the times returned from `GstBaseSinkClass::get_times`. If this
58    /// function returns `GST_CLOCK_TIME_NONE` for the start time, no synchronisation
59    /// will be done. Synchronisation can be disabled entirely by setting the object
60    /// [`sync`][struct@crate::BaseSink#sync] property to [`false`].
61    ///
62    /// After synchronisation the virtual method `GstBaseSinkClass::render` will be
63    /// called. Subclasses should minimally implement this method.
64    ///
65    /// Subclasses that synchronise on the clock in the `GstBaseSinkClass::render`
66    /// method are supported as well. These classes typically receive a buffer in
67    /// the render method and can then potentially block on the clock while
68    /// rendering. A typical example is an audiosink.
69    /// These subclasses can use [`BaseSinkExt::wait_preroll()`][crate::prelude::BaseSinkExt::wait_preroll()] to perform the
70    /// blocking wait.
71    ///
72    /// Upon receiving the EOS event in the PLAYING state, [`BaseSink`][crate::BaseSink] will wait
73    /// for the clock to reach the time indicated by the stop time of the last
74    /// `GstBaseSinkClass::get_times` call before posting an EOS message. When the
75    /// element receives EOS in PAUSED, preroll completes, the event is queued and an
76    /// EOS message is posted when going to PLAYING.
77    ///
78    /// [`BaseSink`][crate::BaseSink] will internally use the [`gst::EventType::Segment`][crate::gst::EventType::Segment] events to schedule
79    /// synchronisation and clipping of buffers. Buffers that fall completely outside
80    /// of the current segment are dropped. Buffers that fall partially in the
81    /// segment are rendered (and prerolled). Subclasses should do any subbuffer
82    /// clipping themselves when needed.
83    ///
84    /// [`BaseSink`][crate::BaseSink] will by default report the current playback position in
85    /// [`gst::Format::Time`][crate::gst::Format::Time] based on the current clock time and segment information.
86    /// If no clock has been set on the element, the query will be forwarded
87    /// upstream.
88    ///
89    /// The `GstBaseSinkClass::set_caps` function will be called when the subclass
90    /// should configure itself to process a specific media type.
91    ///
92    /// The `GstBaseSinkClass::start` and `GstBaseSinkClass::stop` virtual methods
93    /// will be called when resources should be allocated. Any
94    /// `GstBaseSinkClass::preroll`, `GstBaseSinkClass::render` and
95    /// `GstBaseSinkClass::set_caps` function will be called between the
96    /// `GstBaseSinkClass::start` and `GstBaseSinkClass::stop` calls.
97    ///
98    /// The `GstBaseSinkClass::event` virtual method will be called when an event is
99    /// received by [`BaseSink`][crate::BaseSink]. Normally this method should only be overridden by
100    /// very specific elements (such as file sinks) which need to handle the
101    /// newsegment event specially.
102    ///
103    /// The `GstBaseSinkClass::unlock` method is called when the elements should
104    /// unblock any blocking operations they perform in the
105    /// `GstBaseSinkClass::render` method. This is mostly useful when the
106    /// `GstBaseSinkClass::render` method performs a blocking write on a file
107    /// descriptor, for example.
108    ///
109    /// The [`max-lateness`][struct@crate::BaseSink#max-lateness] property affects how the sink deals with
110    /// buffers that arrive too late in the sink. A buffer arrives too late in the
111    /// sink when the presentation time (as a combination of the last segment, buffer
112    /// timestamp and element base_time) plus the duration is before the current
113    /// time of the clock.
114    /// If the frame is later than max-lateness, the sink will drop the buffer
115    /// without calling the render method.
116    /// This feature is disabled if sync is disabled, the
117    /// `GstBaseSinkClass::get_times` method does not return a valid start time or
118    /// max-lateness is set to -1 (the default).
119    /// Subclasses can use [`BaseSinkExt::set_max_lateness()`][crate::prelude::BaseSinkExt::set_max_lateness()] to configure the
120    /// max-lateness value.
121    ///
122    /// The [`qos`][struct@crate::BaseSink#qos] property will enable the quality-of-service features of
123    /// the basesink which gather statistics about the real-time performance of the
124    /// clock synchronisation. For each buffer received in the sink, statistics are
125    /// gathered and a QOS event is sent upstream with these numbers. This
126    /// information can then be used by upstream elements to reduce their processing
127    /// rate, for example.
128    ///
129    /// The [`async`][struct@crate::BaseSink#async] property can be used to instruct the sink to never
130    /// perform an ASYNC state change. This feature is mostly usable when dealing
131    /// with non-synchronized streams or sparse streams.
132    ///
133    /// This is an Abstract Base Class, you cannot instantiate it.
134    ///
135    /// ## Properties
136    ///
137    ///
138    /// #### `async`
139    ///  If set to [`true`], the basesink will perform asynchronous state changes.
140    /// When set to [`false`], the sink will not signal the parent when it prerolls.
141    /// Use this option when dealing with sparse streams or when synchronisation is
142    /// not required.
143    ///
144    /// Readable | Writable
145    ///
146    ///
147    /// #### `blocksize`
148    ///  The amount of bytes to pull when operating in pull mode.
149    ///
150    /// Readable | Writable
151    ///
152    ///
153    /// #### `enable-last-sample`
154    ///  Enable the last-sample property. If [`false`], basesink doesn't keep a
155    /// reference to the last buffer arrived and the last-sample property is always
156    /// set to [`None`]. This can be useful if you need buffers to be released as soon
157    /// as possible, eg. if you're using a buffer pool.
158    ///
159    /// Readable | Writable
160    ///
161    ///
162    /// #### `enable-last-sample-notify`
163    ///  Enable emission of the "notify::last-sample" signal. This is disabled by
164    /// default as it can be expensive: the notification is emitted for every
165    /// buffer that updates the last sample. It has no effect unless
166    /// [`enable-last-sample`][struct@crate::BaseSink#enable-last-sample] is also [`true`].
167    ///
168    /// Readable | Writable
169    ///
170    ///
171    /// #### `last-sample`
172    ///  The last buffer that arrived in the sink and was used for preroll or for
173    /// rendering. This property can be used to generate thumbnails. This property
174    /// can be [`None`] when the sink has not yet received a buffer.
175    ///
176    /// Readable
177    ///
178    ///
179    /// #### `max-bitrate`
180    ///  Control the maximum amount of bits that will be rendered per second.
181    /// Setting this property to a value bigger than 0 will make the sink delay
182    /// rendering of the buffers when it would exceed to max-bitrate.
183    ///
184    /// Readable | Writable
185    ///
186    ///
187    /// #### `max-lateness`
188    ///  Readable | Writable
189    ///
190    ///
191    /// #### `processing-deadline`
192    ///  Maximum amount of time (in nanoseconds) that the pipeline can take
193    /// for processing the buffer. This is added to the latency of live
194    /// pipelines.
195    ///
196    /// Readable | Writable
197    ///
198    ///
199    /// #### `qos`
200    ///  Readable | Writable
201    ///
202    ///
203    /// #### `render-delay`
204    ///  The additional delay between synchronisation and actual rendering of the
205    /// media. This property will add additional latency to the device in order to
206    /// make other sinks compensate for the delay.
207    ///
208    /// Readable | Writable
209    ///
210    ///
211    /// #### `stats`
212    ///  Various [`BaseSink`][crate::BaseSink] statistics. This property returns a [`gst::Structure`][crate::gst::Structure]
213    /// with name `application/x-gst-base-sink-stats` with the following fields:
214    ///
215    /// - "average-rate" G_TYPE_DOUBLE average frame rate
216    /// - "dropped" G_TYPE_UINT64 Number of dropped frames
217    /// - "rendered" G_TYPE_UINT64 Number of rendered frames
218    ///
219    /// Readable
220    ///
221    ///
222    /// #### `sync`
223    ///  Readable | Writable
224    ///
225    ///
226    /// #### `throttle-time`
227    ///  The time to insert between buffers. This property can be used to control
228    /// the maximum amount of buffers per second to render. Setting this property
229    /// to a value bigger than 0 will make the sink create THROTTLE QoS events.
230    ///
231    /// Readable | Writable
232    ///
233    ///
234    /// #### `ts-offset`
235    ///  Controls the final synchronisation, a negative value will render the buffer
236    /// earlier while a positive value delays playback. This property can be
237    /// used to fix synchronisation in bad files.
238    ///
239    /// Readable | Writable
240    /// <details><summary><h4>Object</h4></summary>
241    ///
242    ///
243    /// #### `name`
244    ///  Readable | Writable | Construct
245    ///
246    ///
247    /// #### `parent`
248    ///  The parent of the object. Please note, that when changing the 'parent'
249    /// property, we don't emit [`notify`][struct@crate::glib::Object#notify] and [`deep-notify`][struct@crate::gst::Object#deep-notify]
250    /// signals due to locking issues. In some cases one can use
251    /// `GstBin::element-added` or `GstBin::element-removed` signals on the parent to
252    /// achieve a similar effect.
253    ///
254    /// Readable | Writable
255    /// </details>
256    ///
257    /// # Implements
258    ///
259    /// [`BaseSinkExt`][trait@crate::prelude::BaseSinkExt], [`trait@gst::prelude::ElementExt`], [`trait@gst::prelude::ObjectExt`], [`trait@glib::ObjectExt`], [`BaseSinkExtManual`][trait@crate::prelude::BaseSinkExtManual]
260    #[doc(alias = "GstBaseSink")]
261    pub struct BaseSink(Object<ffi::GstBaseSink, ffi::GstBaseSinkClass>) @extends gst::Element, gst::Object;
262
263    match fn {
264        type_ => || ffi::gst_base_sink_get_type(),
265    }
266}
267
268impl BaseSink {
269    pub const NONE: Option<&'static BaseSink> = None;
270}
271
272unsafe impl Send for BaseSink {}
273unsafe impl Sync for BaseSink {}
274
275/// Trait containing all [`struct@BaseSink`] methods.
276///
277/// # Implementors
278///
279/// [`BaseSink`][struct@crate::BaseSink]
280pub trait BaseSinkExt: IsA<BaseSink> + 'static {
281    //#[doc(alias = "gst_base_sink_do_preroll")]
282    //fn do_preroll(&self, obj: /*Ignored*/&gst::MiniObject) -> Result<gst::FlowSuccess, gst::FlowError> {
283    //    unsafe { TODO: call ffi:gst_base_sink_do_preroll() }
284    //}
285
286    /// Get the number of bytes that the sink will pull when it is operating in pull
287    /// mode.
288    ///
289    /// # Returns
290    ///
291    /// the number of bytes `self` will pull in pull mode.
292    #[doc(alias = "gst_base_sink_get_blocksize")]
293    #[doc(alias = "get_blocksize")]
294    fn blocksize(&self) -> u32 {
295        unsafe { ffi::gst_base_sink_get_blocksize(self.as_ref().to_glib_none().0) }
296    }
297
298    /// Checks if `self` is currently configured to drop buffers which are outside
299    /// the current segment
300    ///
301    /// # Returns
302    ///
303    /// [`true`] if the sink is configured to drop buffers outside the
304    /// current segment.
305    #[doc(alias = "gst_base_sink_get_drop_out_of_segment")]
306    #[doc(alias = "get_drop_out_of_segment")]
307    fn drops_out_of_segment(&self) -> bool {
308        unsafe {
309            from_glib(ffi::gst_base_sink_get_drop_out_of_segment(
310                self.as_ref().to_glib_none().0,
311            ))
312        }
313    }
314
315    /// Get the last sample that arrived in the sink and was used for preroll or for
316    /// rendering. This property can be used to generate thumbnails.
317    ///
318    /// The [`gst::Caps`][crate::gst::Caps] on the sample can be used to determine the type of the buffer.
319    ///
320    /// Free-function: gst_sample_unref
321    ///
322    /// # Returns
323    ///
324    /// a [`gst::Sample`][crate::gst::Sample]. `gst_sample_unref()` after
325    ///  usage. This function returns [`None`] when no buffer has arrived in the
326    ///  sink yet or when the sink is not in PAUSED or PLAYING.
327    #[doc(alias = "gst_base_sink_get_last_sample")]
328    #[doc(alias = "get_last_sample")]
329    #[doc(alias = "last-sample")]
330    fn last_sample(&self) -> Option<gst::Sample> {
331        unsafe {
332            from_glib_full(ffi::gst_base_sink_get_last_sample(
333                self.as_ref().to_glib_none().0,
334            ))
335        }
336    }
337
338    /// Get the currently configured latency.
339    ///
340    /// # Returns
341    ///
342    /// The configured latency.
343    #[doc(alias = "gst_base_sink_get_latency")]
344    #[doc(alias = "get_latency")]
345    fn latency(&self) -> gst::ClockTime {
346        unsafe {
347            try_from_glib(ffi::gst_base_sink_get_latency(
348                self.as_ref().to_glib_none().0,
349            ))
350            .expect("mandatory glib value is None")
351        }
352    }
353
354    /// Get the maximum amount of bits per second that the sink will render.
355    ///
356    /// # Returns
357    ///
358    /// the maximum number of bits per second `self` will render.
359    #[doc(alias = "gst_base_sink_get_max_bitrate")]
360    #[doc(alias = "get_max_bitrate")]
361    #[doc(alias = "max-bitrate")]
362    fn max_bitrate(&self) -> u64 {
363        unsafe { ffi::gst_base_sink_get_max_bitrate(self.as_ref().to_glib_none().0) }
364    }
365
366    /// Gets the max lateness value. See [`set_max_lateness()`][Self::set_max_lateness()] for
367    /// more details.
368    ///
369    /// # Returns
370    ///
371    /// The maximum time in nanoseconds that a buffer can be late
372    /// before it is dropped and not rendered. A value of -1 means an
373    /// unlimited time.
374    #[doc(alias = "gst_base_sink_get_max_lateness")]
375    #[doc(alias = "get_max_lateness")]
376    #[doc(alias = "max-lateness")]
377    fn max_lateness(&self) -> i64 {
378        unsafe { ffi::gst_base_sink_get_max_lateness(self.as_ref().to_glib_none().0) }
379    }
380
381    /// Get the processing deadline of `self`. see
382    /// [`set_processing_deadline()`][Self::set_processing_deadline()] for more information about
383    /// the processing deadline.
384    ///
385    /// # Returns
386    ///
387    /// the processing deadline
388    #[cfg(feature = "v1_16")]
389    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
390    #[doc(alias = "gst_base_sink_get_processing_deadline")]
391    #[doc(alias = "get_processing_deadline")]
392    #[doc(alias = "processing-deadline")]
393    fn processing_deadline(&self) -> gst::ClockTime {
394        unsafe {
395            try_from_glib(ffi::gst_base_sink_get_processing_deadline(
396                self.as_ref().to_glib_none().0,
397            ))
398            .expect("mandatory glib value is None")
399        }
400    }
401
402    /// Get the render delay of `self`. see [`set_render_delay()`][Self::set_render_delay()] for more
403    /// information about the render delay.
404    ///
405    /// # Returns
406    ///
407    /// the render delay of `self`.
408    #[doc(alias = "gst_base_sink_get_render_delay")]
409    #[doc(alias = "get_render_delay")]
410    #[doc(alias = "render-delay")]
411    fn render_delay(&self) -> gst::ClockTime {
412        unsafe {
413            try_from_glib(ffi::gst_base_sink_get_render_delay(
414                self.as_ref().to_glib_none().0,
415            ))
416            .expect("mandatory glib value is None")
417        }
418    }
419
420    /// Return various [`BaseSink`][crate::BaseSink] statistics. This function returns a [`gst::Structure`][crate::gst::Structure]
421    /// with name `application/x-gst-base-sink-stats` with the following fields:
422    ///
423    /// - "average-rate" G_TYPE_DOUBLE average frame rate
424    /// - "dropped" G_TYPE_UINT64 Number of dropped frames
425    /// - "rendered" G_TYPE_UINT64 Number of rendered frames
426    ///
427    /// # Returns
428    ///
429    /// pointer to [`gst::Structure`][crate::gst::Structure]
430    #[cfg(feature = "v1_18")]
431    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
432    #[doc(alias = "gst_base_sink_get_stats")]
433    #[doc(alias = "get_stats")]
434    fn stats(&self) -> gst::Structure {
435        unsafe { from_glib_full(ffi::gst_base_sink_get_stats(self.as_ref().to_glib_none().0)) }
436    }
437
438    /// Checks if `self` is currently configured to synchronize against the
439    /// clock.
440    ///
441    /// # Returns
442    ///
443    /// [`true`] if the sink is configured to synchronize against the clock.
444    #[doc(alias = "gst_base_sink_get_sync")]
445    #[doc(alias = "get_sync")]
446    #[doc(alias = "sync")]
447    fn is_sync(&self) -> bool {
448        unsafe { from_glib(ffi::gst_base_sink_get_sync(self.as_ref().to_glib_none().0)) }
449    }
450
451    /// Get the time that will be inserted between frames to control the
452    /// maximum buffers per second.
453    ///
454    /// # Returns
455    ///
456    /// the number of nanoseconds `self` will put between frames.
457    #[doc(alias = "gst_base_sink_get_throttle_time")]
458    #[doc(alias = "get_throttle_time")]
459    #[doc(alias = "throttle-time")]
460    fn throttle_time(&self) -> u64 {
461        unsafe { ffi::gst_base_sink_get_throttle_time(self.as_ref().to_glib_none().0) }
462    }
463
464    /// Get the synchronisation offset of `self`.
465    ///
466    /// # Returns
467    ///
468    /// The synchronisation offset.
469    #[doc(alias = "gst_base_sink_get_ts_offset")]
470    #[doc(alias = "get_ts_offset")]
471    #[doc(alias = "ts-offset")]
472    fn ts_offset(&self) -> gst::ClockTimeDiff {
473        unsafe { ffi::gst_base_sink_get_ts_offset(self.as_ref().to_glib_none().0) }
474    }
475
476    /// Set the number of bytes that the sink will pull when it is operating in pull
477    /// mode.
478    /// ## `blocksize`
479    /// the blocksize in bytes
480    #[doc(alias = "gst_base_sink_set_blocksize")]
481    #[doc(alias = "blocksize")]
482    fn set_blocksize(&self, blocksize: u32) {
483        unsafe {
484            ffi::gst_base_sink_set_blocksize(self.as_ref().to_glib_none().0, blocksize);
485        }
486    }
487
488    /// Configure `self` to drop buffers which are outside the current segment
489    /// ## `drop_out_of_segment`
490    /// drop buffers outside the segment
491    #[doc(alias = "gst_base_sink_set_drop_out_of_segment")]
492    fn set_drop_out_of_segment(&self, drop_out_of_segment: bool) {
493        unsafe {
494            ffi::gst_base_sink_set_drop_out_of_segment(
495                self.as_ref().to_glib_none().0,
496                drop_out_of_segment.into_glib(),
497            );
498        }
499    }
500
501    /// Set the maximum amount of bits per second that the sink will render.
502    /// ## `max_bitrate`
503    /// the max_bitrate in bits per second
504    #[doc(alias = "gst_base_sink_set_max_bitrate")]
505    #[doc(alias = "max-bitrate")]
506    fn set_max_bitrate(&self, max_bitrate: u64) {
507        unsafe {
508            ffi::gst_base_sink_set_max_bitrate(self.as_ref().to_glib_none().0, max_bitrate);
509        }
510    }
511
512    /// Sets the new max lateness value to `max_lateness`. This value is
513    /// used to decide if a buffer should be dropped or not based on the
514    /// buffer timestamp and the current clock time. A value of -1 means
515    /// an unlimited time.
516    /// ## `max_lateness`
517    /// the new max lateness value.
518    #[doc(alias = "gst_base_sink_set_max_lateness")]
519    #[doc(alias = "max-lateness")]
520    fn set_max_lateness(&self, max_lateness: i64) {
521        unsafe {
522            ffi::gst_base_sink_set_max_lateness(self.as_ref().to_glib_none().0, max_lateness);
523        }
524    }
525
526    /// Maximum amount of time (in nanoseconds) that the pipeline can take
527    /// for processing the buffer. This is added to the latency of live
528    /// pipelines.
529    ///
530    /// This function is usually called by subclasses.
531    /// ## `processing_deadline`
532    /// the new processing deadline in nanoseconds.
533    #[cfg(feature = "v1_16")]
534    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
535    #[doc(alias = "gst_base_sink_set_processing_deadline")]
536    #[doc(alias = "processing-deadline")]
537    fn set_processing_deadline(&self, processing_deadline: gst::ClockTime) {
538        unsafe {
539            ffi::gst_base_sink_set_processing_deadline(
540                self.as_ref().to_glib_none().0,
541                processing_deadline.into_glib(),
542            );
543        }
544    }
545
546    /// Set the render delay in `self` to `delay`. The render delay is the time
547    /// between actual rendering of a buffer and its synchronisation time. Some
548    /// devices might delay media rendering which can be compensated for with this
549    /// function.
550    ///
551    /// After calling this function, this sink will report additional latency and
552    /// other sinks will adjust their latency to delay the rendering of their media.
553    ///
554    /// This function is usually called by subclasses.
555    /// ## `delay`
556    /// the new delay
557    #[doc(alias = "gst_base_sink_set_render_delay")]
558    #[doc(alias = "render-delay")]
559    fn set_render_delay(&self, delay: gst::ClockTime) {
560        unsafe {
561            ffi::gst_base_sink_set_render_delay(self.as_ref().to_glib_none().0, delay.into_glib());
562        }
563    }
564
565    /// Configures `self` to synchronize on the clock or not. When
566    /// `sync` is [`false`], incoming samples will be played as fast as
567    /// possible. If `sync` is [`true`], the timestamps of the incoming
568    /// buffers will be used to schedule the exact render time of its
569    /// contents.
570    /// ## `sync`
571    /// the new sync value.
572    #[doc(alias = "gst_base_sink_set_sync")]
573    #[doc(alias = "sync")]
574    fn set_sync(&self, sync: bool) {
575        unsafe {
576            ffi::gst_base_sink_set_sync(self.as_ref().to_glib_none().0, sync.into_glib());
577        }
578    }
579
580    /// Set the time that will be inserted between rendered buffers. This
581    /// can be used to control the maximum buffers per second that the sink
582    /// will render.
583    /// ## `throttle`
584    /// the throttle time in nanoseconds
585    #[doc(alias = "gst_base_sink_set_throttle_time")]
586    #[doc(alias = "throttle-time")]
587    fn set_throttle_time(&self, throttle: u64) {
588        unsafe {
589            ffi::gst_base_sink_set_throttle_time(self.as_ref().to_glib_none().0, throttle);
590        }
591    }
592
593    /// Adjust the synchronisation of `self` with `offset`. A negative value will
594    /// render buffers earlier than their timestamp. A positive value will delay
595    /// rendering. This function can be used to fix playback of badly timestamped
596    /// buffers.
597    /// ## `offset`
598    /// the new offset
599    #[doc(alias = "gst_base_sink_set_ts_offset")]
600    #[doc(alias = "ts-offset")]
601    fn set_ts_offset(&self, offset: gst::ClockTimeDiff) {
602        unsafe {
603            ffi::gst_base_sink_set_ts_offset(self.as_ref().to_glib_none().0, offset);
604        }
605    }
606
607    /// This function will wait for preroll to complete and will then block until `time`
608    /// is reached. It is usually called by subclasses that use their own internal
609    /// synchronisation but want to let some synchronization (like EOS) be handled
610    /// by the base class.
611    ///
612    /// This function should only be called with the PREROLL_LOCK held (like when
613    /// receiving an EOS event in the ::event vmethod or when handling buffers in
614    /// ::render).
615    ///
616    /// The `time` argument should be the running_time of when the timeout should happen
617    /// and will be adjusted with any latency and offset configured in the sink.
618    /// ## `time`
619    /// the running_time to be reached
620    ///
621    /// # Returns
622    ///
623    /// [`gst::FlowReturn`][crate::gst::FlowReturn]
624    ///
625    /// ## `jitter`
626    /// the jitter to be filled with time diff, or [`None`]
627    #[doc(alias = "gst_base_sink_wait")]
628    fn wait(
629        &self,
630        time: impl Into<Option<gst::ClockTime>>,
631    ) -> (Result<gst::FlowSuccess, gst::FlowError>, gst::ClockTimeDiff) {
632        unsafe {
633            let mut jitter = std::mem::MaybeUninit::uninit();
634            let ret = try_from_glib(ffi::gst_base_sink_wait(
635                self.as_ref().to_glib_none().0,
636                time.into().into_glib(),
637                jitter.as_mut_ptr(),
638            ));
639            (ret, jitter.assume_init())
640        }
641    }
642
643    /// This function will block until `time` is reached. It is usually called by
644    /// subclasses that use their own internal synchronisation.
645    ///
646    /// If `time` is not valid, no synchronisation is done and [`gst::ClockReturn::Badtime`][crate::gst::ClockReturn::Badtime] is
647    /// returned. Likewise, if synchronisation is disabled in the element or there
648    /// is no clock, no synchronisation is done and [`gst::ClockReturn::Badtime`][crate::gst::ClockReturn::Badtime] is returned.
649    ///
650    /// This function should only be called with the PREROLL_LOCK held, like when
651    /// receiving an EOS event in the `GstBaseSinkClass::event` vmethod or when
652    /// receiving a buffer in
653    /// the `GstBaseSinkClass::render` vmethod.
654    ///
655    /// The `time` argument should be the running_time of when this method should
656    /// return and is not adjusted with any latency or offset configured in the
657    /// sink.
658    /// ## `time`
659    /// the running_time to be reached
660    ///
661    /// # Returns
662    ///
663    /// [`gst::ClockReturn`][crate::gst::ClockReturn]
664    ///
665    /// ## `jitter`
666    /// the jitter to be filled with time diff, or [`None`]
667    #[doc(alias = "gst_base_sink_wait_clock")]
668    fn wait_clock(
669        &self,
670        time: gst::ClockTime,
671    ) -> (
672        Result<gst::ClockSuccess, gst::ClockError>,
673        gst::ClockTimeDiff,
674    ) {
675        unsafe {
676            let mut jitter = std::mem::MaybeUninit::uninit();
677            let ret = try_from_glib(ffi::gst_base_sink_wait_clock(
678                self.as_ref().to_glib_none().0,
679                time.into_glib(),
680                jitter.as_mut_ptr(),
681            ));
682            (ret, jitter.assume_init())
683        }
684    }
685
686    /// If the `GstBaseSinkClass::render` method performs its own synchronisation
687    /// against the clock it must unblock when going from PLAYING to the PAUSED state
688    /// and call this method before continuing to render the remaining data.
689    ///
690    /// If the `GstBaseSinkClass::render` method can block on something else than
691    /// the clock, it must also be ready to unblock immediately on
692    /// the `GstBaseSinkClass::unlock` method and cause the
693    /// `GstBaseSinkClass::render` method to immediately call this function.
694    /// In this case, the subclass must be prepared to continue rendering where it
695    /// left off if this function returns [`gst::FlowReturn::Ok`][crate::gst::FlowReturn::Ok].
696    ///
697    /// This function will block until a state change to PLAYING happens (in which
698    /// case this function returns [`gst::FlowReturn::Ok`][crate::gst::FlowReturn::Ok]) or the processing must be stopped due
699    /// to a state change to READY or a FLUSH event (in which case this function
700    /// returns [`gst::FlowReturn::Flushing`][crate::gst::FlowReturn::Flushing]).
701    ///
702    /// This function should only be called with the PREROLL_LOCK held, like in the
703    /// render function.
704    ///
705    /// # Returns
706    ///
707    /// [`gst::FlowReturn::Ok`][crate::gst::FlowReturn::Ok] if the preroll completed and processing can
708    /// continue. Any other return value should be returned from the render vmethod.
709    #[doc(alias = "gst_base_sink_wait_preroll")]
710    fn wait_preroll(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
711        unsafe {
712            try_from_glib(ffi::gst_base_sink_wait_preroll(
713                self.as_ref().to_glib_none().0,
714            ))
715        }
716    }
717
718    /// If set to [`true`], the basesink will perform asynchronous state changes.
719    /// When set to [`false`], the sink will not signal the parent when it prerolls.
720    /// Use this option when dealing with sparse streams or when synchronisation is
721    /// not required.
722    #[doc(alias = "async")]
723    fn is_async(&self) -> bool {
724        ObjectExt::property(self.as_ref(), "async")
725    }
726
727    /// If set to [`true`], the basesink will perform asynchronous state changes.
728    /// When set to [`false`], the sink will not signal the parent when it prerolls.
729    /// Use this option when dealing with sparse streams or when synchronisation is
730    /// not required.
731    #[doc(alias = "async")]
732    fn set_async(&self, async_: bool) {
733        ObjectExt::set_property(self.as_ref(), "async", async_)
734    }
735
736    /// Enable the last-sample property. If [`false`], basesink doesn't keep a
737    /// reference to the last buffer arrived and the last-sample property is always
738    /// set to [`None`]. This can be useful if you need buffers to be released as soon
739    /// as possible, eg. if you're using a buffer pool.
740    #[doc(alias = "enable-last-sample")]
741    fn enables_last_sample(&self) -> bool {
742        ObjectExt::property(self.as_ref(), "enable-last-sample")
743    }
744
745    /// Enable the last-sample property. If [`false`], basesink doesn't keep a
746    /// reference to the last buffer arrived and the last-sample property is always
747    /// set to [`None`]. This can be useful if you need buffers to be released as soon
748    /// as possible, eg. if you're using a buffer pool.
749    #[doc(alias = "enable-last-sample")]
750    fn set_enable_last_sample(&self, enable_last_sample: bool) {
751        ObjectExt::set_property(self.as_ref(), "enable-last-sample", enable_last_sample)
752    }
753
754    /// Enable emission of the "notify::last-sample" signal. This is disabled by
755    /// default as it can be expensive: the notification is emitted for every
756    /// buffer that updates the last sample. It has no effect unless
757    /// [`enable-last-sample`][struct@crate::BaseSink#enable-last-sample] is also [`true`].
758    #[cfg(feature = "v1_30")]
759    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
760    #[doc(alias = "enable-last-sample-notify")]
761    fn enables_last_sample_notify(&self) -> bool {
762        ObjectExt::property(self.as_ref(), "enable-last-sample-notify")
763    }
764
765    /// Enable emission of the "notify::last-sample" signal. This is disabled by
766    /// default as it can be expensive: the notification is emitted for every
767    /// buffer that updates the last sample. It has no effect unless
768    /// [`enable-last-sample`][struct@crate::BaseSink#enable-last-sample] is also [`true`].
769    #[cfg(feature = "v1_30")]
770    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
771    #[doc(alias = "enable-last-sample-notify")]
772    fn set_enable_last_sample_notify(&self, enable_last_sample_notify: bool) {
773        ObjectExt::set_property(
774            self.as_ref(),
775            "enable-last-sample-notify",
776            enable_last_sample_notify,
777        )
778    }
779
780    fn is_qos(&self) -> bool {
781        ObjectExt::property(self.as_ref(), "qos")
782    }
783
784    fn set_qos(&self, qos: bool) {
785        ObjectExt::set_property(self.as_ref(), "qos", qos)
786    }
787
788    #[doc(alias = "async")]
789    fn connect_async_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
790        unsafe extern "C" fn notify_async_trampoline<
791            P: IsA<BaseSink>,
792            F: Fn(&P) + Send + Sync + 'static,
793        >(
794            this: *mut ffi::GstBaseSink,
795            _param_spec: glib::ffi::gpointer,
796            f: glib::ffi::gpointer,
797        ) {
798            unsafe {
799                let f: &F = &*(f as *const F);
800                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
801            }
802        }
803        unsafe {
804            let f: Box_<F> = Box_::new(f);
805            connect_raw(
806                self.as_ptr() as *mut _,
807                c"notify::async".as_ptr(),
808                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
809                    notify_async_trampoline::<Self, F> as *const (),
810                )),
811                Box_::into_raw(f),
812            )
813        }
814    }
815
816    #[doc(alias = "blocksize")]
817    fn connect_blocksize_notify<F: Fn(&Self) + Send + Sync + 'static>(
818        &self,
819        f: F,
820    ) -> SignalHandlerId {
821        unsafe extern "C" fn notify_blocksize_trampoline<
822            P: IsA<BaseSink>,
823            F: Fn(&P) + Send + Sync + 'static,
824        >(
825            this: *mut ffi::GstBaseSink,
826            _param_spec: glib::ffi::gpointer,
827            f: glib::ffi::gpointer,
828        ) {
829            unsafe {
830                let f: &F = &*(f as *const F);
831                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
832            }
833        }
834        unsafe {
835            let f: Box_<F> = Box_::new(f);
836            connect_raw(
837                self.as_ptr() as *mut _,
838                c"notify::blocksize".as_ptr(),
839                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
840                    notify_blocksize_trampoline::<Self, F> as *const (),
841                )),
842                Box_::into_raw(f),
843            )
844        }
845    }
846
847    #[doc(alias = "enable-last-sample")]
848    fn connect_enable_last_sample_notify<F: Fn(&Self) + Send + Sync + 'static>(
849        &self,
850        f: F,
851    ) -> SignalHandlerId {
852        unsafe extern "C" fn notify_enable_last_sample_trampoline<
853            P: IsA<BaseSink>,
854            F: Fn(&P) + Send + Sync + 'static,
855        >(
856            this: *mut ffi::GstBaseSink,
857            _param_spec: glib::ffi::gpointer,
858            f: glib::ffi::gpointer,
859        ) {
860            unsafe {
861                let f: &F = &*(f as *const F);
862                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
863            }
864        }
865        unsafe {
866            let f: Box_<F> = Box_::new(f);
867            connect_raw(
868                self.as_ptr() as *mut _,
869                c"notify::enable-last-sample".as_ptr(),
870                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
871                    notify_enable_last_sample_trampoline::<Self, F> as *const (),
872                )),
873                Box_::into_raw(f),
874            )
875        }
876    }
877
878    #[cfg(feature = "v1_30")]
879    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
880    #[doc(alias = "enable-last-sample-notify")]
881    fn connect_enable_last_sample_notify_notify<F: Fn(&Self) + Send + Sync + 'static>(
882        &self,
883        f: F,
884    ) -> SignalHandlerId {
885        unsafe extern "C" fn notify_enable_last_sample_notify_trampoline<
886            P: IsA<BaseSink>,
887            F: Fn(&P) + Send + Sync + 'static,
888        >(
889            this: *mut ffi::GstBaseSink,
890            _param_spec: glib::ffi::gpointer,
891            f: glib::ffi::gpointer,
892        ) {
893            unsafe {
894                let f: &F = &*(f as *const F);
895                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
896            }
897        }
898        unsafe {
899            let f: Box_<F> = Box_::new(f);
900            connect_raw(
901                self.as_ptr() as *mut _,
902                c"notify::enable-last-sample-notify".as_ptr(),
903                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
904                    notify_enable_last_sample_notify_trampoline::<Self, F> as *const (),
905                )),
906                Box_::into_raw(f),
907            )
908        }
909    }
910
911    #[doc(alias = "last-sample")]
912    fn connect_last_sample_notify<F: Fn(&Self) + Send + Sync + 'static>(
913        &self,
914        f: F,
915    ) -> SignalHandlerId {
916        unsafe extern "C" fn notify_last_sample_trampoline<
917            P: IsA<BaseSink>,
918            F: Fn(&P) + Send + Sync + 'static,
919        >(
920            this: *mut ffi::GstBaseSink,
921            _param_spec: glib::ffi::gpointer,
922            f: glib::ffi::gpointer,
923        ) {
924            unsafe {
925                let f: &F = &*(f as *const F);
926                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
927            }
928        }
929        unsafe {
930            let f: Box_<F> = Box_::new(f);
931            connect_raw(
932                self.as_ptr() as *mut _,
933                c"notify::last-sample".as_ptr(),
934                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
935                    notify_last_sample_trampoline::<Self, F> as *const (),
936                )),
937                Box_::into_raw(f),
938            )
939        }
940    }
941
942    #[doc(alias = "max-bitrate")]
943    fn connect_max_bitrate_notify<F: Fn(&Self) + Send + Sync + 'static>(
944        &self,
945        f: F,
946    ) -> SignalHandlerId {
947        unsafe extern "C" fn notify_max_bitrate_trampoline<
948            P: IsA<BaseSink>,
949            F: Fn(&P) + Send + Sync + 'static,
950        >(
951            this: *mut ffi::GstBaseSink,
952            _param_spec: glib::ffi::gpointer,
953            f: glib::ffi::gpointer,
954        ) {
955            unsafe {
956                let f: &F = &*(f as *const F);
957                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
958            }
959        }
960        unsafe {
961            let f: Box_<F> = Box_::new(f);
962            connect_raw(
963                self.as_ptr() as *mut _,
964                c"notify::max-bitrate".as_ptr(),
965                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
966                    notify_max_bitrate_trampoline::<Self, F> as *const (),
967                )),
968                Box_::into_raw(f),
969            )
970        }
971    }
972
973    #[doc(alias = "max-lateness")]
974    fn connect_max_lateness_notify<F: Fn(&Self) + Send + Sync + 'static>(
975        &self,
976        f: F,
977    ) -> SignalHandlerId {
978        unsafe extern "C" fn notify_max_lateness_trampoline<
979            P: IsA<BaseSink>,
980            F: Fn(&P) + Send + Sync + 'static,
981        >(
982            this: *mut ffi::GstBaseSink,
983            _param_spec: glib::ffi::gpointer,
984            f: glib::ffi::gpointer,
985        ) {
986            unsafe {
987                let f: &F = &*(f as *const F);
988                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
989            }
990        }
991        unsafe {
992            let f: Box_<F> = Box_::new(f);
993            connect_raw(
994                self.as_ptr() as *mut _,
995                c"notify::max-lateness".as_ptr(),
996                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
997                    notify_max_lateness_trampoline::<Self, F> as *const (),
998                )),
999                Box_::into_raw(f),
1000            )
1001        }
1002    }
1003
1004    #[cfg(feature = "v1_16")]
1005    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1006    #[doc(alias = "processing-deadline")]
1007    fn connect_processing_deadline_notify<F: Fn(&Self) + Send + Sync + 'static>(
1008        &self,
1009        f: F,
1010    ) -> SignalHandlerId {
1011        unsafe extern "C" fn notify_processing_deadline_trampoline<
1012            P: IsA<BaseSink>,
1013            F: Fn(&P) + Send + Sync + 'static,
1014        >(
1015            this: *mut ffi::GstBaseSink,
1016            _param_spec: glib::ffi::gpointer,
1017            f: glib::ffi::gpointer,
1018        ) {
1019            unsafe {
1020                let f: &F = &*(f as *const F);
1021                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
1022            }
1023        }
1024        unsafe {
1025            let f: Box_<F> = Box_::new(f);
1026            connect_raw(
1027                self.as_ptr() as *mut _,
1028                c"notify::processing-deadline".as_ptr(),
1029                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1030                    notify_processing_deadline_trampoline::<Self, F> as *const (),
1031                )),
1032                Box_::into_raw(f),
1033            )
1034        }
1035    }
1036
1037    #[doc(alias = "qos")]
1038    fn connect_qos_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
1039        unsafe extern "C" fn notify_qos_trampoline<
1040            P: IsA<BaseSink>,
1041            F: Fn(&P) + Send + Sync + 'static,
1042        >(
1043            this: *mut ffi::GstBaseSink,
1044            _param_spec: glib::ffi::gpointer,
1045            f: glib::ffi::gpointer,
1046        ) {
1047            unsafe {
1048                let f: &F = &*(f as *const F);
1049                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
1050            }
1051        }
1052        unsafe {
1053            let f: Box_<F> = Box_::new(f);
1054            connect_raw(
1055                self.as_ptr() as *mut _,
1056                c"notify::qos".as_ptr(),
1057                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1058                    notify_qos_trampoline::<Self, F> as *const (),
1059                )),
1060                Box_::into_raw(f),
1061            )
1062        }
1063    }
1064
1065    #[doc(alias = "render-delay")]
1066    fn connect_render_delay_notify<F: Fn(&Self) + Send + Sync + 'static>(
1067        &self,
1068        f: F,
1069    ) -> SignalHandlerId {
1070        unsafe extern "C" fn notify_render_delay_trampoline<
1071            P: IsA<BaseSink>,
1072            F: Fn(&P) + Send + Sync + 'static,
1073        >(
1074            this: *mut ffi::GstBaseSink,
1075            _param_spec: glib::ffi::gpointer,
1076            f: glib::ffi::gpointer,
1077        ) {
1078            unsafe {
1079                let f: &F = &*(f as *const F);
1080                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
1081            }
1082        }
1083        unsafe {
1084            let f: Box_<F> = Box_::new(f);
1085            connect_raw(
1086                self.as_ptr() as *mut _,
1087                c"notify::render-delay".as_ptr(),
1088                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1089                    notify_render_delay_trampoline::<Self, F> as *const (),
1090                )),
1091                Box_::into_raw(f),
1092            )
1093        }
1094    }
1095
1096    #[cfg(feature = "v1_18")]
1097    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1098    #[doc(alias = "stats")]
1099    fn connect_stats_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
1100        unsafe extern "C" fn notify_stats_trampoline<
1101            P: IsA<BaseSink>,
1102            F: Fn(&P) + Send + Sync + 'static,
1103        >(
1104            this: *mut ffi::GstBaseSink,
1105            _param_spec: glib::ffi::gpointer,
1106            f: glib::ffi::gpointer,
1107        ) {
1108            unsafe {
1109                let f: &F = &*(f as *const F);
1110                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
1111            }
1112        }
1113        unsafe {
1114            let f: Box_<F> = Box_::new(f);
1115            connect_raw(
1116                self.as_ptr() as *mut _,
1117                c"notify::stats".as_ptr(),
1118                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1119                    notify_stats_trampoline::<Self, F> as *const (),
1120                )),
1121                Box_::into_raw(f),
1122            )
1123        }
1124    }
1125
1126    #[doc(alias = "sync")]
1127    fn connect_sync_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
1128        unsafe extern "C" fn notify_sync_trampoline<
1129            P: IsA<BaseSink>,
1130            F: Fn(&P) + Send + Sync + 'static,
1131        >(
1132            this: *mut ffi::GstBaseSink,
1133            _param_spec: glib::ffi::gpointer,
1134            f: glib::ffi::gpointer,
1135        ) {
1136            unsafe {
1137                let f: &F = &*(f as *const F);
1138                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
1139            }
1140        }
1141        unsafe {
1142            let f: Box_<F> = Box_::new(f);
1143            connect_raw(
1144                self.as_ptr() as *mut _,
1145                c"notify::sync".as_ptr(),
1146                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1147                    notify_sync_trampoline::<Self, F> as *const (),
1148                )),
1149                Box_::into_raw(f),
1150            )
1151        }
1152    }
1153
1154    #[doc(alias = "throttle-time")]
1155    fn connect_throttle_time_notify<F: Fn(&Self) + Send + Sync + 'static>(
1156        &self,
1157        f: F,
1158    ) -> SignalHandlerId {
1159        unsafe extern "C" fn notify_throttle_time_trampoline<
1160            P: IsA<BaseSink>,
1161            F: Fn(&P) + Send + Sync + 'static,
1162        >(
1163            this: *mut ffi::GstBaseSink,
1164            _param_spec: glib::ffi::gpointer,
1165            f: glib::ffi::gpointer,
1166        ) {
1167            unsafe {
1168                let f: &F = &*(f as *const F);
1169                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
1170            }
1171        }
1172        unsafe {
1173            let f: Box_<F> = Box_::new(f);
1174            connect_raw(
1175                self.as_ptr() as *mut _,
1176                c"notify::throttle-time".as_ptr(),
1177                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1178                    notify_throttle_time_trampoline::<Self, F> as *const (),
1179                )),
1180                Box_::into_raw(f),
1181            )
1182        }
1183    }
1184
1185    #[doc(alias = "ts-offset")]
1186    fn connect_ts_offset_notify<F: Fn(&Self) + Send + Sync + 'static>(
1187        &self,
1188        f: F,
1189    ) -> SignalHandlerId {
1190        unsafe extern "C" fn notify_ts_offset_trampoline<
1191            P: IsA<BaseSink>,
1192            F: Fn(&P) + Send + Sync + 'static,
1193        >(
1194            this: *mut ffi::GstBaseSink,
1195            _param_spec: glib::ffi::gpointer,
1196            f: glib::ffi::gpointer,
1197        ) {
1198            unsafe {
1199                let f: &F = &*(f as *const F);
1200                f(BaseSink::from_glib_borrow(this).unsafe_cast_ref())
1201            }
1202        }
1203        unsafe {
1204            let f: Box_<F> = Box_::new(f);
1205            connect_raw(
1206                self.as_ptr() as *mut _,
1207                c"notify::ts-offset".as_ptr(),
1208                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1209                    notify_ts_offset_trampoline::<Self, F> as *const (),
1210                )),
1211                Box_::into_raw(f),
1212            )
1213        }
1214    }
1215}
1216
1217impl<O: IsA<BaseSink>> BaseSinkExt for O {}