[gst-devel] gtk and threads

Tim Müller t.i.m at zen.co.uk
Tue Aug 29 16:40:53 CEST 2006


On Tue, 2006-08-29 at 15:01 +0100, alberto colombo wrote:

> I'm using gstreamer for a small video analysis application written in
> gtk. I am trying to update the GUI with some information about the
> current frame of the video (i.e., the position of a tracked
> target, ...). 
> 
> To make it simpler, suppose I have a frame-counter plugin and that I
> want to show the current frame number in a GtkLabel. I can think of two
> ways of doing it:
> 
>         1) have the frame-counter emit a custom signal with the current
>         frame number, catch the signal from the application and update
>         the label, or
>         
>         2) have a GtkLabel property in the plugin, and update if from
>         within the plugin on the _chain function.
>         
> Alas, none of the above work. When the pipeline is playing, the
> interface is frozen and does not repaint until the pipeline is paused. I
> tried to queue_redraw() it, the I tried with gtk_main_iteration(), then 
> g_main_context_iteration(): they only make things worse (deadlocks).
> 
> What can I do? What am I doing wrong?

Since you haven't mentioned it, you should probably check out

 http://www.gtk.org/faq/#AEN482
 http://www.gtk.org/faq/#AEN492

and the following questions. The gist of it is: Gtk+ isn't thread-safe,
and if you use it from multiple threads you'll need to do proper locking
or you'll get into trouble (or things just won't work as expected).

Both your solutions aren't really good ideas IMHO. GStreamer will create
threads of its own to do the data processing and outputting, and your
chain function will be called from that one of those GStreamer streaming
threads, which is guaranteed to be different from your main thread where
you started the Gtk+ main loop with gtk_main().

Now, you could go and do proper Gtk/Gdk locking as per the FAQs above,
but I'd advise against that. Your program will (in IMHO) be much easier
to structure and to debug if you don't bother with doing correct locking
and instead only do Gtk/Gdk things (like updating labels/progress bars
etc.) from the main thread. If you want anything done to a Gtk widget,
marshal the information into the main thread and let a function handle
it there.

With GStreamer-0.10, the easiest way to marshal information into the
main thread is by using the pipeline's GstBus. This is the standard
mechanism for plugins to send information (like errors or tags) to the
application in a thread-safe manner. Your element can post custom
messages with arbitrary data (via the message's GstStructure) on the bus
and your application can then catch that custom message in its bus watch
callback. Since you will already have a bus watch to catch errors, tags
and to recognise the end of the stream, adding support for your custom
message should be fairly easy. 

Check the application developer's manual and the GStreamer API docs for
more information on how to use a pipeline's bus.

Btw, for your specific case (showing the current processing position) it
might be sufficient to just set up a timeout with g_timeout_add() and
query the pipeline for the current position in TIME format (if you're
lucky DEFAULT format will work too and give you the frame number).

Hope this helps.

 Cheers
  -Tim






More information about the gstreamer-devel mailing list