Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/Makefile.in | 1 - dlls/quartz/enumfilters.c | 215 ------------------------------------------- dlls/quartz/filtergraph.c | 182 +++++++++++++++++++++++++++++++++++- dlls/quartz/quartz_private.h | 1 - 4 files changed, 178 insertions(+), 221 deletions(-) delete mode 100644 dlls/quartz/enumfilters.c
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 5eb8d44..147d395 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -7,7 +7,6 @@ C_SRCS = \ avidec.c \ avisplit.c \ dsoundrender.c \ - enumfilters.c \ enummedia.c \ enummoniker.c \ enumregfilters.c \ diff --git a/dlls/quartz/enumfilters.c b/dlls/quartz/enumfilters.c deleted file mode 100644 index 331991b..0000000 --- a/dlls/quartz/enumfilters.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Implementation of IEnumFilters Interface - * - * Copyright 2004 Christian Costa - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "quartz_private.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(quartz); - -typedef struct IEnumFiltersImpl -{ - IEnumFilters IEnumFilters_iface; - LONG refCount; - IGraphVersion * pVersionSource; - LONG Version; - IBaseFilter *** pppFilters; - ULONG * pNumFilters; - ULONG uIndex; -} IEnumFiltersImpl; - -static const struct IEnumFiltersVtbl IEnumFiltersImpl_Vtbl; - -static inline IEnumFiltersImpl *impl_from_IEnumFilters(IEnumFilters *iface) -{ - return CONTAINING_RECORD(iface, IEnumFiltersImpl, IEnumFilters_iface); -} - -HRESULT IEnumFiltersImpl_Construct(IGraphVersion * pVersionSource, IBaseFilter *** pppFilters, ULONG * pNumFilters, IEnumFilters ** ppEnum) -{ - /* Note: The incoming IBaseFilter interfaces are not AddRef'd here as in Windows, - * they should have been previously AddRef'd. */ - IEnumFiltersImpl * pEnumFilters = CoTaskMemAlloc(sizeof(IEnumFiltersImpl)); - HRESULT hr; - LONG currentVersion; - - TRACE("(%p, %p, %p)\n", pppFilters, pNumFilters, ppEnum); - - *ppEnum = NULL; - - if (!pEnumFilters) - { - return E_OUTOFMEMORY; - } - - pEnumFilters->IEnumFilters_iface.lpVtbl = &IEnumFiltersImpl_Vtbl; - pEnumFilters->refCount = 1; - pEnumFilters->uIndex = 0; - pEnumFilters->pNumFilters = pNumFilters; - pEnumFilters->pppFilters = pppFilters; - IGraphVersion_AddRef(pVersionSource); - pEnumFilters->pVersionSource = pVersionSource; - - /* Store the current version of the graph */ - hr = IGraphVersion_QueryVersion(pVersionSource, ¤tVersion); - pEnumFilters->Version = (hr==S_OK) ? currentVersion : 0; - - *ppEnum = &pEnumFilters->IEnumFilters_iface; - return S_OK; -} - -static HRESULT WINAPI IEnumFiltersImpl_QueryInterface(IEnumFilters * iface, REFIID riid, LPVOID * ppv) -{ - TRACE("(%p)->(%s, %p)\n", iface, qzdebugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = iface; - else if (IsEqualIID(riid, &IID_IEnumFilters)) - *ppv = iface; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", qzdebugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static ULONG WINAPI IEnumFiltersImpl_AddRef(IEnumFilters * iface) -{ - IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p)->()\n", iface); - - return refCount; -} - -static ULONG WINAPI IEnumFiltersImpl_Release(IEnumFilters * iface) -{ - IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("(%p)->()\n", iface); - - if (!refCount) - { - IGraphVersion_Release(This->pVersionSource); - CoTaskMemFree(This); - return 0; - } - else - return refCount; -} - -static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters, IBaseFilter ** ppFilters, ULONG * pcFetched) -{ - ULONG cFetched; - ULONG i; - LONG currentVersion; - IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); - HRESULT hr; - - cFetched = min(*This->pNumFilters, This->uIndex + cFilters) - This->uIndex; - - TRACE("(%p)->(%u, %p, %p)\n", iface, cFilters, ppFilters, pcFetched); - - /* First of all check if the graph has changed */ - hr = IGraphVersion_QueryVersion(This->pVersionSource, ¤tVersion); - if (hr==S_OK && This->Version != currentVersion) - return VFW_E_ENUM_OUT_OF_SYNC; - - - if (!ppFilters) - return E_POINTER; - - for (i = 0; i < cFetched; i++) - { - ppFilters[i] = (*This->pppFilters)[This->uIndex + i]; - IBaseFilter_AddRef(ppFilters[i]); - } - - This->uIndex += cFetched; - - if (pcFetched) - *pcFetched = cFetched; - - if (cFetched != cFilters) - return S_FALSE; - return S_OK; -} - -static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters) -{ - IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); - - TRACE("(%p)->(%u)\n", iface, cFilters); - - if (This->uIndex + cFilters < *This->pNumFilters) - { - This->uIndex += cFilters; - return S_OK; - } - return S_FALSE; -} - -static HRESULT WINAPI IEnumFiltersImpl_Reset(IEnumFilters * iface) -{ - IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); - HRESULT hr; - LONG currentVersion; - - TRACE("(%p)->()\n", iface); - - This->uIndex = 0; - hr = IGraphVersion_QueryVersion(This->pVersionSource, ¤tVersion); - if (hr == S_OK) - This->Version = currentVersion; - return S_OK; -} - -static HRESULT WINAPI IEnumFiltersImpl_Clone(IEnumFilters * iface, IEnumFilters ** ppEnum) -{ - HRESULT hr; - IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); - - TRACE("(%p)->(%p)\n", iface, ppEnum); - - hr = IEnumFiltersImpl_Construct(This->pVersionSource, This->pppFilters, This->pNumFilters, ppEnum); - if (FAILED(hr)) - return hr; - return IEnumFilters_Skip(*ppEnum, This->uIndex); -} - -static const IEnumFiltersVtbl IEnumFiltersImpl_Vtbl = -{ - IEnumFiltersImpl_QueryInterface, - IEnumFiltersImpl_AddRef, - IEnumFiltersImpl_Release, - IEnumFiltersImpl_Next, - IEnumFiltersImpl_Skip, - IEnumFiltersImpl_Reset, - IEnumFiltersImpl_Clone -}; diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 983e2c0..f0e91cb 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -36,6 +36,7 @@ #include "strmif.h" #include "vfwmsgs.h" #include "evcode.h" +#include "wine/heap.h" #include "wine/unicode.h"
@@ -206,6 +207,179 @@ typedef struct _IFilterGraphImpl { LONG version; } IFilterGraphImpl;
+struct enum_filters +{ + IEnumFilters IEnumFilters_iface; + LONG ref; + IGraphVersion *version_source; + LONG version; + IBaseFilter ***filters; + ULONG *count; + ULONG index; +}; + +static HRESULT create_enum_filters(IGraphVersion *version_source, + IBaseFilter ***filters, ULONG *count, IEnumFilters **out); + +static inline struct enum_filters *impl_from_IEnumFilters(IEnumFilters *iface) +{ + return CONTAINING_RECORD(iface, struct enum_filters, IEnumFilters_iface); +} + +static HRESULT WINAPI EnumFilters_QueryInterface(IEnumFilters *iface, REFIID iid, void **out) +{ + struct enum_filters *enum_filters = impl_from_IEnumFilters(iface); + TRACE("enum_filters %p, iid %s, out %p.\n", enum_filters, qzdebugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IEnumFilters)) + { + IEnumFilters_AddRef(*out = iface); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", qzdebugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI EnumFilters_AddRef(IEnumFilters *iface) +{ + struct enum_filters *enum_filters = impl_from_IEnumFilters(iface); + ULONG ref = InterlockedIncrement(&enum_filters->ref); + + TRACE("%p increasing refcount to %u.\n", enum_filters, ref); + + return ref; +} + +static ULONG WINAPI EnumFilters_Release(IEnumFilters *iface) +{ + struct enum_filters *enum_filters = impl_from_IEnumFilters(iface); + ULONG ref = InterlockedDecrement(&enum_filters->ref); + + TRACE("%p decreasing refcount to %u.\n", enum_filters, ref); + + if (!ref) + { + IGraphVersion_Release(enum_filters->version_source); + heap_free(enum_filters); + } + + return ref; +} + +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; + LONG version; + HRESULT hr; + + TRACE("enum_filters %p, count %u, filters %p, fetched %p.\n", + enum_filters, count, filters, fetched); + + cFetched = min(*enum_filters->count, enum_filters->index + count) - enum_filters->index; + + hr = IGraphVersion_QueryVersion(enum_filters->version_source, &version); + if (hr == S_OK && enum_filters->version != version) + return VFW_E_ENUM_OUT_OF_SYNC; + + if (!filters) + return E_POINTER; + + for (i = 0; i < cFetched; i++) + { + filters[i] = (*enum_filters->filters)[enum_filters->index + i]; + IBaseFilter_AddRef(filters[i]); + } + + enum_filters->index += cFetched; + + if (fetched) + *fetched = cFetched; + + if (cFetched != count) + return S_FALSE; + return S_OK; +} + +static HRESULT WINAPI EnumFilters_Skip(IEnumFilters *iface, ULONG count) +{ + struct enum_filters *enum_filters = impl_from_IEnumFilters(iface); + + TRACE("enum_filters %p, count %u.\n", enum_filters, count); + + if (enum_filters->index + count < *enum_filters->count) + { + enum_filters->index += count; + return S_OK; + } + return S_FALSE; +} + +static HRESULT WINAPI EnumFilters_Reset(IEnumFilters *iface) +{ + struct enum_filters *enum_filters = impl_from_IEnumFilters(iface); + LONG version; + HRESULT hr; + + TRACE("enum_filters %p.\n", enum_filters); + + enum_filters->index = 0; + hr = IGraphVersion_QueryVersion(enum_filters->version_source, &version); + if (hr == S_OK) + enum_filters->version = version; + return S_OK; +} + +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->version_source, enum_filters->filters, enum_filters->count, out); + if (FAILED(hr)) + return hr; + return IEnumFilters_Skip(*out, enum_filters->index); +} + +static const IEnumFiltersVtbl EnumFilters_vtbl = +{ + EnumFilters_QueryInterface, + EnumFilters_AddRef, + EnumFilters_Release, + EnumFilters_Next, + EnumFilters_Skip, + EnumFilters_Reset, + EnumFilters_Clone, +}; + +static HRESULT create_enum_filters(IGraphVersion *version_source, + IBaseFilter ***filters, ULONG *count, IEnumFilters **out) +{ + struct enum_filters *enum_filters; + LONG version; + HRESULT hr; + + if (!(enum_filters = heap_alloc(sizeof(*enum_filters)))) + return E_OUTOFMEMORY; + + enum_filters->IEnumFilters_iface.lpVtbl = &EnumFilters_vtbl; + enum_filters->ref = 1; + enum_filters->index = 0; + enum_filters->filters = filters; + enum_filters->count = count; + IGraphVersion_AddRef(enum_filters->version_source = version_source); + hr = IGraphVersion_QueryVersion(version_source, &version); + enum_filters->version = (hr == S_OK) ? version : 0; + + *out = &enum_filters->IEnumFilters_iface; + return S_OK; +} + static inline IFilterGraphImpl *impl_from_IUnknown(IUnknown *iface) { return CONTAINING_RECORD(iface, IFilterGraphImpl, IUnknown_inner); @@ -558,13 +732,13 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte return hr; /* FIXME: check this error code */ }
-static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface, IEnumFilters **ppEnum) +static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface, IEnumFilters **out) { - IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); + IFilterGraphImpl *graph = impl_from_IFilterGraph2(iface);
- TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); + TRACE("graph %p, out %p.\n", graph, out);
- return IEnumFiltersImpl_Construct(&This->IGraphVersion_iface, &This->ppFiltersInGraph, &This->nFilters, ppEnum); + return create_enum_filters(&graph->IGraphVersion_iface, &graph->ppFiltersInGraph, &graph->nFilters, out); }
static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface, diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index a9855e9..db9c3bd 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -61,7 +61,6 @@ HRESULT VMR9Impl_create(IUnknown *pUnkOuter, LPVOID *ppv) DECLSPEC_HIDDEN; HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum) DECLSPEC_HIDDEN;
HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum) DECLSPEC_HIDDEN; -HRESULT IEnumFiltersImpl_Construct(IGraphVersion * pVersionSource, IBaseFilter *** pppFilters, ULONG * pNumFilters, IEnumFilters ** ppEnum) DECLSPEC_HIDDEN;
extern const char * qzdebugstr_guid(const GUID * id) DECLSPEC_HIDDEN; extern void video_unregister_windowclass(void) DECLSPEC_HIDDEN;