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:
parent
d30fd37176
commit
d5d6cfbf63
|
@ -24,16 +24,11 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
|
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
|
||||||
|
|
||||||
static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl;
|
|
||||||
static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl;
|
|
||||||
|
|
||||||
typedef struct PassThruImpl {
|
typedef struct PassThruImpl {
|
||||||
IUnknown IUnknown_inner;
|
|
||||||
ISeekingPassThru ISeekingPassThru_iface;
|
ISeekingPassThru ISeekingPassThru_iface;
|
||||||
IMediaSeeking IMediaSeeking_iface;
|
IMediaSeeking IMediaSeeking_iface;
|
||||||
IMediaPosition IMediaPosition_iface;
|
IMediaPosition IMediaPosition_iface;
|
||||||
|
|
||||||
LONG ref;
|
|
||||||
IUnknown * outer_unk;
|
IUnknown * outer_unk;
|
||||||
IPin * pin;
|
IPin * pin;
|
||||||
BOOL renderer;
|
BOOL renderer;
|
||||||
|
@ -42,11 +37,6 @@ typedef struct PassThruImpl {
|
||||||
REFERENCE_TIME time_earliest;
|
REFERENCE_TIME time_earliest;
|
||||||
} PassThruImpl;
|
} 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)
|
static inline PassThruImpl *impl_from_ISeekingPassThru(ISeekingPassThru *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, PassThruImpl, 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);
|
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)
|
static HRESULT WINAPI SeekingPassThru_QueryInterface(ISeekingPassThru *iface, REFIID iid, void **out)
|
||||||
{
|
{
|
||||||
PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface);
|
PassThruImpl *passthrough = impl_from_ISeekingPassThru(iface);
|
||||||
|
@ -182,29 +112,6 @@ HRESULT WINAPI CreatePosPassThru(IUnknown* pUnkOuter, BOOL bRenderer, IPin *pPin
|
||||||
return hr;
|
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)
|
static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
|
||||||
{
|
{
|
||||||
PassThruImpl *passthrough = impl_from_IMediaSeeking(iface);
|
PassThruImpl *passthrough = impl_from_IMediaSeeking(iface);
|
||||||
|
@ -523,41 +430,6 @@ static HRESULT WINAPI MediaSeekingPassThru_GetPreroll(IMediaSeeking * iface, LON
|
||||||
return hr;
|
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 =
|
static const IMediaSeekingVtbl IMediaSeekingPassThru_Vtbl =
|
||||||
{
|
{
|
||||||
MediaSeekingPassThru_QueryInterface,
|
MediaSeekingPassThru_QueryInterface,
|
||||||
|
@ -870,3 +742,150 @@ static const IMediaPositionVtbl IMediaPositionPassThru_Vtbl =
|
||||||
MediaPositionPassThru_CanSeekForward,
|
MediaPositionPassThru_CanSeekForward,
|
||||||
MediaPositionPassThru_CanSeekBackward
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue