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