GNOME Bugzilla – Bug 670795
xwindow run outside for a few tenth of a second
Last modified: 2012-02-28 12:50:00 UTC
I get for few tenth of a second the xwindow outside my desidered gtk drawing area, before it is embedded, when this area is hidden by another widget. This is the Python code of my application: <<< self.player = gst.element_factory_make('playbin2', 'player') bus = self.player.get_bus() bus.add_signal_watch() bus.connect('message', self.newBusMessage) videobin = gst.Bin('videobin') videosink = gst.element_factory_make('xvimagesink', 'videosink') videosink.set_property('force-aspect-ratio', True) videosink.set_property('handle-expose', True) videosink.set_property('sync', True) videobin.add(videosink) self.player.set_property('video-sink', videobin) ... def newBusMessage(self, bus, msg): """ New bus message """ if msg.type == gst.MESSAGE_EOS: self.trackEnded(False) log.c.debug(msg) elif msg.type == gst.MESSAGE_ERROR: self.trackEnded(True) log.c.error(msg) elif msg.type == gst.MESSAGE_ELEMENT: if msg.structure.get_name() == 'prepare-xwindow-id': gtk.gdk.threads_enter() gtk.gdk.display_get_default().sync() self.videosink = msg.src self.videosink.set_xwindow_id(self.widget) self.videosink.expose() gtk.gdk.threads_leave() print msg <<< This is a bug or I'm doing something wrong?
This happens also when waiting the buffer of a stream or a play an audio cd :(
This is a bug in your code. Please read the documentation in http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstxoverlay.html in full, especially the section/example about Gtk/Gdk. Here's the problem with your code. You handle the prepare-xwindow-id message asynchronously via the normal message callback, in the application thread. By then it's too late. You need to set up a *sync* message handler and handle the message there (however, you need to obtain and save the window/widget XID from the main thread before you start the pipeline, you can't reliably do that from the other thread in the sync message handler). However, if you know that your video sink is xvimagesink anyway (and not a dynamic one like autovideosink or so), then you don't need to bother with the prepare-xwindow-id messages at all. Just set the xid/window_handle on the xvimagesink element directly before you start up the pipeline (xvimagesink implements the GstXOverlay interface).
Thanks much for explanation, but I don't understand how set my 'xid/window_handle' to my 'xvimagesink' when my pipeline is the 'playbin2', especially with the Python code, this line: >> self.videosink.set_window_handle(self.widget) returns an error: AttributeError: '__main__.GstXvImageSink' object has no attribute 'set_window_handle' because I think needs the GstXOverlay as interface, but I don't know how retrieve it.
If I set it before start the pipeline in this way... <<< videosink.set_xwindow_id(xid_handle) playbin.set_property('uri', 1st_uri) playbin.set_state(gst.STATE_PLAYING) ...1st_uri is ended, play the 2nd_uri... playbin.set_property('uri', 2nd_uri) playbin.set_state(gst.STATE_PLAYING) >>> The xwindow is shown in my gtk.DrawingArea only the first time, I must set the 'xid' at each pipeline stop?
> The xwindow is shown in my gtk.DrawingArea only the first time, > I must set the 'xid' at each pipeline stop? No, I think the xid setting persists. However, you will need handle the drawing area's "expose" or "draw" events, and then call xvimagesink.expose() from that. The gstreamer-devel mailing list or the #gstreamer IRC channel on freenode.net are good places to get support with problems using the GStreamer API.
Yes, the xid is lost every times, a bug of xvimagesink? I could not get any help from mailing list until now and the 'sync' handler doesn't want to work for some stupid reason, the my solution, even if ugly, is re add the xid after each gst.STATE_NULL, I give up!
Well, you already knew the solution for your question before you posted (you use .set_xwindow_id() in comment #4; _set_xwindow_id() is the same as _set_window_handle(), both are equivalent, one just sounds more platform-neutral). And it does seem like xvimagesink clears the window id when set to NULL. I guess that's ok after all. But you don't have to set playbin2 to NULL anyway when changing URIs or so, setting to READY should be enough.
Ok, but if the URI is not accessible because is a http stream or a corrupted file, or just moved after adding to playlist, I have to monitor each gst.MESSAGE_EOS and gst.MESSAGE_ERROR for add this damned 'xid' :D