[vlc-commits] dshow: Use ComPtr to simplify resource management.

Hugo Beauzée-Luyssen git at videolan.org
Tue Dec 6 17:47:51 CET 2016


vlc | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Sun Dec  4 12:22:15 2016 +0100| [cde72d924e46fd70ff8473742c6d90c9b1a4288d] | committer: 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.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=cde72d924e46fd70ff8473742c6d90c9b1a4288d
---

 modules/access/dshow/access.h     |  11 +-
 modules/access/dshow/crossbar.cpp |  72 ++++------
 modules/access/dshow/dshow.cpp    | 284 ++++++++++++++------------------------
 modules/access/dshow/filter.cpp   |  57 +++-----
 modules/access/dshow/filter.h     |  27 ++--
 5 files changed, 174 insertions(+), 277 deletions(-)

diff --git a/modules/access/dshow/access.h b/modules/access/dshow/access.h
index 7a02a58..18665f6 100644
--- a/modules/access/dshow/access.h
+++ b/modules/access/dshow/access.h
@@ -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];
diff --git a/modules/access/dshow/crossbar.cpp b/modules/access/dshow/crossbar.cpp
index 7b163f6..fc3a0b5 100644
--- a/modules/access/dshow/crossbar.cpp
+++ b/modules/access/dshow/crossbar.cpp
@@ -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;
 }
diff --git a/modules/access/dshow/dshow.cpp b/modules/access/dshow/dshow.cpp
index 29de75b..57407a9 100644
--- a/modules/access/dshow/dshow.cpp
+++ b/modules/access/dshow/dshow.cpp
@@ -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 );
-                        p_moniker->Release();
-                        p_class_enum->Release();
                         return NULL;
                     }
-                    p_moniker->Release();
-                    p_class_enum->Release();
                     return p_base_filter;
                 }
             }
         }
-
-        p_moniker->Release();
     }
 
-    p_class_enum->Release();
-
     if( p_listdevices ) {
         devicelist.sort();
         *p_listdevices = devicelist;
     }
-    return NULL;
+    return p_base_filter;
 }
 
 static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
@@ -1313,9 +1269,9 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                               int i_bitspersample, AM_MEDIA_TYPE *mt,
                               size_t mt_max )
 {
-    IEnumPins *p_enumpins;
-    IPin *p_output_pin;
-    IEnumMediaTypes *p_enummt;
+    ComPtr<IEnumPins> p_enumpins;
+    ComPtr<IPin> p_output_pin;
+    ComPtr<IEnumMediaTypes> p_enummt;
     size_t mt_count = 0;
 
     LONGLONG i_AvgTimePerFrame = 0;
@@ -1323,13 +1279,13 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
     if( r_fps )
         i_AvgTimePerFrame = 10000000000LL/(LONGLONG)(r_fps*1000.0f);
 
-    if( FAILED(p_filter->EnumPins( &p_enumpins )) )
+    if( FAILED(p_filter->EnumPins( p_enumpins.GetAddressOf() )) )
     {
         msg_Dbg( p_this, "EnumDeviceCaps failed: no pin enumeration !");
         return 0;
     }
 
-    while( S_OK == p_enumpins->Next( 1, &p_output_pin, NULL ) )
+    while( S_OK == p_enumpins->Next( 1, p_output_pin.ReleaseAndGetAddressOf(), NULL ) )
     {
         PIN_INFO info;
 
@@ -1340,13 +1296,11 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                      info.achName );
             if( info.pFilter ) info.pFilter->Release();
         }
-
-        p_output_pin->Release();
     }
 
     p_enumpins->Reset();
 
-    while( !mt_count && p_enumpins->Next( 1, &p_output_pin, NULL ) == S_OK )
+    while( !mt_count && p_enumpins->Next( 1, p_output_pin.ReleaseAndGetAddressOf(), NULL ) == S_OK )
     {
         PIN_INFO info;
 
@@ -1354,10 +1308,7 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
         {
             if( info.pFilter ) info.pFilter->Release();
             if( info.dir == PINDIR_INPUT )
-            {
-                p_output_pin->Release();
                 continue;
-            }
             msg_Dbg( p_this, "EnumDeviceCaps: trying pin %S", info.achName );
         }
 
@@ -1367,9 +1318,9 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
         ** Configure pin with a default compatible media if possible
         */
 
-        IAMStreamConfig *pSC;
+        ComPtr<IAMStreamConfig> pSC;
         if( SUCCEEDED(p_output_pin->QueryInterface( IID_IAMStreamConfig,
-                                            (void **)&pSC )) )
+                                            (void**)pSC.GetAddressOf() )) )
         {
             int piCount, piSize;
             if( SUCCEEDED(pSC->GetNumberOfCapabilities(&piCount, &piSize)) )
@@ -1562,16 +1513,14 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                         msg_Dbg( p_this, "EnumDeviceCaps: input pin default format configured");
                 }
             }
