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 {}