[PATCH v2 5/6] quartz/filtergraph: Use a linked list to store filters.

Zebediah Figura z.figura12 at gmail.com
Tue Sep 18 09:40:45 CDT 2018


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/quartz/filtergraph.c       | 215 +++++++++++++++++++---------------------
 dlls/quartz/tests/filtergraph.c |   7 --
 2 files changed, 100 insertions(+), 122 deletions(-)

diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 76cc0c7..9d34bd4 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -37,6 +37,7 @@
 #include "vfwmsgs.h"
 #include "evcode.h"
 #include "wine/heap.h"
+#include "wine/list.h"
 #include "wine/unicode.h"
 
 
@@ -149,6 +150,13 @@ typedef struct _ITF_CACHE_ENTRY {
    IUnknown* iface;
 } ITF_CACHE_ENTRY;
 
+struct filter
+{
+    struct list entry;
+    IBaseFilter *filter;
+    WCHAR *name;
+};
+
 typedef struct _IFilterGraphImpl {
     IUnknown IUnknown_inner;
     IFilterGraph2 IFilterGraph2_iface;
@@ -177,10 +185,7 @@ typedef struct _IFilterGraphImpl {
     IUnknown *outer_unk;
     LONG ref;
     IUnknown *punkFilterMapper2;
-    IBaseFilter ** ppFiltersInGraph;
-    LPWSTR * pFilterNames;
-    ULONG nFilters;
-    int filterCapacity;
+    struct list filters;
     LONG nameIndex;
     IReferenceClock *refClock;
     IBaseFilter *refClockProvider;
@@ -213,10 +218,10 @@ struct enum_filters
     LONG ref;
     IFilterGraphImpl *graph;
     LONG version;
-    ULONG index;
+    struct list *cursor;
 };
 
-static HRESULT create_enum_filters(IFilterGraphImpl *graph, IEnumFilters **out);
+static HRESULT create_enum_filters(IFilterGraphImpl *graph, struct list *cursor, IEnumFilters **out);
 
 static inline struct enum_filters *impl_from_IEnumFilters(IEnumFilters *iface)
 {
@@ -269,33 +274,32 @@ static HRESULT WINAPI EnumFilters_Next(IEnumFilters *iface, ULONG count,
         IBaseFilter **filters, ULONG *fetched)
 {
     struct enum_filters *enum_filters = impl_from_IEnumFilters(iface);
-    unsigned int i, cFetched;
+    unsigned int i = 0;
 
     TRACE("enum_filters %p, count %u, filters %p, fetched %p.\n",
             enum_filters, count, filters, fetched);
 
-    cFetched = min(enum_filters->graph->nFilters, enum_filters->index + count) - enum_filters->index;
-
     if (enum_filters->version != enum_filters->graph->version)
         return VFW_E_ENUM_OUT_OF_SYNC;
 
     if (!filters)
         return E_POINTER;
 
-    for (i = 0; i < cFetched; i++)
+    for (i = 0; i < count; ++i)
     {
-        filters[i] = enum_filters->graph->ppFiltersInGraph[enum_filters->index + i];
-        IBaseFilter_AddRef(filters[i]);
+        struct filter *filter = LIST_ENTRY(enum_filters->cursor, struct filter, entry);
+
+        if (!enum_filters->cursor)
+            break;
+
+        IBaseFilter_AddRef(filters[i] = filter->filter);
+        enum_filters->cursor = list_next(&enum_filters->graph->filters, enum_filters->cursor);
     }
 
-    enum_filters->index += cFetched;
-
     if (fetched)
-        *fetched = cFetched;
+        *fetched = i;
 
-    if (cFetched != count)
-        return S_FALSE;
-    return S_OK;
+    return (i == count) ? S_OK : S_FALSE;
 }
 
 static HRESULT WINAPI EnumFilters_Skip(IEnumFilters *iface, ULONG count)
@@ -304,12 +308,16 @@ static HRESULT WINAPI EnumFilters_Skip(IEnumFilters *iface, ULONG count)
 
     TRACE("enum_filters %p, count %u.\n", enum_filters, count);
 
-    if (enum_filters->index + count < enum_filters->graph->nFilters)
+    if (!enum_filters->cursor)
+        return S_FALSE;
+
+    while (count--)
     {
-        enum_filters->index += count;
-        return S_OK;
+        if (!(enum_filters->cursor = list_next(&enum_filters->graph->filters, enum_filters->cursor)))
+            return S_FALSE;
     }
-    return S_FALSE;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI EnumFilters_Reset(IEnumFilters *iface)
@@ -318,7 +326,7 @@ static HRESULT WINAPI EnumFilters_Reset(IEnumFilters *iface)
 
     TRACE("enum_filters %p.\n", enum_filters);
 
-    enum_filters->index = 0;
+    enum_filters->cursor = list_head(&enum_filters->graph->filters);
     enum_filters->version = enum_filters->graph->version;
     return S_OK;
 }
@@ -326,14 +334,10 @@ static HRESULT WINAPI EnumFilters_Reset(IEnumFilters *iface)
 static HRESULT WINAPI EnumFilters_Clone(IEnumFilters *iface, IEnumFilters **out)
 {
     struct enum_filters *enum_filters = impl_from_IEnumFilters(iface);
-    HRESULT hr;
 
     TRACE("enum_filters %p, out %p.\n", enum_filters, out);
 
-    hr = create_enum_filters(enum_filters->graph, out);
-    if (FAILED(hr))
-        return hr;
-    return IEnumFilters_Skip(*out, enum_filters->index);
+    return create_enum_filters(enum_filters->graph, enum_filters->cursor, out);
 }
 
 static const IEnumFiltersVtbl EnumFilters_vtbl =
@@ -347,7 +351,7 @@ static const IEnumFiltersVtbl EnumFilters_vtbl =
     EnumFilters_Clone,
 };
 
