After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 670795 - xwindow run outside for a few tenth of a second
xwindow run outside for a few tenth of a second
Status: RESOLVED INVALID
Product: GStreamer
Classification: Platform
Component: dont know
0.10.x
Other Linux
: Normal normal
: NONE
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2012-02-25 16:39 UTC by mickyz
Modified: 2012-02-28 12:50 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description mickyz 2012-02-25 16:39:03 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?
Comment 1 mickyz 2012-02-26 02:39:34 UTC
This happens also when waiting the buffer of a stream or a play an audio cd :(
Comment 2 Tim-Philipp Müller 2012-02-26 15:57:20 UTC
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).
Comment 3 mickyz 2012-02-26 23:26:42 UTC
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.
Comment 4 mickyz 2012-02-27 03:05:57 UTC
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?
Comment 5 Tim-Philipp Müller 2012-02-27 10:44:09 UTC
> 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.
Comment 6 mickyz 2012-02-28 02:44:02 UTC
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!
Comment 7 Tim-Philipp Müller 2012-02-28 11:20:16 UTC
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.
Comment 8 mickyz 2012-02-28 12:50:00 UTC
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