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