Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/quartz/tests/Makefile.in | 1 + dlls/quartz/tests/passthrough.c | 133 ++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 dlls/quartz/tests/passthrough.c
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in index fe1a45e8ec5..46b3728ab82 100644 --- a/dlls/quartz/tests/Makefile.in +++ b/dlls/quartz/tests/Makefile.in @@ -11,6 +11,7 @@ C_SRCS = \ filtermapper.c \ memallocator.c \ mpegsplit.c \ + passthrough.c \ systemclock.c \ videorenderer.c \ vmr7.c \ diff --git a/dlls/quartz/tests/passthrough.c b/dlls/quartz/tests/passthrough.c new file mode 100644 index 00000000000..6042bc7f5ab --- /dev/null +++ b/dlls/quartz/tests/passthrough.c @@ -0,0 +1,133 @@ +/* + * Seeking passthrough unit tests + * + * Copyright 2020 Zebediah Figura for CodeWeavers + * + * 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 + */ + +#define COBJMACROS +#include "dshow.h" +#include "wine/test.h" + +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + +static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1; + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_ISeekingPassThru) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + return InterlockedIncrement(&outer_ref); +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + return InterlockedDecrement(&outer_ref); +} + +static const IUnknownVtbl outer_vtbl = +{ + outer_QueryInterface, + outer_AddRef, + outer_Release, +}; + +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) +{ + ISeekingPassThru *passthrough, *passthrough2; + IUnknown *unk, *unk2; + HRESULT hr; + ULONG ref; + + passthrough = (ISeekingPassThru *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_SeekingPassThru, &test_outer, CLSCTX_INPROC_SERVER, + &IID_ISeekingPassThru, (void **)&passthrough); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!passthrough, "Got interface %p.\n", passthrough); + + hr = CoCreateInstance(&CLSID_SeekingPassThru, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); + ref = get_refcount(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IUnknown_QueryInterface(unk, &IID_ISeekingPassThru, (void **)&passthrough); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = ISeekingPassThru_QueryInterface(passthrough, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + hr = ISeekingPassThru_QueryInterface(passthrough, &IID_ISeekingPassThru, (void **)&passthrough2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(passthrough2 == (ISeekingPassThru *)0xdeadbeef, "Got unexpected ISeekingPassThru %p.\n", passthrough2); + + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + hr = ISeekingPassThru_QueryInterface(passthrough, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + ISeekingPassThru_Release(passthrough); + ref = IUnknown_Release(unk); + todo_wine ok(!ref, "Got unexpected refcount %d.\n", ref); + todo_wine ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); +} + +START_TEST(passthrough) +{ + CoInitialize(NULL); + + test_aggregation(); + + CoUninitialize(); +}
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/quartz/tests/passthrough.c | 6 +- dlls/strmbase/pospass.c | 112 +++++++------------------------- 2 files changed, 25 insertions(+), 93 deletions(-)
diff --git a/dlls/quartz/tests/passthrough.c b/dlls/quartz/tests/passthrough.c index 6042bc7f5ab..ce7365928e5 100644 --- a/dlls/quartz/tests/passthrough.c +++ b/dlls/quartz/tests/passthrough.c @@ -103,7 +103,7 @@ static void test_aggregation(void)
hr = ISeekingPassThru_QueryInterface(passthrough, &IID_IUnknown, (void **)&unk2); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
hr = ISeekingPassThru_QueryInterface(passthrough, &IID_ISeekingPassThru, (void **)&passthrough2); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -119,8 +119,8 @@ static void test_aggregation(void)
ISeekingPassThru_Release(passthrough); ref = IUnknown_Release(unk); - todo_wine ok(!ref, "Got unexpected refcount %d.\n", ref); - todo_wine ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + ok(!ref, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); }
START_TEST(passthrough) diff --git a/dlls/strmbase/pospass.c b/dlls/strmbase/pospass.c index 148d4fae3c5..6920b378650 100644 --- a/dlls/strmbase/pospass.c +++ b/dlls/strmbase/pospass.c @@ -36,8 +36,6 @@ typedef struct PassThruImpl { LONG ref; IUnknown * outer_unk; IPin * pin; - BOOL bUnkOuterValid; - BOOL bAggregatable; BOOL renderer; CRITICAL_SECTION time_cs; BOOL timevalid; @@ -70,9 +68,6 @@ static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface, PassThruImpl *This = impl_from_IUnknown_inner(iface); TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObj);
- if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - if (IsEqualGUID(&IID_IUnknown, riid)) { *ppvObj = &(This->IUnknown_inner); @@ -127,74 +122,25 @@ static const IUnknownVtbl IInner_VTable = SeekInner_Release };
-/* Generic functions for aggregation */ -static HRESULT SeekOuter_QueryInterface(PassThruImpl *This, REFIID riid, LPVOID *ppv) -{ - if (This->bAggregatable) - This->bUnkOuterValid = TRUE; - - if (This->outer_unk) - { - if (This->bAggregatable) - return IUnknown_QueryInterface(This->outer_unk, riid, ppv); - - if (IsEqualIID(riid, &IID_IUnknown)) - { - HRESULT hr; - - IUnknown_AddRef(&This->IUnknown_inner); - hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv); - IUnknown_Release(&This->IUnknown_inner); - This->bAggregatable = TRUE; - return hr; - } - - *ppv = NULL; - return E_NOINTERFACE; - } - - return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv); -} - -static ULONG SeekOuter_AddRef(PassThruImpl *This) -{ - if (This->outer_unk && This->bUnkOuterValid) - return IUnknown_AddRef(This->outer_unk); - return IUnknown_AddRef(&This->IUnknown_inner); -} - -static ULONG SeekOuter_Release(PassThruImpl *This) -{ - if (This->outer_unk && This->bUnkOuterValid) - return IUnknown_Release(This->outer_unk); - return IUnknown_Release(&This->IUnknown_inner); -} - -static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID riid, LPVOID *ppvObj) +static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID iid, void **out) { - PassThruImpl *This = impl_from_ISeekingPassThru(iface); - - TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj); + PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface);
- return SeekOuter_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(passthrough->outer_unk, iid, out); }
static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface) { - PassThruImpl *This = impl_from_ISeekingPassThru(iface); + PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface);
- TRACE("(%p/%p)->()\n", This, iface); - - return SeekOuter_AddRef(This); + return IUnknown_AddRef(passthrough->outer_unk); }
static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface) { - PassThruImpl *This = impl_from_ISeekingPassThru(iface); + PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface);
- TRACE("(%p/%p)->()\n", This, iface); - - return SeekOuter_Release(This); + return IUnknown_Release(passthrough->outer_unk); }
static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin) @@ -246,9 +192,7 @@ HRESULT WINAPI PosPassThru_Construct(IUnknown *pUnkOuter, LPVOID *ppPassThru) if (!fimpl) return E_OUTOFMEMORY;
- fimpl->outer_unk = pUnkOuter; - fimpl->bUnkOuterValid = FALSE; - fimpl->bAggregatable = FALSE; + fimpl->outer_unk = pUnkOuter ? pUnkOuter : &fimpl->IUnknown_inner; fimpl->IUnknown_inner.lpVtbl = &IInner_VTable; fimpl->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl; fimpl->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl; @@ -261,31 +205,25 @@ HRESULT WINAPI PosPassThru_Construct(IUnknown *pUnkOuter, LPVOID *ppPassThru) return S_OK; }
-static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID riid, LPVOID *ppvObj) +static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + PassThruImpl *passthrough = impl_from_IMediaSeeking(iface);
- TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj); - - return SeekOuter_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(passthrough->outer_unk, iid, out); }
static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + PassThruImpl *passthrough = impl_from_IMediaSeeking(iface);
- TRACE("(%p/%p)->()\n", iface, This); - - return SeekOuter_AddRef(This); + return IUnknown_AddRef(passthrough->outer_unk); }
static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); - - TRACE("(%p/%p)->()\n", iface, This); + PassThruImpl *passthrough = impl_from_IMediaSeeking(iface);
- return SeekOuter_Release(This); + return IUnknown_Release(passthrough->outer_unk); }
static HRESULT get_connected(PassThruImpl *This, REFIID riid, LPVOID *ppvObj) { @@ -644,31 +582,25 @@ static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl = MediaSeekingPassThru_GetPreroll };
-static HRESULT WINAPI MediaPositionPassThru_QueryInterface(IMediaPosition *iface, REFIID riid, LPVOID *ppvObj) +static HRESULT WINAPI MediaPositionPassThru_QueryInterface(IMediaPosition *iface, REFIID iid, void **out) { - PassThruImpl *This = impl_from_IMediaPosition(iface); - - TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj); + PassThruImpl *passthrough = impl_from_IMediaPosition(iface);
- return SeekOuter_QueryInterface(This, riid, ppvObj); + return IUnknown_QueryInterface(passthrough->outer_unk, iid, out); }
static ULONG WINAPI MediaPositionPassThru_AddRef(IMediaPosition *iface) { - PassThruImpl *This = impl_from_IMediaPosition(iface); - - TRACE("(%p/%p)->()\n", iface, This); + PassThruImpl *passthrough = impl_from_IMediaPosition(iface);
- return SeekOuter_AddRef(This); + return IUnknown_AddRef(passthrough->outer_unk); }
static ULONG WINAPI MediaPositionPassThru_Release(IMediaPosition *iface) { - PassThruImpl *This = impl_from_IMediaPosition(iface); - - TRACE("(%p/%p)->()\n", iface, This); + PassThruImpl *passthrough = impl_from_IMediaPosition(iface);
- return SeekOuter_Release(This); + return IUnknown_Release(passthrough->outer_unk); }
static HRESULT WINAPI MediaPositionPassThru_GetTypeInfoCount(IMediaPosition *iface, UINT *count)
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/strmbase/pospass.c | 275 +++++++++++++++++++++------------------- 1 file changed, 147 insertions(+), 128 deletions(-)
diff --git a/dlls/strmbase/pospass.c b/dlls/strmbase/pospass.c index 6920b378650..c5be17ec62b 100644 --- a/dlls/strmbase/pospass.c +++ b/dlls/strmbase/pospass.c @@ -24,16 +24,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
-static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl; -static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl; - typedef struct PassThruImpl { - IUnknown IUnknown_inner; ISeekingPassThru ISeekingPassThru_iface; IMediaSeeking IMediaSeeking_iface; IMediaPosition IMediaPosition_iface;
- LONG ref; IUnknown * outer_unk; IPin * pin; BOOL renderer; @@ -42,11 +37,6 @@ typedef struct PassThruImpl { REFERENCE_TIME time_earliest; } PassThruImpl;
-static inline PassThruImpl *impl_from_IUnknown_inner(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, PassThruImpl, IUnknown_inner); -} - static inline PassThruImpl *impl_from_ISeekingPassThru(ISeekingPassThru *iface) { return CONTAINING_RECORD(iface, PassThruImpl, ISeekingPassThru_iface); @@ -62,66 +52,6 @@ static inline PassThruImpl *impl_from_IMediaPosition(IMediaPosition *iface) return CONTAINING_RECORD(iface, PassThruImpl, IMediaPosition_iface); }
-static HRESULT WINAPI SeekInner_QueryInterface(IUnknown * iface, - REFIID riid, - LPVOID *ppvObj) { - PassThruImpl *This = impl_from_IUnknown_inner(iface); - TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObj); - - if (IsEqualGUID(&IID_IUnknown, riid)) - { - *ppvObj = &(This->IUnknown_inner); - TRACE(" returning IUnknown interface (%p)\n", *ppvObj); - } else if (IsEqualGUID(&IID_ISeekingPassThru, riid)) { - *ppvObj = &(This->ISeekingPassThru_iface); - TRACE(" returning ISeekingPassThru interface (%p)\n", *ppvObj); - } else if (IsEqualGUID(&IID_IMediaSeeking, riid)) { - *ppvObj = &(This->IMediaSeeking_iface); - TRACE(" returning IMediaSeeking interface (%p)\n", *ppvObj); - } else if (IsEqualGUID(&IID_IMediaPosition, riid)) { - *ppvObj = &(This->IMediaPosition_iface); - TRACE(" returning IMediaPosition interface (%p)\n", *ppvObj); - } else { - *ppvObj = NULL; - FIXME("unknown interface %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown *)(*ppvObj)); - return S_OK; -} - -static ULONG WINAPI SeekInner_AddRef(IUnknown * iface) { - PassThruImpl *This = impl_from_IUnknown_inner(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(): new ref = %d\n", This, ref); - - return ref; -} - -static ULONG WINAPI SeekInner_Release(IUnknown * iface) { - PassThruImpl *This = impl_from_IUnknown_inner(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(): new ref = %d\n", This, ref); - - if (ref == 0) - { - This->time_cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->time_cs); - CoTaskMemFree(This); - } - return ref; -} - -static const IUnknownVtbl IInner_VTable = -{ - SeekInner_QueryInterface, - SeekInner_AddRef, - SeekInner_Release -}; - static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID iid, void **out) { PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface); @@ -182,29 +112,6 @@ HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin return hr; }
-HRESULT WINAPI PosPassThru_Construct(IUnknown *pUnkOuter, LPVOID *ppPassThru) -{ - PassThruImpl *fimpl; - - TRACE("(%p,%p)\n", pUnkOuter, ppPassThru); - - *ppPassThru = fimpl = CoTaskMemAlloc(sizeof(*fimpl)); - if (!fimpl) - return E_OUTOFMEMORY; - - fimpl->outer_unk = pUnkOuter ? pUnkOuter : &fimpl->IUnknown_inner; - fimpl->IUnknown_inner.lpVtbl = &IInner_VTable; - fimpl->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl; - fimpl->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl; - fimpl->IMediaPosition_iface.lpVtbl = &IMediaPositionPassThru_Vtbl; - fimpl->ref = 1; - fimpl->pin = NULL; - fimpl->timevalid = FALSE; - InitializeCriticalSection(&fimpl->time_cs); - fimpl->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs"); - return S_OK; -} - static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out) { PassThruImpl *passthrough = impl_from_IMediaSeeking(iface); @@ -523,41 +430,6 @@ static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LON return hr; }
-HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start) -{ - PassThruImpl *This = impl_from_IUnknown_inner(iface); - EnterCriticalSection(&This->time_cs); - This->time_earliest = start; - This->timevalid = TRUE; - LeaveCriticalSection(&This->time_cs); - return S_OK; -} - -HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface) -{ - PassThruImpl *This = impl_from_IUnknown_inner(iface); - EnterCriticalSection(&This->time_cs); - This->timevalid = FALSE; - LeaveCriticalSection(&This->time_cs); - return S_OK; -} - -HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface) -{ - PassThruImpl *This = impl_from_IUnknown_inner(iface); - REFERENCE_TIME time; - HRESULT hr; - hr = IMediaSeeking_GetStopPosition(&This->IMediaSeeking_iface, &time); - EnterCriticalSection(&This->time_cs); - if (SUCCEEDED(hr)) { - This->timevalid = TRUE; - This->time_earliest = time; - } else - This->timevalid = FALSE; - LeaveCriticalSection(&This->time_cs); - return hr; -} - static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl = { MediaSeekingPassThru_QueryInterface, @@ -870,3 +742,150 @@ static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl = MediaPositionPassThru_CanSeekForward, MediaPositionPassThru_CanSeekBackward }; + +void strmbase_passthrough_init(PassThruImpl *passthrough, IUnknown *outer) +{ + memset(passthrough, 0, sizeof(*passthrough)); + + passthrough->outer_unk = outer; + passthrough->IMediaPosition_iface.lpVtbl = &IMediaPositionPassThru_Vtbl; + passthrough->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl; + passthrough->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl; + InitializeCriticalSection(&passthrough->time_cs); + passthrough->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs" ); +} + +void strmbase_passthrough_cleanup(PassThruImpl *passthrough) +{ + passthrough->time_cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&passthrough->time_cs); +} + +struct seeking_passthrough +{ + PassThruImpl passthrough; + + IUnknown IUnknown_inner; + IUnknown *outer_unk; + LONG refcount; +}; + +static struct seeking_passthrough *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct seeking_passthrough, IUnknown_inner); +} + +static HRESULT WINAPI seeking_passthrough_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + + TRACE("passthrough %p, iid %s, out %p.\n", passthrough, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown)) + *out = iface; + else if (IsEqualGUID(iid, &IID_IMediaPosition)) + *out = &passthrough->passthrough.IMediaPosition_iface; + else if (IsEqualGUID(iid, &IID_IMediaSeeking)) + *out = &passthrough->passthrough.IMediaSeeking_iface; + else if (IsEqualGUID(iid, &IID_ISeekingPassThru)) + *out = &passthrough->passthrough.ISeekingPassThru_iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI seeking_passthrough_AddRef(IUnknown *iface) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&passthrough->refcount); + + TRACE("%p increasing refcount to %u.\n", passthrough, refcount); + return refcount; +} + +static ULONG WINAPI seeking_passthrough_Release(IUnknown *iface) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&passthrough->refcount); + + TRACE("%p decreasing refcount to %u.\n", passthrough, refcount); + if (!refcount) + { + strmbase_passthrough_cleanup(&passthrough->passthrough); + heap_free(passthrough); + } + return refcount; +} + +static const IUnknownVtbl seeking_passthrough_vtbl = +{ + seeking_passthrough_QueryInterface, + seeking_passthrough_AddRef, + seeking_passthrough_Release, +}; + +HRESULT WINAPI PosPassThru_Construct(IUnknown *outer, void **out) +{ + struct seeking_passthrough *object; + + TRACE("outer %p, out %p.\n", outer, out); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IUnknown_inner.lpVtbl = &seeking_passthrough_vtbl; + object->outer_unk = outer ? outer : &object->IUnknown_inner; + object->refcount = 1; + + strmbase_passthrough_init(&object->passthrough, object->outer_unk); + + TRACE("Created seeking passthrough %p.\n", object); + *out = &object->IUnknown_inner; + return S_OK; +} + +HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + + EnterCriticalSection(&passthrough->passthrough.time_cs); + passthrough->passthrough.time_earliest = start; + passthrough->passthrough.timevalid = TRUE; + LeaveCriticalSection(&passthrough->passthrough.time_cs); + return S_OK; +} + +HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + + EnterCriticalSection(&passthrough->passthrough.time_cs); + passthrough->passthrough.timevalid = FALSE; + LeaveCriticalSection(&passthrough->passthrough.time_cs); + return S_OK; +} + +HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + REFERENCE_TIME time; + HRESULT hr; + + hr = IMediaSeeking_GetStopPosition(&passthrough->passthrough.IMediaSeeking_iface, &time); + EnterCriticalSection(&passthrough->passthrough.time_cs); + if (SUCCEEDED(hr)) + { + passthrough->passthrough.timevalid = TRUE; + passthrough->passthrough.time_earliest = time; + } + else + passthrough->passthrough.timevalid = FALSE; + LeaveCriticalSection(&passthrough->passthrough.time_cs); + return hr; +}
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/strmbase/pospass.c | 104 ++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 51 deletions(-)
diff --git a/dlls/strmbase/pospass.c b/dlls/strmbase/pospass.c index c5be17ec62b..086e3e6aeb5 100644 --- a/dlls/strmbase/pospass.c +++ b/dlls/strmbase/pospass.c @@ -24,7 +24,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
-typedef struct PassThruImpl { +struct strmbase_passthrough +{ ISeekingPassThru ISeekingPassThru_iface; IMediaSeeking IMediaSeeking_iface; IMediaPosition IMediaPosition_iface; @@ -35,47 +36,47 @@ typedef struct PassThruImpl { CRITICAL_SECTION time_cs; BOOL timevalid; REFERENCE_TIME time_earliest; -} PassThruImpl; +};
-static inline PassThruImpl *impl_from_ISeekingPassThru(ISeekingPassThru *iface) +static struct strmbase_passthrough *impl_from_ISeekingPassThru(ISeekingPassThru *iface) { - return CONTAINING_RECORD(iface, PassThruImpl, ISeekingPassThru_iface); + return CONTAINING_RECORD(iface, struct strmbase_passthrough, ISeekingPassThru_iface); }
-static inline PassThruImpl *impl_from_IMediaSeeking(IMediaSeeking *iface) +static struct strmbase_passthrough *impl_from_IMediaSeeking(IMediaSeeking *iface) { - return CONTAINING_RECORD(iface, PassThruImpl, IMediaSeeking_iface); + return CONTAINING_RECORD(iface, struct strmbase_passthrough, IMediaSeeking_iface); }
-static inline PassThruImpl *impl_from_IMediaPosition(IMediaPosition *iface) +static struct strmbase_passthrough *impl_from_IMediaPosition(IMediaPosition *iface) { - return CONTAINING_RECORD(iface, PassThruImpl, IMediaPosition_iface); + return CONTAINING_RECORD(iface, struct strmbase_passthrough, IMediaPosition_iface); }
static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID iid, void **out) { - PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface); + struct strmbase_passthrough *passthrough = impl_from_ISeekingPassThru(iface);
return IUnknown_QueryInterface(passthrough->outer_unk, iid, out); }
static ULONG WINAPI SeekingPassThru_AddRef(ISeekingPassThru *iface) { - PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface); + struct strmbase_passthrough *passthrough = impl_from_ISeekingPassThru(iface);
return IUnknown_AddRef(passthrough->outer_unk); }
static ULONG WINAPI SeekingPassThru_Release(ISeekingPassThru *iface) { - PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface); + struct strmbase_passthrough *passthrough = impl_from_ISeekingPassThru(iface);
return IUnknown_Release(passthrough->outer_unk); }
static HRESULT WINAPI SeekingPassThru_Init(ISeekingPassThru *iface, BOOL renderer, IPin *pin) { - PassThruImpl *This = impl_from_ISeekingPassThru(iface); + struct strmbase_passthrough *This = impl_from_ISeekingPassThru(iface);
TRACE("(%p/%p)->(%d, %p)\n", This, iface, renderer, pin);
@@ -114,26 +115,27 @@ HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin
static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out) { - PassThruImpl *passthrough = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
return IUnknown_QueryInterface(passthrough->outer_unk, iid, out); }
static ULONG WINAPI MediaSeekingPassThru_AddRef(IMediaSeeking *iface) { - PassThruImpl *passthrough = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
return IUnknown_AddRef(passthrough->outer_unk); }
static ULONG WINAPI MediaSeekingPassThru_Release(IMediaSeeking *iface) { - PassThruImpl *passthrough = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
return IUnknown_Release(passthrough->outer_unk); }
-static HRESULT get_connected(PassThruImpl *This, REFIID riid, LPVOID *ppvObj) { +static HRESULT get_connected(struct strmbase_passthrough *This, REFIID riid, void **ppvObj) +{ HRESULT hr; IPin *pin; *ppvObj = NULL; @@ -149,7 +151,7 @@ static HRESULT get_connected(PassThruImpl *This, REFIID riid, LPVOID *ppvObj) {
static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities); @@ -165,7 +167,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetCapabilities(IMediaSeeking * iface
static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p)\n", iface, This, pCapabilities); @@ -181,7 +183,7 @@ static HRESULT WINAPI MediaSeekingPassThru_CheckCapabilities(IMediaSeeking * ifa
static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * iface, const GUID * pFormat) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat)); @@ -197,7 +199,7 @@ static HRESULT WINAPI MediaSeekingPassThru_IsFormatSupported(IMediaSeeking * ifa
static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking * iface, GUID * pFormat) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p)\n", iface, This, pFormat); @@ -213,7 +215,7 @@ static HRESULT WINAPI MediaSeekingPassThru_QueryPreferredFormat(IMediaSeeking *
static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface, GUID * pFormat) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p)\n", iface, This, pFormat); @@ -229,7 +231,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetTimeFormat(IMediaSeeking * iface,
static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * iface, const GUID * pFormat) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat)); @@ -245,7 +247,7 @@ static HRESULT WINAPI MediaSeekingPassThru_IsUsingTimeFormat(IMediaSeeking * ifa
static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface, const GUID * pFormat) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%s)\n", iface, This, debugstr_guid(pFormat)); @@ -261,7 +263,7 @@ static HRESULT WINAPI MediaSeekingPassThru_SetTimeFormat(IMediaSeeking * iface,
static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LONGLONG * pDuration) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p)\n", iface, This, pDuration); @@ -277,7 +279,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetDuration(IMediaSeeking * iface, LO
static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface, LONGLONG * pStop) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p)\n", iface, This, pStop); @@ -293,7 +295,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetStopPosition(IMediaSeeking * iface
static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * iface, LONGLONG * pCurrent) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr = S_OK; TRACE("(%p/%p)->(%p)\n", iface, This, pCurrent); @@ -321,7 +323,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetCurrentPosition(IMediaSeeking * if
static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * iface, LONGLONG * pTarget, const GUID * pTargetFormat, LONGLONG Source, const GUID * pSourceFormat) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p,%s,%x%08x,%s)\n", iface, This, pTarget, debugstr_guid(pTargetFormat), (DWORD)(Source>>32), (DWORD)Source, debugstr_guid(pSourceFormat)); @@ -337,7 +339,7 @@ static HRESULT WINAPI MediaSeekingPassThru_ConvertTimeFormat(IMediaSeeking * ifa
static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, DWORD dwCurrentFlags, LONGLONG * pStop, DWORD dwStopFlags) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p,%x,%p,%x)\n", iface, This, pCurrent, dwCurrentFlags, pStop, dwStopFlags); @@ -352,7 +354,7 @@ static HRESULT WINAPI MediaSeekingPassThru_SetPositions(IMediaSeeking * iface, L
static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, LONGLONG * pCurrent, LONGLONG * pStop) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p, %p)\n", iface, This, pCurrent, pStop); @@ -368,7 +370,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetPositions(IMediaSeeking * iface, L
static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, LONGLONG * pEarliest, LONGLONG * pLatest) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p,%p)\n", iface, This, pEarliest, pLatest); @@ -384,7 +386,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetAvailable(IMediaSeeking * iface, L
static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double dRate) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%e)\n", iface, This, dRate); @@ -400,7 +402,7 @@ static HRESULT WINAPI MediaSeekingPassThru_SetRate(IMediaSeeking * iface, double
static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double * dRate) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p/%p)->(%p)\n", iface, This, dRate); @@ -416,7 +418,7 @@ static HRESULT WINAPI MediaSeekingPassThru_GetRate(IMediaSeeking * iface, double
static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll) { - PassThruImpl *This = impl_from_IMediaSeeking(iface); + struct strmbase_passthrough *This = impl_from_IMediaSeeking(iface); IMediaSeeking *seek; HRESULT hr; TRACE("(%p)\n", pPreroll); @@ -456,21 +458,21 @@ static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl =
static HRESULT WINAPI MediaPositionPassThru_QueryInterface(IMediaPosition *iface, REFIID iid, void **out) { - PassThruImpl *passthrough = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *passthrough = impl_from_IMediaPosition(iface);
return IUnknown_QueryInterface(passthrough->outer_unk, iid, out); }
static ULONG WINAPI MediaPositionPassThru_AddRef(IMediaPosition *iface) { - PassThruImpl *passthrough = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *passthrough = impl_from_IMediaPosition(iface);
return IUnknown_AddRef(passthrough->outer_unk); }
static ULONG WINAPI MediaPositionPassThru_Release(IMediaPosition *iface) { - PassThruImpl *passthrough = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *passthrough = impl_from_IMediaPosition(iface);
return IUnknown_Release(passthrough->outer_unk); } @@ -525,7 +527,7 @@ static HRESULT WINAPI MediaPositionPassThru_Invoke(IMediaPosition *iface, DISPID
static HRESULT WINAPI MediaPositionPassThru_get_Duration(IMediaPosition *iface, REFTIME *plength) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -543,7 +545,7 @@ static HRESULT WINAPI MediaPositionPassThru_get_Duration(IMediaPosition *iface,
static HRESULT WINAPI MediaPositionPassThru_put_CurrentPosition(IMediaPosition *iface, REFTIME llTime) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -561,7 +563,7 @@ static HRESULT WINAPI MediaPositionPassThru_put_CurrentPosition(IMediaPosition *
static HRESULT WINAPI MediaPositionPassThru_get_CurrentPosition(IMediaPosition *iface, REFTIME *pllTime) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -579,7 +581,7 @@ static HRESULT WINAPI MediaPositionPassThru_get_CurrentPosition(IMediaPosition *
static HRESULT WINAPI MediaPositionPassThru_get_StopTime(IMediaPosition *iface, REFTIME *pllTime) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -597,7 +599,7 @@ static HRESULT WINAPI MediaPositionPassThru_get_StopTime(IMediaPosition *iface,
static HRESULT WINAPI MediaPositionPassThru_put_StopTime(IMediaPosition *iface, REFTIME llTime) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -615,7 +617,7 @@ static HRESULT WINAPI MediaPositionPassThru_put_StopTime(IMediaPosition *iface,
static HRESULT WINAPI MediaPositionPassThru_get_PrerollTime(IMediaPosition *iface, REFTIME *pllTime) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -633,7 +635,7 @@ static HRESULT WINAPI MediaPositionPassThru_get_PrerollTime(IMediaPosition *ifac
static HRESULT WINAPI MediaPositionPassThru_put_PrerollTime(IMediaPosition *iface, REFTIME llTime) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -651,7 +653,7 @@ static HRESULT WINAPI MediaPositionPassThru_put_PrerollTime(IMediaPosition *ifac
static HRESULT WINAPI MediaPositionPassThru_put_Rate(IMediaPosition *iface, double dRate) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -669,7 +671,7 @@ static HRESULT WINAPI MediaPositionPassThru_put_Rate(IMediaPosition *iface, doub
static HRESULT WINAPI MediaPositionPassThru_get_Rate(IMediaPosition *iface, double *pdRate) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -687,7 +689,7 @@ static HRESULT WINAPI MediaPositionPassThru_get_Rate(IMediaPosition *iface, doub
static HRESULT WINAPI MediaPositionPassThru_CanSeekForward(IMediaPosition *iface, LONG *pCanSeekForward) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -705,7 +707,7 @@ static HRESULT WINAPI MediaPositionPassThru_CanSeekForward(IMediaPosition *iface
static HRESULT WINAPI MediaPositionPassThru_CanSeekBackward(IMediaPosition *iface, LONG *pCanSeekBackward) { - PassThruImpl *This = impl_from_IMediaPosition(iface); + struct strmbase_passthrough *This = impl_from_IMediaPosition(iface); IMediaPosition *pos; HRESULT hr;
@@ -743,7 +745,7 @@ static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl = MediaPositionPassThru_CanSeekBackward };
-void strmbase_passthrough_init(PassThruImpl *passthrough, IUnknown *outer) +void strmbase_passthrough_init(struct strmbase_passthrough *passthrough, IUnknown *outer) { memset(passthrough, 0, sizeof(*passthrough));
@@ -752,10 +754,10 @@ void strmbase_passthrough_init(PassThruImpl *passthrough, IUnknown *outer) passthrough->IMediaSeeking_iface.lpVtbl = &IMediaSeekingPassThru_Vtbl; passthrough->ISeekingPassThru_iface.lpVtbl = &ISeekingPassThru_Vtbl; InitializeCriticalSection(&passthrough->time_cs); - passthrough->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PassThruImpl.time_cs" ); + passthrough->time_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": strmbase_passthrough.time_cs" ); }
-void strmbase_passthrough_cleanup(PassThruImpl *passthrough) +void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough) { passthrough->time_cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&passthrough->time_cs); @@ -763,7 +765,7 @@ void strmbase_passthrough_cleanup(PassThruImpl *passthrough)
struct seeking_passthrough { - PassThruImpl passthrough; + struct strmbase_passthrough passthrough;
IUnknown IUnknown_inner; IUnknown *outer_unk;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/strmbase/pospass.c | 102 ++++++++++--------------------- dlls/strmbase/renderer.c | 42 ++++++------- dlls/strmbase/strmbase_private.h | 6 +- include/wine/strmbase.h | 22 ++++++- 4 files changed, 72 insertions(+), 100 deletions(-)
diff --git a/dlls/strmbase/pospass.c b/dlls/strmbase/pospass.c index 086e3e6aeb5..3b4560d35eb 100644 --- a/dlls/strmbase/pospass.c +++ b/dlls/strmbase/pospass.c @@ -24,20 +24,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
-struct strmbase_passthrough -{ - ISeekingPassThru ISeekingPassThru_iface; - IMediaSeeking IMediaSeeking_iface; - IMediaPosition IMediaPosition_iface; - - IUnknown * outer_unk; - IPin * pin; - BOOL renderer; - CRITICAL_SECTION time_cs; - BOOL timevalid; - REFERENCE_TIME time_earliest; -}; - static struct strmbase_passthrough *impl_from_ISeekingPassThru(ISeekingPassThru *iface) { return CONTAINING_RECORD(iface, struct strmbase_passthrough, ISeekingPassThru_iface); @@ -97,22 +83,6 @@ static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl = SeekingPassThru_Init };
-HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru) -{ - HRESULT hr; - ISeekingPassThru *passthru; - - hr = CoCreateInstance(&CLSID_SeekingPassThru, pUnkOuter, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)ppPassThru); - if (FAILED(hr)) - return hr; - - IUnknown_QueryInterface(*ppPassThru, &IID_ISeekingPassThru, (void**)&passthru); - hr = ISeekingPassThru_Init(passthru, bRenderer, pPin); - ISeekingPassThru_Release(passthru); - - return hr; -} - static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out) { struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface); @@ -763,6 +733,38 @@ void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough) DeleteCriticalSection(&passthrough->time_cs); }
+void strmbase_passthrough_update_time(struct strmbase_passthrough *passthrough, REFERENCE_TIME time) +{ + EnterCriticalSection(&passthrough->time_cs); + passthrough->time_earliest = time; + passthrough->timevalid = TRUE; + LeaveCriticalSection(&passthrough->time_cs); +} + +void strmbase_passthrough_invalidate_time(struct strmbase_passthrough *passthrough) +{ + EnterCriticalSection(&passthrough->time_cs); + passthrough->timevalid = FALSE; + LeaveCriticalSection(&passthrough->time_cs); +} + +void strmbase_passthrough_eos(struct strmbase_passthrough *passthrough) +{ + REFERENCE_TIME time; + HRESULT hr; + + hr = IMediaSeeking_GetStopPosition(&passthrough->IMediaSeeking_iface, &time); + EnterCriticalSection(&passthrough->time_cs); + if (SUCCEEDED(hr)) + { + passthrough->timevalid = TRUE; + passthrough->time_earliest = time; + } + else + passthrough->timevalid = FALSE; + LeaveCriticalSection(&passthrough->time_cs); +} + struct seeking_passthrough { struct strmbase_passthrough passthrough; @@ -851,43 +853,3 @@ HRESULT WINAPI PosPassThru_Construct(IUnknown *outer, void **out) *out = &object->IUnknown_inner; return S_OK; } - -HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start) -{ - struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); - - EnterCriticalSection(&passthrough->passthrough.time_cs); - passthrough->passthrough.time_earliest = start; - passthrough->passthrough.timevalid = TRUE; - LeaveCriticalSection(&passthrough->passthrough.time_cs); - return S_OK; -} - -HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface) -{ - struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); - - EnterCriticalSection(&passthrough->passthrough.time_cs); - passthrough->passthrough.timevalid = FALSE; - LeaveCriticalSection(&passthrough->passthrough.time_cs); - return S_OK; -} - -HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface) -{ - struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); - REFERENCE_TIME time; - HRESULT hr; - - hr = IMediaSeeking_GetStopPosition(&passthrough->passthrough.IMediaSeeking_iface, &time); - EnterCriticalSection(&passthrough->passthrough.time_cs); - if (SUCCEEDED(hr)) - { - passthrough->passthrough.timevalid = TRUE; - passthrough->passthrough.time_earliest = time; - } - else - passthrough->passthrough.timevalid = FALSE; - LeaveCriticalSection(&passthrough->passthrough.time_cs); - return hr; -} diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 6b5a5e80e3e..57e0d2041ca 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -66,15 +66,17 @@ static HRESULT renderer_query_interface(struct strmbase_filter *iface, REFIID ii return hr; }
- if (IsEqualIID(iid, &IID_IMediaSeeking) || IsEqualIID(iid, &IID_IMediaPosition)) - return IUnknown_QueryInterface(filter->pPosition, iid, out); - else if (IsEqualIID(iid, &IID_IQualityControl)) - { + if (IsEqualGUID(iid, &IID_IMediaPosition)) + *out = &filter->passthrough.IMediaPosition_iface; + else if (IsEqualGUID(iid, &IID_IMediaSeeking)) + *out = &filter->passthrough.IMediaSeeking_iface; + else if (IsEqualGUID(iid, &IID_IQualityControl)) *out = &filter->qcimpl->IQualityControl_iface; - IUnknown_AddRef((IUnknown *)*out); - return S_OK; - } - return E_NOINTERFACE; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; }
static HRESULT renderer_init_stream(struct strmbase_filter *iface) @@ -120,7 +122,7 @@ static HRESULT renderer_cleanup_stream(struct strmbase_filter *iface) { struct strmbase_renderer *filter = impl_from_strmbase_filter(iface);
- RendererPosPassThru_ResetMediaTime(filter->pPosition); + strmbase_passthrough_invalidate_time(&filter->passthrough); SetEvent(filter->state_event); SetEvent(filter->flush_event);
@@ -213,7 +215,7 @@ static HRESULT sink_eos(struct strmbase_sink *iface) (LONG_PTR)&filter->filter.IBaseFilter_iface); IMediaEventSink_Release(event_sink); } - RendererPosPassThru_EOS(filter->pPosition); + strmbase_passthrough_eos(&filter->passthrough); SetEvent(filter->state_event);
if (filter->pFuncsTable->pfnEndOfStream) @@ -241,7 +243,7 @@ static HRESULT sink_end_flush(struct strmbase_sink *iface)
filter->eos = FALSE; QualityControlRender_Start(filter->qcimpl, filter->stream_start); - RendererPosPassThru_ResetMediaTime(filter->pPosition); + strmbase_passthrough_invalidate_time(&filter->passthrough); ResetEvent(filter->flush_event);
if (filter->pFuncsTable->pfnEndFlush) @@ -271,8 +273,7 @@ void strmbase_renderer_cleanup(struct strmbase_renderer *filter) IPin_Disconnect(&filter->sink.pin.IPin_iface); strmbase_sink_cleanup(&filter->sink);
- if (filter->pPosition) - IUnknown_Release(filter->pPosition); + strmbase_passthrough_cleanup(&filter->passthrough);
filter->csRenderLock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&filter->csRenderLock); @@ -328,7 +329,7 @@ HRESULT WINAPI BaseRendererImpl_Receive(struct strmbase_renderer *This, IMediaSa if (This->filter.clock && SUCCEEDED(IMediaSample_GetTime(pSample, &start, &stop))) { hr = S_FALSE; - RendererPosPassThru_RegisterMediaTime(This->pPosition, start); + strmbase_passthrough_update_time(&This->passthrough, start); if (This->pFuncsTable->pfnShouldDrawSampleNow) hr = This->pFuncsTable->pfnShouldDrawSampleNow(This, pSample, &start, &stop);
@@ -390,24 +391,15 @@ HRESULT WINAPI BaseRendererImpl_Receive(struct strmbase_renderer *This, IMediaSa HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown *outer, const CLSID *clsid, const WCHAR *sink_name, const struct strmbase_renderer_ops *ops) { - HRESULT hr; - memset(filter, 0, sizeof(*filter)); strmbase_filter_init(&filter->filter, outer, clsid, &filter_ops); + strmbase_passthrough_init(&filter->passthrough, (IUnknown *)&filter->filter.IBaseFilter_iface); + ISeekingPassThru_Init(&filter->passthrough.ISeekingPassThru_iface, TRUE, &filter->sink.pin.IPin_iface);
filter->pFuncsTable = ops;
strmbase_sink_init(&filter->sink, &filter->filter, sink_name, &sink_ops, NULL);
- hr = CreatePosPassThru(outer ? outer : (IUnknown *)&filter->filter.IBaseFilter_iface, - TRUE, &filter->sink.pin.IPin_iface, &filter->pPosition); - if (FAILED(hr)) - { - strmbase_sink_cleanup(&filter->sink); - strmbase_filter_cleanup(&filter->filter); - return hr; - } - InitializeCriticalSection(&filter->csRenderLock); filter->csRenderLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": strmbase_renderer.csRenderLock"); filter->state_event = CreateEventW(NULL, TRUE, TRUE, NULL); diff --git a/dlls/strmbase/strmbase_private.h b/dlls/strmbase/strmbase_private.h index f9ddcad9a6e..e0628c13a1e 100644 --- a/dlls/strmbase/strmbase_private.h +++ b/dlls/strmbase/strmbase_private.h @@ -79,8 +79,8 @@ void QualityControlRender_DoQOS(QualityControlImpl *priv); void QualityControlRender_BeginRender(QualityControlImpl *This, REFERENCE_TIME start, REFERENCE_TIME stop); void QualityControlRender_EndRender(QualityControlImpl *This);
-HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start); -HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface); -HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface); +void strmbase_passthrough_update_time(struct strmbase_passthrough *passthrough, REFERENCE_TIME time); +void strmbase_passthrough_invalidate_time(struct strmbase_passthrough *passthrough); +void strmbase_passthrough_eos(struct strmbase_passthrough *passthrough);
#endif /* __WINE_STRMBASE_PRIVATE_H */ diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 0bcac13ebbc..6d620c79337 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "dshow.h" #include "wine/list.h"
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc); @@ -203,7 +204,6 @@ HRESULT WINAPI SourceSeekingImpl_SetRate(IMediaSeeking * iface, double dRate); HRESULT WINAPI SourceSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate); HRESULT WINAPI SourceSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll);
-HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru); HRESULT WINAPI PosPassThru_Construct(IUnknown* pUnkOuter, LPVOID *ppPassThru);
/* Output Queue */ @@ -255,12 +255,30 @@ enum strmbase_type_id
HRESULT strmbase_get_typeinfo(enum strmbase_type_id tid, ITypeInfo **typeinfo);
+struct strmbase_passthrough +{ + ISeekingPassThru ISeekingPassThru_iface; + IMediaSeeking IMediaSeeking_iface; + IMediaPosition IMediaPosition_iface; + + IUnknown *outer_unk; + IPin *pin; + BOOL renderer; + BOOL timevalid; + CRITICAL_SECTION time_cs; + REFERENCE_TIME time_earliest; +}; + +void strmbase_passthrough_init(struct strmbase_passthrough *passthrough, IUnknown *outer); +void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough); + struct strmbase_renderer { struct strmbase_filter filter; + struct strmbase_passthrough passthrough;
struct strmbase_sink sink; - IUnknown *pPosition; + CRITICAL_SECTION csRenderLock; /* Signaled when the filter has completed a state change. The filter waits * for this event in IBaseFilter::GetState(). */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=67030
Your paranoid android.
=== debiant (build log) ===
error: patch failed: include/wine/strmbase.h:255 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: include/wine/strmbase.h:255 Task: Patch failed to apply
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/quartz/Makefile.in | 1 + dlls/quartz/main.c | 5 -- dlls/quartz/passthrough.c | 112 +++++++++++++++++++++++++++++++++++ dlls/quartz/quartz_private.h | 1 + dlls/strmbase/pospass.c | 89 ---------------------------- include/wine/strmbase.h | 2 - 6 files changed, 114 insertions(+), 96 deletions(-) create mode 100644 dlls/quartz/passthrough.c
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in index 858b9578792..ec29ef53c6b 100644 --- a/dlls/quartz/Makefile.in +++ b/dlls/quartz/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ filtermapper.c \ main.c \ memallocator.c \ + passthrough.c \ regsvr.c \ systemclock.c \ video.c \ diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c index 284f2cacaea..89c7fe9bb15 100644 --- a/dlls/quartz/main.c +++ b/dlls/quartz/main.c @@ -36,11 +36,6 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) return QUARTZ_DllMain(instance, reason, reserved); }
-static HRESULT seeking_passthrough_create(IUnknown *outer, IUnknown **out) -{ - return PosPassThru_Construct(outer, (void **)out); -} - /****************************************************************************** * DirectShow ClassFactory */ diff --git a/dlls/quartz/passthrough.c b/dlls/quartz/passthrough.c new file mode 100644 index 00000000000..2f8fe9dc370 --- /dev/null +++ b/dlls/quartz/passthrough.c @@ -0,0 +1,112 @@ +/* + * Seeking passthrough object + * + * Copyright 2020 Zebediah Figura for CodeWeavers + * + * 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" + +WINE_DEFAULT_DEBUG_CHANNEL(quartz); + +struct seeking_passthrough +{ + struct strmbase_passthrough passthrough; + + IUnknown IUnknown_inner; + IUnknown *outer_unk; + LONG refcount; +}; + +static struct seeking_passthrough *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct seeking_passthrough, IUnknown_inner); +} + +static HRESULT WINAPI seeking_passthrough_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + + TRACE("passthrough %p, iid %s, out %p.\n", passthrough, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown)) + *out = iface; + else if (IsEqualGUID(iid, &IID_IMediaPosition)) + *out = &passthrough->passthrough.IMediaPosition_iface; + else if (IsEqualGUID(iid, &IID_IMediaSeeking)) + *out = &passthrough->passthrough.IMediaSeeking_iface; + else if (IsEqualGUID(iid, &IID_ISeekingPassThru)) + *out = &passthrough->passthrough.ISeekingPassThru_iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI seeking_passthrough_AddRef(IUnknown *iface) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&passthrough->refcount); + + TRACE("%p increasing refcount to %u.\n", passthrough, refcount); + return refcount; +} + +static ULONG WINAPI seeking_passthrough_Release(IUnknown *iface) +{ + struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&passthrough->refcount); + + TRACE("%p decreasing refcount to %u.\n", passthrough, refcount); + if (!refcount) + { + strmbase_passthrough_cleanup(&passthrough->passthrough); + free(passthrough); + } + return refcount; +} + +static const IUnknownVtbl seeking_passthrough_vtbl = +{ + seeking_passthrough_QueryInterface, + seeking_passthrough_AddRef, + seeking_passthrough_Release, +}; + +HRESULT seeking_passthrough_create(IUnknown *outer, IUnknown **out) +{ + struct seeking_passthrough *object; + + TRACE("outer %p, out %p.\n", outer, out); + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IUnknown_inner.lpVtbl = &seeking_passthrough_vtbl; + object->outer_unk = outer ? outer : &object->IUnknown_inner; + object->refcount = 1; + + strmbase_passthrough_init(&object->passthrough, object->outer_unk); + + TRACE("Created seeking passthrough %p.\n", object); + *out = &object->IUnknown_inner; + return S_OK; +} diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 3332c27d21a..55385379085 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -69,6 +69,7 @@ HRESULT filter_graph_no_thread_create(IUnknown *outer, IUnknown **out) DECLSPEC_ HRESULT filter_mapper_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT mem_allocator_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT system_clock_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; +HRESULT seeking_passthrough_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT video_renderer_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT video_renderer_default_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; HRESULT vmr7_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN; diff --git a/dlls/strmbase/pospass.c b/dlls/strmbase/pospass.c index 3b4560d35eb..b9e6f23a974 100644 --- a/dlls/strmbase/pospass.c +++ b/dlls/strmbase/pospass.c @@ -764,92 +764,3 @@ void strmbase_passthrough_eos(struct strmbase_passthrough *passthrough) passthrough->timevalid = FALSE; LeaveCriticalSection(&passthrough->time_cs); } - -struct seeking_passthrough -{ - struct strmbase_passthrough passthrough; - - IUnknown IUnknown_inner; - IUnknown *outer_unk; - LONG refcount; -}; - -static struct seeking_passthrough *impl_from_IUnknown(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, struct seeking_passthrough, IUnknown_inner); -} - -static HRESULT WINAPI seeking_passthrough_QueryInterface(IUnknown *iface, REFIID iid, void **out) -{ - struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); - - TRACE("passthrough %p, iid %s, out %p.\n", passthrough, debugstr_guid(iid), out); - - if (IsEqualGUID(iid, &IID_IUnknown)) - *out = iface; - else if (IsEqualGUID(iid, &IID_IMediaPosition)) - *out = &passthrough->passthrough.IMediaPosition_iface; - else if (IsEqualGUID(iid, &IID_IMediaSeeking)) - *out = &passthrough->passthrough.IMediaSeeking_iface; - else if (IsEqualGUID(iid, &IID_ISeekingPassThru)) - *out = &passthrough->passthrough.ISeekingPassThru_iface; - else - { - *out = NULL; - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown *)*out); - return S_OK; -} - -static ULONG WINAPI seeking_passthrough_AddRef(IUnknown *iface) -{ - struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); - ULONG refcount = InterlockedIncrement(&passthrough->refcount); - - TRACE("%p increasing refcount to %u.\n", passthrough, refcount); - return refcount; -} - -static ULONG WINAPI seeking_passthrough_Release(IUnknown *iface) -{ - struct seeking_passthrough *passthrough = impl_from_IUnknown(iface); - ULONG refcount = InterlockedDecrement(&passthrough->refcount); - - TRACE("%p decreasing refcount to %u.\n", passthrough, refcount); - if (!refcount) - { - strmbase_passthrough_cleanup(&passthrough->passthrough); - heap_free(passthrough); - } - return refcount; -} - -static const IUnknownVtbl seeking_passthrough_vtbl = -{ - seeking_passthrough_QueryInterface, - seeking_passthrough_AddRef, - seeking_passthrough_Release, -}; - -HRESULT WINAPI PosPassThru_Construct(IUnknown *outer, void **out) -{ - struct seeking_passthrough *object; - - TRACE("outer %p, out %p.\n", outer, out); - - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; - - object->IUnknown_inner.lpVtbl = &seeking_passthrough_vtbl; - object->outer_unk = outer ? outer : &object->IUnknown_inner; - object->refcount = 1; - - strmbase_passthrough_init(&object->passthrough, object->outer_unk); - - TRACE("Created seeking passthrough %p.\n", object); - *out = &object->IUnknown_inner; - return S_OK; -} diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 6d620c79337..732ba1be269 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -204,8 +204,6 @@ HRESULT WINAPI SourceSeekingImpl_SetRate(IMediaSeeking * iface, double dRate); HRESULT WINAPI SourceSeekingImpl_GetRate(IMediaSeeking * iface, double * dRate); HRESULT WINAPI SourceSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll);
-HRESULT WINAPI PosPassThru_Construct(IUnknown* pUnkOuter, LPVOID *ppPassThru); - /* Output Queue */ typedef struct tagOutputQueue { CRITICAL_SECTION csQueue;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=67031
Your paranoid android.
=== debiant (build log) ===
error: patch failed: include/wine/strmbase.h:255 error: patch failed: dlls/quartz/Makefile.in:15 error: patch failed: dlls/quartz/main.c:36 error: patch failed: dlls/quartz/quartz_private.h:69 error: patch failed: include/wine/strmbase.h:204 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: include/wine/strmbase.h:255 error: patch failed: dlls/quartz/Makefile.in:15 error: patch failed: dlls/quartz/main.c:36 error: patch failed: dlls/quartz/quartz_private.h:69 error: patch failed: include/wine/strmbase.h:204 Task: Patch failed to apply
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48734 Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/quartz/acmwrapper.c | 2 ++ dlls/quartz/avidec.c | 2 ++ dlls/quartz/dsoundrender.c | 2 ++ dlls/quartz/filesource.c | 2 ++ dlls/quartz/filtergraph.c | 2 ++ dlls/quartz/filtermapper.c | 4 ++++ dlls/quartz/main.c | 9 +++++---- dlls/quartz/memallocator.c | 2 ++ dlls/quartz/passthrough.c | 2 ++ dlls/quartz/quartz_private.h | 2 ++ dlls/quartz/systemclock.c | 2 ++ dlls/quartz/videorenderer.c | 2 ++ dlls/quartz/vmr9.c | 2 ++ 13 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c index b354ae4009a..7c511471ff0 100644 --- a/dlls/quartz/acmwrapper.c +++ b/dlls/quartz/acmwrapper.c @@ -493,6 +493,8 @@ static void acm_wrapper_destroy(struct strmbase_filter *iface) IUnknown_Release(filter->seeking); strmbase_filter_cleanup(&filter->filter); free(filter); + + InterlockedDecrement(&object_locks); }
static HRESULT acm_wrapper_init_stream(struct strmbase_filter *iface) diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c index 7b6838e466d..0837ae2b8da 100644 --- a/dlls/quartz/avidec.c +++ b/dlls/quartz/avidec.c @@ -489,6 +489,8 @@ static void avi_decompressor_destroy(struct strmbase_filter *iface) IUnknown_Release(filter->seeking); strmbase_filter_cleanup(&filter->filter); free(filter); + + InterlockedDecrement(&object_locks); }
static HRESULT avi_decompressor_init_stream(struct strmbase_filter *iface) diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 8dc93abd628..84b31930a5c 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -500,6 +500,8 @@ static void dsound_render_destroy(struct strmbase_renderer *iface)
strmbase_renderer_cleanup(&filter->renderer); CoTaskMemFree(filter); + + InterlockedDecrement(&object_locks); }
static HRESULT dsound_render_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out) diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c index 09ab5e51fea..72e52dd01c7 100644 --- a/dlls/quartz/filesource.c +++ b/dlls/quartz/filesource.c @@ -353,6 +353,8 @@ static void async_reader_destroy(struct strmbase_filter *iface)
strmbase_filter_cleanup(&filter->filter); free(filter); + + InterlockedDecrement(&object_locks); }
static HRESULT async_reader_query_interface(struct strmbase_filter *iface, REFIID iid, void **out) diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index dfda734d8a9..c659cf96e4c 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -518,6 +518,8 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown *iface) } DeleteCriticalSection(&This->cs); CoTaskMemFree(This); + + InterlockedDecrement(&object_locks); } return ref; } diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c index 0d1403b5168..db162c01339 100644 --- a/dlls/quartz/filtermapper.c +++ b/dlls/quartz/filtermapper.c @@ -193,8 +193,12 @@ static ULONG WINAPI Inner_Release(IUnknown *iface) TRACE("(%p)->(): new ref = %d\n", This, ref);
if (ref == 0) + { CoTaskMemFree(This);
+ InterlockedDecrement(&object_locks); + } + return ref; }
diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c index 89c7fe9bb15..4acb4f1a795 100644 --- a/dlls/quartz/main.c +++ b/dlls/quartz/main.c @@ -27,7 +27,7 @@ extern HRESULT WINAPI QUARTZ_DllGetClassObject(REFCLSID, REFIID, LPVOID *) DECLS extern HRESULT WINAPI QUARTZ_DllCanUnloadNow(void) DECLSPEC_HIDDEN; extern BOOL WINAPI QUARTZ_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN;
-static LONG server_locks = 0; +LONG object_locks = 0;
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { @@ -124,6 +124,7 @@ static HRESULT WINAPI DSCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter
if (SUCCEEDED(hres = This->create_instance(pOuter, &punk))) { + InterlockedIncrement(&object_locks); hres = IUnknown_QueryInterface(punk, riid, ppobj); IUnknown_Release(punk); } @@ -135,9 +136,9 @@ static HRESULT WINAPI DSCF_LockServer(IClassFactory *iface, BOOL dolock) IClassFactoryImpl *This = impl_from_IClassFactory(iface); FIXME("(%p)->(%d),stub!\n",This,dolock); if(dolock) - InterlockedIncrement(&server_locks); + InterlockedIncrement(&object_locks); else - InterlockedDecrement(&server_locks); + InterlockedDecrement(&object_locks); return S_OK; }
@@ -200,7 +201,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) */ HRESULT WINAPI DllCanUnloadNow(void) { - if(server_locks == 0 && QUARTZ_DllCanUnloadNow() == S_OK) + if (!object_locks && QUARTZ_DllCanUnloadNow() == S_OK) return S_OK; return S_FALSE; } diff --git a/dlls/quartz/memallocator.c b/dlls/quartz/memallocator.c index 531fbe874cf..cc13f776cfb 100644 --- a/dlls/quartz/memallocator.c +++ b/dlls/quartz/memallocator.c @@ -911,6 +911,8 @@ static void StdMemAllocator_Destroy(IMemAllocator *iface) DeleteCriticalSection(&This->csState);
CoTaskMemFree(This); + + InterlockedDecrement(&object_locks); }
HRESULT mem_allocator_create(IUnknown *lpUnkOuter, IUnknown **out) diff --git a/dlls/quartz/passthrough.c b/dlls/quartz/passthrough.c index 2f8fe9dc370..7f81ae8a1be 100644 --- a/dlls/quartz/passthrough.c +++ b/dlls/quartz/passthrough.c @@ -80,6 +80,8 @@ static ULONG WINAPI seeking_passthrough_Release(IUnknown *iface) { strmbase_passthrough_cleanup(&passthrough->passthrough); free(passthrough); + + InterlockedDecrement(&object_locks); } return refcount; } diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index 55385379085..1812b1c37ef 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -56,6 +56,8 @@ static inline const char *debugstr_time(REFERENCE_TIME time) return wine_dbg_sprintf("%s", rev); }
+extern LONG object_locks; + /* see IAsyncReader::Request on MSDN for the explanation of this */ #define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000) #define BYTES_FROM_MEDIATIME(time) ((time) / 10000000) diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c index 8ccd6df47ce..24d8651aaba 100644 --- a/dlls/quartz/systemclock.c +++ b/dlls/quartz/systemclock.c @@ -105,6 +105,8 @@ static ULONG WINAPI system_clock_inner_Release(IUnknown *iface) clock->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&clock->cs); heap_free(clock); + + InterlockedDecrement(&object_locks); } return refcount; } diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index 1b5e68e7d5b..37227bfa210 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -248,6 +248,8 @@ static void video_renderer_destroy(struct strmbase_renderer *iface) CloseHandle(filter->run_event); strmbase_renderer_cleanup(&filter->renderer); CoTaskMemFree(filter); + + InterlockedDecrement(&object_locks); }
static HRESULT video_renderer_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out) diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index b8cf0698ecd..e7a588e28a0 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -519,6 +519,8 @@ static void vmr_destroy(struct strmbase_renderer *iface) BaseControlWindow_Destroy(&filter->baseControlWindow); strmbase_renderer_cleanup(&filter->renderer); CoTaskMemFree(filter); + + InterlockedDecrement(&object_locks); }
static HRESULT vmr_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=67032
Your paranoid android.
=== debiant (build log) ===
error: patch failed: include/wine/strmbase.h:255 error: patch failed: dlls/quartz/Makefile.in:15 error: patch failed: dlls/quartz/main.c:36 error: patch failed: dlls/quartz/quartz_private.h:69 error: patch failed: include/wine/strmbase.h:204 error: patch failed: dlls/quartz/main.c:27 error: patch failed: dlls/quartz/memallocator.c:911 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: include/wine/strmbase.h:255 error: patch failed: dlls/quartz/Makefile.in:15 error: patch failed: dlls/quartz/main.c:36 error: patch failed: dlls/quartz/quartz_private.h:69 error: patch failed: include/wine/strmbase.h:204 error: patch failed: dlls/quartz/main.c:27 error: patch failed: dlls/quartz/memallocator.c:911 Task: Patch failed to apply