[PATCH 4/4] amstream: Reimplement IBaseFilter methods in the media stream filter.

Zebediah Figura z.figura12 at gmail.com
Fri May 17 00:31:06 CDT 2019


In the long (or even short) term we probably want to decouple amstream from
strmbase entirely. The fact that pins and filters belong to separate objects
(and either one can even be provided by the application) prevents us from
performing some helpful restructuring.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/amstream/mediastreamfilter.c | 225 +++++++++++++++++++-----------
 1 file changed, 144 insertions(+), 81 deletions(-)

diff --git a/dlls/amstream/mediastreamfilter.c b/dlls/amstream/mediastreamfilter.c
index e9f98b63ca..2daffeabdb 100644
--- a/dlls/amstream/mediastreamfilter.c
+++ b/dlls/amstream/mediastreamfilter.c
@@ -18,19 +18,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "wine/debug.h"
-
 #define COBJMACROS
-
-#include "winbase.h"
-#include "wingdi.h"
-#include "dshow.h"
-
-#include "wine/strmbase.h"
-
 #include "amstream_private.h"
-
-#include "ddstream.h"
+#include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(amstream);
 
@@ -171,18 +161,22 @@ static const IEnumPinsVtbl enum_pins_vtbl =
 };
 
 typedef struct {
-    BaseFilter filter;
+    IMediaStreamFilter IMediaStreamFilter_iface;
+    LONG refcount;
+    CRITICAL_SECTION cs;
+
+    IReferenceClock *clock;
+    WCHAR name[128];
+    IFilterGraph *graph;
     ULONG nb_streams;
     IAMMediaStream** streams;
 } IMediaStreamFilterImpl;
 
 static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface)
 {
-    return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, filter);
+    return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, IMediaStreamFilter_iface);
 }
 
-/*** IUnknown methods ***/
-
 static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *iface, REFIID riid, void **ret_iface)
 {
     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface);
@@ -207,47 +201,45 @@ static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *i
 
 static ULONG WINAPI MediaStreamFilterImpl_AddRef(IMediaStreamFilter *iface)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    ULONG ref = BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface);
+    IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+    ULONG refcount = InterlockedIncrement(&filter->refcount);
 
-    TRACE("(%p)->(): new ref = %u\n", iface, ref);
+    TRACE("%p increasing refcount to %u.\n", iface, refcount);
 
-    return ref;
+    return refcount;
 }
 
 static ULONG WINAPI MediaStreamFilterImpl_Release(IMediaStreamFilter *iface)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    ULONG ref = InterlockedDecrement(&This->filter.refCount);
+    IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+    ULONG refcount = InterlockedDecrement(&filter->refcount);
+    unsigned int i;
 
-    TRACE("(%p)->(): new ref = %u\n", iface, ref);
+    TRACE("%p decreasing refcount to %u.\n", iface, refcount);
 
-    if (!ref)
+    if (!refcount)
     {
-        ULONG i;
-        for (i = 0; i < This->nb_streams; i++)
+        for (i = 0; i < filter->nb_streams; ++i)
         {
-            IAMMediaStream_JoinFilter(This->streams[i], NULL);
-            IAMMediaStream_Release(This->streams[i]);
+            IAMMediaStream_JoinFilter(filter->streams[i], NULL);
+            IAMMediaStream_Release(filter->streams[i]);
         }
-        CoTaskMemFree(This->streams);
-        BaseFilter_Destroy(&This->filter);
-        HeapFree(GetProcessHeap(), 0, This);
+        heap_free(filter->streams);
+        if (filter->clock)
+            IReferenceClock_Release(filter->clock);
+        DeleteCriticalSection(&filter->cs);
+        heap_free(filter);
     }
 
-    return ref;
+    return refcount;
 }
 
-/*** IPersist methods ***/
-
 static HRESULT WINAPI MediaStreamFilterImpl_GetClassID(IMediaStreamFilter *iface, CLSID *clsid)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_GetClassID(&This->filter.IBaseFilter_iface, clsid);
