Maarten Lankhorst : quartz: Implement state transitions in video renderer.
Alexandre Julliard
julliard at winehq.org
Fri Jul 4 13:59:19 CDT 2008
Module: wine
Branch: master
Commit: 9985f2efc9d1e92932dd3d7f351ded3ae1db0b80
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9985f2efc9d1e92932dd3d7f351ded3ae1db0b80
Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Fri Jul 4 01:33:04 2008 -0700
quartz: Implement state transitions in video renderer.
---
dlls/quartz/videorenderer.c | 101 +++++++++++++++++++++++++++++++++---------
1 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c
index 23a5cd9..1ade1c8 100644
--- a/dlls/quartz/videorenderer.c
+++ b/dlls/quartz/videorenderer.c
@@ -71,6 +71,8 @@ typedef struct VideoRendererImpl
BOOL init;
HANDLE hThread;
+ HANDLE blocked;
+
DWORD ThreadID;
HANDLE hEvent;
BOOL ThreadResult;
@@ -231,7 +233,7 @@ static DWORD WINAPI MessageLoop(LPVOID lpParameter)
static BOOL CreateRenderingSubsystem(VideoRendererImpl* This)
{
- This->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ This->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!This->hEvent)
return FALSE;
@@ -243,10 +245,10 @@ static BOOL CreateRenderingSubsystem(VideoRendererImpl* This)
}
WaitForSingleObject(This->hEvent, INFINITE);
- CloseHandle(This->hEvent);
if (!This->ThreadResult)
{
+ CloseHandle(This->hEvent);
CloseHandle(This->hThread);
return FALSE;
}
@@ -411,13 +413,19 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
}
#endif
+ SetEvent(This->hEvent);
if (This->state == State_Paused)
{
- if (This->sample_held)
- IMediaSample_Release(This->sample_held);
-
This->sample_held = pSample;
- IMediaSample_AddRef(pSample);
+ LeaveCriticalSection(&This->csFilter);
+ WaitForSingleObject(This->blocked, INFINITE);
+ EnterCriticalSection(&This->csFilter);
+ This->sample_held = NULL;
+ if (This->state == State_Paused)
+ /* Flushing */
+ return S_OK;
+ if (This->state == State_Stopped)
+ return VFW_E_WRONG_STATE;
}
if (This->pClock && This->state == State_Running)
@@ -611,7 +619,14 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
if (!CreateRenderingSubsystem(pVideoRenderer))
return E_FAIL;
-
+
+ pVideoRenderer->blocked = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if (!pVideoRenderer->blocked)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ IUnknown_Release((IUnknown *)pVideoRenderer);
+ }
+
return hr;
}
@@ -683,6 +698,7 @@ static ULONG WINAPI VideoRendererInner_Release(IUnknown * iface)
PostThreadMessageA(This->ThreadID, WM_QUIT, 0, 0);
WaitForSingleObject(This->hThread, INFINITE);
CloseHandle(This->hThread);
+ CloseHandle(This->hEvent);
if (This->pClock)
IReferenceClock_Release(This->pClock);
@@ -789,12 +805,8 @@ static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface)
EnterCriticalSection(&This->csFilter);
{
This->state = State_Stopped;
-
- if (This->sample_held)
- {
- IMediaSample_Release(This->sample_held);
- This->sample_held = NULL;
- }
+ SetEvent(This->hEvent);
+ SetEvent(This->blocked);
}
LeaveCriticalSection(&This->csFilter);
@@ -808,11 +820,16 @@ static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
TRACE("(%p/%p)->()\n", This, iface);
EnterCriticalSection(&This->csFilter);
+ if (This->state != State_Paused)
{
if (This->state == State_Stopped)
+ {
This->pInputPin->end_of_stream = 0;
+ ResetEvent(This->hEvent);
+ }
This->state = State_Paused;
+ ResetEvent(This->blocked);
}
LeaveCriticalSection(&This->csFilter);
@@ -829,16 +846,14 @@ static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tSta
if (This->state != State_Running)
{
if (This->state == State_Stopped)
+ {
This->pInputPin->end_of_stream = 0;
+ ResetEvent(This->hEvent);
+ }
+ SetEvent(This->blocked);
This->rtStreamStart = tStart;
This->state = State_Running;
-
- if (This->sample_held)
- {
- IMediaSample_Release(This->sample_held);
- This->sample_held = NULL;
- }
}
LeaveCriticalSection(&This->csFilter);
@@ -848,16 +863,22 @@ static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tSta
static HRESULT WINAPI VideoRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
{
VideoRendererImpl *This = (VideoRendererImpl *)iface;
+ HRESULT hr;
TRACE("(%p/%p)->(%d, %p)\n", This, iface, dwMilliSecsTimeout, pState);
+ if (WaitForSingleObject(This->hEvent, dwMilliSecsTimeout) == WAIT_TIMEOUT)
+ hr = VFW_S_STATE_INTERMEDIATE;
+ else
+ hr = S_OK;
+
EnterCriticalSection(&This->csFilter);
{
*pState = This->state;
}
LeaveCriticalSection(&This->csFilter);
- return S_OK;
+ return hr;
}
static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
@@ -1013,6 +1034,42 @@ static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface)
return hr;
}
+static HRESULT WINAPI VideoRenderer_InputPin_BeginFlush(IPin * iface)
+{
+ InputPin* This = (InputPin*)iface;
+ VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter;
+ HRESULT hr;
+
+ TRACE("(%p/%p)->()\n", This, iface);
+
+ EnterCriticalSection(This->pin.pCritSec);
+ if (pVideoRenderer->state == State_Paused)
+ SetEvent(pVideoRenderer->blocked);
+
+ hr = InputPin_BeginFlush(iface);
+ LeaveCriticalSection(This->pin.pCritSec);
+
+ return hr;
+}
+
+static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface)
+{
+ InputPin* This = (InputPin*)iface;
+ VideoRendererImpl *pVideoRenderer = (VideoRendererImpl *)This->pin.pinInfo.pFilter;
+ HRESULT hr;
+
+ TRACE("(%p/%p)->()\n", This, iface);
+
+ EnterCriticalSection(This->pin.pCritSec);
+ if (pVideoRenderer->state == State_Paused)
+ ResetEvent(pVideoRenderer->blocked);
+
+ hr = InputPin_EndFlush(iface);
+ LeaveCriticalSection(This->pin.pCritSec);
+
+ return hr;
+}
+
static const IPinVtbl VideoRenderer_InputPin_Vtbl =
{
InputPin_QueryInterface,
@@ -1030,8 +1087,8 @@ static const IPinVtbl VideoRenderer_InputPin_Vtbl =
IPinImpl_EnumMediaTypes,
IPinImpl_QueryInternalConnections,
VideoRenderer_InputPin_EndOfStream,
- InputPin_BeginFlush,
- InputPin_EndFlush,
+ VideoRenderer_InputPin_BeginFlush,
+ VideoRenderer_InputPin_EndFlush,
InputPin_NewSegment
};
More information about the wine-cvs
mailing list