-            pSC->Release();
         }
 
         /*
         ** Probe pin for available medias (may be a previously configured one)
         */
 
-        if( FAILED( p_output_pin->EnumMediaTypes( &p_enummt ) ) )
+        if( FAILED( p_output_pin->EnumMediaTypes( p_enummt.ReleaseAndGetAddressOf() ) ) )
         {
-            p_output_pin->Release();
             continue;
         }
 
@@ -1631,9 +1580,9 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                     mt[mt_count++] = *p_mt;
 
                     /* Setup a few properties like the audio latency */
-                    IAMBufferNegotiation *p_ambuf;
+                    ComPtr<IAMBufferNegotiation> p_ambuf;
                     if( SUCCEEDED( p_output_pin->QueryInterface(
-                          IID_IAMBufferNegotiation, (void **)&p_ambuf ) ) )
+                          IID_IAMBufferNegotiation, (void **)p_ambuf.GetAddressOf() ) ) )
                     {
                         ALLOCATOR_PROPERTIES AllocProp;
                         AllocProp.cbAlign = -1;
@@ -1646,7 +1595,6 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                         AllocProp.cbPrefix = -1;
                         AllocProp.cBuffers = -1;
                         p_ambuf->SuggestAllocatorProperties( &AllocProp );
-                        p_ambuf->Release();
                     }
                 }
                 else FreeMediaType( *p_mt );
@@ -1737,12 +1685,8 @@ static size_t EnumDeviceCaps( vlc_object_t *p_this, IBaseFilter *p_filter,
                 FreeMediaType( *p_mt );
             }
         }
-
-        p_enummt->Release();
-        p_output_pin->Release();
     }
 
-    p_enumpins->Release();
     return mt_count;
 }
 
@@ -1762,9 +1706,7 @@ static block_t *ReadCompressed( access_t *p_access, bool *eof )
     /* Get new sample/frame from the elementary stream (blocking). */
     vlc_mutex_lock( &p_sys->lock );
 
-    CaptureFilter *p_filter = p_stream->p_capture_filter;
-
-    if( p_filter->CustomGetPin()->CustomGetSample(&sample) != S_OK )
+    if( p_stream->p_capture_filter->CustomGetPin()->CustomGetSample(&sample) != S_OK )
     {   /* No data available. Wait until some data has arrived */
         vlc_cond_wait( &p_sys->wait, &p_sys->lock );
         vlc_mutex_unlock( &p_sys->lock );
@@ -1789,7 +1731,6 @@ static block_t *ReadCompressed( access_t *p_access, bool *eof )
     memcpy( p_block->p_buffer, p_data, i_data_size );
     /* The caller got what he wanted */
 out:
-    sample.p_sample->Release();
     (void) eof;
     return p_block;
 }
@@ -1878,7 +1819,6 @@ static int Demux( demux_t *p_demux )
             p_block = block_Alloc( i_data_size );
             memcpy( p_block->p_buffer, p_data, i_data_size );
             p_block->i_pts = p_block->i_dts = i_pts;
-            sample.p_sample->Release();
 
             if( i_pts > VLC_TS_INVALID )
                 es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_pts );
@@ -2023,11 +1963,11 @@ static int FindDevices( vlc_object_t *p_this, const char *psz_name,
 
 static void ShowPropertyPage( IUnknown *obj )
 {
-    ISpecifyPropertyPages *p_spec;
+    ComPtr<ISpecifyPropertyPages> p_spec;
     CAUUID cauuid;
 
     HRESULT hr = obj->QueryInterface( IID_ISpecifyPropertyPages,
-                                      (void **)&p_spec );
+                                      (void **)p_spec.GetAddressOf() );
     if( FAILED(hr) ) return;
 
     if( SUCCEEDED(p_spec->GetPages( &cauuid )) )
@@ -2041,7 +1981,6 @@ static void ShowPropertyPage( IUnknown *obj )
 
             CoTaskMemFree( cauuid.pElems );
         }
