forked from Mirrors/wine-wine
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
parent
54ee53382f
commit
191ae9f3ff
|
@ -24,20 +24,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(strmbase);
|
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)
|
static struct strmbase_passthrough *impl_from_ISeekingPassThru(ISeekingPassThru *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, struct strmbase_passthrough, ISeekingPassThru_iface);
|
return CONTAINING_RECORD(iface, struct strmbase_passthrough, ISeekingPassThru_iface);
|
||||||
|
@ -97,22 +83,6 @@ static const ISeekingPassThruVtbl ISeekingPassThru_Vtbl =
|
||||||
SeekingPassThru_Init
|
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)
|
static HRESULT WINAPI MediaSeekingPassThru_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
|
||||||
{
|
{
|
||||||
struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
|
struct strmbase_passthrough *passthrough = impl_from_IMediaSeeking(iface);
|
||||||
|
@ -763,6 +733,38 @@ void strmbase_passthrough_cleanup(struct strmbase_passthrough *passthrough)
|
||||||
DeleteCriticalSection(&passthrough->time_cs);
|
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 seeking_passthrough
|
||||||
{
|
{
|
||||||
struct strmbase_passthrough passthrough;
|
struct strmbase_passthrough passthrough;
|
||||||
|
@ -851,43 +853,3 @@ HRESULT WINAPI PosPassThru_Construct(IUnknown *outer, void **out)
|
||||||
*out = &object->IUnknown_inner;
|
*out = &object->IUnknown_inner;
|
||||||
return S_OK;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -66,15 +66,17 @@ static HRESULT renderer_query_interface(struct strmbase_filter *iface, REFIID ii
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsEqualIID(iid, &IID_IMediaSeeking) || IsEqualIID(iid, &IID_IMediaPosition))
|
if (IsEqualGUID(iid, &IID_IMediaPosition))
|
||||||
return IUnknown_QueryInterface(filter->pPosition, iid, out);
|
*out = &filter->passthrough.IMediaPosition_iface;
|
||||||
else if (IsEqualIID(iid, &IID_IQualityControl))
|
else if (IsEqualGUID(iid, &IID_IMediaSeeking))
|
||||||
{
|
*out = &filter->passthrough.IMediaSeeking_iface;
|
||||||
|
else if (IsEqualGUID(iid, &IID_IQualityControl))
|
||||||
*out = &filter->qcimpl->IQualityControl_iface;
|
*out = &filter->qcimpl->IQualityControl_iface;
|
||||||
IUnknown_AddRef((IUnknown *)*out);
|
else
|
||||||
return S_OK;
|
return E_NOINTERFACE;
|
||||||
}
|
|
||||||
return E_NOINTERFACE;
|
IUnknown_AddRef((IUnknown *)*out);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT renderer_init_stream(struct strmbase_filter *iface)
|
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);
|
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->state_event);
|
||||||
SetEvent(filter->flush_event);
|
SetEvent(filter->flush_event);
|
||||||
|
|
||||||
|
@ -213,7 +215,7 @@ static HRESULT sink_eos(struct strmbase_sink *iface)
|
||||||
(LONG_PTR)&filter->filter.IBaseFilter_iface);
|
(LONG_PTR)&filter->filter.IBaseFilter_iface);
|
||||||
IMediaEventSink_Release(event_sink);
|
IMediaEventSink_Release(event_sink);
|
||||||
}
|
}
|
||||||
RendererPosPassThru_EOS(filter->pPosition);
|
strmbase_passthrough_eos(&filter->passthrough);
|
||||||
SetEvent(filter->state_event);
|
SetEvent(filter->state_event);
|
||||||
|
|
||||||
if (filter->pFuncsTable->pfnEndOfStream)
|
if (filter->pFuncsTable->pfnEndOfStream)
|
||||||
|
@ -241,7 +243,7 @@ static HRESULT sink_end_flush(struct strmbase_sink *iface)
|
||||||
|
|
||||||
filter->eos = FALSE;
|
filter->eos = FALSE;
|
||||||
QualityControlRender_Start(filter->qcimpl, filter->stream_start);
|
QualityControlRender_Start(filter->qcimpl, filter->stream_start);
|
||||||
RendererPosPassThru_ResetMediaTime(filter->pPosition);
|
strmbase_passthrough_invalidate_time(&filter->passthrough);
|
||||||
ResetEvent(filter->flush_event);
|
ResetEvent(filter->flush_event);
|
||||||
|
|
||||||
if (filter->pFuncsTable->pfnEndFlush)
|
if (filter->pFuncsTable->pfnEndFlush)
|
||||||
|
@ -271,8 +273,7 @@ void strmbase_renderer_cleanup(struct strmbase_renderer *filter)
|
||||||
IPin_Disconnect(&filter->sink.pin.IPin_iface);
|
IPin_Disconnect(&filter->sink.pin.IPin_iface);
|
||||||
strmbase_sink_cleanup(&filter->sink);
|
strmbase_sink_cleanup(&filter->sink);
|
||||||
|
|
||||||
if (filter->pPosition)
|
strmbase_passthrough_cleanup(&filter->passthrough);
|
||||||
IUnknown_Release(filter->pPosition);
|
|
||||||
|
|
||||||
filter->csRenderLock.DebugInfo->Spare[0] = 0;
|
filter->csRenderLock.DebugInfo->Spare[0] = 0;
|
||||||
DeleteCriticalSection(&filter->csRenderLock);
|
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)))
|
if (This->filter.clock && SUCCEEDED(IMediaSample_GetTime(pSample, &start, &stop)))
|
||||||
{
|
{
|
||||||
hr = S_FALSE;
|
hr = S_FALSE;
|
||||||
RendererPosPassThru_RegisterMediaTime(This->pPosition, start);
|
strmbase_passthrough_update_time(&This->passthrough, start);
|
||||||
if (This->pFuncsTable->pfnShouldDrawSampleNow)
|
if (This->pFuncsTable->pfnShouldDrawSampleNow)
|
||||||
hr = This->pFuncsTable->pfnShouldDrawSampleNow(This, pSample, &start, &stop);
|
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,
|
HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown *outer,
|
||||||
const CLSID *clsid, const WCHAR *sink_name, const struct strmbase_renderer_ops *ops)
|
const CLSID *clsid, const WCHAR *sink_name, const struct strmbase_renderer_ops *ops)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
memset(filter, 0, sizeof(*filter));
|
memset(filter, 0, sizeof(*filter));
|
||||||
strmbase_filter_init(&filter->filter, outer, clsid, &filter_ops);
|
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;
|
filter->pFuncsTable = ops;
|
||||||
|
|
||||||
strmbase_sink_init(&filter->sink, &filter->filter, sink_name, &sink_ops, NULL);
|
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);
|
InitializeCriticalSection(&filter->csRenderLock);
|
||||||
filter->csRenderLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": strmbase_renderer.csRenderLock");
|
filter->csRenderLock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": strmbase_renderer.csRenderLock");
|
||||||
filter->state_event = CreateEventW(NULL, TRUE, TRUE, NULL);
|
filter->state_event = CreateEventW(NULL, TRUE, TRUE, NULL);
|
||||||
|
|
|
@ -79,8 +79,8 @@ void QualityControlRender_DoQOS(QualityControlImpl *priv);
|
||||||
void QualityControlRender_BeginRender(QualityControlImpl *This, REFERENCE_TIME start, REFERENCE_TIME stop);
|
void QualityControlRender_BeginRender(QualityControlImpl *This, REFERENCE_TIME start, REFERENCE_TIME stop);
|
||||||
void QualityControlRender_EndRender(QualityControlImpl *This);
|
void QualityControlRender_EndRender(QualityControlImpl *This);
|
||||||
|
|
||||||
HRESULT WINAPI RendererPosPassThru_RegisterMediaTime(IUnknown *iface, REFERENCE_TIME start);
|
void strmbase_passthrough_update_time(struct strmbase_passthrough *passthrough, REFERENCE_TIME time);
|
||||||
HRESULT WINAPI RendererPosPassThru_ResetMediaTime(IUnknown *iface);
|
void strmbase_passthrough_invalidate_time(struct strmbase_passthrough *passthrough);
|
||||||
HRESULT WINAPI RendererPosPassThru_EOS(IUnknown *iface);
|
void strmbase_passthrough_eos(struct strmbase_passthrough *passthrough);
|
||||||
|
|
||||||
#endif /* __WINE_STRMBASE_PRIVATE_H */
|
#endif /* __WINE_STRMBASE_PRIVATE_H */
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "dshow.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
|
|
||||||
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc);
|
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_GetRate(IMediaSeeking * iface, double * dRate);
|
||||||
HRESULT WINAPI SourceSeekingImpl_GetPreroll(IMediaSeeking * iface, LONGLONG * pPreroll);
|
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);
|
HRESULT WINAPI PosPassThru_Construct(IUnknown* pUnkOuter, LPVOID *ppPassThru);
|
||||||
|
|
||||||
/* Output Queue */
|
/* Output Queue */
|
||||||
|
@ -255,12 +255,30 @@ enum strmbase_type_id
|
||||||
|
|
||||||
HRESULT strmbase_get_typeinfo(enum strmbase_type_id tid, ITypeInfo **typeinfo);
|
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_renderer
|
||||||
{
|
{
|
||||||
struct strmbase_filter filter;
|
struct strmbase_filter filter;
|
||||||
|
struct strmbase_passthrough passthrough;
|
||||||
|
|
||||||
struct strmbase_sink sink;
|
struct strmbase_sink sink;
|
||||||
IUnknown *pPosition;
|
|
||||||
CRITICAL_SECTION csRenderLock;
|
CRITICAL_SECTION csRenderLock;
|
||||||
/* Signaled when the filter has completed a state change. The filter waits
|
/* Signaled when the filter has completed a state change. The filter waits
|
||||||
* for this event in IBaseFilter::GetState(). */
|
* for this event in IBaseFilter::GetState(). */
|
||||||
|
|
Loading…
Reference in New Issue