[vlc-devel] [PATCH] dshow: Use MTA and stop leaking thread context out of the module
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Thu Jun 1 18:43:19 CEST 2017
Fix #16935
---
modules/access/dshow/dshow.cpp | 44 +++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/modules/access/dshow/dshow.cpp b/modules/access/dshow/dshow.cpp
index d42ec0871e..817584f86d 100644
--- a/modules/access/dshow/dshow.cpp
+++ b/modules/access/dshow/dshow.cpp
@@ -35,6 +35,7 @@
#include <list>
#include <string>
#include <assert.h>
+#include <stdexcept>
#define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS
#include <vlc_common.h>
@@ -299,6 +300,19 @@ vlc_module_begin ()
vlc_module_end ()
+struct ComContext
+{
+ ComContext( int mode )
+ {
+ if( !SUCCEEDED( CoInitializeEx( NULL, mode ) ) )
+ throw std::runtime_error( "CoInitializeEx failed" );
+ }
+ ~ComContext()
+ {
+ CoUninitialize();
+ }
+
+};
/*****************************************************************************
* DirectShow elementary stream descriptor
@@ -392,10 +406,6 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
bool b_use_audio = true;
bool b_use_video = true;
- /* Initialize OLE/COM */
- if( FAILED(CoInitializeEx( NULL, COINIT_APARTMENTTHREADED )) )
- vlc_assert_unreachable();
-
var_Create( p_this, CFG_PREFIX "config", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_this, CFG_PREFIX "tuner", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
psz_val = var_CreateGetString( p_this, CFG_PREFIX "vdev" );
@@ -665,6 +675,8 @@ static int DemuxOpen( vlc_object_t *p_this )
return VLC_ENOMEM;
p_demux->p_sys = (demux_sys_t *)p_sys;
+ ComContext ctx( COINIT_MULTITHREADED );
+
if( CommonOpen( p_this, p_sys, true ) != VLC_SUCCESS )
{
CommonClose( p_this, p_sys );
@@ -770,6 +782,8 @@ static int AccessOpen( vlc_object_t *p_this )
if( !p_sys )
return VLC_ENOMEM;
+ ComContext ctx( COINIT_MULTITHREADED );
+
if( CommonOpen( p_this, p_sys, false ) != VLC_SUCCESS )
{
CommonClose( p_this, p_sys );
@@ -804,9 +818,6 @@ static void CommonClose( vlc_object_t *p_this, access_sys_t *p_sys )
DeleteDirectShowGraph( p_this, p_sys );
- /* Uninitialize OLE/COM */
- CoUninitialize();
-
vlc_delete_all( p_sys->pp_streams );
vlc_mutex_destroy( &p_sys->lock );
@@ -823,6 +834,8 @@ static void AccessClose( vlc_object_t *p_this )
access_t *p_access = (access_t *)p_this;
access_sys_t *p_sys = (access_sys_t *)p_access->p_sys;
+ ComContext ctx( COINIT_MULTITHREADED );
+
/* Stop capturing stuff */
p_sys->p_control->Stop();
@@ -837,6 +850,8 @@ static void DemuxClose( vlc_object_t *p_this )
demux_t *p_demux = (demux_t *)p_this;
access_sys_t *p_sys = (access_sys_t *)p_demux->p_sys;
+ ComContext ctx( COINIT_MULTITHREADED );
+
/* Stop capturing stuff */
p_sys->p_control->Stop();
@@ -1738,6 +1753,8 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
*****************************************************************************/
static block_t *ReadCompressed( access_t *p_access, bool *eof )
{
+ ComContext ctx( COINIT_MULTITHREADED );
+
access_sys_t *p_sys = (access_sys_t *)p_access->p_sys;
/* There must be only 1 elementary stream to produce a valid stream
* of MPEG or DV data */
@@ -1783,6 +1800,8 @@ out:
****************************************************************************/
static int Demux( demux_t *p_demux )
{
+ ComContext ctx( COINIT_MULTITHREADED );
+
access_sys_t *p_sys = (access_sys_t *)p_demux->p_sys;
int i_found_samples;
@@ -2017,11 +2036,12 @@ static int FindDevices( vlc_object_t *p_this, const char *psz_name,
{
/* Find list of devices */
std::list<std::string> list_devices;
- if( SUCCEEDED(CoInitializeEx( NULL, COINIT_MULTITHREADED ))
- || SUCCEEDED(CoInitializeEx( NULL, COINIT_APARTMENTTHREADED )) )
+ try
{
bool b_audio = !strcmp( psz_name, CFG_PREFIX "adev" );
+ ComContext ctx( COINIT_MULTITHREADED );
+
FindCaptureDevice( p_this, NULL, &list_devices, b_audio );
if( b_audio )
@@ -2031,8 +2051,10 @@ static int FindDevices( vlc_object_t *p_this, const char *psz_name,
if( !list_vdevs.empty() )
AppendAudioEnabledVDevs( p_this, list_devices, list_vdevs );
}
-
- CoUninitialize();
+ }
+ catch (const std::runtime_error& ex)
+ {
+ msg_Err( p_this, "Failed fetch devices: %s", ex.what() );
}
unsigned count = 2 + list_devices.size(), i = 2;
--
2.11.0
More information about the vlc-devel
mailing list