-static HRESULT create_enum_filters(IFilterGraphImpl *graph, IEnumFilters **out)
+static HRESULT create_enum_filters(IFilterGraphImpl *graph, struct list *cursor, IEnumFilters **out)
 {
     struct enum_filters *enum_filters;
 
@@ -356,7 +360,7 @@ static HRESULT create_enum_filters(IFilterGraphImpl *graph, IEnumFilters **out)
 
     enum_filters->IEnumFilters_iface.lpVtbl = &EnumFilters_vtbl;
     enum_filters->ref = 1;
-    enum_filters->index = 0;
+    enum_filters->cursor = cursor;
     enum_filters->graph = graph;
     IUnknown_AddRef(graph->outer_unk);
     enum_filters->version = graph->version;
@@ -455,6 +459,7 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface)
 {
     IFilterGraphImpl *This = impl_from_IUnknown(iface);
     ULONG ref = InterlockedDecrement(&This->ref);
+    struct filter *filter, *next;
 
     TRACE("(%p)->(): new ref = %d\n", This, ref);
 
@@ -465,8 +470,10 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface)
 
         IMediaControl_Stop(&This->IMediaControl_iface);
 
-        while (This->nFilters)
-            IFilterGraph2_RemoveFilter(&This->IFilterGraph2_iface, This->ppFiltersInGraph[0]);
+        LIST_FOR_EACH_ENTRY_SAFE(filter, next, &This->filters, struct filter, entry)
+        {
+            IFilterGraph2_RemoveFilter(&This->IFilterGraph2_iface, filter->filter);
+        }
 
         if (This->refClock)
             IReferenceClock_Release(This->refClock);
@@ -485,8 +492,6 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface)
 	EventsQueue_Destroy(&This->evqueue);
         This->cs.DebugInfo->Spare[0] = 0;
 	DeleteCriticalSection(&This->cs);
-	CoTaskMemFree(This->ppFiltersInGraph);
-	CoTaskMemFree(This->pFilterNames);
 	CoTaskMemFree(This);
     }
     return ref;
@@ -526,12 +531,12 @@ static ULONG WINAPI FilterGraph2_Release(IFilterGraph2 *iface)
 
 static IBaseFilter *find_filter_by_name(IFilterGraphImpl *graph, const WCHAR *name)
 {
-    unsigned int i;
+    struct filter *filter;
 
-    for (i = 0; i < graph->nFilters; ++i)
+    LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry)
     {
-        if (!strcmpW(graph->pFilterNames[i], name))
-            return graph->ppFiltersInGraph[i];
+        if (!strcmpW(filter->name, name))
+            return filter->filter;
     }
 
     return NULL;
