Commit bf8a9613 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

evr/presenter: Create dedicated thread to handle presentation time.

parent a8a03eb3
...@@ -40,6 +40,18 @@ enum presenter_state ...@@ -40,6 +40,18 @@ enum presenter_state
PRESENTER_STATE_PAUSED, PRESENTER_STATE_PAUSED,
}; };
enum streaming_thread_message
{
EVRM_STOP = WM_USER,
};
struct streaming_thread
{
HANDLE hthread;
HANDLE ready_event;
DWORD tid;
};
struct video_presenter struct video_presenter
{ {
IMFVideoPresenter IMFVideoPresenter_iface; IMFVideoPresenter IMFVideoPresenter_iface;
...@@ -58,6 +70,7 @@ struct video_presenter ...@@ -58,6 +70,7 @@ struct video_presenter
IMediaEventSink *event_sink; IMediaEventSink *event_sink;
IDirect3DDeviceManager9 *device_manager; IDirect3DDeviceManager9 *device_manager;
struct streaming_thread thread;
UINT reset_token; UINT reset_token;
HWND video_window; HWND video_window;
MFVideoNormalizedRect src_rect; MFVideoNormalizedRect src_rect;
...@@ -184,6 +197,80 @@ static HRESULT video_presenter_invalidate_media_type(struct video_presenter *pre ...@@ -184,6 +197,80 @@ static HRESULT video_presenter_invalidate_media_type(struct video_presenter *pre
return hr; return hr;
} }
static DWORD CALLBACK video_presenter_streaming_thread(void *arg)
{
struct video_presenter *presenter = arg;
BOOL stop_thread = FALSE;
MSG msg;
PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
SetEvent(presenter->thread.ready_event);
while (!stop_thread)
{
MsgWaitForMultipleObjects(0, NULL, FALSE, INFINITE, QS_POSTMESSAGE);
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
switch (msg.message)
{
case EVRM_STOP:
stop_thread = TRUE;
break;
default:
;
}
}
}
return 0;
}
static HRESULT video_presenter_start_streaming(struct video_presenter *presenter)
{
if (presenter->thread.hthread)
return S_OK;
if (!(presenter->thread.ready_event = CreateEventW(NULL, FALSE, FALSE, NULL)))
return HRESULT_FROM_WIN32(GetLastError());
if (!(presenter->thread.hthread = CreateThread(NULL, 0, video_presenter_streaming_thread,
presenter, 0, &presenter->thread.tid)))
{
WARN("Failed to create streaming thread.\n");
CloseHandle(presenter->thread.ready_event);
presenter->thread.ready_event = NULL;
return E_FAIL;
}
WaitForSingleObject(presenter->thread.ready_event, INFINITE);
CloseHandle(presenter->thread.ready_event);
presenter->thread.ready_event = NULL;
TRACE("Started streaming thread, tid %#x.\n", presenter->thread.tid);
return S_OK;
}
static HRESULT video_presenter_end_streaming(struct video_presenter *presenter)
{
if (!presenter->thread.hthread)
return S_OK;
PostThreadMessageW(presenter->thread.tid, EVRM_STOP, 0, 0);
WaitForSingleObject(presenter->thread.hthread, INFINITE);
CloseHandle(presenter->thread.hthread);
TRACE("Terminated streaming thread tid %#x.\n", presenter->thread.tid);
memset(&presenter->thread, 0, sizeof(presenter->thread));
return S_OK;
}
static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj) static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
{ {
struct video_presenter *presenter = impl_from_IUnknown(iface); struct video_presenter *presenter = impl_from_IUnknown(iface);
...@@ -266,6 +353,7 @@ static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface) ...@@ -266,6 +353,7 @@ static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface)
if (!refcount) if (!refcount)
{ {
video_presenter_end_streaming(presenter);
video_presenter_clear_container(presenter); video_presenter_clear_container(presenter);
DeleteCriticalSection(&presenter->cs); DeleteCriticalSection(&presenter->cs);
if (presenter->device_manager) if (presenter->device_manager)
...@@ -374,6 +462,12 @@ static HRESULT WINAPI video_presenter_ProcessMessage(IMFVideoPresenter *iface, M ...@@ -374,6 +462,12 @@ static HRESULT WINAPI video_presenter_ProcessMessage(IMFVideoPresenter *iface, M
case MFVP_MESSAGE_INVALIDATEMEDIATYPE: case MFVP_MESSAGE_INVALIDATEMEDIATYPE:
hr = video_presenter_invalidate_media_type(presenter); hr = video_presenter_invalidate_media_type(presenter);
break; break;
case MFVP_MESSAGE_BEGINSTREAMING:
hr = video_presenter_start_streaming(presenter);
break;
case MFVP_MESSAGE_ENDSTREAMING:
hr = video_presenter_end_streaming(presenter);
break;
default: default:
FIXME("Unsupported message %u.\n", message); FIXME("Unsupported message %u.\n", message);
hr = E_NOTIMPL; hr = E_NOTIMPL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment