strmbase: Separate the seeking passthrough object from its implementation.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-03-12 21:34:08 -05:00 committed by Alexandre Julliard
parent d30fd37176
commit d5d6cfbf63
1 changed files with 147 additions and 128 deletions

View File

@ -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;
}