[PATCH v4 0/4] MR3319: evr: Leave critical section before waiting for streaming thread.
I'm not sure how could I test this behavior, right now the test I wrote works but there are times where it doesn't enter into the deadlock. -- v4: evr: Remove process input handling from streaming thread. evr: Don't lock allocator in NotifyRelease call. evr: Create critical section for sample queue. evr: Release sample queue when streaming ends. https://gitlab.winehq.org/wine/wine/-/merge_requests/3319
From: Santino Mazza <smazza(a)codeweavers.com> --- dlls/evr/presenter.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 06592f8766e..97080717288 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -467,6 +467,18 @@ static BOOL video_presenter_sample_queue_pop(struct video_presenter *presenter, return *sample != NULL; } + +static void video_presenter_sample_queue_free(struct video_presenter *presenter) +{ + struct sample_queue *queue = &presenter->thread.queue; + IMFSample *sample; + + while (video_presenter_sample_queue_pop(presenter, &sample)) + IMFSample_Release(sample); + + free(queue->samples); +} + static HRESULT video_presenter_get_sample_surface(IMFSample *sample, IDirect3DSurface9 **surface) { IMFMediaBuffer *buffer; @@ -754,6 +766,7 @@ static HRESULT video_presenter_end_streaming(struct video_presenter *presenter) if (presenter->thread.queue.last_presented) IMFSample_Release(presenter->thread.queue.last_presented); + video_presenter_sample_queue_free(presenter); memset(&presenter->thread, 0, sizeof(presenter->thread)); video_presenter_set_allocator_callback(presenter, NULL); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3319
From: Santino Mazza <smazza(a)codeweavers.com> --- dlls/evr/presenter.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 97080717288..00bc00fbf2b 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -66,6 +66,7 @@ struct sample_queue unsigned int front; unsigned int back; IMFSample *last_presented; + CRITICAL_SECTION cs; }; struct streaming_thread @@ -425,6 +426,7 @@ static HRESULT video_presenter_sample_queue_init(struct video_presenter *present queue->size = presenter->allocator_capacity; queue->back = queue->size - 1; + InitializeCriticalSection(&queue->cs); return S_OK; } @@ -435,7 +437,7 @@ static void video_presenter_sample_queue_push(struct video_presenter *presenter, struct sample_queue *queue = &presenter->thread.queue; unsigned int idx; - EnterCriticalSection(&presenter->cs); + EnterCriticalSection(&queue->cs); if (queue->used != queue->size) { if (at_front) @@ -446,14 +448,14 @@ static void video_presenter_sample_queue_push(struct video_presenter *presenter, queue->used++; IMFSample_AddRef(sample); } - LeaveCriticalSection(&presenter->cs); + LeaveCriticalSection(&queue->cs); } static BOOL video_presenter_sample_queue_pop(struct video_presenter *presenter, IMFSample **sample) { struct sample_queue *queue = &presenter->thread.queue; - EnterCriticalSection(&presenter->cs); + EnterCriticalSection(&queue->cs); if (queue->used) { *sample = queue->samples[queue->front]; @@ -462,7 +464,7 @@ static BOOL video_presenter_sample_queue_pop(struct video_presenter *presenter, } else *sample = NULL; - LeaveCriticalSection(&presenter->cs); + LeaveCriticalSection(&queue->cs); return *sample != NULL; } @@ -477,6 +479,7 @@ static void video_presenter_sample_queue_free(struct video_presenter *presenter) IMFSample_Release(sample); free(queue->samples); + DeleteCriticalSection(&queue->cs); } static HRESULT video_presenter_get_sample_surface(IMFSample *sample, IDirect3DSurface9 **surface) @@ -527,12 +530,12 @@ static void video_presenter_sample_present(struct video_presenter *presenter, IM WARN("Failed to get a backbuffer, hr %#lx.\n", hr); } - EnterCriticalSection(&presenter->cs); + EnterCriticalSection(&presenter->thread.queue.cs); if (presenter->thread.queue.last_presented) IMFSample_Release(presenter->thread.queue.last_presented); presenter->thread.queue.last_presented = sample; IMFSample_AddRef(presenter->thread.queue.last_presented); - LeaveCriticalSection(&presenter->cs); + LeaveCriticalSection(&presenter->thread.queue.cs); IDirect3DSurface9_Release(surface); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3319
From: Santino Mazza <smazza(a)codeweavers.com> --- dlls/evr/sample.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dlls/evr/sample.c b/dlls/evr/sample.c index 6a1bbf564f5..c99ba3dd1b0 100644 --- a/dlls/evr/sample.c +++ b/dlls/evr/sample.c @@ -809,6 +809,7 @@ static HRESULT WINAPI sample_allocator_tracking_callback_Invoke(IMFAsyncCallback struct queued_sample *iter; IUnknown *object = NULL; IMFSample *sample = NULL; + IMFVideoSampleAllocatorNotify *callback; HRESULT hr; if (FAILED(IMFAsyncResult_GetObject(result, &object))) @@ -834,12 +835,13 @@ static HRESULT WINAPI sample_allocator_tracking_callback_Invoke(IMFAsyncCallback } IMFSample_Release(sample); - - if (allocator->callback) - IMFVideoSampleAllocatorNotify_NotifyRelease(allocator->callback); + callback = allocator->callback; LeaveCriticalSection(&allocator->cs); + if (callback) + IMFVideoSampleAllocatorNotify_NotifyRelease(allocator->callback); + return S_OK; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3319
From: Santino Mazza <smazza(a)codeweavers.com> --- dlls/evr/presenter.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 00bc00fbf2b..cd40e470830 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -55,7 +55,6 @@ enum streaming_thread_message { EVRM_STOP = WM_USER, EVRM_PRESENT = WM_USER + 1, - EVRM_PROCESS_INPUT = WM_USER + 2, }; struct sample_queue @@ -705,11 +704,6 @@ static DWORD CALLBACK video_presenter_streaming_thread(void *arg) } break; - case EVRM_PROCESS_INPUT: - EnterCriticalSection(&presenter->cs); - video_presenter_process_input(presenter); - LeaveCriticalSection(&presenter->cs); - break; default: ; } @@ -1810,9 +1804,9 @@ static HRESULT WINAPI video_presenter_allocator_cb_NotifyRelease(IMFVideoSampleA { struct video_presenter *presenter = impl_from_IMFVideoSampleAllocatorNotify(iface); - /* Release notification is executed under allocator lock, instead of processing samples here - notify streaming thread. */ - PostThreadMessageW(presenter->thread.tid, EVRM_PROCESS_INPUT, 0, 0); + EnterCriticalSection(&presenter->cs); + video_presenter_process_input(presenter); + LeaveCriticalSection(&presenter->cs); return S_OK; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3319
participants (2)
-
Santino Mazza -
Santino Mazza (@tati1454)