From ea16925d8c531828090084ae8aa05b80581e00e6 Mon Sep 17 00:00:00 2001 From: Alessandro Pignotti Date: Tue, 19 Feb 2013 15:56:17 +0100 Subject: [PATCH] quartz: IEnumFiltersImpl needs to access data from IGraphFilterImpl. --- dlls/quartz/enumfilters.c | 51 ++++++++++++++++++++++------------ dlls/quartz/filtergraph.c | 53 ++++++++++++++++++++++++++++++++++-- dlls/quartz/quartz_private.h | 2 +- 3 files changed, 84 insertions(+), 22 deletions(-) diff --git a/dlls/quartz/enumfilters.c b/dlls/quartz/enumfilters.c index 2b9dc53c75..735fd79b3c 100644 --- a/dlls/quartz/enumfilters.c +++ b/dlls/quartz/enumfilters.c @@ -28,8 +28,10 @@ typedef struct IEnumFiltersImpl { IEnumFilters IEnumFilters_iface; LONG refCount; - IBaseFilter ** ppFilters; - int nFilters; + IGraphVersion * pVersionSource; + LONG Version; + IBaseFilter *** pppFilters; + ULONG * pNumFilters; ULONG uIndex; } IEnumFiltersImpl; @@ -40,13 +42,15 @@ static inline IEnumFiltersImpl *impl_from_IEnumFilters(IEnumFilters *iface) return CONTAINING_RECORD(iface, IEnumFiltersImpl, IEnumFilters_iface); } -HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum) +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, %d, %p)\n", ppFilters, nFilters, ppEnum); + TRACE("(%p, %p, %p)\n", pppFilters, pNumFilters, ppEnum); *ppEnum = NULL; @@ -58,15 +62,14 @@ HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEn pEnumFilters->IEnumFilters_iface.lpVtbl = &IEnumFiltersImpl_Vtbl; pEnumFilters->refCount = 1; pEnumFilters->uIndex = 0; - pEnumFilters->nFilters = nFilters; - pEnumFilters->ppFilters = CoTaskMemAlloc(sizeof(IBaseFilter*) * nFilters); - if (!pEnumFilters->ppFilters) - { - CoTaskMemFree(pEnumFilters); - return E_OUTOFMEMORY; - } + pEnumFilters->pNumFilters = pNumFilters; + pEnumFilters->pppFilters = pppFilters; + IGraphVersion_AddRef(pVersionSource); + pEnumFilters->pVersionSource = pVersionSource; - memcpy(pEnumFilters->ppFilters, ppFilters, nFilters * sizeof(IBaseFilter*)); + /* 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; @@ -113,8 +116,7 @@ static ULONG WINAPI IEnumFiltersImpl_Release(IEnumFilters * iface) if (!refCount) { - CoTaskMemFree(This->ppFilters); - CoTaskMemFree(This); + IGraphVersion_Release(This->pVersionSource); return 0; } else @@ -125,18 +127,26 @@ static HRESULT WINAPI IEnumFiltersImpl_Next(IEnumFilters * iface, ULONG cFilters { ULONG cFetched; ULONG i; + LONG currentVersion; IEnumFiltersImpl *This = impl_from_IEnumFilters(iface); + HRESULT hr; - cFetched = min(This->nFilters, This->uIndex + cFilters) - This->uIndex; + 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->ppFilters[This->uIndex + i]; + ppFilters[i] = (*This->pppFilters)[This->uIndex + i]; IBaseFilter_AddRef(ppFilters[i]); } @@ -156,7 +166,7 @@ static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters TRACE("(%p)->(%u)\n", iface, cFilters); - if (This->uIndex + cFilters < This->nFilters) + if (This->uIndex + cFilters < *This->pNumFilters) { This->uIndex += cFilters; return S_OK; @@ -167,10 +177,15 @@ static HRESULT WINAPI IEnumFiltersImpl_Skip(IEnumFilters * iface, ULONG cFilters 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) + This->Version = currentVersion; return S_OK; } @@ -181,7 +196,7 @@ static HRESULT WINAPI IEnumFiltersImpl_Clone(IEnumFilters * iface, IEnumFilters TRACE("(%p)->(%p)\n", iface, ppEnum); - hr = IEnumFiltersImpl_Construct(This->ppFilters, This->nFilters, ppEnum); + hr = IEnumFiltersImpl_Construct(This->pVersionSource, This->pppFilters, This->pNumFilters, ppEnum); if (FAILED(hr)) return hr; return IEnumFilters_Skip(*ppEnum, This->uIndex); diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index c31de59bf7..fb0f977e76 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -162,11 +162,11 @@ typedef struct _IFilterGraphImpl { IGraphConfig IGraphConfig_iface; IMediaPosition IMediaPosition_iface; IObjectWithSite IObjectWithSite_iface; + IGraphVersion IGraphVersion_iface; /* IAMGraphStreams */ /* IAMStats */ /* IFilterChain */ /* IFilterMapper2 */ - /* IGraphVersion */ /* IQueueCommand */ /* IRegisterServiceProvider */ /* IResourceMananger */ @@ -179,7 +179,7 @@ typedef struct _IFilterGraphImpl { IFilterMapper2 * pFilterMapper2; IBaseFilter ** ppFiltersInGraph; LPWSTR * pFilterNames; - int nFilters; + ULONG nFilters; int filterCapacity; LONG nameIndex; IReferenceClock *refClock; @@ -269,6 +269,9 @@ static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown *iface, REFIID ri } else if (IsEqualGUID(&IID_IFilterMapper3, riid)) { *ppvObj = This->pFilterMapper2; TRACE(" returning IFilterMapper3 interface from aggregated filtermapper (%p)\n", *ppvObj); + } else if (IsEqualGUID(&IID_IGraphVersion, riid)) { + *ppvObj = &This->IGraphConfig_iface; + TRACE(" returning IGraphConfig interface (%p)\n", *ppvObj); } else { *ppvObj = NULL; FIXME("unknown interface %s\n", debugstr_guid(riid)); @@ -562,7 +565,7 @@ static HRESULT WINAPI FilterGraph2_EnumFilters(IFilterGraph2 *iface, IEnumFilter TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum); - return IEnumFiltersImpl_Construct(This->ppFiltersInGraph, This->nFilters, ppEnum); + return IEnumFiltersImpl_Construct(&This->IGraphVersion_iface, &This->ppFiltersInGraph, &This->nFilters, ppEnum); } static HRESULT WINAPI FilterGraph2_FindFilterByName(IFilterGraph2 *iface, LPCWSTR pName, @@ -5547,6 +5550,49 @@ static const IGraphConfigVtbl IGraphConfig_VTable = GraphConfig_RemoveFilterEx }; +static inline IFilterGraphImpl *impl_from_IGraphVersion(IGraphVersion *iface) +{ + return CONTAINING_RECORD(iface, IFilterGraphImpl, IGraphVersion_iface); +} + +static HRESULT WINAPI GraphVersion_QueryInterface(IGraphVersion *iface, REFIID riid, void **ppv) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + return IUnknown_QueryInterface(This->outer_unk, riid, ppv); +} + +static ULONG WINAPI GraphVersion_AddRef(IGraphVersion *iface) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + return IUnknown_AddRef(This->outer_unk); +} + +static ULONG WINAPI GraphVersion_Release(IGraphVersion *iface) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + return IUnknown_Release(This->outer_unk); +} + +static HRESULT WINAPI GraphVersion_QueryVersion(IGraphVersion *iface, LONG *pVersion) +{ + IFilterGraphImpl *This = impl_from_IGraphVersion(iface); + + FIXME("(%p)->(%p): stub!\n", This, pVersion); + + return E_NOTIMPL; +} + +static const IGraphVersionVtbl IGraphVersion_VTable = +{ + GraphVersion_QueryInterface, + GraphVersion_AddRef, + GraphVersion_Release, + GraphVersion_QueryVersion, +}; + static const IUnknownVtbl IInner_VTable = { FilterGraphInner_QueryInterface, @@ -5579,6 +5625,7 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj) fimpl->IGraphConfig_iface.lpVtbl = &IGraphConfig_VTable; fimpl->IMediaPosition_iface.lpVtbl = &IMediaPosition_VTable; fimpl->IObjectWithSite_iface.lpVtbl = &IObjectWithSite_VTable; + fimpl->IGraphVersion_iface.lpVtbl = &IGraphVersion_VTable; fimpl->ref = 1; fimpl->ppFiltersInGraph = NULL; fimpl->pFilterNames = NULL; diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 7498ea999e..d8bcdbfe42 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -59,7 +59,7 @@ 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(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** 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; -- 2.32.0.93.g670b81a890