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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue