Nikolay Sivov : evr/presenter: Create dedicated thread to handle presentation time.
Alexandre Julliard
julliard at winehq.org
Thu Nov 5 15:37:15 CST 2020
Module: wine
Branch: master
Commit: bf8a9613c500689206448760bd3d20aa707225d1
URL: https://source.winehq.org/git/wine.git/?a=commit;h=bf8a9613c500689206448760bd3d20aa707225d1
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu Nov 5 18:37:23 2020 +0300
evr/presenter: Create dedicated thread to handle presentation time.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/evr/presenter.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c
index 54ad9fee994..01623815dd3 100644
--- a/dlls/evr/presenter.c
+++ b/dlls/evr/presenter.c
@@ -40,6 +40,18 @@ enum presenter_state
PRESENTER_STATE_PAUSED,
};
+enum streaming_thread_message
+{
+ EVRM_STOP = WM_USER,
+};
+
+struct streaming_thread
+{
+ HANDLE hthread;
+ HANDLE ready_event;
+ DWORD tid;
+};
+
struct video_presenter
{
IMFVideoPresenter IMFVideoPresenter_iface;
@@ -58,6 +70,7 @@ struct video_presenter
IMediaEventSink *event_sink;
IDirect3DDeviceManager9 *device_manager;
+ struct streaming_thread thread;
UINT reset_token;
HWND video_window;
MFVideoNormalizedRect src_rect;
@@ -184,6 +197,80 @@ static HRESULT video_presenter_invalidate_media_type(struct video_presenter *pre
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)
{
struct video_presenter *presenter = impl_from_IUnknown(iface);
@@ -266,6 +353,7 @@ static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface)
if (!refcount)
{
+ video_presenter_end_streaming(presenter);
video_presenter_clear_container(presenter);
DeleteCriticalSection(&presenter->cs);
if (presenter->device_manager)
@@ -374,6 +462,12 @@ static HRESULT WINAPI video_presenter_ProcessMessage(IMFVideoPresenter *iface, M
case MFVP_MESSAGE_INVALIDATEMEDIATYPE:
hr = video_presenter_invalidate_media_type(presenter);
break;
+ case MFVP_MESSAGE_BEGINSTREAMING:
+ hr = video_presenter_start_streaming(presenter);
+ break;
+ case MFVP_MESSAGE_ENDSTREAMING:
+ hr = video_presenter_end_streaming(presenter);
+ break;
default:
FIXME("Unsupported message %u.\n", message);
hr = E_NOTIMPL;
More information about the wine-cvs
mailing list