-        p_spec->Release();
     }
 }
 
@@ -2063,30 +2002,28 @@ static void ShowDeviceProperties( vlc_object_t *p_this,
      */
     if( p_graph && b_audio )
     {
-        IAMStreamConfig *p_SC;
+        ComPtr<IAMStreamConfig> p_SC;
 
         msg_Dbg( p_this, "showing WDM Audio Configuration Pages" );
 
         hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                      &MEDIATYPE_Audio, p_device_filter,
-                                     IID_IAMStreamConfig, (void **)&p_SC );
+                                     IID_IAMStreamConfig, (void **)p_SC.GetAddressOf() );
         if( SUCCEEDED(hr) )
         {
-            ShowPropertyPage(p_SC);
-            p_SC->Release();
+            ShowPropertyPage(p_SC.Get());
         }
 
         /*
          * TV Audio filter
          */
-        IAMTVAudio *p_TVA;
+        ComPtr<IAMTVAudio> p_TVA;
         HRESULT hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                              &MEDIATYPE_Audio, p_device_filter,
-                                             IID_IAMTVAudio, (void **)&p_TVA );
+                                             IID_IAMTVAudio, (void **)p_TVA.GetAddressOf() );
         if( SUCCEEDED(hr) )
         {
-            ShowPropertyPage(p_TVA);
-            p_TVA->Release();
+            ShowPropertyPage(p_TVA.Get());
         }
     }
 
@@ -2095,31 +2032,30 @@ static void ShowDeviceProperties( vlc_object_t *p_this,
      */
     if( p_graph && !b_audio )
     {
-        IAMStreamConfig *p_SC;
+        ComPtr<IAMStreamConfig> p_SC;
 
         msg_Dbg( p_this, "showing WDM Video Configuration Pages" );
 
         hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                      &MEDIATYPE_Interleaved, p_device_filter,
-                                     IID_IAMStreamConfig, (void **)&p_SC );
+                                     IID_IAMStreamConfig, (void **)p_SC.GetAddressOf() );
         if( FAILED(hr) )
         {
             hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                          &MEDIATYPE_Video, p_device_filter,
-                                         IID_IAMStreamConfig, (void **)&p_SC );
+                                         IID_IAMStreamConfig, (void **)p_SC.GetAddressOf() );
         }
 
         if( FAILED(hr) )
         {
             hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                          &MEDIATYPE_Stream, p_device_filter,
-                                         IID_IAMStreamConfig, (void **)&p_SC );
+                                         IID_IAMStreamConfig, (void **)p_SC.GetAddressOf() );
         }
 
         if( SUCCEEDED(hr) )
         {
-            ShowPropertyPage(p_SC);
-            p_SC->Release();
+            ShowPropertyPage(p_SC.Get());
         }
     }
 }
@@ -2134,28 +2070,27 @@ static void ShowTunerProperties( vlc_object_t *p_this,
 
     if( !p_graph || b_audio ) return;
 
-    IAMTVTuner *p_TV;
+    ComPtr<IAMTVTuner> p_TV;
     hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                  &MEDIATYPE_Interleaved, p_device_filter,
-                                 IID_IAMTVTuner, (void **)&p_TV );
+                                 IID_IAMTVTuner, (void **)p_TV.GetAddressOf() );
     if( FAILED(hr) )
     {
         hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                      &MEDIATYPE_Video, p_device_filter,
-                                     IID_IAMTVTuner, (void **)&p_TV );
+                                     IID_IAMTVTuner, (void **)p_TV.GetAddressOf() );
     }
 
     if( FAILED(hr) )
     {
         hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE,
                                      &MEDIATYPE_Stream, p_device_filter,
-                                     IID_IAMTVTuner, (void **)&p_TV );
+                                     IID_IAMTVTuner, (void **)p_TV.GetAddressOf() );
     }
 
     if( SUCCEEDED(hr) )
     {
-        ShowPropertyPage(p_TV);
-        p_TV->Release();
+        ShowPropertyPage(p_TV.Get());
     }
 }
 
