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 gstreamerc.gstreamer; 34 public import gstreamerc.gstreamertypes; 35 public import gtkc.gdktypes; 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() 86 { 87 return gstBus; 88 } 89 90 /** the main Gtk struct as a void* */ 91 protected override void* getStruct() 92 { 93 return cast(void*)gstBus; 94 } 95 96 protected override void setStruct(GObject* obj) 97 { 98 gstBus = cast(GstBus*)obj; 99 super.setStruct(obj); 100 } 101 102 /** 103 * Sets our main struct and passes it to the parent class. 104 */ 105 public this (GstBus* gstBus, bool ownedRef = false) 106 { 107 this.gstBus = gstBus; 108 super(cast(GstObject*)gstBus, ownedRef); 109 } 110 111 /** 112 * Adds a bus watch to the default main context with the default priority. 113 * This function is used to receive asynchronous messages in the main loop. 114 * The watch can be removed using g_source_remove() or by returning FALSE 115 * from func. 116 * MT safe. 117 * Params: 118 * dlg = A function to call when a message is received. 119 * Returns: 120 * The event source id. 121 */ 122 public uint addWatch( bool delegate(Message) dlg ) 123 { 124 onWatchListener = dlg; 125 return gst_bus_add_watch(gstBus, cast(GstBusFunc)&watchCallBack, cast(void*)this); 126 } 127 128 bool delegate(Message) onWatchListener; 129 130 extern(C) static int watchCallBack(GstBus* bus, GstMessage* msg, Bus bus_d )//gpointer data) 131 { 132 Message msg_d = new Message( msg ); 133 134 return bus_d.onWatchListener( msg_d ); 135 } 136 137 /** 138 * Use this for making an XOverlay. 139 * Sets the synchronous handler on the bus. The function will be called 140 * every time a new message is posted on the bus. Note that the function 141 * will be called in the same thread context as the posting object. This 142 * function is usually only called by the creator of the bus. Applications 143 * should handle messages asynchronously using the gst_bus watch and poll 144 * functions. 145 * You cannot replace an existing sync_handler. You can pass NULL to this 146 * function, which will clear the existing handler. 147 * Params: 148 * dlg = The handler function to install 149 */ 150 public void setSyncHandler( GstBusSyncReply delegate(Message) dlg ) 151 { 152 onSyncHandlerListener = dlg; 153 gst_bus_set_sync_handler(gstBus, cast(GstBusSyncHandler)&syncHandlerCallBack, cast(void*)this, null); 154 } 155 156 GstBusSyncReply delegate(Message) onSyncHandlerListener; 157 158 extern(C) static GstBusSyncReply syncHandlerCallBack(GstBus* bus, GstMessage* msg, Bus bus_d) 159 { 160 Message msg_d = new Message( msg ); 161 162 return bus_d.onSyncHandlerListener( msg_d ); 163 } 164 165 /** 166 */ 167 168 public static GType getType() 169 { 170 return gst_bus_get_type(); 171 } 172 173 /** 174 * Creates a new #GstBus instance. 175 * 176 * Return: a new #GstBus instance 177 * 178 * Throws: ConstructionException GTK+ fails to create the object. 179 */ 180 public this() 181 { 182 auto p = gst_bus_new(); 183 184 if(p is null) 185 { 186 throw new ConstructionException("null returned by new"); 187 } 188 189 this(cast(GstBus*) p, true); 190 } 191 192 /** 193 * Adds a bus signal watch to the default main context with the default priority 194 * (%G_PRIORITY_DEFAULT). It is also possible to use a non-default 195 * main context set up using g_main_context_push_thread_default() (before 196 * one had to create a bus watch source and attach it to the desired main 197 * context 'manually'). 198 * 199 * After calling this statement, the bus will emit the "message" signal for each 200 * message posted on the bus. 201 * 202 * This function may be called multiple times. To clean up, the caller is 203 * responsible for calling gst_bus_remove_signal_watch() as many times as this 204 * function is called. 205 * 206 * MT safe. 207 */ 208 public void addSignalWatch() 209 { 210 gst_bus_add_signal_watch(gstBus); 211 } 212 213 /** 214 * Adds a bus signal watch to the default main context with the given @priority 215 * (e.g. %G_PRIORITY_DEFAULT). It is also possible to use a non-default main 216 * context set up using g_main_context_push_thread_default() 217 * (before one had to create a bus watch source and attach it to the desired 218 * main context 'manually'). 219 * 220 * After calling this statement, the bus will emit the "message" signal for each 221 * message posted on the bus when the main loop is running. 222 * 223 * This function may be called multiple times. To clean up, the caller is 224 * responsible for calling gst_bus_remove_signal_watch() as many times as this 225 * function is called. 226 * 227 * There can only be a single bus watch per bus, you must remove any signal 228 * watch before you can set another type of watch. 229 * 230 * MT safe. 231 * 232 * Params: 233 * priority = The priority of the watch. 234 */ 235 public void addSignalWatchFull(int priority) 236 { 237 gst_bus_add_signal_watch_full(gstBus, priority); 238 } 239 240 /** 241 * Adds a bus watch to the default main context with the given @priority (e.g. 242 * %G_PRIORITY_DEFAULT). It is also possible to use a non-default main 243 * context set up using g_main_context_push_thread_default() (before 244 * one had to create a bus watch source and attach it to the desired main 245 * context 'manually'). 246 * 247 * This function is used to receive asynchronous messages in the main loop. 248 * There can only be a single bus watch per bus, you must remove it before you 249 * can set a new one. 250 * 251 * When @func is called, the message belongs to the caller; if you want to 252 * keep a copy of it, call gst_message_ref() before leaving @func. 253 * 254 * The watch can be removed using g_source_remove() or by returning %FALSE 255 * from @func. 256 * 257 * MT safe. 258 * 259 * Params: 260 * priority = The priority of the watch. 261 * func = A function to call when a message is received. 262 * userData = user data passed to @func. 263 * notify = the function to call when the source is removed. 264 * 265 * Return: The event source id. 266 */ 267 public uint addWatchFull(int priority, GstBusFunc func, void* userData, GDestroyNotify notify) 268 { 269 return gst_bus_add_watch_full(gstBus, priority, func, userData, notify); 270 } 271 272 /** 273 * A helper #GstBusFunc that can be used to convert all asynchronous messages 274 * into signals. 275 * 276 * Params: 277 * message = the #GstMessage received 278 * data = user data 279 * 280 * Return: %TRUE 281 */ 282 public bool asyncSignalFunc(Message message, void* data) 283 { 284 return gst_bus_async_signal_func(gstBus, (message is null) ? null : message.getMessageStruct(), data) != 0; 285 } 286 287 /** 288 * Create watch for this bus. The GSource will be dispatched whenever 289 * a message is on the bus. After the GSource is dispatched, the 290 * message is popped off the bus and unreffed. 291 * 292 * Return: a #GSource that can be added to a mainloop. 293 */ 294 public Source createWatch() 295 { 296 auto p = gst_bus_create_watch(gstBus); 297 298 if(p is null) 299 { 300 return null; 301 } 302 303 return new Source(cast(GSource*) p); 304 } 305 306 /** 307 * Instructs GStreamer to stop emitting the "sync-message" signal for this bus. 308 * See gst_bus_enable_sync_message_emission() for more information. 309 * 310 * In the event that multiple pieces of code have called 311 * gst_bus_enable_sync_message_emission(), the sync-message emissions will only 312 * be stopped after all calls to gst_bus_enable_sync_message_emission() were 313 * "cancelled" by calling this function. In this way the semantics are exactly 314 * the same as gst_object_ref() that which calls enable should also call 315 * disable. 316 * 317 * MT safe. 318 */ 319 public void disableSyncMessageEmission() 320 { 321 gst_bus_disable_sync_message_emission(gstBus); 322 } 323 324 /** 325 * Instructs GStreamer to emit the "sync-message" signal after running the bus's 326 * sync handler. This function is here so that code can ensure that they can 327 * synchronously receive messages without having to affect what the bin's sync 328 * handler is. 329 * 330 * This function may be called multiple times. To clean up, the caller is 331 * responsible for calling gst_bus_disable_sync_message_emission() as many times 332 * as this function is called. 333 * 334 * While this function looks similar to gst_bus_add_signal_watch(), it is not 335 * exactly the same -- this function enables <emphasis>synchronous</emphasis> emission of 336 * signals when messages arrive; gst_bus_add_signal_watch() adds an idle callback 337 * to pop messages off the bus <emphasis>asynchronously</emphasis>. The sync-message signal 338 * comes from the thread of whatever object posted the message; the "message" 339 * signal is marshalled to the main thread via the main loop. 340 * 341 * MT safe. 342 */ 343 public void enableSyncMessageEmission() 344 { 345 gst_bus_enable_sync_message_emission(gstBus); 346 } 347 348 /** 349 * Check if there are pending messages on the bus that 350 * should be handled. 351 * 352 * Return: %TRUE if there are messages on the bus to be handled, %FALSE 353 * otherwise. 354 * 355 * MT safe. 356 */ 357 public bool havePending() 358 { 359 return gst_bus_have_pending(gstBus) != 0; 360 } 361 362 /** 363 * Peek the message on the top of the bus' queue. The message will remain 364 * on the bus' message queue. A reference is returned, and needs to be unreffed 365 * by the caller. 366 * 367 * Return: the #GstMessage that is on the 368 * bus, or %NULL if the bus is empty. 369 * 370 * MT safe. 371 */ 372 public Message peek() 373 { 374 auto p = gst_bus_peek(gstBus); 375 376 if(p is null) 377 { 378 return null; 379 } 380 381 return ObjectG.getDObject!(Message)(cast(GstMessage*) p); 382 } 383 384 /** 385 * Poll the bus for messages. Will block while waiting for messages to come. 386 * You can specify a maximum time to poll with the @timeout parameter. If 387 * @timeout is negative, this function will block indefinitely. 388 * 389 * All messages not in @events will be popped off the bus and will be ignored. 390 * It is not possible to use message enums beyond #GST_MESSAGE_EXTENDED in the 391 * @events mask 392 * 393 * Because poll is implemented using the "message" signal enabled by 394 * gst_bus_add_signal_watch(), calling gst_bus_poll() will cause the "message" 395 * signal to be emitted for every message that poll sees. Thus a "message" 396 * signal handler will see the same messages that this function sees -- neither 397 * will steal messages from the other. 398 * 399 * This function will run a main loop from the default main context when 400 * polling. 401 * 402 * You should never use this function, since it is pure evil. This is 403 * especially true for GUI applications based on Gtk+ or Qt, but also for any 404 * other non-trivial application that uses the GLib main loop. As this function 405 * runs a GLib main loop, any callback attached to the default GLib main 406 * context may be invoked. This could be timeouts, GUI events, I/O events etc.; 407 * even if gst_bus_poll() is called with a 0 timeout. Any of these callbacks 408 * may do things you do not expect, e.g. destroy the main application window or 409 * some other resource; change other application state; display a dialog and 410 * run another main loop until the user clicks it away. In short, using this 411 * function may add a lot of complexity to your code through unexpected 412 * re-entrancy and unexpected changes to your application's state. 413 * 414 * For 0 timeouts use gst_bus_pop_filtered() instead of this function; for 415 * other short timeouts use gst_bus_timed_pop_filtered(); everything else is 416 * better handled by setting up an asynchronous bus watch and doing things 417 * from there. 418 * 419 * Params: 420 * events = a mask of #GstMessageType, representing the set of message types to 421 * poll for (note special handling of extended message types below) 422 * timeout = the poll timeout, as a #GstClockTime, or #GST_CLOCK_TIME_NONE to poll 423 * indefinitely. 424 * 425 * Return: the message that was received, 426 * or %NULL if the poll timed out. The message is taken from the 427 * bus and needs to be unreffed with gst_message_unref() after 428 * usage. 429 */ 430 public Message poll(GstMessageType events, GstClockTime timeout) 431 { 432 auto p = gst_bus_poll(gstBus, events, timeout); 433 434 if(p is null) 435 { 436 return null; 437 } 438 439 return ObjectG.getDObject!(Message)(cast(GstMessage*) p); 440 } 441 442 /** 443 * Get a message from the bus. 444 * 445 * Return: the #GstMessage that is on the 446 * bus, or %NULL if the bus is empty. The message is taken from 447 * the bus and needs to be unreffed with gst_message_unref() after 448 * usage. 449 * 450 * MT safe. 451 */ 452 public Message pop() 453 { 454 auto p = gst_bus_pop(gstBus); 455 456 if(p is null) 457 { 458 return null; 459 } 460 461 return ObjectG.getDObject!(Message)(cast(GstMessage*) p); 462 } 463 464 /** 465 * Get a message matching @type from the bus. Will discard all messages on 466 * the bus that do not match @type and that have been posted before the first 467 * message that does match @type. If there is no message matching @type on 468 * the bus, all messages will be discarded. It is not possible to use message 469 * enums beyond #GST_MESSAGE_EXTENDED in the @events mask. 470 * 471 * Params: 472 * types = message types to take into account 473 * 474 * Return: the next #GstMessage matching 475 * @type that is on the bus, or %NULL if the bus is empty or there 476 * is no message matching @type. The message is taken from the bus 477 * and needs to be unreffed with gst_message_unref() after usage. 478 * 479 * MT safe. 480 */ 481 public Message popFiltered(GstMessageType types) 482 { 483 auto p = gst_bus_pop_filtered(gstBus, types); 484 485 if(p is null) 486 { 487 return null; 488 } 489 490 return ObjectG.getDObject!(Message)(cast(GstMessage*) p); 491 } 492 493 /** 494 * Post a message on the given bus. Ownership of the message 495 * is taken by the bus. 496 * 497 * Params: 498 * message = the #GstMessage to post 499 * 500 * Return: %TRUE if the message could be posted, %FALSE if the bus is flushing. 501 * 502 * MT safe. 503 */ 504 public bool post(Message message) 505 { 506 return gst_bus_post(gstBus, (message is null) ? null : message.getMessageStruct()) != 0; 507 } 508 509 /** 510 * Removes a signal watch previously added with gst_bus_add_signal_watch(). 511 * 512 * MT safe. 513 */ 514 public void removeSignalWatch() 515 { 516 gst_bus_remove_signal_watch(gstBus); 517 } 518 519 /** 520 * If @flushing, flush out and unref any messages queued in the bus. Releases 521 * references to the message origin objects. Will flush future messages until 522 * gst_bus_set_flushing() sets @flushing to %FALSE. 523 * 524 * MT safe. 525 * 526 * Params: 527 * flushing = whether or not to flush the bus 528 */ 529 public void setFlushing(bool flushing) 530 { 531 gst_bus_set_flushing(gstBus, flushing); 532 } 533 534 /** 535 * A helper GstBusSyncHandler that can be used to convert all synchronous 536 * messages into signals. 537 * 538 * Params: 539 * message = the #GstMessage received 540 * data = user data 541 * 542 * Return: GST_BUS_PASS 543 */ 544 public GstBusSyncReply syncSignalHandler(Message message, void* data) 545 { 546 return gst_bus_sync_signal_handler(gstBus, (message is null) ? null : message.getMessageStruct(), data); 547 } 548 549 /** 550 * Get a message from the bus, waiting up to the specified timeout. 551 * 552 * If @timeout is 0, this function behaves like gst_bus_pop(). If @timeout is 553 * #GST_CLOCK_TIME_NONE, this function will block forever until a message was 554 * posted on the bus. 555 * 556 * Params: 557 * timeout = a timeout 558 * 559 * Return: the #GstMessage that is on the 560 * bus after the specified timeout or %NULL if the bus is empty 561 * after the timeout expired. The message is taken from the bus 562 * and needs to be unreffed with gst_message_unref() after usage. 563 * 564 * MT safe. 565 */ 566 public Message timedPop(GstClockTime timeout) 567 { 568 auto p = gst_bus_timed_pop(gstBus, timeout); 569 570 if(p is null) 571 { 572 return null; 573 } 574 575 return ObjectG.getDObject!(Message)(cast(GstMessage*) p); 576 } 577 578 /** 579 * Get a message from the bus whose type matches the message type mask @types, 580 * waiting up to the specified timeout (and discarding any messages that do not 581 * match the mask provided). 582 * 583 * If @timeout is 0, this function behaves like gst_bus_pop_filtered(). If 584 * @timeout is #GST_CLOCK_TIME_NONE, this function will block forever until a 585 * matching message was posted on the bus. 586 * 587 * Params: 588 * timeout = a timeout in nanoseconds, or GST_CLOCK_TIME_NONE to wait forever 589 * types = message types to take into account, GST_MESSAGE_ANY for any type 590 * 591 * Return: a #GstMessage matching the 592 * filter in @types, or %NULL if no matching message was found on 593 * the bus until the timeout expired. The message is taken from 594 * the bus and needs to be unreffed with gst_message_unref() after 595 * usage. 596 * 597 * MT safe. 598 */ 599 public Message timedPopFiltered(GstClockTime timeout, GstMessageType types) 600 { 601 auto p = gst_bus_timed_pop_filtered(gstBus, timeout, types); 602 603 if(p is null) 604 { 605 return null; 606 } 607 608 return ObjectG.getDObject!(Message)(cast(GstMessage*) p); 609 } 610 611 int[string] connectedSignals; 612 613 void delegate(Message, Bus)[] onMessageListeners; 614 /** 615 * A message has been posted on the bus. This signal is emitted from a 616 * GSource added to the mainloop. this signal will only be emitted when 617 * there is a mainloop running. 618 * 619 * Params: 620 * message = the message that has been posted asynchronously 621 */ 622 void addOnMessage(void delegate(Message, Bus) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 623 { 624 if ( "message" !in connectedSignals ) 625 { 626 Signals.connectData( 627 this, 628 "message", 629 cast(GCallback)&callBackMessage, 630 cast(void*)this, 631 null, 632 connectFlags); 633 connectedSignals["message"] = 1; 634 } 635 onMessageListeners ~= dlg; 636 } 637 extern(C) static void callBackMessage(GstBus* busStruct, GstMessage* message, Bus _bus) 638 { 639 foreach ( void delegate(Message, Bus) dlg; _bus.onMessageListeners ) 640 { 641 dlg(ObjectG.getDObject!(Message)(message), _bus); 642 } 643 } 644 645 void delegate(Message, Bus)[] onSyncMessageListeners; 646 /** 647 * A message has been posted on the bus. This signal is emitted from the 648 * thread that posted the message so one has to be careful with locking. 649 * 650 * This signal will not be emitted by default, you have to call 651 * gst_bus_enable_sync_message_emission() before. 652 * 653 * Params: 654 * message = the message that has been posted synchronously 655 */ 656 void addOnSyncMessage(void delegate(Message, Bus) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 657 { 658 if ( "sync-message" !in connectedSignals ) 659 { 660 Signals.connectData( 661 this, 662 "sync-message", 663 cast(GCallback)&callBackSyncMessage, 664 cast(void*)this, 665 null, 666 connectFlags); 667 connectedSignals["sync-message"] = 1; 668 } 669 onSyncMessageListeners ~= dlg; 670 } 671 extern(C) static void callBackSyncMessage(GstBus* busStruct, GstMessage* message, Bus _bus) 672 { 673 foreach ( void delegate(Message, Bus) dlg; _bus.onSyncMessageListeners ) 674 { 675 dlg(ObjectG.getDObject!(Message)(message), _bus); 676 } 677 } 678 }