+    *clsid = CLSID_MediaStreamFilter;
+    return S_OK;
 }
 
-/*** IBaseFilter methods ***/
-
 static HRESULT WINAPI MediaStreamFilterImpl_Stop(IMediaStreamFilter *iface)
 {
     FIXME("(%p)->(): Stub!\n", iface);
@@ -269,22 +261,48 @@ static HRESULT WINAPI MediaStreamFilterImpl_Run(IMediaStreamFilter *iface, REFER
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter *iface, DWORD ms_timeout, FILTER_STATE *state)
+static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter *iface, DWORD timeout, FILTER_STATE *state)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_GetState(&This->filter.IBaseFilter_iface, ms_timeout, state);
+    FIXME("iface %p, timeout %u, state %p, stub!\n", iface, timeout, state);
+
+    *state = State_Stopped;
+    return S_OK;
 }
 
 static HRESULT WINAPI MediaStreamFilterImpl_SetSyncSource(IMediaStreamFilter *iface, IReferenceClock *clock)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_SetSyncSource(&This->filter.IBaseFilter_iface, clock);
+    IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+
+    TRACE("iface %p, clock %p.\n", iface, clock);
+
+    EnterCriticalSection(&filter->cs);
+
+    if (clock)
+        IReferenceClock_AddRef(clock);
+    if (filter->clock)
+        IReferenceClock_Release(filter->clock);
+    filter->clock = clock;
+
+    LeaveCriticalSection(&filter->cs);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter *iface, IReferenceClock **clock)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_GetSyncSource(&This->filter.IBaseFilter_iface, clock);
+    IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+
+    TRACE("iface %p, clock %p.\n", iface, clock);
+
+    EnterCriticalSection(&filter->cs);
+
+    if (filter->clock)
+        IReferenceClock_AddRef(filter->clock);
+    *clock = filter->clock;
+
+    LeaveCriticalSection(&filter->cs);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins)
@@ -295,6 +313,8 @@ static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface,
 
     TRACE("iface %p, enum_pins %p.\n", iface, enum_pins);
 
+    EnterCriticalSection(&filter->cs);
+
     if (!enum_pins)
         return E_POINTER;
 
@@ -316,32 +336,91 @@ static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface,
             WARN("Stream %p does not support IPin.\n", filter->streams[i]);
     }
 
+    LeaveCriticalSection(&filter->cs);
+
     *enum_pins = &object->IEnumPins_iface;
     return S_OK;
 }
 
-static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, LPCWSTR id, IPin **pin)
+static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, const WCHAR *id, IPin **out)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_FindPin(&This->filter.IBaseFilter_iface, id, pin);
+    IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+    unsigned int i;
+    WCHAR *ret_id;
+    IPin *pin;
+
+    TRACE("iface %p, id %s, out %p.\n", iface, debugstr_w(id), out);
+
+    EnterCriticalSection(&filter->cs);
+
+    for (i = 0; i < filter->nb_streams; ++i)
+    {
+        if (FAILED(IAMMediaStream_QueryInterface(filter->streams[i], &IID_IPin, (void **)&pin)))
+        {
+            WARN("Stream %p does not support IPin.\n", filter->streams[i]);
+            continue;
+        }
+
+        if (SUCCEEDED(IPin_QueryId(pin, &ret_id)))
+        {
+            if (!lstrcmpW(id, ret_id))
+            {
+                CoTaskMemFree(ret_id);
+                *out = pin;
+                return S_OK;
+            }
+            CoTaskMemFree(ret_id);
+        }
+        IPin_Release(pin);
+    }
+
+    LeaveCriticalSection(&filter->cs);
+
+    return VFW_E_NOT_FOUND;
 }
 
 static HRESULT WINAPI MediaStreamFilterImpl_QueryFilterInfo(IMediaStreamFilter *iface, FILTER_INFO *info)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_QueryFilterInfo(&This->filter.IBaseFilter_iface, info);