@@ -2165,7 +2100,7 @@ static void ConfigTuner( vlc_object_t *p_this, ICaptureGraphBuilder2 *p_graph,
     int i_channel, i_country, i_input, i_amtuner_mode, i_standard;
     long l_modes = 0;
     unsigned i_frequency;
-    IAMTVTuner *p_TV;
+    ComPtr<IAMTVTuner> p_TV;
     HRESULT hr;
 
     if( !p_graph ) return;
@@ -2185,19 +2120,19 @@ static void ConfigTuner( vlc_object_t *p_this, ICaptureGraphBuilder2 *p_graph,
 
     hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved,
                                  p_device_filter, IID_IAMTVTuner,
-                                 (void **)&p_TV );
+                                 (void **)p_TV.GetAddressOf() );
     if( FAILED(hr) )
     {
         hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
                                      p_device_filter, IID_IAMTVTuner,
-                                     (void **)&p_TV );
+                                     (void **)p_TV.GetAddressOf() );
     }
 
     if( FAILED(hr) )
     {
         hr = p_graph->FindInterface( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Stream,
                                      p_device_filter, IID_IAMTVTuner,
-                                     (void **)&p_TV );
+                                     (void **)p_TV.GetAddressOf() );
     }
 
     if( FAILED(hr) )
@@ -2221,17 +2156,16 @@ static void ConfigTuner( vlc_object_t *p_this, ICaptureGraphBuilder2 *p_graph,
                        AMTUNER_SUBCHAN_NO_TUNE );
 
     if( i_frequency > 0 || i_standard > 0) {
-        IKsPropertySet *pKs = NULL;
+        ComPtr<IKsPropertySet> pKs;
         DWORD dw_supported = 0;
         KSPROPERTY_TUNER_MODE_CAPS_S ModeCaps;
         KSPROPERTY_TUNER_FREQUENCY_S Frequency;
         KSPROPERTY_TUNER_STANDARD_S Standard;
 
-        hr = p_TV->QueryInterface(IID_IKsPropertySet,(void **)&pKs);
+        hr = p_TV->QueryInterface(IID_IKsPropertySet,(void **)pKs.GetAddressOf());
         if (FAILED(hr))
         {
             msg_Dbg( p_this, "Couldn't QI for IKsPropertySet" );
-            p_TV->Release();
             return;
         }
 
@@ -2255,7 +2189,7 @@ static void ConfigTuner( vlc_object_t *p_this, ICaptureGraphBuilder2 *p_graph,
         else
         {
             msg_Dbg( p_this, "KSPROPERTY_TUNER_MODE_CAPS not supported!" );
-            goto free_on_error;
+            return;
         }
 
         msg_Dbg( p_this, "Frequency range supported from %ld to %ld.",
@@ -2285,13 +2219,13 @@ static void ConfigTuner( vlc_object_t *p_this, ICaptureGraphBuilder2 *p_graph,
                 if(FAILED(hr))
                 {
                     msg_Dbg( p_this, "Couldn't set KSPROPERTY_TUNER_FREQUENCY!" );
-                    goto free_on_error;
+                    return;
                 }
             }
             else
             {
                 msg_Dbg( p_this, "Requested frequency exceeds the supported range!" );
-                goto free_on_error;
+                return;
             }
         }
 
@@ -2308,18 +2242,14 @@ static void ConfigTuner( vlc_object_t *p_this, ICaptureGraphBuilder2 *p_graph,
                 if(FAILED(hr))
                 {
                     msg_Dbg( p_this, "Couldn't set KSPROPERTY_TUNER_STANDARD!" );
-                    goto free_on_error;
+                    return;
                 }
             }
             else
             {
                 msg_Dbg( p_this, "Requested video standard is not supported by the tuner!" );
-                goto free_on_error;
+                return;
             }
         }
-free_on_error:
-        pKs->Release();
     }
-
-    p_TV->Release();
 }
diff --git a/modules/access/dshow/filter.cpp b/modules/access/dshow/filter.cpp
index a6b0995..64d65e2 100644
--- a/modules/access/dshow/filter.cpp
+++ b/modules/access/dshow/filter.cpp
@@ -206,11 +206,11 @@ int GetFourCCFromMediaType( const AM_MEDIA_TYPE &media_type )
  ****************************************************************************/
 
 CapturePin::CapturePin( vlc_object_t *_p_input, access_sys_t *_p_sys,
-                        CaptureFilter *_p_filter,
+                        CaptureFilter* _p_filter,
                         AM_MEDIA_TYPE *mt, size_t mt_count )
   : p_input( _p_input ), p_sys( _p_sys ), p_filter( _p_filter ),
     p_connected_pin( NULL ),  media_types(mt), media_type_count(mt_count),
-    i_ref( 1 )
+    i_ref( 0 )
 {
     cx_media_type.majortype = mt[0].majortype;
     cx_media_type.subtype   = GUID_NULL;
@@ -354,7 +354,7 @@ STDMETHODIMP CapturePin::Connect( IPin *,
     }
 
     if( !pmt ) return S_OK;
- 
+
     if( GUID_NULL != pmt->majortype &&
         media_types[0].majortype != pmt->majortype )
     {
@@ -414,7 +414,6 @@ STDMETHODIMP CapturePin::ReceiveConnection( IPin * pConnector,
     msg_Dbg( p_input, "CapturePin::ReceiveConnection [OK]" );
 
     p_connected_pin = pConnector;
-    p_connected_pin->AddRef();
 
     FreeMediaType( cx_media_type );
     return CopyMediaType( &cx_media_type, pmt );
@@ -431,8 +430,7 @@ STDMETHODIMP CapturePin::Disconnect()
 
     /* samples_queue was already flushed in EndFlush() */
 
-    p_connected_pin->Release();
-    p_connected_pin = NULL;
+    p_connected_pin.Reset();
     //FreeMediaType( cx_media_type );
     //cx_media_type.subtype = GUID_NULL;
 
@@ -446,8 +444,7 @@ STDMETHODIMP CapturePin::ConnectedTo( IPin **pPin )
         return VFW_E_NOT_CONNECTED;
     }
 
-    p_connected_pin->AddRef();
-    *pPin = p_connected_pin;
+    p_connected_pin.CopyTo( pPin );
 
     msg_Dbg( p_input, "CapturePin::ConnectedTo [OK]" );
 
@@ -470,7 +467,7 @@ STDMETHODIMP CapturePin::QueryPinInfo( PIN_INFO * pInfo )
 #endif
 
     pInfo->pFilter = p_filter;
-    if( p_filter ) p_filter->AddRef();
+    p_filter->AddRef();
 
     memcpy(pInfo->achName, PIN_NAME, sizeof(PIN_NAME));
     pInfo->dir = PINDIR_INPUT;
@@ -597,14 +594,10 @@ STDMETHODIMP CapturePin::EndFlush( void )
     msg_Dbg( p_input, "CapturePin::EndFlush" );
 #endif
 
-    VLCMediaSample vlc_sample;
-
     vlc_mutex_lock( &p_sys->lock );
     while( !samples_queue.empty() )
     {
-        vlc_sample = samples_queue.back();
         samples_queue.pop_back();
-        vlc_sample.p_sample->Release();
     }
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -649,7 +642,6 @@ STDMETHODIMP CapturePin::Receive( IMediaSample *pSample )
     msg_Dbg( p_input, "CapturePin::Receive" );
 #endif
 
-    pSample->AddRef();
     mtime_t i_timestamp = mdate() * 10;
     VLCMediaSample vlc_sample = {pSample, i_timestamp};
 
@@ -659,10 +651,8 @@ STDMETHODIMP CapturePin::Receive( IMediaSample *pSample )
     /* Make sure we don't cache too many samples */
     if( samples_queue.size() > 10 )
     {
-        vlc_sample = samples_queue.back();
         samples_queue.pop_back();
         msg_Dbg( p_input, "CapturePin::Receive trashing late input sample" );
-        vlc_sample.p_sample->Release();
     }
 
     vlc_cond_signal( &p_sys->wait );
@@ -701,7 +691,7 @@ CaptureFilter::CaptureFilter( vlc_object_t *_p_input, access_sys_t *p_sys,
                               AM_MEDIA_TYPE *mt, size_t mt_count )
   : p_input( _p_input ),
     p_pin( new CapturePin( _p_input, p_sys, this, mt, mt_count ) ),
-    state( State_Stopped ), i_ref( 1 )
+    state( State_Stopped ), i_ref( 0 )
 {
 }
 
@@ -710,7 +700,6 @@ CaptureFilter::~CaptureFilter()
 #ifdef DEBUG_DSHOW
     msg_Dbg( p_input, "CaptureFilter::~CaptureFilter" );
 #endif
-    p_pin->Release();
 }
 
 /* IUnknown methods */
@@ -853,7 +842,9 @@ STDMETHODIMP CaptureFilter::EnumPins( IEnumPins ** ppEnum )
 
     /* Create a new ref counted enumerator */
     *ppEnum = new (std::nothrow) CaptureEnumPins( p_input, this, NULL );
-    return *ppEnum == NULL ? E_OUTOFMEMORY : NOERROR;
+    if ( *ppEnum == NULL ) return E_OUTOFMEMORY;
+    (*ppEnum)->AddRef();
+    return NOERROR;
 };
 STDMETHODIMP CaptureFilter::FindPin( LPCWSTR, IPin ** )
 {
@@ -870,8 +861,7 @@ STDMETHODIMP CaptureFilter::QueryFilterInfo( FILTER_INFO * pInfo )
 
     memcpy(pInfo->achName, FILTER_NAME, sizeof(FILTER_NAME));
 
-    pInfo->pGraph = p_graph;
-    if( p_graph ) p_graph->AddRef();
+    p_graph.CopyTo( &pInfo->pGraph );
 
     return NOERROR;
 };
