Commit 61c5a86a authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Qt4: fix race in requestVideo and simplify

We were accessing some main interface variables from random threads
without serialization. This simply moves the blocking connection signal
from sole size setting to the whole video widget request call. In the
process, we can remove two signals. We still need a blocking connection
signal. It does not add any new deadlock case, since there was already
blocking connection signal in the same call and in the same direction.
(cherry picked from commit 7c6ef80c)

Conflicts:

	modules/gui/qt4/main_interface.cpp
	modules/gui/qt4/main_interface.hpp
	modules/gui/qt4/qt4.cpp
parent b22d5fd3
...@@ -215,18 +215,18 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf ) ...@@ -215,18 +215,18 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf ); var_AddCallback( p_intf->p_libvlc, "intf-popupmenu", PopupMenuCB, p_intf );
/* VideoWidget connects to avoid different threads speaking to each other */ /* VideoWidget connects for asynchronous calls */
connect( this, SIGNAL(askGetVideo(WId*,vout_thread_t*,int*,int*,unsigned*,unsigned *)),
this, SLOT(getVideoSlot(WId*,vout_thread_t*,int*,int*,unsigned*,unsigned*)),
Qt::BlockingQueuedConnection );
connect( this, SIGNAL(askReleaseVideo( void )), connect( this, SIGNAL(askReleaseVideo( void )),
this, SLOT(releaseVideoSlot( void )), Qt::BlockingQueuedConnection ); this, SLOT(releaseVideoSlot( void )),
Qt::BlockingQueuedConnection );
if( videoWidget ) if( videoWidget )
{ {
CONNECT( this, askVideoToResize( unsigned int, unsigned int ), CONNECT( this, askVideoToResize( unsigned int, unsigned int ),
videoWidget, SetSizing( unsigned int, unsigned int ) ); videoWidget, SetSizing( unsigned int, unsigned int ) );
connect( this, SIGNAL(askVideoToShow( unsigned int, unsigned int)),
videoWidget, SLOT(SetSizing(unsigned int, unsigned int )),
Qt::BlockingQueuedConnection );
} }
CONNECT( this, askUpdate(), this, doComponentsUpdate() ); CONNECT( this, askUpdate(), this, doComponentsUpdate() );
...@@ -372,7 +372,6 @@ void MainInterface::createMainWidget( QSettings *settings ) ...@@ -372,7 +372,6 @@ void MainInterface::createMainWidget( QSettings *settings )
bgWidget->resize( bgWidget->resize(
settings->value( "backgroundSize", QSize( 300, 200 ) ).toSize() ); settings->value( "backgroundSize", QSize( 300, 200 ) ).toSize() );
bgWidget->updateGeometry(); bgWidget->updateGeometry();
CONNECT( this, askBgWidgetToToggle(), bgWidget, toggle() );
if( i_visualmode != QT_ALWAYS_VIDEO_MODE && if( i_visualmode != QT_ALWAYS_VIDEO_MODE &&
i_visualmode != QT_MINIMAL_MODE ) i_visualmode != QT_MINIMAL_MODE )
...@@ -702,41 +701,55 @@ private: ...@@ -702,41 +701,55 @@ private:
}; };
/** /**
* README * NOTE:
* Thou shall not call/resize/hide widgets from on another thread. * You must note change the state of this object or other Qt4 UI objects,
* This is wrong, and this is THE reason to emit signals on those Video Functions * from the video output thread - only from the Qt4 UI main loop thread.
**/ * All window provider queries must be handled through signals or events.
WId MainInterface::requestVideo( vout_thread_t *p_nvout, int *pi_x, * That's why we have all those emit statements...
int *pi_y, unsigned int *pi_width, */
unsigned int *pi_height ) WId MainInterface::getVideo( vout_thread_t *p_nvout, int *pi_x, int *pi_y,
unsigned int *pi_width, unsigned int *pi_height )
{
if( !videoWidget )
return 0;
/* This is a blocking call signal. Results are returned through pointers.
* Beware of deadlocks! */
WId id;
emit askGetVideo( &id, p_nvout, pi_x, pi_y, pi_width, pi_height );
return id;
}
void MainInterface::getVideoSlot( WId *p_id, vout_thread_t *p_nvout,
int *pi_x, int *pi_y,
unsigned *pi_width, unsigned *pi_height )
{ {
/* Request the videoWidget */ /* Request the videoWidget */
if( !videoWidget ) return 0; WId ret = videoWidget->request( p_nvout, pi_x, pi_y,
WId ret = videoWidget->request( p_nvout,pi_x, pi_y,
pi_width, pi_height, b_keep_size ); pi_width, pi_height, b_keep_size );
*p_id = ret;
if( ret ) /* The videoWidget is available */ if( ret ) /* The videoWidget is available */
{ {
/* Did we have a bg ? Hide it! */ /* Did we have a bg ? Hide it! */
if( VISIBLE( bgWidget) ) if( VISIBLE( bgWidget) )
{ {
bgWasVisible = true; bgWasVisible = true;
emit askBgWidgetToToggle(); bgWidget->toggle();
} }
else else
bgWasVisible = false; bgWasVisible = false;
/* ask videoWidget to show */ /* ask videoWidget to show */
emit askVideoToShow( *pi_width, *pi_height ); videoWidget->SetSizing( *pi_width, *pi_height );
/* Consider the video active now */ /* Consider the video active now */
videoIsActive = true; videoIsActive = true;
emit askUpdate(); emit askUpdate();
} }
return ret;
} }
/* Call from the WindowClose function */ /* Asynchronous call from the WindowClose function */
void MainInterface::releaseVideo( void ) void MainInterface::releaseVideo( void )
{ {
emit askReleaseVideo( ); emit askReleaseVideo( );
...@@ -760,7 +773,7 @@ void MainInterface::releaseVideoSlot( void ) ...@@ -760,7 +773,7 @@ void MainInterface::releaseVideoSlot( void )
if( !isFullScreen() ) doComponentsUpdate(); if( !isFullScreen() ) doComponentsUpdate();
} }
/* Call from WindowControl function */ /* Asynchronous call from WindowControl function */
int MainInterface::controlVideo( int i_query, va_list args ) int MainInterface::controlVideo( int i_query, va_list args )
{ {
int i_ret = VLC_SUCCESS; int i_ret = VLC_SUCCESS;
...@@ -850,7 +863,7 @@ void MainInterface::toggleMinimalView( bool b_switch ) ...@@ -850,7 +863,7 @@ void MainInterface::toggleMinimalView( bool b_switch )
{ /* NORMAL MODE then */ { /* NORMAL MODE then */
if( !videoWidget || videoWidget->isHidden() ) if( !videoWidget || videoWidget->isHidden() )
{ {
emit askBgWidgetToToggle(); bgWidget->toggle();
} }
else else
{ {
......
...@@ -74,9 +74,8 @@ public: ...@@ -74,9 +74,8 @@ public:
virtual ~MainInterface(); virtual ~MainInterface();
/* Video requests from core */ /* Video requests from core */
WId requestVideo( vout_thread_t *p_nvout, int *pi_x, WId getVideo( vout_thread_t *p_nvout, int *pi_x, int *pi_y,
int *pi_y, unsigned int *pi_width, unsigned int *pi_width, unsigned int *pi_height );
unsigned int *pi_height );
void releaseVideo( void ); void releaseVideo( void );
int controlVideo( int i_query, va_list args ); int controlVideo( int i_query, va_list args );
...@@ -160,6 +159,8 @@ public slots: ...@@ -160,6 +159,8 @@ public slots:
void popupMenu( const QPoint& ); void popupMenu( const QPoint& );
/* Manage the Video Functions from the vout threads */ /* Manage the Video Functions from the vout threads */
void getVideoSlot( WId *p_id, vout_thread_t *, int *pi_x, int *pi_y,
unsigned *pi_width, unsigned *pi_height );
void releaseVideoSlot( void ); void releaseVideoSlot( void );
private slots: private slots:
...@@ -178,11 +179,10 @@ private slots: ...@@ -178,11 +179,10 @@ private slots:
void showCryptedLabel( bool ); void showCryptedLabel( bool );
signals: signals:
void askGetVideo( WId *p_id, vout_thread_t *, int *pi_x, int *pi_y,
unsigned int *pi_width, unsigned int *pi_height );
void askReleaseVideo( ); void askReleaseVideo( );
void askVideoToResize( unsigned int, unsigned int ); void askVideoToResize( unsigned int, unsigned int );
void askVideoToShow( unsigned int, unsigned int );
void askVideoToToggle();
void askBgWidgetToToggle();
void askUpdate(); void askUpdate();
void minimalViewToggled( bool ); void minimalViewToggled( bool );
void fullscreenInterfaceToggled( bool ); void fullscreenInterfaceToggled( bool );
......
...@@ -550,13 +550,13 @@ static int WindowOpen (vlc_object_t *obj) ...@@ -550,13 +550,13 @@ static int WindowOpen (vlc_object_t *obj)
msg_Dbg (obj, "requesting video..."); msg_Dbg (obj, "requesting video...");
#if defined (Q_WS_X11) #if defined (Q_WS_X11)
wnd->handle.xid = p_mi->requestVideo (wnd->vout, &wnd->pos_x, &wnd->pos_y, wnd->handle.xid = p_mi->getVideo (wnd->vout, &wnd->pos_x, &wnd->pos_y,
&wnd->width, &wnd->height); &wnd->width, &wnd->height);
if (!wnd->handle.xid) if (!wnd->handle.xid)
return VLC_EGENERIC; return VLC_EGENERIC;
#elif defined (WIN32) #elif defined (WIN32)
wnd->handle.hwnd = p_mi->requestVideo (wnd->vout, &wnd->pos_x, &wnd->pos_y, wnd->handle.hwnd = p_mi->getVideo (wnd->vout, &wnd->pos_x, &wnd->pos_y,
&wnd->width, &wnd->height); &wnd->width, &wnd->height);
if (!wnd->handle.hwnd) if (!wnd->handle.hwnd)
return VLC_EGENERIC; return VLC_EGENERIC;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment