strmbase: Use strmbase_passthrough directly in strmbase_renderer.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Zebediah Figura 2020-03-12 21:34:10 -05:00 committed by Alexandre Julliard
parent 54ee53382f
commit 191ae9f3ff
4 changed files with 72 additions and 100 deletions

View File

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

View File

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

View File

@ -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 */

View File

@ -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(). */