@@ -542,6 +547,7 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, IBaseFilter *
         LPCWSTR pName)
 {
     IFilterGraphImpl *This = impl_from_IFilterGraph2(iface);
+    struct filter *entry;
     HRESULT hr;
     int j;
     WCHAR* wszFilterName = NULL;
@@ -588,46 +594,31 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, IBaseFilter *
     else
 	memcpy(wszFilterName, pName, (strlenW(pName) + 1) * sizeof(WCHAR));
 
-    if (This->nFilters + 1 > This->filterCapacity)
-    {
-        int newCapacity = This->filterCapacity ? 2 * This->filterCapacity : 1;
-        IBaseFilter ** ppNewFilters = CoTaskMemAlloc(newCapacity * sizeof(IBaseFilter*));
-        LPWSTR * pNewNames = CoTaskMemAlloc(newCapacity * sizeof(LPWSTR));
-        memcpy(ppNewFilters, This->ppFiltersInGraph, This->nFilters * sizeof(IBaseFilter*));
-        memcpy(pNewNames, This->pFilterNames, This->nFilters * sizeof(LPWSTR));
-        if (This->filterCapacity)
-        {
-            CoTaskMemFree(This->ppFiltersInGraph);
-            CoTaskMemFree(This->pFilterNames);
-        }
-        This->ppFiltersInGraph = ppNewFilters;
-        This->pFilterNames = pNewNames;
-        This->filterCapacity = newCapacity;
-    }
-
     hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)&This->IFilterGraph2_iface, wszFilterName);
-
-    if (SUCCEEDED(hr))
+    if (FAILED(hr))
     {
-        IBaseFilter_AddRef(pFilter);
-        This->ppFiltersInGraph[This->nFilters] = pFilter;
-        This->pFilterNames[This->nFilters] = wszFilterName;
-        This->nFilters++;
-        This->version++;
-        IBaseFilter_SetSyncSource(pFilter, This->refClock);
-    }
-    else
         CoTaskMemFree(wszFilterName);
+        return hr;
+    }
 
-    if (SUCCEEDED(hr) && duplicate_name)
-        return VFW_S_DUPLICATE_NAME;
+    if (!(entry = heap_alloc(sizeof(*entry))))
+    {
+        CoTaskMemFree(wszFilterName);
+        return E_OUTOFMEMORY;
+    }
 
-    return hr;
+    IBaseFilter_AddRef(entry->filter = pFilter);
+    entry->name = wszFilterName;
+    list_add_head(&This->filters, &entry->entry);
+    This->version++;
+
+    return duplicate_name ? VFW_S_DUPLICATE_NAME : hr;
 }
 
 static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilter *pFilter)
 {
     IFilterGraphImpl *This = impl_from_IFilterGraph2(iface);
+    struct filter *entry;
     int i;
     HRESULT hr = E_FAIL;
 
@@ -635,9 +626,9 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte
 
     /* FIXME: check graph is stopped */
 
-    for (i = 0; i < This->nFilters; i++)
+    LIST_FOR_EACH_ENTRY(entry, &This->filters, struct filter, entry)
     {
-        if (This->ppFiltersInGraph[i] == pFilter)
+        if (entry->filter == pFilter)
         {
             IEnumPins *penumpins = NULL;
             FILTER_STATE state;
@@ -648,7 +639,7 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte
                 This->defaultclock = TRUE;
             }
 
-            TRACE("Removing filter %s\n", debugstr_w(This->pFilterNames[i]));
+            TRACE("Removing filter %s.\n", debugstr_w(entry->name));
             IBaseFilter_GetState(pFilter, 0, &state);
             if (state == State_Running)
                 IBaseFilter_Pause(pFilter);
@@ -690,15 +681,13 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte
                 IEnumPins_Release(penumpins);
             }
 
-            hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, This->pFilterNames[i]);
+            hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, entry->name);
             if (SUCCEEDED(hr))
             {
                 IBaseFilter_SetSyncSource(pFilter, NULL);
                 IBaseFilter_Release(pFilter);
-                CoTaskMemFree(This->pFilterNames[i]);
-                memmove(This->ppFiltersInGraph+i, This->ppFiltersInGraph+i+1, sizeof(IBaseFilter*)*(This->nFilters - 1 - i));
-                memmove(This->pFilterNames+i, This->pFilterNames+i+1, sizeof(LPWSTR)*(This->nFilters - 1 - i));
-                This->nFilters--;
+                list_remove(&entry->entry);
+                heap_free(entry);
                 This->version++;
                 /* Invalidate interfaces in the cache */
                 for (i = 0; i < This->nItfCacheEntries; i++)
@@ -723,7 +712,7 @@ static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface, IEnumFilter
 
     TRACE("graph %p, out %p.\n", graph, out);
 
-    return create_enum_filters(graph, out);
+    return create_enum_filters(graph, list_head(&graph->filters), out);
 }
 
 static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface,
