gstreamer/auto/bus.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, ClockTime, Message, Object};
7use glib::{
8 object::ObjectType as _,
9 prelude::*,
10 signal::{connect_raw, SignalHandlerId},
11 translate::*,
12};
13use std::boxed::Box as Box_;
14
15glib::wrapper! {
16 /// The [`Bus`][crate::Bus] is an object responsible for delivering [`Message`][crate::Message] packets in
17 /// a first-in first-out way from the streaming threads (see [`Task`][crate::Task]) to the
18 /// application.
19 ///
20 /// Since the application typically only wants to deal with delivery of these
21 /// messages from one thread, the GstBus will marshall the messages between
22 /// different threads. This is important since the actual streaming of media
23 /// is done in another thread than the application.
24 ///
25 /// The GstBus provides support for [`glib::Source`][crate::glib::Source] based notifications. This makes it
26 /// possible to handle the delivery in the glib `GMainLoop`.
27 ///
28 /// The [`glib::Source`][crate::glib::Source] callback function `gst_bus_async_signal_func()` can be used to
29 /// convert all bus messages into signal emissions.
30 ///
31 /// A message is posted on the bus with the [`post()`][Self::post()] method. With the
32 /// [`peek()`][Self::peek()] and [`pop()`][Self::pop()] methods one can look at or retrieve a
33 /// previously posted message.
34 ///
35 /// The bus can be polled with the [`poll()`][Self::poll()] method. This methods blocks
36 /// up to the specified timeout value until one of the specified messages types
37 /// is posted on the bus. The application can then [`pop()`][Self::pop()] the messages
38 /// from the bus to handle them.
39 /// Alternatively the application can register an asynchronous bus function
40 /// using [`add_watch_full()`][Self::add_watch_full()] or [`add_watch()`][Self::add_watch()]. This function will
41 /// install a [`glib::Source`][crate::glib::Source] in the default glib main loop and will deliver messages
42 /// a short while after they have been posted. Note that the main loop should
43 /// be running for the asynchronous callbacks.
44 ///
45 /// It is also possible to get messages from the bus without any thread
46 /// marshalling with the [`set_sync_handler()`][Self::set_sync_handler()] method. This makes it
47 /// possible to react to a message in the same thread that posted the
48 /// message on the bus. This should only be used if the application is able
49 /// to deal with messages from different threads.
50 ///
51 /// Every [`Pipeline`][crate::Pipeline] has one bus.
52 ///
53 /// Note that a [`Pipeline`][crate::Pipeline] will set its bus into flushing state when changing
54 /// from READY to NULL state.
55 ///
56 /// ## Properties
57 ///
58 ///
59 /// #### `enable-async`
60 /// Enables async message delivery support for bus watches,
61 /// [`Bus::pop()`][crate::Bus::pop()] and similar API. Without this only the
62 /// synchronous message handlers are called.
63 ///
64 /// This property is used to create the child element buses
65 /// in [`Bin`][crate::Bin].
66 ///
67 /// Writeable | Construct Only
68 /// <details><summary><h4>Object</h4></summary>
69 ///
70 ///
71 /// #### `name`
72 /// Readable | Writeable | Construct
73 ///
74 ///
75 /// #### `parent`
76 /// The parent of the object. Please note, that when changing the 'parent'
77 /// property, we don't emit [`notify`][struct@crate::glib::Object#notify] and [`deep-notify`][struct@crate::Object#deep-notify]
78 /// signals due to locking issues. In some cases one can use
79 /// [`element-added`][struct@crate::Bin#element-added] or [`element-removed`][struct@crate::Bin#element-removed] signals on the parent to
80 /// achieve a similar effect.
81 ///
82 /// Readable | Writeable
83 /// </details>
84 ///
85 /// ## Signals
86 ///
87 ///
88 /// #### `message`
89 /// A message has been posted on the bus. This signal is emitted from a
90 /// [`glib::Source`][crate::glib::Source] added to the mainloop. this signal will only be emitted when
91 /// there is a `GMainLoop` running.
92 ///
93 /// Detailed
94 ///
95 ///
96 /// #### `sync-message`
97 /// A message has been posted on the bus. This signal is emitted from the
98 /// thread that posted the message so one has to be careful with locking.
99 ///
100 /// This signal will not be emitted by default, you have to call
101 /// [`Bus::enable_sync_message_emission()`][crate::Bus::enable_sync_message_emission()] before.
102 ///
103 /// Detailed
104 /// <details><summary><h4>Object</h4></summary>
105 ///
106 ///
107 /// #### `deep-notify`
108 /// The deep notify signal is used to be notified of property changes. It is
109 /// typically attached to the toplevel bin to receive notifications from all
110 /// the elements contained in that bin.
111 ///
112 /// Detailed
113 /// </details>
114 ///
115 /// # Implements
116 ///
117 /// [`GstObjectExt`][trait@crate::prelude::GstObjectExt], [`trait@glib::ObjectExt`]
118 #[doc(alias = "GstBus")]
119 pub struct Bus(Object<ffi::GstBus, ffi::GstBusClass>) @extends Object;
120
121 match fn {
122 type_ => || ffi::gst_bus_get_type(),
123 }
124}
125
126impl Bus {
127 /// Creates a new [`Bus`][crate::Bus] instance.
128 ///
129 /// # Returns
130 ///
131 /// a new [`Bus`][crate::Bus] instance
132 #[doc(alias = "gst_bus_new")]
133 pub fn new() -> Bus {
134 assert_initialized_main_thread!();
135 unsafe { from_glib_full(ffi::gst_bus_new()) }
136 }
137
138 /// Adds a bus signal watch to the default main context with the default priority
139 /// ( `G_PRIORITY_DEFAULT` ). It is also possible to use a non-default
140 /// main context set up using [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()] (before
141 /// one had to create a bus watch source and attach it to the desired main
142 /// context 'manually').
143 ///
144 /// After calling this statement, the bus will emit the "message" signal for each
145 /// message posted on the bus.
146 ///
147 /// This function may be called multiple times. To clean up, the caller is
148 /// responsible for calling [`remove_signal_watch()`][Self::remove_signal_watch()] as many times as this
149 /// function is called.
150 #[doc(alias = "gst_bus_add_signal_watch")]
151 pub fn add_signal_watch(&self) {
152 unsafe {
153 ffi::gst_bus_add_signal_watch(self.to_glib_none().0);
154 }
155 }
156
157 //#[doc(alias = "gst_bus_async_signal_func")]
158 //pub fn async_signal_func(&self, message: &Message, data: /*Unimplemented*/Option<Basic: Pointer>) -> bool {
159 // unsafe { TODO: call ffi:gst_bus_async_signal_func() }
160 //}
161
162 /// Instructs GStreamer to stop emitting the "sync-message" signal for this bus.
163 /// See [`enable_sync_message_emission()`][Self::enable_sync_message_emission()] for more information.
164 ///
165 /// In the event that multiple pieces of code have called
166 /// [`enable_sync_message_emission()`][Self::enable_sync_message_emission()], the sync-message emissions will only
167 /// be stopped after all calls to [`enable_sync_message_emission()`][Self::enable_sync_message_emission()] were
168 /// "cancelled" by calling this function. In this way the semantics are exactly
169 /// the same as `gst_object_ref()` that which calls enable should also call
170 /// disable.
171 #[doc(alias = "gst_bus_disable_sync_message_emission")]
172 pub fn disable_sync_message_emission(&self) {
173 unsafe {
174 ffi::gst_bus_disable_sync_message_emission(self.to_glib_none().0);
175 }
176 }
177
178 /// Instructs GStreamer to emit the "sync-message" signal after running the bus's
179 /// sync handler. This function is here so that code can ensure that they can
180 /// synchronously receive messages without having to affect what the bin's sync
181 /// handler is.
182 ///
183 /// This function may be called multiple times. To clean up, the caller is
184 /// responsible for calling [`disable_sync_message_emission()`][Self::disable_sync_message_emission()] as many times
185 /// as this function is called.
186 ///
187 /// While this function looks similar to [`add_signal_watch()`][Self::add_signal_watch()], it is not
188 /// exactly the same -- this function enables *synchronous* emission of
189 /// signals when messages arrive; [`add_signal_watch()`][Self::add_signal_watch()] adds an idle callback
190 /// to pop messages off the bus *asynchronously*. The sync-message signal
191 /// comes from the thread of whatever object posted the message; the "message"
192 /// signal is marshalled to the main thread via the `GMainLoop`.
193 #[doc(alias = "gst_bus_enable_sync_message_emission")]
194 pub fn enable_sync_message_emission(&self) {
195 unsafe {
196 ffi::gst_bus_enable_sync_message_emission(self.to_glib_none().0);
197 }
198 }
199
200 //#[doc(alias = "gst_bus_get_pollfd")]
201 //#[doc(alias = "get_pollfd")]
202 //pub fn pollfd(&self, fd: /*Ignored*/glib::PollFD) {
203 // unsafe { TODO: call ffi:gst_bus_get_pollfd() }
204 //}
205
206 /// Checks if there are pending messages on the bus that
207 /// should be handled.
208 ///
209 /// # Returns
210 ///
211 /// [`true`] if there are messages on the bus to be handled, [`false`]
212 /// otherwise.
213 #[doc(alias = "gst_bus_have_pending")]
214 pub fn have_pending(&self) -> bool {
215 unsafe { from_glib(ffi::gst_bus_have_pending(self.to_glib_none().0)) }
216 }
217
218 /// Peeks the message on the top of the bus' queue. The message will remain
219 /// on the bus' message queue.
220 ///
221 /// # Returns
222 ///
223 /// the [`Message`][crate::Message] that is on the
224 /// bus, or [`None`] if the bus is empty.
225 #[doc(alias = "gst_bus_peek")]
226 pub fn peek(&self) -> Option<Message> {
227 unsafe { from_glib_full(ffi::gst_bus_peek(self.to_glib_none().0)) }
228 }
229
230 /// Gets a message from the bus.
231 ///
232 /// # Returns
233 ///
234 /// the [`Message`][crate::Message] that is on the
235 /// bus, or [`None`] if the bus is empty.
236 #[doc(alias = "gst_bus_pop")]
237 pub fn pop(&self) -> Option<Message> {
238 unsafe { from_glib_full(ffi::gst_bus_pop(self.to_glib_none().0)) }
239 }
240
241 /// Posts a message on the given bus. Ownership of the message
242 /// is taken by the bus.
243 /// ## `message`
244 /// the [`Message`][crate::Message] to post
245 ///
246 /// # Returns
247 ///
248 /// [`true`] if the message could be posted, [`false`] if the bus is flushing.
249 #[doc(alias = "gst_bus_post")]
250 pub fn post(&self, message: Message) -> Result<(), glib::error::BoolError> {
251 unsafe {
252 glib::result_from_gboolean!(
253 ffi::gst_bus_post(self.to_glib_none().0, message.into_glib_ptr()),
254 "Failed to post message"
255 )
256 }
257 }
258
259 /// Removes a signal watch previously added with [`add_signal_watch()`][Self::add_signal_watch()].
260 #[doc(alias = "gst_bus_remove_signal_watch")]
261 pub fn remove_signal_watch(&self) {
262 unsafe {
263 ffi::gst_bus_remove_signal_watch(self.to_glib_none().0);
264 }
265 }
266
267 /// Removes an installed bus watch from `self`.
268 ///
269 /// # Returns
270 ///
271 /// [`true`] on success or [`false`] if `self` has no event source.
272 #[doc(alias = "gst_bus_remove_watch")]
273 #[allow(dead_code)]
274 pub(crate) fn remove_watch(&self) -> Result<(), glib::error::BoolError> {
275 unsafe {
276 glib::result_from_gboolean!(
277 ffi::gst_bus_remove_watch(self.to_glib_none().0),
278 "Bus has no event source"
279 )
280 }
281 }
282
283 /// If `flushing`, flushes out and unrefs any messages queued in the bus. Releases
284 /// references to the message origin objects. Will flush future messages until
285 /// [`set_flushing()`][Self::set_flushing()] sets `flushing` to [`false`].
286 /// ## `flushing`
287 /// whether or not to flush the bus
288 #[doc(alias = "gst_bus_set_flushing")]
289 pub fn set_flushing(&self, flushing: bool) {
290 unsafe {
291 ffi::gst_bus_set_flushing(self.to_glib_none().0, flushing.into_glib());
292 }
293 }
294
295 //#[doc(alias = "gst_bus_sync_signal_handler")]
296 //pub fn sync_signal_handler(&self, message: &Message, data: /*Unimplemented*/Option<Basic: Pointer>) -> BusSyncReply {
297 // unsafe { TODO: call ffi:gst_bus_sync_signal_handler() }
298 //}
299
300 /// Gets a message from the bus, waiting up to the specified timeout.
301 ///
302 /// If `timeout` is 0, this function behaves like [`pop()`][Self::pop()]. If `timeout` is
303 /// `GST_CLOCK_TIME_NONE`, this function will block forever until a message was
304 /// posted on the bus.
305 /// ## `timeout`
306 /// a timeout
307 ///
308 /// # Returns
309 ///
310 /// the [`Message`][crate::Message] that is on the
311 /// bus after the specified timeout or [`None`] if the bus is empty
312 /// after the timeout expired.
313 #[doc(alias = "gst_bus_timed_pop")]
314 pub fn timed_pop(&self, timeout: impl Into<Option<ClockTime>>) -> Option<Message> {
315 unsafe {
316 from_glib_full(ffi::gst_bus_timed_pop(
317 self.to_glib_none().0,
318 timeout.into().into_glib(),
319 ))
320 }
321 }
322
323 /// A message has been posted on the bus. This signal is emitted from a
324 /// [`glib::Source`][crate::glib::Source] added to the mainloop. this signal will only be emitted when
325 /// there is a `GMainLoop` running.
326 /// ## `message`
327 /// the message that has been posted asynchronously
328 #[doc(alias = "message")]
329 pub fn connect_message<F: Fn(&Self, &Message) + Send + 'static>(
330 &self,
331 detail: Option<&str>,
332 f: F,
333 ) -> SignalHandlerId {
334 unsafe extern "C" fn message_trampoline<F: Fn(&Bus, &Message) + Send + 'static>(
335 this: *mut ffi::GstBus,
336 message: *mut ffi::GstMessage,
337 f: glib::ffi::gpointer,
338 ) {
339 let f: &F = &*(f as *const F);
340 f(&from_glib_borrow(this), &from_glib_borrow(message))
341 }
342 unsafe {
343 let f: Box_<F> = Box_::new(f);
344 let detailed_signal_name = detail.map(|name| format!("message::{name}\0"));
345 let signal_name: &[u8] = detailed_signal_name
346 .as_ref()
347 .map_or(c"message".to_bytes(), |n| n.as_bytes());
348 connect_raw(
349 self.as_ptr() as *mut _,
350 signal_name.as_ptr() as *const _,
351 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
352 message_trampoline::<F> as *const (),
353 )),
354 Box_::into_raw(f),
355 )
356 }
357 }
358
359 /// A message has been posted on the bus. This signal is emitted from the
360 /// thread that posted the message so one has to be careful with locking.
361 ///
362 /// This signal will not be emitted by default, you have to call
363 /// [`enable_sync_message_emission()`][Self::enable_sync_message_emission()] before.
364 /// ## `message`
365 /// the message that has been posted synchronously
366 #[doc(alias = "sync-message")]
367 pub fn connect_sync_message<F: Fn(&Self, &Message) + Send + Sync + 'static>(
368 &self,
369 detail: Option<&str>,
370 f: F,
371 ) -> SignalHandlerId {
372 unsafe extern "C" fn sync_message_trampoline<
373 F: Fn(&Bus, &Message) + Send + Sync + 'static,
374 >(
375 this: *mut ffi::GstBus,
376 message: *mut ffi::GstMessage,
377 f: glib::ffi::gpointer,
378 ) {
379 let f: &F = &*(f as *const F);
380 f(&from_glib_borrow(this), &from_glib_borrow(message))
381 }
382 unsafe {
383 let f: Box_<F> = Box_::new(f);
384 let detailed_signal_name = detail.map(|name| format!("sync-message::{name}\0"));
385 let signal_name: &[u8] = detailed_signal_name
386 .as_ref()
387 .map_or(c"sync-message".to_bytes(), |n| n.as_bytes());
388 connect_raw(
389 self.as_ptr() as *mut _,
390 signal_name.as_ptr() as *const _,
391 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
392 sync_message_trampoline::<F> as *const (),
393 )),
394 Box_::into_raw(f),
395 )
396 }
397 }
398}
399
400impl Default for Bus {
401 fn default() -> Self {
402 Self::new()
403 }
404}
405
406unsafe impl Send for Bus {}
407unsafe impl Sync for Bus {}