+    IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+
+    TRACE("iface %p, info %p.\n", iface, info);
+
+    EnterCriticalSection(&filter->cs);
+
+    lstrcpyW(info->achName, filter->name);
+    if (filter->graph)
+        IFilterGraph_AddRef(filter->graph);
+    info->pGraph = filter->graph;
+
+    LeaveCriticalSection(&filter->cs);
+
+    return S_OK;
 }
 
-static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter *iface, IFilterGraph *graph, LPCWSTR name)
+static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter *iface,
+        IFilterGraph *graph, const WCHAR *name)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_JoinFilterGraph(&This->filter.IBaseFilter_iface, graph, name);
+    IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface);
+
+    TRACE("iface %p, graph %p, name.%s.\n", iface, graph, debugstr_w(name));
+
+    EnterCriticalSection(&filter->cs);
+
+    if (name)
+        lstrcpynW(filter->name, name, ARRAY_SIZE(filter->name));
+    else
+        filter->name[0] = 0;
+    filter->graph = graph;
+
+    LeaveCriticalSection(&filter->cs);
+
+    return S_OK;
 }
 
 static HRESULT WINAPI MediaStreamFilterImpl_QueryVendorInfo(IMediaStreamFilter *iface, LPWSTR *vendor_info)
 {
-    IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
-    return BaseFilterImpl_QueryVendorInfo(&This->filter.IBaseFilter_iface, vendor_info);
+    WARN("iface %p, vendor_info %p, stub!\n", iface, vendor_info);
+    return E_NOTIMPL;
 }
 
 /*** IMediaStreamFilter methods ***/
@@ -470,40 +549,24 @@ static const IMediaStreamFilterVtbl MediaStreamFilter_Vtbl =
     MediaStreamFilterImpl_EndOfStream
 };
 
-static IPin* WINAPI MediaStreamFilterImpl_GetPin(BaseFilter *iface, int pos)
+HRESULT MediaStreamFilter_create(IUnknown *outer, void **out)
 {
-    IMediaStreamFilterImpl* This = (IMediaStreamFilterImpl*)iface;
+    IMediaStreamFilterImpl *object;
 
-    if (pos < This->nb_streams)
-    {
-        IPin *pin = NULL;
-        IAMMediaStream_QueryInterface(This->streams[pos], &IID_IPin, (void **)&pin);
-        return pin;
-    }
-
-    return NULL;
-}
-
-static const BaseFilterFuncTable BaseFuncTable = {
-    MediaStreamFilterImpl_GetPin,
-};
+    TRACE("outer %p, out %p.\n", outer, out);
 
-HRESULT MediaStreamFilter_create(IUnknown *pUnkOuter, void **ppObj)
-{
-    IMediaStreamFilterImpl* object;
-
-    TRACE("(%p,%p)\n", pUnkOuter, ppObj);
-
-    if( pUnkOuter )
+    if (outer)
         return CLASS_E_NOAGGREGATION;
 
-    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMediaStreamFilterImpl));
-    if (!object)
+    if (!(object = heap_alloc_zero(sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    BaseFilter_Init(&object->filter, (IBaseFilterVtbl*)&MediaStreamFilter_Vtbl, &CLSID_MediaStreamFilter, (DWORD_PTR)(__FILE__ ": MediaStreamFilterImpl.csFilter"), &BaseFuncTable);
-
-    *ppObj = &object->filter.IBaseFilter_iface;
+    object->IMediaStreamFilter_iface.lpVtbl = &MediaStreamFilter_Vtbl;
+    object->refcount = 1;
+    InitializeCriticalSection(&object->cs);
+    object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MediaStreamFilter.cs");
 
+    TRACE("Created media stream filter %p.\n", object);
+    *out = &object->IMediaStreamFilter_iface;
     return S_OK;
 }
-- 
2.21.0




More information about the wine-devel mailing list