@@ -895,7 +885,7 @@ STDMETHODIMP CaptureFilter::QueryVendorInfo( LPWSTR* )
 };
 
 /* Custom methods */
-CapturePin *CaptureFilter::CustomGetPin()
+ComPtr<CapturePin>& CaptureFilter::CustomGetPin()
 {
     return p_pin;
 }
@@ -905,13 +895,10 @@ CapturePin *CaptureFilter::CustomGetPin()
  ****************************************************************************/
 
 CaptureEnumPins::CaptureEnumPins( vlc_object_t *_p_input,
-                                  CaptureFilter *_p_filter,
-                                  CaptureEnumPins *pEnumPins )
-  : p_input( _p_input ), p_filter( _p_filter ), i_ref( 1 )
+                                  ComPtr<CaptureFilter> _p_filter,
+                                  ComPtr<CaptureEnumPins> pEnumPins )
+  : p_input( _p_input ), p_filter( _p_filter ), i_ref( 0 )
 {
-    /* Hold a reference count on our filter */
-    p_filter->AddRef();
-
     /* Are we creating a new enumerator */
 
     if( pEnumPins == NULL )
@@ -929,7 +916,6 @@ CaptureEnumPins::~CaptureEnumPins()
 #ifdef DEBUG_DSHOW_L1
     msg_Dbg( p_input, "CaptureEnumPins::~CaptureEnumPins" );
 #endif
-    p_filter->Release();
 }
 
 /* IUnknown methods */
@@ -983,9 +969,8 @@ STDMETHODIMP CaptureEnumPins::Next( ULONG cPins, IPin ** ppPins,
 
     if( i_position < 1 && cPins > 0 )
     {
-        IPin *pPin = p_filter->CustomGetPin();
-        *ppPins = pPin;
-        pPin->AddRef();
+        ComPtr<CapturePin> pPin = p_filter->CustomGetPin();
+        pPin.CopyTo( ppPins );
         i_fetched = 1;
         i_position++;
     }
@@ -1026,7 +1011,7 @@ STDMETHODIMP CaptureEnumPins::Clone( IEnumPins **ppEnum )
 
     *ppEnum = new (std::nothrow) CaptureEnumPins( p_input, p_filter, this );
     if( *ppEnum == NULL ) return E_OUTOFMEMORY;
-
+    (*ppEnum)->AddRef();
     return NOERROR;
 };
 
