[vlc-devel] [PATCH] vout: fix fullscreen race condition

Romain Vimont rom1v at videolabs.io
Tue Apr 17 14:58:48 CEST 2018


There are at least two VLC variables "fullscreen", associated to
different vlc objects: the playlist and the vout. If fullscreen is
toggled while vout is not initialized yet, these 2 variables may contain
different values, so the FSC and the video fullscreen mode are
inconsistent.

Always copy the playlist "fullscreen" variable to vout on vout changes
to fix the issue.

== Race condition details ==

The vout is initially created by the call to
input_resource_RequestVout() in decoder.c:vout_update_format(). During
this creation, the vout variable "fullscreen" is created with the value
inherited from the playlist variable (in vout_intf.c:vout_IntfInit()).

Only then, INPUT_EVENT_VOUT is triggered by input_SendEventVout(),
leading to initialize the p_vout variable in hotkeys.c:ChangeVout().
Before it is initialized, ACTION_IDTOGGLE_FULLSCREEN events are ignored.

Therefore, if fullscreen is toggled after the vout variable "fullscreen"
is created but before INPUT_EVENT_VOUT is handled, then the toggle is
not applied to the vout, while it is applied to the playlist (and the
FSC).

Fixes #19697
---
 modules/gui/qt/components/controller.cpp |  3 ---
 modules/gui/qt/input_manager.cpp         | 10 ++++++++++
 modules/gui/qt/input_manager.hpp         |  1 +
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/modules/gui/qt/components/controller.cpp b/modules/gui/qt/components/controller.cpp
index e10b1e4208..4d32652b20 100644
--- a/modules/gui/qt/components/controller.cpp
+++ b/modules/gui/qt/components/controller.cpp
@@ -1209,9 +1209,6 @@ void FullscreenControllerWidget::setVoutList( vout_thread_t **pp_vout, int i_vou
         vout.append( p_vout );
         var_AddCallback( p_vout, "fullscreen",
                          FullscreenControllerWidget::FullscreenChanged, this );
-        /* I miss a add and fire */
-        emit fullscreenChanged( p_vout, var_InheritBool( THEPL, "fullscreen" ),
-                           var_GetInteger( p_vout, "mouse-hide-timeout" ) );
         vlc_mutex_unlock( &lock );
     }
 }
diff --git a/modules/gui/qt/input_manager.cpp b/modules/gui/qt/input_manager.cpp
index ceb3f8dfac..a47071529d 100644
--- a/modules/gui/qt/input_manager.cpp
+++ b/modules/gui/qt/input_manager.cpp
@@ -79,6 +79,8 @@ InputManager::InputManager( MainInputManager *mim, intf_thread_t *_p_intf) :
     f_cache      = -1.; /* impossible initial value, different from all */
     registerAndCheckEventIds( IMEvent::PositionUpdate, IMEvent::FullscreenControlPlanHide );
     registerAndCheckEventIds( PLEvent::PLItemAppended, PLEvent::PLEmpty );
+
+    CONNECT( this, voutChanged( bool ), this, syncVars() );
 }
 
 InputManager::~InputManager()
@@ -86,6 +88,14 @@ InputManager::~InputManager()
     delInput();
 }
 
+void InputManager::syncVars()
+{
+    vout_thread_t *p_vout = p_mim->getVout();
+    if ( !p_vout )
+        return;
+    var_SetBool( p_vout, "fullscreen", var_GetBool( THEPL, "fullscreen" ) );
+}
+
 void InputManager::inputChangedHandler()
 {
     setInput( p_mim->getInput() );
diff --git a/modules/gui/qt/input_manager.hpp b/modules/gui/qt/input_manager.hpp
index 2e2116b82b..dd34e1af5b 100644
--- a/modules/gui/qt/input_manager.hpp
+++ b/modules/gui/qt/input_manager.hpp
@@ -212,6 +212,7 @@ public slots:
 
 private slots:
     void AtoBLoop( float, int64_t, int );
+    void syncVars();
 
 signals:
     /// Send new position, new time and new length
-- 
2.17.0



More information about the vlc-devel mailing list