From c2b1dbda83031b2d560fdf1907958ad357b09c9d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 2 Sep 2020 23:24:05 +0200 Subject: [PATCH] Call GDK functions from main thread in wxGStreamerMediaBackend This fixes another problem similar to the one fixed in be1854c617 (Avoid UI functions in non-main thread in wxGStreamerMediaBackend, 2020-09-02) and does it in a similar way: SetupXOverlay(), which calls gdk_flush(), was called from gst_bus_sync_callback() which is executed in the worker thread, so use CallAfter() to call it from the main thread later. --- src/unix/mediactrl.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/unix/mediactrl.cpp b/src/unix/mediactrl.cpp index 93dbb7c995..3720b0fedd 100644 --- a/src/unix/mediactrl.cpp +++ b/src/unix/mediactrl.cpp @@ -149,7 +149,12 @@ public: void HandleStateChange(GstState oldstate, GstState newstate); bool QueryVideoSizeFromElement(GstElement* element); bool QueryVideoSizeFromPad(GstPad* caps); + + // SetupXOverlay() can only be called from the main thread, use + // CallSetupXOverlay() to call it from another thread. void SetupXOverlay(); + void CallSetupXOverlay(); + bool SyncStateChange(GstElement* element, GstState state, gint64 llTimeout = wxGSTREAMER_TIMEOUT); bool TryAudioSink(GstElement* audiosink); @@ -210,6 +215,7 @@ class wxGStreamerMediaEventHandler : public wxEvtHandler void OnMediaFinish(wxMediaEvent& event); void NotifyMovieSizeChanged(); + void NotifySetupXOverlay() { return m_be->SetupXOverlay(); } wxGStreamerMediaBackend* m_be; }; @@ -478,7 +484,7 @@ static GstBusSyncReply gst_bus_sync_callback(GstBus* bus, } wxLogTrace(wxTRACE_GStreamer, wxT("Got prepare-xwindow-id")); - be->SetupXOverlay(); + be->CallSetupXOverlay(); return GST_BUS_DROP; // We handled this message - drop from the queue } } @@ -654,6 +660,8 @@ bool wxGStreamerMediaBackend::QueryVideoSizeFromPad(GstPad* pad) //----------------------------------------------------------------------------- void wxGStreamerMediaBackend::SetupXOverlay() { + wxASSERT( wxIsMainThread() ); + // Use the xoverlay extension to tell gstreamer to play in our window #ifdef __WXGTK__ if (!gtk_widget_get_realized(m_ctrl->m_wxwindow)) @@ -693,6 +701,11 @@ void wxGStreamerMediaBackend::SetupXOverlay() #endif } +void wxGStreamerMediaBackend::CallSetupXOverlay() +{ + m_eventHandler->CallAfter(&wxGStreamerMediaEventHandler::NotifySetupXOverlay); +} + //----------------------------------------------------------------------------- // wxGStreamerMediaBackend::SyncStateChange //