1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gstreamer.Bus; 26 27 private import glib.ConstructionException; 28 private import glib.Source; 29 private import gobject.ObjectG; 30 private import gobject.Signals; 31 private import gstreamer.Message; 32 private import gstreamer.ObjectGst; 33 private import gstreamer.c.functions; 34 public import gstreamer.c.types; 35 private import std.algorithm; 36 37 38 /** 39 * The #GstBus is an object responsible for delivering #GstMessage packets in 40 * a first-in first-out way from the streaming threads (see #GstTask) to the 41 * application. 42 * 43 * Since the application typically only wants to deal with delivery of these 44 * messages from one thread, the GstBus will marshall the messages between 45 * different threads. This is important since the actual streaming of media 46 * is done in another thread than the application. 47 * 48 * The GstBus provides support for #GSource based notifications. This makes it 49 * possible to handle the delivery in the glib mainloop. 50 * 51 * The #GSource callback function gst_bus_async_signal_func() can be used to 52 * convert all bus messages into signal emissions. 53 * 54 * A message is posted on the bus with the gst_bus_post() method. With the 55 * gst_bus_peek() and gst_bus_pop() methods one can look at or retrieve a 56 * previously posted message. 57 * 58 * The bus can be polled with the gst_bus_poll() method. This methods blocks 59 * up to the specified timeout value until one of the specified messages types 60 * is posted on the bus. The application can then gst_bus_pop() the messages 61 * from the bus to handle them. 62 * Alternatively the application can register an asynchronous bus function 63 * using gst_bus_add_watch_full() or gst_bus_add_watch(). This function will 64 * install a #GSource in the default glib main loop and will deliver messages 65 * a short while after they have been posted. Note that the main loop should 66 * be running for the asynchronous callbacks. 67 * 68 * It is also possible to get messages from the bus without any thread 69 * marshalling with the gst_bus_set_sync_handler() method. This makes it 70 * possible to react to a message in the same thread that posted the 71 * message on the bus. This should only be used if the application is able 72 * to deal with messages from different threads. 73 * 74 * Every #GstPipeline has one bus. 75 * 76 * Note that a #GstPipeline will set its bus into flushing state when changing 77 * from READY to NULL state. 78 */ 79 public class Bus : ObjectGst 80 { 81 /** the main Gtk struct */ 82 protected GstBus* gstBus; 83 84 /** Get the main Gtk struct */ 85 public GstBus* getBusStruct(bool transferOwnership = false) 86 { 87 if (transferOwnership) 88 ownedRef = false; 89 return gstBus; 90 } 91 92 /** the main Gtk struct as a void* */ 93 protected override void* getStruct() 94 { 95 return cast(void*)gstBus; 96 } 97 98 /** 99 * Sets our main struct and passes it to the parent class. 100 */ 101 public this (GstBus* gstBus, bool ownedRef = false) 102 { 103 this.gstBus = gstBus; 104 super(cast(GstObject*)gstBus, ownedRef); 105 } 106 107 /** 108 * Adds a bus watch to the default main context with the default priority. 109 * This function is used to receive asynchronous messages in the main loop. 110 * The watch can be removed using g_source_remove() or by returning FALSE 111 * from func. 112 * MT safe. 113 * Params: 114 * dlg = A function to call when a message is received. 115 * Returns: 116 * The event source id. 117 */ 118 public uint addWatch( bool delegate(Message) dlg ) 119 { 120 onWatchListener = dlg; 121 return gst_bus_add_watch(gstBus, cast(GstBusFunc)&watchCallBack, cast(void*)this); 122 } 123 124 bool delegate(Message) onWatchListener; 125 126 extern(C) static int watchCallBack(GstBus* bus, GstMessage* msg, Bus bus_d )//gpointer data) 127 { 128 Message msg_d = new Message( msg ); 129 130 return bus_d.onWatchListener( msg_d ); 131 } 132 133 /** 134 * Use this for making an XOverlay. 135 * Sets the synchronous handler on the bus. The function will be called 136 * every time a new message is posted on the bus. Note that the function 137 * will be called in the same thread context as the posting object. This 138 * function is usually only called by the creator of the bus. Applications 139 * should handle messages asynchronously using the gst_bus watch and poll 140 * functions. 141 * You cannot replace an existing sync_handler. You can pass NULL to this 142 * function, which will clear the existing handler. 143 * Params: 144 * dlg = The handler function to install 145 */ 146 public void setSyncHandler( GstBusSyncReply delegate(Message) dlg ) 147 { 148 onSyncHandlerListener = dlg; 149 gst_bus_set_sync_handler(gstBus, cast(GstBusSyncHandler)&syncHandlerCallBack, cast(void*)this, null); 150 } 151 152 GstBusSyncReply delegate(Message) onSyncHandlerListener; 153 154 extern(C) static GstBusSyncReply syncHandlerCallBack(GstBus* bus, GstMessage* msg, Bus bus_d) 155 { 156 Message msg_d = new Message( msg ); 157 158 return bus_d.onSyncHandlerListener( msg_d ); 159 } 160 161 /** 162 */ 163 164 /** */ 165 public static GType getType() 166 { 167 return gst_bus_get_type(); 168 } 169 170 /** 171 * Creates a new #GstBus instance. 172 * 173 * Returns: a new #GstBus instance 174 * 175 * Throws: ConstructionException GTK+ fails to create the object. 176 */ 177 public this() 178 { 179 auto __p = gst_bus_new(); 180 181 if(__p is null) 182 { 183 throw new ConstructionException("null returned by new"); 184 } 185 186 this(cast(GstBus*) __p, true); 187 } 188 189 /** 190 * Adds a bus signal watch to the default main context with the default priority 191 * (%G_PRIORITY_DEFAULT). It is also possible to use a non-default 192 * main context set up using g_main_context_push_thread_default() (before 193 * one had to create a bus watch source and attach it to the desired main 194 * context 'manually'). 195 * 196 * After calling this statement, the bus will emit the "message" signal for each 197 * message posted on the bus. 198 * 199 * This function may be called multiple times. To clean up, the caller is 200 * responsible for calling gst_bus_remove_signal_watch() as many times as this 201 * function is called. 202 * 203 * MT safe. 204 */ 205 public void addSignalWatch() 206 { 207 gst_bus_add_signal_watch(gstBus); 208 } 209 210 /** 211 * Adds a bus signal watch to the default main context with the given @priority 212 * (e.g. %G_PRIORITY_DEFAULT). It is also possible to use a non-default main 213 * context set up using g_main_context_push_thread_default() 214 * (before one had to create a bus watch source and attach it to the desired 215 * main context 'manually'). 216 * 217 * After calling this statement, the bus will emit the "message" signal for each 218 * message posted on the bus when the main loop is running. 219 * 220 * This function may be called multiple times. To clean up, the caller is 221 * responsible for calling gst_bus_remove_signal_watch() as many times as this 222 * function is called. 223 * 224 * There can only be a single bus watch per bus, you must remove any signal 225 * watch before you can set another type of watch. 226 * 227 * MT safe. 228 * 229 * Params: 230 * priority = The priority of the watch. 231 */ 232 public void addSignalWatchFull(int priority) 233 { 234 gst_bus_add_signal_watch_full(gstBus, priority); 235 } 236 237 /** 238 * Adds a bus watch to the default main context with the given @priority (e.g. 239 * %G_PRIORITY_DEFAULT). It is also possible to use a non-default main 240 * context set up using g_main_context_push_thread_default() (before 241 * one had to create a bus watch source and attach it to the desired main 242 * context 'manually'). 243 * 244 * This function is used to receive asynchronous messages in the main loop. 245 * There can only be a single bus watch per bus, you must remove it before you 246 * can set a new one. 247 * 248 * The bus watch will only work if a GLib main loop is being run. 249 * 250 * When @func is called, the message belongs to the caller; if you want to 251 * keep a copy of it, call gst_message_ref() before leaving @func. 252 * 253 * The watch can be removed using gst_bus_remove_watch() or by returning %FALSE 254 * from @func. If the watch was added to the default main context it is also 255 * possible to remove the watch using g_source_remove(). 256 * 257 * The bus watch will take its own reference to the @bus, so it is safe to unref 258 * @bus using gst_object_unref() after setting the bus watch. 259 * 260 * MT safe. 261 * 262 * Params: 263 * priority = The priority of the watch. 264 * func = A function to call when a message is received. 265 * userData = user data passed to @func. 266 * notify = the function to call when the source is removed. 267 * 268 * Returns: The event source id or 0 if @bus already got an event source. 269 */ 270 public uint addWatchFull(int priority, GstBusFunc func, void* userData, GDestroyNotify notify) 271 { 272 return gst_bus_add_watch_full(gstBus, priority, func, userData, notify); 273 } 274 275 /** 276 * A helper #GstBusFunc that can be used to convert all asynchronous messages 277 * into signals. 278 * 279 * Params: 280 * message = the #GstMessage received 281 * data = user data 282 * 283 * Returns: %TRUE 284 */ 285 public bool asyncSignalFunc(Message message, void* data) 286 { 287 return gst_bus_async_signal_func(gstBus, (message is null) ? null : message.getMessageStruct(), data) != 0; 288 } 289 290 /** 291 * Create watch for this bus. The GSource will be dispatched whenever 292 * a message is on the bus. After the GSource is dispatched, the 293 * message is popped off the bus and unreffed. 294 * 295 * Returns: a #GSource that can be added to a mainloop. 296 */ 297 public Source createWatch() 298 { 299 auto __p = gst_bus_create_watch(gstBus); 300 301 if(__p is null) 302 { 303 return null; 304 } 305 306 return new Source(cast(GSource*) __p, true); 307 } 308 309 /** 310 * Instructs GStreamer to stop emitting the "sync-message" signal for this bus. 311 * See gst_bus_enable_sync_message_emission() for more information. 312 * 313 * In the event that multiple pieces of code have called 314 * gst_bus_enable_sync_message_emission(), the sync-message emissions will only 315 * be stopped after all calls to gst_bus_enable_sync_message_emission() were 316 * "cancelled" by calling this function. In this way the semantics are exactly 317 * the same as gst_object_ref() that which calls enable should also call 318 * disable. 319 * 320 * MT safe. 321 */ 322 public void disableSyncMessageEmission() 323 { 324 gst_bus_disable_sync_message_emission(gstBus); 325 } 326 327 /** 328 * Instructs GStreamer to emit the "sync-message" signal after running the bus's 329 * sync handler. This function is here so that code can ensure that they can 330 * synchronously receive messages without having to affect what the bin's sync 331 * handler is. 332 * 333 * This function may be called multiple times. To clean up, the caller is 334 * responsible for calling gst_bus_disable_sync_message_emission() as many times 335 * as this function is called. 336 * 337 * While this function looks similar to gst_bus_add_signal_watch(), it is not 338 * exactly the same -- this function enables *synchronous* emission of 339 * signals when messages arrive; gst_bus_add_signal_watch() adds an idle callback 340 * to pop messages off the bus *asynchronously*. The sync-message signal 341 * comes from the thread of whatever object posted the message; the "message" 342 * signal is marshalled to the main thread via the main loop. 343 * 344 * MT safe. 345 */ 346 public void enableSyncMessageEmission() 347 { 348 gst_bus_enable_sync_message_emission(gstBus); 349 } 350 351 /** 352 * Gets the file descriptor from the bus which can be used to get notified about 353 * messages being available with functions like g_poll(), and allows integration 354 * into other event loops based on file descriptors. 355 * Whenever a message is available, the POLLIN / %G_IO_IN event is set. 356 * 357 * Warning: NEVER read or write anything to the returned fd but only use it 358 * for getting notifications via g_poll() or similar and then use the normal 359 * GstBus API, e.g. gst_bus_pop(). 360 * 361 * Params: 362 * fd = A GPollFD to fill 363 * 364 * Since: 1.14 365 */ 366 public void getPollfd(out GPollFD fd) 367 { 368 gst_bus_get_pollfd(gstBus, &fd); 369 } 370 371 /** 372 * Check if there are pending messages on the bus that 373 * should be handled. 374 * 375 * Returns: %TRUE if there are messages on the bus to be handled, %FALSE 376 * otherwise. 377 * 378 * MT safe. 379 */ 380 public bool havePending() 381 { 382 return gst_bus_have_pending(gstBus) != 0; 383 } 384 385 /** 386 * Peek the message on the top of the bus' queue. The message will remain 387 * on the bus' message queue. A reference is returned, and needs to be unreffed 388 * by the caller. 389 * 390 * Returns: the #GstMessage that is on the 391 * bus, or %NULL if the bus is empty. 392 * 393 * MT safe. 394 */ 395 public Message peek() 396 { 397 auto __p = gst_bus_peek(gstBus); 398 399 if(__p is null) 400 { 401 return null; 402 } 403 404 return ObjectG.getDObject!(Message)(cast(GstMessage*) __p, true); 405 } 406 407 /** 408 * Poll the bus for messages. Will block while waiting for messages to come. 409 * You can specify a maximum time to poll with the @timeout parameter. If 410 * @timeout is negative, this function will block indefinitely. 411 * 412 * All messages not in @events will be popped off the bus and will be ignored. 413 * It is not possible to use message enums beyond #GST_MESSAGE_EXTENDED in the 414 * @events mask 415 * 416 * Because poll is implemented using the "message" signal enabled by 417 * gst_bus_add_signal_watch(), calling gst_bus_poll() will cause the "message" 418 * signal to be emitted for every message that poll sees. Thus a "message" 419 * signal handler will see the same messages that this function sees -- neither 420 * will steal messages from the other. 421 * 422 * This function will run a main loop from the default main context when 423 * polling. 424 * 425 * You should never use this function, since it is pure evil. This is 426 * especially true for GUI applications based on Gtk+ or Qt, but also for any 427 * other non-trivial application that uses the GLib main loop. As this function 428 * runs a GLib main loop, any callback attached to the default GLib main 429 * context may be invoked. This could be timeouts, GUI events, I/O events etc.; 430 * even if gst_bus_poll() is called with a 0 timeout. Any of these callbacks 431 * may do things you do not expect, e.g. destroy the main application window or 432 * some other resource; change other application state; display a dialog and 433 * run another main loop until the user clicks it away. In short, using this 434 * function may add a lot of complexity to your code through unexpected 435 * re-entrancy and unexpected changes to your application's state. 436 * 437 * For 0 timeouts use gst_bus_pop_filtered() instead of this function; for 438 * other short timeouts use gst_bus_timed_pop_filtered(); everything else is 439 * better handled by setting up an asynchronous bus watch and doing things 440 * from there. 441 * 442 * Params: 443 * events = a mask of #GstMessageType, representing the set of message types to 444 * poll for (note special handling of extended message types below) 445 * timeout = the poll timeout, as a #GstClockTime, or #GST_CLOCK_TIME_NONE to poll 446 * indefinitely. 447 * 448 * Returns: the message that was received, 449 * or %NULL if the poll timed out. The message is taken from the 450 * bus and needs to be unreffed with gst_message_unref() after 451 * usage. 452 */ 453 public Message poll(GstMessageType events, GstClockTime timeout) 454 { 455 auto __p = gst_bus_poll(gstBus, events, timeout); 456 457 if(__p is null) 458 { 459 return null; 460 } 461 462 return ObjectG.getDObject!(Message)(cast(GstMessage*) __p, true); 463 } 464 465 /** 466 * Get a message from the bus. 467 * 468 * Returns: the #GstMessage that is on the 469 * bus, or %NULL if the bus is empty. The message is taken from 470 * the bus and needs to be unreffed with gst_message_unref() after 471 * usage. 472 * 473 * MT safe. 474 */ 475 public Message pop() 476 { 477 auto __p = gst_bus_pop(gstBus); 478 479 if(__p is null) 480 { 481 return null; 482 } 483 484 return ObjectG.getDObject!(Message)(cast(GstMessage*) __p, true); 485 } 486 487 /** 488 * Get a message matching @type from the bus. Will discard all messages on 489 * the bus that do not match @type and that have been posted before the first 490 * message that does match @type. If there is no message matching @type on 491 * the bus, all messages will be discarded. It is not possible to use message 492 * enums beyond #GST_MESSAGE_EXTENDED in the @events mask. 493 * 494 * Params: 495 * types = message types to take into account 496 * 497 * Returns: the next #GstMessage matching 498 * @type that is on the bus, or %NULL if the bus is empty or there 499 * is no message matching @type. The message is taken from the bus 500 * and needs to be unreffed with gst_message_unref() after usage. 501 * 502 * MT safe. 503 */ 504 public Message popFiltered(GstMessageType types) 505 { 506 auto __p = gst_bus_pop_filtered(gstBus, types); 507 508 if(__p is null) 509 { 510 return null; 511 } 512 513 return ObjectG.getDObject!(Message)(cast(GstMessage*) __p, true); 514 } 515 516 /** 517 * Post a message on the given bus. Ownership of the message 518 * is taken by the bus. 519 * 520 * Params: 521 * message = the #GstMessage to post 522 * 523 * Returns: %TRUE if the message could be posted, %FALSE if the bus is flushing. 524 * 525 * MT safe. 526 */ 527 public bool post(Message message) 528 { 529 return gst_bus_post(gstBus, (message is null) ? null : message.getMessageStruct()) != 0; 530 } 531 532 /** 533 * Removes a signal watch previously added with gst_bus_add_signal_watch(). 534 * 535 * MT safe. 536 */ 537 public void removeSignalWatch() 538 { 539 gst_bus_remove_signal_watch(gstBus); 540 } 541 542 /** 543 * Removes an installed bus watch from @bus. 544 * 545 * Returns: %TRUE on success or %FALSE if @bus has no event source. 546 * 547 * Since: 1.6 548 */ 549 public bool removeWatch() 550 { 551 return gst_bus_remove_watch(gstBus) != 0; 552 } 553 554 /** 555 * If @flushing, flush out and unref any messages queued in the bus. Releases 556 * references to the message origin objects. Will flush future messages until 557 * gst_bus_set_flushing() sets @flushing to %FALSE. 558 * 559 * MT safe. 560 * 561 * Params: 562 * flushing = whether or not to flush the bus 563 */ 564 public void setFlushing(bool flushing) 565 { 566 gst_bus_set_flushing(gstBus, flushing); 567 } 568 569 /** 570 * A helper GstBusSyncHandler that can be used to convert all synchronous 571 * messages into signals. 572 * 573 * Params: 574 * message = the #GstMessage received 575 * data = user data 576 * 577 * Returns: GST_BUS_PASS 578 */ 579 public GstBusSyncReply syncSignalHandler(Message message, void* data) 580 { 581 return gst_bus_sync_signal_handler(gstBus, (message is null) ? null : message.getMessageStruct(), data); 582 } 583 584 /** 585 * Get a message from the bus, waiting up to the specified timeout. 586 * 587 * If @timeout is 0, this function behaves like gst_bus_pop(). If @timeout is 588 * #GST_CLOCK_TIME_NONE, this function will block forever until a message was 589 * posted on the bus. 590 * 591 * Params: 592 * timeout = a timeout 593 * 594 * Returns: the #GstMessage that is on the 595 * bus after the specified timeout or %NULL if the bus is empty 596 * after the timeout expired. The message is taken from the bus 597 * and needs to be unreffed with gst_message_unref() after usage. 598 * 599 * MT safe. 600 */ 601 public Message timedPop(GstClockTime timeout) 602 { 603 auto __p = gst_bus_timed_pop(gstBus, timeout); 604 605 if(__p is null) 606 { 607 return null; 608 } 609 610 return ObjectG.getDObject!(Message)(cast(GstMessage*) __p, true); 611 } 612 613 /** 614 * Get a message from the bus whose type matches the message type mask @types, 615 * waiting up to the specified timeout (and discarding any messages that do not 616 * match the mask provided). 617 * 618 * If @timeout is 0, this function behaves like gst_bus_pop_filtered(). If 619 * @timeout is #GST_CLOCK_TIME_NONE, this function will block forever until a 620 * matching message was posted on the bus. 621 * 622 * Params: 623 * timeout = a timeout in nanoseconds, or GST_CLOCK_TIME_NONE to wait forever 624 * types = message types to take into account, GST_MESSAGE_ANY for any type 625 * 626 * Returns: a #GstMessage matching the 627 * filter in @types, or %NULL if no matching message was found on 628 * the bus until the timeout expired. The message is taken from 629 * the bus and needs to be unreffed with gst_message_unref() after 630 * usage. 631 * 632 * MT safe. 633 */ 634 public Message timedPopFiltered(GstClockTime timeout, GstMessageType types) 635 { 636 auto __p = gst_bus_timed_pop_filtered(gstBus, timeout, types); 637 638 if(__p is null) 639 { 640 return null; 641 } 642 643 return ObjectG.getDObject!(Message)(cast(GstMessage*) __p, true); 644 } 645 646 /** 647 * A message has been posted on the bus. This signal is emitted from a 648 * GSource added to the mainloop. this signal will only be emitted when 649 * there is a mainloop running. 650 * 651 * Params: 652 * message = the message that has been posted asynchronously 653 */ 654 gulong addOnMessage(void delegate(Message, Bus) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 655 { 656 return Signals.connect(this, "message", dlg, connectFlags ^ ConnectFlags.SWAPPED); 657 } 658 659 /** 660 * A message has been posted on the bus. This signal is emitted from the 661 * thread that posted the message so one has to be careful with locking. 662 * 663 * This signal will not be emitted by default, you have to call 664 * gst_bus_enable_sync_message_emission() before. 665 * 666 * Params: 667 * message = the message that has been posted synchronously 668 */ 669 gulong addOnSyncMessage(void delegate(Message, Bus) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 670 { 671 return Signals.connect(this, "sync-message", dlg, connectFlags ^ ConnectFlags.SWAPPED); 672 } 673 }