@@ -919,24 +908,24 @@ static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface)
 {
     IFilterGraphImpl *This = impl_from_IFilterGraph2(iface);
     IReferenceClock *pClock = NULL;
+    struct filter *filter;
     HRESULT hr = S_OK;
-    int i;
 
     TRACE("(%p/%p)->() live sources not handled properly!\n", This, iface);
 
     EnterCriticalSection(&This->cs);
 
-    for (i = 0; i < This->nFilters; ++i)
+    LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
     {
         DWORD miscflags;
         IAMFilterMiscFlags *flags = NULL;
-        IBaseFilter_QueryInterface(This->ppFiltersInGraph[i], &IID_IAMFilterMiscFlags, (void**)&flags);
+        IBaseFilter_QueryInterface(filter->filter, &IID_IAMFilterMiscFlags, (void **)&flags);
         if (!flags)
             continue;
         miscflags = IAMFilterMiscFlags_GetMiscFlags(flags);
         IAMFilterMiscFlags_Release(flags);
         if (miscflags == AM_FILTER_MISC_FLAGS_IS_RENDERER)
-            IBaseFilter_QueryInterface(This->ppFiltersInGraph[i], &IID_IReferenceClock, (void**)&pClock);
+            IBaseFilter_QueryInterface(filter->filter, &IID_IReferenceClock, (void **)&pClock);
         if (pClock)
             break;
     }
@@ -947,7 +936,10 @@ static HRESULT WINAPI FilterGraph2_SetDefaultSyncSource(IFilterGraph2 *iface)
         This->refClockProvider = NULL;
     }
     else
-        This->refClockProvider = This->ppFiltersInGraph[i];
+    {
+        filter = LIST_ENTRY(list_tail(&This->filters), struct filter, entry);
+        This->refClockProvider = filter->filter;
+    }
 
     if (SUCCEEDED(hr))
     {
@@ -1422,6 +1414,7 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut)
 {
     IFilterGraphImpl *This = impl_from_IFilterGraph2(iface);
     IEnumMediaTypes* penummt;
+    struct filter *filter;
     AM_MEDIA_TYPE* mt;
     ULONG nbmt;
     HRESULT hr;
@@ -1430,7 +1423,6 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut)
     GUID tab[4];
     ULONG nb;
     IMoniker* pMoniker;
-    INT x;
     IFilterMapper2 *pFilterMapper2 = NULL;
 
     TRACE("(%p/%p)->(%p)\n", This, iface, ppinOut);
@@ -1450,12 +1442,12 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut)
     /* Try to find out if there is a renderer for the specified subtype already, and use that
      */
     EnterCriticalSection(&This->cs);
-    for (x = 0; x < This->nFilters; ++x)
+    LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
     {
         IEnumPins *enumpins = NULL;
         IPin *pin = NULL;
 
-        hr = IBaseFilter_EnumPins(This->ppFiltersInGraph[x], &enumpins);
+        hr = IBaseFilter_EnumPins(filter->filter, &enumpins);
 
         if (FAILED(hr) || !enumpins)
             continue;
@@ -1683,6 +1675,7 @@ static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface, LPCWSTR lpcw
     IBaseFilter* preader = NULL;
     IPin* ppinreader = NULL;
     IEnumPins* penumpins = NULL;
+    struct filter *filter;
     HRESULT hr;
     BOOL partial = FALSE;
     BOOL any = FALSE;
@@ -1706,13 +1699,11 @@ static HRESULT WINAPI FilterGraph2_RenderFile(IFilterGraph2 *iface, LPCWSTR lpcw
             IPin_QueryDirection(ppinreader, &dir);
             if (dir == PINDIR_OUTPUT)
             {
-                INT i;
-
                 hr = IFilterGraph2_Render(iface, ppinreader);
-                TRACE("Render %08x\n", hr);
 
-                for (i = 0; i < This->nFilters; ++i)
-                    TRACE("Filters in chain: %s\n", debugstr_w(This->pFilterNames[i]));
+                TRACE("Filters in chain:\n");
+                LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
+                    TRACE("- %s.\n", debugstr_w(filter->name));
 
                 if (SUCCEEDED(hr))
                     any = TRUE;
@@ -2160,8 +2151,7 @@ static HRESULT WINAPI SendGetState(IBaseFilter *pFilter, DWORD_PTR data)
 
 static HRESULT SendFilterMessage(IFilterGraphImpl *This, fnFoundFilter FoundFilter, DWORD_PTR data)
 {
-    int i;
-    IBaseFilter* pfilter;
+    struct filter *filter;
     IEnumPins* pEnum;
     HRESULT hr;
     IPin* pPin;
@@ -2175,11 +2165,10 @@ static HRESULT SendFilterMessage(IFilterGraphImpl *This, fnFoundFilter FoundFilt
     This->nRenderers = 0;
     ResetEvent(This->hEventCompletion);
 
-    for(i = 0; i < This->nFilters; i++)
+    LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
     {
         BOOL source = TRUE;
-        pfilter = This->ppFiltersInGraph[i];
-        hr = IBaseFilter_EnumPins(pfilter, &pEnum);
+        hr = IBaseFilter_EnumPins(filter->filter, &pEnum);
         if (hr != S_OK)
         {
             WARN("Enum pins failed %x\n", hr);
@@ -2198,7 +2187,7 @@ static HRESULT SendFilterMessage(IFilterGraphImpl *This, fnFoundFilter FoundFilt
         }
         if (source)
         {
-            TRACE("Found a source filter %p\n", pfilter);
+            TRACE("Found source filter %p.\n", filter->filter);
             IEnumPins_Reset(pEnum);
             while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
             {
@@ -2206,7 +2195,7 @@ static HRESULT SendFilterMessage(IFilterGraphImpl *This, fnFoundFilter FoundFilt
                 ExploreGraph(This, pPin, FoundFilter, data);
                 IPin_Release(pPin);
             }
-            FoundFilter(pfilter, data);
+            FoundFilter(filter->filter, data);
         }
         IEnumPins_Release(pEnum);
     }
@@ -2424,19 +2413,18 @@ typedef HRESULT (WINAPI *fnFoundSeek)(IFilterGraphImpl *This, IMediaSeeking*, DW
 
 static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek, DWORD_PTR arg) {
     BOOL allnotimpl = TRUE;
-    int i;
     HRESULT hr, hr_return = S_OK;
+    struct filter *filter;
 
     TRACE("(%p)->(%p %08lx)\n", This, FoundSeek, arg);
     /* Send a message to all renderers, they are responsible for broadcasting it further */
 
-    for(i = 0; i < This->nFilters; i++)
+    LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
     {
         IMediaSeeking *seek = NULL;
-        IBaseFilter* pfilter = This->ppFiltersInGraph[i];
         IAMFilterMiscFlags *flags = NULL;
         ULONG filterflags;
-        IBaseFilter_QueryInterface(pfilter, &IID_IAMFilterMiscFlags, (void**)&flags);
+        IBaseFilter_QueryInterface(filter->filter, &IID_IAMFilterMiscFlags, (void **)&flags);
         if (!flags)
             continue;
         filterflags = IAMFilterMiscFlags_GetMiscFlags(flags);
@@ -2444,7 +2432,7 @@ static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek,
         if (filterflags != AM_FILTER_MISC_FLAGS_IS_RENDERER)
             continue;
 
-        IBaseFilter_QueryInterface(pfilter, &IID_IMediaSeeking, (void**)&seek);
+        IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seek);
         if (!seek)
             continue;
         hr = FoundSeek(This, seek, arg);
@@ -3116,8 +3104,8 @@ static const IObjectWithSiteVtbl IObjectWithSite_VTable =
 
 static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID* ppvObj)
 {
+    struct filter *filter;
     HRESULT hr;
-    int i;
     int entry;
 
     /* Check if the interface type is already registered */
@@ -3140,13 +3128,13 @@ static HRESULT GetTargetInterface(IFilterGraphImpl* pGraph, REFIID riid, LPVOID*
     }
 
     /* Find a filter supporting the requested interface */
-    for (i = 0; i < pGraph->nFilters; i++)
+    LIST_FOR_EACH_ENTRY(filter, &pGraph->filters, struct filter, entry)
     {
-        hr = IBaseFilter_QueryInterface(pGraph->ppFiltersInGraph[i], riid, ppvObj);
+        hr = IBaseFilter_QueryInterface(filter->filter, riid, ppvObj);
         if (hr == S_OK)
         {
             pGraph->ItfCacheEntries[entry].riid = riid;
-            pGraph->ItfCacheEntries[entry].filter = pGraph->ppFiltersInGraph[i];
+            pGraph->ItfCacheEntries[entry].filter = filter->filter;
             pGraph->ItfCacheEntries[entry].iface = *ppvObj;
             if (entry >= pGraph->nItfCacheEntries)
                 pGraph->nItfCacheEntries++;
@@ -5471,24 +5459,24 @@ static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD dwMsTimeou
 static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock)
 {
     IFilterGraphImpl *This = impl_from_IMediaFilter(iface);
+    struct filter *filter;
     HRESULT hr = S_OK;
-    int i;
 
     TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
 
     EnterCriticalSection(&This->cs);
     {
-        for (i = 0;i < This->nFilters;i++)
+        LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
         {
-            hr = IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], pClock);
+            hr = IBaseFilter_SetSyncSource(filter->filter, pClock);
             if (FAILED(hr))
                 break;
         }
 
         if (FAILED(hr))
         {
-            for(;i >= 0;i--)
-                IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], This->refClock);
+            LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
+                IBaseFilter_SetSyncSource(filter->filter, This->refClock);
         }
         else
         {
@@ -5865,10 +5853,7 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
     fimpl->IObjectWithSite_iface.lpVtbl = &IObjectWithSite_VTable;
     fimpl->IGraphVersion_iface.lpVtbl = &IGraphVersion_VTable;
     fimpl->ref = 1;
-    fimpl->ppFiltersInGraph = NULL;
-    fimpl->pFilterNames = NULL;
-    fimpl->nFilters = 0;
-    fimpl->filterCapacity = 0;
+    list_init(&fimpl->filters);
     fimpl->nameIndex = 1;
     fimpl->refClock = NULL;
     fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0);
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index 4f1e9cf..51196c1 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -622,14 +622,12 @@ static void test_enum_filters(void)
 
     hr = IEnumFilters_Next(enum1, 1, filters, NULL);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
-todo_wine
     ok(filters[0] == filter2, "Got filter %p.\n", filters[0]);
     IBaseFilter_Release(filters[0]);
 
     hr = IEnumFilters_Next(enum1, 1, filters, &count);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
     ok(count == 1, "Got count %u.\n", count);
-todo_wine
     ok(filters[0] == filter1, "Got filter %p.\n", filters[0]);
     IBaseFilter_Release(filters[0]);
 
@@ -643,10 +641,8 @@ todo_wine
     hr = IEnumFilters_Next(enum1, 2, filters, &count);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
     ok(count == 2, "Got count %u.\n", count);
-todo_wine {
     ok(filters[0] == filter2, "Got filter %p.\n", filters[0]);
     ok(filters[1] == filter1, "Got filter %p.\n", filters[1]);
-}
     IBaseFilter_Release(filters[0]);
     IBaseFilter_Release(filters[1]);
 
@@ -662,10 +658,8 @@ todo_wine {
     hr = IEnumFilters_Next(enum1, 2, filters, &count);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
     ok(count == 2, "Got count %u.\n", count);
-todo_wine {
     ok(filters[0] == filter1, "Got filter %p.\n", filters[0]);
     ok(filters[1] == filter2, "Got filter %p.\n", filters[1]);
-}
     IBaseFilter_Release(filters[0]);
     IBaseFilter_Release(filters[1]);
 
@@ -681,7 +675,6 @@ todo_wine {
     hr = IEnumFilters_Next(enum2, 2, filters, &count);
     ok(hr == S_FALSE, "Got hr %#x.\n", hr);
     ok(count == 1, "Got count %u.\n", count);
-todo_wine
     ok(filters[0] == filter2, "Got filter %p.\n", filters[0]);
     IBaseFilter_Release(filters[0]);
 
-- 
2.7.4




More information about the wine-devel mailing list