Commit cde72d92 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

dshow: Use ComPtr to simplify resource management.

As a side note, refcounts are now initialized with 0, which is expected
so a "smart" pointer can increment the refcount itself upon acquiring
the pointer.
parent f164f94c
......@@ -28,6 +28,9 @@
#include <dshow.h>
#include <wrl/client.h>
using Microsoft::WRL::ComPtr;
typedef struct dshow_stream_t dshow_stream_t;
/****************************************************************************
......@@ -37,7 +40,7 @@ typedef struct dshow_stream_t dshow_stream_t;
typedef struct CrossbarRouteRec
{
IAMCrossbar *pXbar;
ComPtr<IAMCrossbar> pXbar;
LONG VideoInputIndex;
LONG VideoOutputIndex;
LONG AudioInputIndex;
......@@ -58,9 +61,9 @@ struct access_sys_t
vlc_mutex_t lock;
vlc_cond_t wait;
IFilterGraph *p_graph;
ICaptureGraphBuilder2 *p_capture_graph_builder2;
IMediaControl *p_control;
ComPtr<IFilterGraph> p_graph;
ComPtr<ICaptureGraphBuilder2> p_capture_graph_builder2;
ComPtr<IMediaControl> p_control;
int i_crossbar_route_depth;
CrossbarRoute crossbar_routes[MAX_CROSSBAR_DEPTH];
......
......@@ -80,7 +80,7 @@ void DeleteCrossbarRoutes( access_sys_t *p_sys )
/* Remove crossbar filters from graph */
for( int i = 0; i < p_sys->i_crossbar_route_depth; i++ )
{
p_sys->crossbar_routes[i].pXbar->Release();
p_sys->crossbar_routes[i].pXbar.Reset();
}
p_sys->i_crossbar_route_depth = 0;
}
......@@ -89,30 +89,27 @@ void DeleteCrossbarRoutes( access_sys_t *p_sys )
* RouteCrossbars (Does not AddRef the returned *Pin)
*****************************************************************************/
static HRESULT GetCrossbarIPinAtIndex( IAMCrossbar *pXbar, LONG PinIndex,
BOOL IsInputPin, IPin ** ppPin )
BOOL IsInputPin, ComPtr<IPin>* ppPin )
{
LONG cntInPins, cntOutPins;
IPin *pP = NULL;
IBaseFilter *pFilter = NULL;
IEnumPins *pins = NULL;
ComPtr<IPin> pP;
ComPtr<IBaseFilter> pFilter;
ComPtr<IEnumPins> pins;
ULONG n;
if( !pXbar || !ppPin ) return E_POINTER;
*ppPin = 0;
if( S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins) ) return E_FAIL;
LONG TrueIndex = IsInputPin ? PinIndex : PinIndex + cntInPins;
if( pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter) == S_OK )
if( pXbar->QueryInterface(IID_IBaseFilter, (void **)pFilter.GetAddressOf()) == S_OK )
{
if( SUCCEEDED(pFilter->EnumPins(&pins)) )
if( SUCCEEDED(pFilter->EnumPins(pins.GetAddressOf())) )
{
LONG i = 0;
while( pins->Next(1, &pP, &n) == S_OK )
while( pins->Next(1, pP.ReleaseAndGetAddressOf(), &n) == S_OK )
{
pP->Release();
if( i == TrueIndex )
{
*ppPin = pP;
......@@ -120,9 +117,7 @@ static HRESULT GetCrossbarIPinAtIndex( IAMCrossbar *pXbar, LONG PinIndex,
}
i++;
}
pins->Release();
}
pFilter->Release();
}
return *ppPin ? S_OK : E_FAIL;
......@@ -135,9 +130,9 @@ static HRESULT GetCrossbarIndexFromIPin( IAMCrossbar * pXbar, LONG * PinIndex,
BOOL IsInputPin, IPin * pPin )
{
LONG cntInPins, cntOutPins;
IPin *pP = NULL;
IBaseFilter *pFilter = NULL;
IEnumPins *pins = NULL;
ComPtr<IPin> pP;
ComPtr<IBaseFilter> pFilter;
ComPtr<IEnumPins> pins;
ULONG n;
BOOL fOK = FALSE;
......@@ -147,16 +142,15 @@ static HRESULT GetCrossbarIndexFromIPin( IAMCrossbar * pXbar, LONG * PinIndex,
if( S_OK != pXbar->get_PinCounts(&cntOutPins, &cntInPins) )
return E_FAIL;
if( pXbar->QueryInterface(IID_IBaseFilter, (void **)&pFilter) == S_OK )
if( pXbar->QueryInterface(IID_IBaseFilter, (void **)pFilter.GetAddressOf()) == S_OK )
{
if( SUCCEEDED(pFilter->EnumPins(&pins)) )
{
LONG i=0;
while( pins->Next(1, &pP, &n) == S_OK )
while( pins->Next(1, pP.ReleaseAndGetAddressOf(), &n) == S_OK )
{
pP->Release();
if( pPin == pP )
if( pPin == pP.Get() )
{
*PinIndex = IsInputPin ? i : i - cntInPins;
fOK = TRUE;
......@@ -164,9 +158,7 @@ static HRESULT GetCrossbarIndexFromIPin( IAMCrossbar * pXbar, LONG * PinIndex,
}
i++;
}
pins->Release();
}
pFilter->Release();
}
return fOK ? S_OK : E_FAIL;
......@@ -180,48 +172,42 @@ HRESULT FindCrossbarRoutes( vlc_object_t *p_this, access_sys_t *p_sys,
{
HRESULT result = S_FALSE;
IPin *p_output_pin;
if( FAILED(p_input_pin->ConnectedTo(&p_output_pin)) ) return S_FALSE;
ComPtr<IPin> p_output_pin;
if( FAILED(p_input_pin->ConnectedTo(p_output_pin.GetAddressOf())) ) return S_FALSE;
// It is connected, so now find out if the filter supports IAMCrossbar
PIN_INFO pinInfo;
if( FAILED(p_output_pin->QueryPinInfo(&pinInfo)) ||
PINDIR_OUTPUT != pinInfo.dir )
{
p_output_pin->Release ();
return S_FALSE;
}
IAMCrossbar *pXbar = NULL;
ComPtr<IAMCrossbar> pXbar;
if( FAILED(pinInfo.pFilter->QueryInterface(IID_IAMCrossbar,
(void **)&pXbar)) )
(void **)pXbar.GetAddressOf())) )
{
pinInfo.pFilter->Release();
p_output_pin->Release ();
return S_FALSE;
}
LONG inputPinCount, outputPinCount;
if( FAILED(pXbar->get_PinCounts(&outputPinCount, &inputPinCount)) )
{
pXbar->Release();
pinInfo.pFilter->Release();
p_output_pin->Release ();
return S_FALSE;
}
LONG inputPinIndexRelated, outputPinIndexRelated;
LONG inputPinPhysicalType = 0, outputPinPhysicalType;
LONG inputPinIndex = 0, outputPinIndex;
if( FAILED(GetCrossbarIndexFromIPin( pXbar, &outputPinIndex,
FALSE, p_output_pin )) ||
if( FAILED(GetCrossbarIndexFromIPin( pXbar.Get(), &outputPinIndex,
FALSE, p_output_pin.Get() )) ||
FAILED(pXbar->get_CrossbarPinInfo( FALSE, outputPinIndex,
&outputPinIndexRelated,
&outputPinPhysicalType )) )
{
pXbar->Release();
pinInfo.pFilter->Release();
p_output_pin->Release ();
return S_FALSE;
}
......@@ -269,22 +255,19 @@ HRESULT FindCrossbarRoutes( vlc_object_t *p_this, access_sys_t *p_sys,
// Can we route it?
if( FAILED(pXbar->CanRoute(outputPinIndex, inputPinIndex)) ) continue;
IPin *pPin;
if( FAILED(GetCrossbarIPinAtIndex( pXbar, inputPinIndex,
TRUE, &pPin)) ) continue;
result = FindCrossbarRoutes( p_this, p_sys, pPin,
ComPtr<IPin> pPin;
if( FAILED(GetCrossbarIPinAtIndex( pXbar.Get(), inputPinIndex,
TRUE, &pPin ) ) ) continue;
result = FindCrossbarRoutes( p_this, p_sys, pPin.Get(),
physicalType, depth+1 );
if( S_OK == result || (S_FALSE == result &&
physicalType == inputPinPhysicalType &&
(p_sys->i_crossbar_route_depth = depth+1) < MAX_CROSSBAR_DEPTH) )
{
// hold on crossbar, will be released when graph is destroyed
pXbar->AddRef();
// remember crossbar route
p_sys->crossbar_routes[depth].pXbar = pXbar;
p_sys->crossbar_routes[depth].VideoInputIndex = inputPinIndex;
......@@ -300,10 +283,7 @@ HRESULT FindCrossbarRoutes( vlc_object_t *p_this, access_sys_t *p_sys,
result = S_OK;
}
}
pXbar->Release();
pinInfo.pFilter->Release();
p_output_pin->Release ();
return result;
}
......@@ -64,7 +64,7 @@ static int Demux ( demux_t * );
static int DemuxControl( demux_t *, int, va_list );
static int OpenDevice( vlc_object_t *, access_sys_t *, std::string, bool );
static IBaseFilter *FindCaptureDevice( vlc_object_t *, std::string *,
static ComPtr<IBaseFilter> FindCaptureDevice( vlc_object_t *, std::string *,
std::list<std::string> *, bool );
static size_t EnumDeviceCaps( vlc_object_t *, IBaseFilter *,
int, int, int, int, int, int,
......@@ -305,9 +305,9 @@ vlc_module_end ()
*****************************************************************************/
typedef struct dshow_stream_t
{
std::string devicename;
IBaseFilter *p_device_filter;
CaptureFilter *p_capture_filter;
std::string devicename;
ComPtr<IBaseFilter> p_device_filter;
ComPtr<CaptureFilter> p_capture_filter;
AM_MEDIA_TYPE mt;
union
......@@ -334,19 +334,19 @@ static void CreateDirectShowGraph( access_sys_t *p_sys )
/* Create directshow filter graph */
if( SUCCEEDED( CoCreateInstance( CLSID_FilterGraph, 0, CLSCTX_INPROC,
(REFIID)IID_IFilterGraph, (void **)&p_sys->p_graph) ) )
(REFIID)IID_IFilterGraph, (void**)p_sys->p_graph.GetAddressOf() ) ) )
{
/* Create directshow capture graph builder if available */
if( SUCCEEDED( CoCreateInstance( CLSID_CaptureGraphBuilder2, 0,
CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2,
(void **)&p_sys->p_capture_graph_builder2 ) ) )
(void**)p_sys->p_capture_graph_builder2.GetAddressOf() ) ) )
{
p_sys->p_capture_graph_builder2->
SetFiltergraph((IGraphBuilder *)p_sys->p_graph);
SetFiltergraph((IGraphBuilder *)p_sys->p_graph.Get() );
}
p_sys->p_graph->QueryInterface( IID_IMediaControl,
(void **)&p_sys->p_control );
(void**)p_sys->p_control.GetAddressOf() );
}
}
......@@ -361,31 +361,18 @@ static void DeleteDirectShowGraph( vlc_object_t *p_this, access_sys_t *p_sys )
/* RemoveFilter does an undocumented Release()
* but does not set item to NULL */
msg_Dbg( p_this, "DeleteDirectShowGraph: Removing capture filter" );
p_sys->p_graph->RemoveFilter( p_sys->pp_streams[i]->p_capture_filter );
p_sys->pp_streams[i]->p_capture_filter = NULL;
p_sys->p_graph->RemoveFilter( p_sys->pp_streams[i]->p_capture_filter.Get() );
p_sys->pp_streams[i]->p_capture_filter.Reset();
msg_Dbg( p_this, "DeleteDirectShowGraph: Removing device filter" );
p_sys->p_graph->RemoveFilter( p_sys->pp_streams[i]->p_device_filter );
p_sys->pp_streams[i]->p_device_filter = NULL;
p_sys->p_graph->RemoveFilter( p_sys->pp_streams[i]->p_device_filter.Get() );
p_sys->pp_streams[i]->p_device_filter.Reset();
}
/* Release directshow objects */
if( p_sys->p_control )
{
p_sys->p_control->Release();
p_sys->p_control = NULL;
}
if( p_sys->p_capture_graph_builder2 )
{
p_sys->p_capture_graph_builder2->Release();
p_sys->p_capture_graph_builder2 = NULL;
}
if( p_sys->p_graph )
{
p_sys->p_graph->Release();
p_sys->p_graph = NULL;
}
p_sys->p_control.Reset();
p_sys->p_capture_graph_builder2.Reset();
p_sys->p_graph.Reset();
}
/*****************************************************************************
......@@ -508,10 +495,6 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
p_sys->i_height = i_height;
p_sys->i_chroma = i_chroma;
p_sys->p_graph = NULL;
p_sys->p_capture_graph_builder2 = NULL;
p_sys->p_control = NULL;
/* Build directshow graph */
CreateDirectShowGraph( p_sys );
......@@ -572,8 +555,8 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
{
/* FIXME: we do MEDIATYPE_Stream here so we don't do
* it twice. */
ShowTunerProperties( p_this, p_sys->p_capture_graph_builder2,
p_stream->p_device_filter, 0 );
ShowTunerProperties( p_this, p_sys->p_capture_graph_builder2.Get(),
p_stream->p_device_filter.Get(), 0 );
}
}
}
......@@ -615,7 +598,7 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
if( i_val >= 0 )
p_sys->crossbar_routes[i].AudioOutputIndex = i_val;
IAMCrossbar *pXbar = p_sys->crossbar_routes[i].pXbar;
IAMCrossbar *pXbar = p_sys->crossbar_routes[i].pXbar.Get();
LONG VideoInputIndex = p_sys->crossbar_routes[i].VideoInputIndex;
LONG VideoOutputIndex = p_sys->crossbar_routes[i].VideoOutputIndex;
LONG AudioInputIndex = p_sys->crossbar_routes[i].AudioInputIndex;
......@@ -650,14 +633,13 @@ static int CommonOpen( vlc_object_t *p_this, access_sys_t *p_sys,
{
for( int i = p_sys->i_crossbar_route_depth-1; i >= 0 ; --i )
{
IAMCrossbar *pXbar = p_sys->crossbar_routes[i].pXbar;
IBaseFilter *p_XF;
IAMCrossbar *pXbar = p_sys->crossbar_routes[i].pXbar.Get();
ComPtr<IBaseFilter> p_XF;
if( SUCCEEDED( pXbar->QueryInterface( IID_IBaseFilter,
(void **)&p_XF ) ) )
(void**)p_XF.ReleaseAndGetAddressOf() ) ) )
{
ShowPropertyPage( p_XF );
p_XF->Release();
ShowPropertyPage( p_XF.Get() );
}
}
}
......@@ -856,7 +838,7 @@ static bool ConnectFilters( vlc_object_t *p_this, access_sys_t *p_sys,
IBaseFilter *p_filter,
CaptureFilter *p_capture_filter )
{
CapturePin *p_input_pin = p_capture_filter->CustomGetPin();
ComPtr<CapturePin> p_input_pin = p_capture_filter->CustomGetPin();
AM_MEDIA_TYPE mediaType = p_input_pin->CustomGetMediaType();
......@@ -871,27 +853,27 @@ static bool ConnectFilters( vlc_object_t *p_this, access_sys_t *p_sys,
// Sort out all the possible video inputs
// The class needs to be given the capture filters ANALOGVIDEO input pin
IEnumPins *pins = NULL;
ComPtr<IEnumPins> pins;
if( ( mediaType.majortype == MEDIATYPE_Video ||
mediaType.majortype == MEDIATYPE_Stream ) &&
SUCCEEDED(p_filter->EnumPins(&pins)) )
SUCCEEDED(p_filter->EnumPins(pins.GetAddressOf())) )
{
IPin *pP = NULL;
ComPtr<IPin> pP;
ULONG n;
PIN_INFO pinInfo;
BOOL Found = FALSE;
IKsPropertySet *pKs = NULL;
GUID guid;
DWORD dw;
while( !Found && ( S_OK == pins->Next(1, &pP, &n) ) )
while( !Found && ( S_OK == pins->Next(1, pP.ReleaseAndGetAddressOf(), &n) ) )
{
if( S_OK == pP->QueryPinInfo(&pinInfo) )
{
ComPtr<IKsPropertySet> pKs;
// is this pin an ANALOGVIDEOIN input pin?
if( pinInfo.dir == PINDIR_INPUT &&
pP->QueryInterface( IID_IKsPropertySet,
(void **)&pKs ) == S_OK )
(void**)pKs.GetAddressOf() ) == S_OK )
{
if( pKs->Get( AMPROPSETID_Pin,
AMPROPERTY_PIN_CATEGORY, NULL, 0,
......@@ -900,18 +882,15 @@ static bool ConnectFilters( vlc_object_t *p_this, access_sys_t *p_sys,
if( guid == PIN_CATEGORY_ANALOGVIDEOIN )
{
// recursively search crossbar routes
FindCrossbarRoutes( p_this, p_sys, pP, 0 );
FindCrossbarRoutes( p_this, p_sys, pP.Get(), 0 );
// found it
Found = TRUE;
}
}
pKs->Release();
}
pinInfo.pFilter->Release();
}
pP->Release();
}
pins->Release();
msg_Dbg( p_this, "ConnectFilters: graph_builder2 available.") ;
if ( !Found )
msg_Warn( p_this, "ConnectFilters: No crossBar routes found (incompatible pin types)" ) ;
......@@ -920,28 +899,23 @@ static bool ConnectFilters( vlc_object_t *p_this, access_sys_t *p_sys,
}
else
{
IEnumPins *p_enumpins;
IPin *p_pin;
ComPtr<IEnumPins> p_enumpins;
ComPtr<IPin> p_pin;
if( S_OK != p_filter->EnumPins( &p_enumpins ) ) return false;
if( S_OK != p_filter->EnumPins( p_enumpins.GetAddressOf() ) ) return false;
while( S_OK == p_enumpins->Next( 1, &p_pin, NULL ) )
while( S_OK == p_enumpins->Next( 1, p_pin.ReleaseAndGetAddressOf(), NULL ) )
{
PIN_DIRECTION pin_dir;
p_pin->QueryDirection( &pin_dir );
if( pin_dir == PINDIR_OUTPUT &&
p_sys->p_graph->ConnectDirect( p_pin, (IPin *)p_input_pin,
p_sys->p_graph->ConnectDirect( p_pin.Get(), p_input_pin.Get(),
0 ) == S_OK )
{
p_pin->Release();
p_enumpins->Release();
return true;
}
p_pin->Release();
}
p_enumpins->Release();
return false;
}
}
......@@ -1008,7 +982,7 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
msg_Dbg( p_this, "asking for device: %s", devicename.c_str() ) ;
// Use the system device enumerator and class enumerator to find
// a capture/preview device, such as a desktop USB video camera.
IBaseFilter *p_device_filter =
ComPtr<IBaseFilter> p_device_filter =
FindCaptureDevice( p_this, &devicename, NULL, b_audio );
if( p_device_filter )
......@@ -1026,7 +1000,7 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
// Retreive acceptable media types supported by device
AM_MEDIA_TYPE media_types[MAX_MEDIA_TYPES];
size_t media_count =
EnumDeviceCaps( p_this, p_device_filter, b_audio ? 0 : p_sys->i_chroma,
EnumDeviceCaps( p_this, p_device_filter.Get(), b_audio ? 0 : p_sys->i_chroma,
p_sys->i_width, p_sys->i_height,
b_audio ? var_CreateGetInteger( p_this, CFG_PREFIX "audio-channels" ) : 0,
b_audio ? var_CreateGetInteger( p_this, CFG_PREFIX "audio-samplerate" ) : 0,
......@@ -1073,22 +1047,21 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
vlc_dialog_display_error( p_this, _("Capture failed"),
_("The capture device \"%s\" does not support the "
"required parameters."), devicename.c_str() );
p_device_filter->Release();
return VLC_EGENERIC;
}
/* Create and add our capture filter */
CaptureFilter *p_capture_filter =
new CaptureFilter( p_this, p_sys, mt, media_count );
p_sys->p_graph->AddFilter( p_capture_filter, 0 );
ComPtr<CaptureFilter> p_capture_filter(
new CaptureFilter( p_this, p_sys, mt, media_count ) );
p_sys->p_graph->AddFilter( p_capture_filter.Get(), 0 );
/* Add the device filter to the graph (seems necessary with VfW before
* accessing pin attributes). */
p_sys->p_graph->AddFilter( p_device_filter, 0 );
p_sys->p_graph->AddFilter( p_device_filter.Get(), 0 );
/* Attempt to connect one of this device's capture output pins */
msg_Dbg( p_this, "connecting filters" );
if( ConnectFilters( p_this, p_sys, p_device_filter, p_capture_filter ) )
if( ConnectFilters( p_this, p_sys, p_device_filter.Get(), p_capture_filter.Get() ) )
{
/* Success */
msg_Dbg( p_this, "filters connected successfully !" );
......@@ -1103,19 +1076,19 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
* the proper parameters. */
if( var_GetBool( p_this, CFG_PREFIX "config" ) )
{
ShowDeviceProperties( p_this, p_sys->p_capture_graph_builder2,
p_device_filter, b_audio );
ShowDeviceProperties( p_this, p_sys->p_capture_graph_builder2.Get(),
p_device_filter.Get(), b_audio );
}
ConfigTuner( p_this, p_sys->p_capture_graph_builder2,
p_device_filter );
ConfigTuner( p_this, p_sys->p_capture_graph_builder2.Get(),
p_device_filter.Get() );
if( var_GetBool( p_this, CFG_PREFIX "tuner" ) &&
dshow_stream.mt.majortype != MEDIATYPE_Stream )
{
/* FIXME: we do MEDIATYPE_Stream later so we don't do it twice. */
ShowTunerProperties( p_this, p_sys->p_capture_graph_builder2,
p_device_filter, b_audio );
ShowTunerProperties( p_this, p_sys->p_capture_graph_builder2.Get(),
p_device_filter.Get(), b_audio );
}
dshow_stream.mt =
......@@ -1168,15 +1141,8 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
fail:
/* Remove filters from graph */
msg_Dbg( p_this, "OpenDevice: Removing filters" ) ;
p_sys->p_graph->RemoveFilter( p_device_filter );
p_sys->p_graph->RemoveFilter( p_capture_filter );
/* Release objects */
/* RemoveFilter does an undocumented Release()
* but does not set item to NULL*/
p_device_filter = NULL;
p_capture_filter = NULL;
p_sys->p_graph->RemoveFilter( p_device_filter.Get() );
p_sys->p_graph->RemoveFilter( p_capture_filter.Get() );
return VLC_EGENERIC;
}
......@@ -1186,40 +1152,39 @@ static int OpenDevice( vlc_object_t *p_this, access_sys_t *p_sys,
Creates an IBaseFilter when p_devicename corresponds to an existing devname
These actions *may* be requested whith a single call.
*/
static IBaseFilter *
static ComPtr<IBaseFilter>
FindCaptureDevice( vlc_object_t *p_this, std::string *p_devicename,
std::list<std::string> *p_listdevices, bool b_audio )
{
IBaseFilter *p_base_filter = NULL;
IMoniker *p_moniker = NULL;
ComPtr<IBaseFilter> p_base_filter;
ComPtr<IMoniker> p_moniker;
ULONG i_fetched;
HRESULT hr;
std::list<std::string> devicelist;
/* Create the system device enumerator */
ICreateDevEnum *p_dev_enum = NULL;
ComPtr<ICreateDevEnum> p_dev_enum;
hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **)&p_dev_enum );
IID_ICreateDevEnum, (void**)p_dev_enum.GetAddressOf() );
if( FAILED(hr) )
{
msg_Err( p_this, "failed to create the device enumerator (0x%lx)", hr);
return NULL;
return p_base_filter;
}
/* Create an enumerator for the video capture devices */
IEnumMoniker *p_class_enum = NULL;
ComPtr<IEnumMoniker> p_class_enum;
if( !b_audio )
hr = p_dev_enum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory,
&p_class_enum, 0 );
p_class_enum.GetAddressOf(), 0 );
else
hr = p_dev_enum->CreateClassEnumerator( CLSID_AudioInputDeviceCategory,
&p_class_enum, 0 );
p_dev_enum->Release();
p_class_enum.GetAddressOf(), 0 );
if( FAILED(hr) )
{
msg_Err( p_this, "failed to create the class enumerator (0x%lx)", hr );
return NULL;
return p_base_filter;
}
/* If there are no enumerators for the requested type, then
......@@ -1227,7 +1192,7 @@ FindCaptureDevice( vlc_object_t *p_this, std::string *p_devicename,
if( p_class_enum == NULL )
{
msg_Err( p_this, "no %s capture device was detected", ( b_audio ? "audio" : "video" ) );
return NULL;
return p_base_filter;
}
/* Enumerate the devices */
......@@ -1236,18 +1201,17 @@ FindCaptureDevice( vlc_object_t *p_this, std::string *p_devicename,
* it will return S_FALSE (which is not a failure). Therefore, we check
* that the return code is S_OK instead of using SUCCEEDED() macro. */
while( p_class_enum->Next( 1, &p_moniker, &i_fetched ) == S_OK )
while( p_class_enum->Next( 1, p_moniker.ReleaseAndGetAddressOf(), &i_fetched ) == S_OK )
{
/* Getting the property page to get the device name */
IPropertyBag *p_bag;
ComPtr<IPropertyBag> p_bag;
hr = p_moniker->BindToStorage( 0, 0, IID_IPropertyBag,
(void **)&p_bag );
(void**)p_bag.GetAddressOf() );
if( SUCCEEDED(hr) )
{
VARIANT var;
var.vt = VT_BSTR;
hr = p_bag->Read( L"FriendlyName", &var, NULL );
p_bag->Release();
if( SUCCEEDED(hr) )
{
char *p_buf = FromWide( var.bstrVal );
......@@ -1279,32 +1243,24 @@ FindCaptureDevice( vlc_object_t *p_this, std::string *p_devicename,
msg_Dbg( p_this, "asked for %s, binding to %s", p_devicename->c_str() , devname.c_str() ) ;
/* NULL possibly means we don't need BindMoniker BindCtx ?? */
hr = p_moniker->BindToObject( NULL, 0, IID_IBaseFilter,
(void **)&p_base_filter );
(void**)p_base_filter.GetAddressOf() );
if( FAILED(hr) )
{
msg_Err( p_this, "couldn't bind moniker to filter "
"object (0x%lx)", hr );