@@ -1034,12 +1019,9 @@ STDMETHODIMP CaptureEnumPins::Clone( IEnumPins **ppEnum )
  * Implementation of our dummy directshow enummediatypes class
  ****************************************************************************/
 CaptureEnumMediaTypes::CaptureEnumMediaTypes( vlc_object_t *_p_input,
-    CapturePin *_p_pin, CaptureEnumMediaTypes *pEnumMediaTypes )
+    ComPtr<CapturePin> _p_pin, CaptureEnumMediaTypes *pEnumMediaTypes )
   : p_input( _p_input ), p_pin( _p_pin ), i_ref( 1 )
 {
-    /* Hold a reference count on our filter */
-    p_pin->AddRef();
-
     /* Are we creating a new enumerator */
     if( pEnumMediaTypes == NULL )
     {
@@ -1059,7 +1041,6 @@ CaptureEnumMediaTypes::~CaptureEnumMediaTypes()
     msg_Dbg( p_input, "CaptureEnumMediaTypes::~CaptureEnumMediaTypes" );
 #endif
     FreeMediaType(cx_media_type);
-    p_pin->Release();
 }
 
 /* IUnknown methods */
diff --git a/modules/access/dshow/filter.h b/modules/access/dshow/filter.h
index 69c3c0c..65030cc 100644
--- a/modules/access/dshow/filter.h
+++ b/modules/access/dshow/filter.h
@@ -30,7 +30,7 @@
 
 typedef struct VLCMediaSample
 {
-    IMediaSample *p_sample;
+    ComPtr<IMediaSample> p_sample;
     mtime_t i_timestamp;
 
 } VLCMediaSample;
@@ -52,9 +52,12 @@ class CapturePin: public IPin, public IMemInputPin
 
     vlc_object_t *p_input;
     access_sys_t *p_sys;
-    CaptureFilter  *p_filter;
+    // Don't store this filter as a ComPtr to avoid a circular reference.
+    // p_filter is the parent filter, and already has a refcounter pointer to this CapturePin
+    // instance
+    CaptureFilter* p_filter;
 
-    IPin *p_connected_pin;
+    ComPtr<IPin> p_connected_pin;
 
     AM_MEDIA_TYPE *media_types;
     size_t media_type_count;
@@ -67,7 +70,7 @@ class CapturePin: public IPin, public IMemInputPin
 
   public:
     CapturePin( vlc_object_t *_p_input, access_sys_t *p_sys,
-                CaptureFilter *_p_filter,
+                CaptureFilter* _p_filter,
                 AM_MEDIA_TYPE *mt, size_t mt_count );
     virtual ~CapturePin();
 
@@ -120,8 +123,8 @@ class CaptureFilter : public IBaseFilter
     friend class CapturePin;
 
     vlc_object_t   *p_input;
-    CapturePin     *p_pin;
-    IFilterGraph   *p_graph;
+    ComPtr<CapturePin>   p_pin;
+    ComPtr<IFilterGraph> p_graph;
     //AM_MEDIA_TYPE  media_type;
     FILTER_STATE   state;
 
@@ -156,7 +159,7 @@ class CaptureFilter : public IBaseFilter
     STDMETHODIMP QueryVendorInfo( LPWSTR* pVendorInfo );
 
     /* Custom methods */
-    CapturePin *CustomGetPin();
+    ComPtr<CapturePin>& CustomGetPin();
 };
 
 /****************************************************************************
@@ -165,14 +168,14 @@ class CaptureFilter : public IBaseFilter
 class CaptureEnumPins : public IEnumPins
 {
     vlc_object_t *p_input;
-    CaptureFilter  *p_filter;
+    ComPtr<CaptureFilter> p_filter;
 
     int i_position;
     long i_ref;
 
 public:
-    CaptureEnumPins( vlc_object_t *_p_input, CaptureFilter *_p_filter,
-                     CaptureEnumPins *pEnumPins );
+    CaptureEnumPins( vlc_object_t *_p_input, ComPtr<CaptureFilter> _p_filter,
+                     ComPtr<CaptureEnumPins> pEnumPins );
     virtual ~CaptureEnumPins();
 
     // IUnknown
@@ -193,14 +196,14 @@ public:
 class CaptureEnumMediaTypes : public IEnumMediaTypes
 {
     vlc_object_t *p_input;
-    CapturePin     *p_pin;
+    ComPtr<CapturePin> p_pin;
     AM_MEDIA_TYPE cx_media_type;
 
     size_t i_position;
     long i_ref;
 
 public:
-    CaptureEnumMediaTypes( vlc_object_t *_p_input, CapturePin *_p_pin,
+    CaptureEnumMediaTypes( vlc_object_t *_p_input, ComPtr<CapturePin> _p_pin,
                            CaptureEnumMediaTypes *pEnumMediaTypes );
 
     virtual ~CaptureEnumMediaTypes();



More information about the vlc-commits mailing list