[PATCH 1/3] mf/evr: Consistently check for shutdown flag within a lock.
Nikolay Sivov
wine at gitlab.winehq.org
Mon Jul 4 14:06:40 CDT 2022
From: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/mf/evr.c | 115 +++++++++++++++++++++++++++++---------------------
1 file changed, 66 insertions(+), 49 deletions(-)
diff --git a/dlls/mf/evr.c b/dlls/mf/evr.c
index c9506af9143..db7053a1405 100644
--- a/dlls/mf/evr.c
+++ b/dlls/mf/evr.c
@@ -1432,38 +1432,43 @@ static HRESULT WINAPI video_renderer_sink_GetPresentationClock(IMFMediaSink *ifa
static HRESULT WINAPI video_renderer_sink_Shutdown(IMFMediaSink *iface)
{
struct video_renderer *renderer = impl_from_IMFMediaSink(iface);
+ HRESULT hr = S_OK;
size_t i;
TRACE("%p.\n", iface);
- if (renderer->flags & EVR_SHUT_DOWN)
- return MF_E_SHUTDOWN;
-
EnterCriticalSection(&renderer->cs);
- renderer->flags |= EVR_SHUT_DOWN;
- /* Detach streams from the sink. */
- for (i = 0; i < renderer->stream_count; ++i)
+
+ if (renderer->flags & EVR_SHUT_DOWN)
+ hr = MF_E_SHUTDOWN;
+ else
{
- struct video_stream *stream = renderer->streams[i];
+ renderer->flags |= EVR_SHUT_DOWN;
+ /* Detach streams from the sink. */
+ for (i = 0; i < renderer->stream_count; ++i)
+ {
+ struct video_stream *stream = renderer->streams[i];
- EnterCriticalSection(&stream->cs);
- stream->parent = NULL;
- LeaveCriticalSection(&stream->cs);
+ EnterCriticalSection(&stream->cs);
+ stream->parent = NULL;
+ LeaveCriticalSection(&stream->cs);
- IMFMediaEventQueue_Shutdown(stream->event_queue);
- IMFStreamSink_Release(&stream->IMFStreamSink_iface);
- IMFMediaSink_Release(iface);
- renderer->streams[i] = NULL;
+ IMFMediaEventQueue_Shutdown(stream->event_queue);
+ IMFStreamSink_Release(&stream->IMFStreamSink_iface);
+ IMFMediaSink_Release(iface);
+ renderer->streams[i] = NULL;
+ }
+ free(renderer->streams);
+ renderer->stream_count = 0;
+ renderer->stream_size = 0;
+ IMFMediaEventQueue_Shutdown(renderer->event_queue);
+ video_renderer_set_presentation_clock(renderer, NULL);
+ video_renderer_release_services(renderer);
}
- free(renderer->streams);
- renderer->stream_count = 0;
- renderer->stream_size = 0;
- IMFMediaEventQueue_Shutdown(renderer->event_queue);
- video_renderer_set_presentation_clock(renderer, NULL);
- video_renderer_release_services(renderer);
+
LeaveCriticalSection(&renderer->cs);
- return S_OK;
+ return hr;
}
static const IMFMediaSinkVtbl video_renderer_sink_vtbl =
@@ -1742,52 +1747,64 @@ static HRESULT video_renderer_initialize(struct video_renderer *renderer, IMFTra
return hr;
}
-static HRESULT WINAPI video_renderer_InitializeRenderer(IMFVideoRenderer *iface, IMFTransform *mixer,
- IMFVideoPresenter *presenter)
+static HRESULT video_renderer_create_mixer_and_presenter(struct video_renderer *renderer,
+ IMFTransform **mixer, IMFVideoPresenter **presenter)
{
- struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface);
HRESULT hr;
- TRACE("%p, %p, %p.\n", iface, mixer, presenter);
-
- EnterCriticalSection(&renderer->cs);
-
- if (renderer->flags & EVR_SHUT_DOWN)
+ if (*mixer)
{
- LeaveCriticalSection(&renderer->cs);
- return MF_E_SHUTDOWN;
+ IMFTransform_AddRef(*mixer);
}
-
- video_renderer_uninitialize(renderer);
-
- if (mixer)
- IMFTransform_AddRef(mixer);
- else if (FAILED(hr = video_renderer_create_mixer(NULL, &mixer)))
+ else if (FAILED(hr = video_renderer_create_mixer(NULL, mixer)))
{
WARN("Failed to create default mixer object, hr %#lx.\n", hr);
- LeaveCriticalSection(&renderer->cs);
return hr;
}
- if (presenter)
- IMFVideoPresenter_AddRef(presenter);
- else if (FAILED(hr = video_renderer_create_presenter(renderer, NULL, &presenter)))
+ if (*presenter)
+ {
+ IMFVideoPresenter_AddRef(*presenter);
+ }
+ else if (FAILED(hr = video_renderer_create_presenter(renderer, NULL, presenter)))
{
WARN("Failed to create default presenter, hr %#lx.\n", hr);
- LeaveCriticalSection(&renderer->cs);
- IMFTransform_Release(mixer);
+ IMFTransform_Release(*mixer);
return hr;
}
- /* FIXME: check clock state */
- /* FIXME: check that streams are not initialized */
+ return S_OK;
+}
- hr = video_renderer_initialize(renderer, mixer, presenter);
+static HRESULT WINAPI video_renderer_InitializeRenderer(IMFVideoRenderer *iface, IMFTransform *mixer,
+ IMFVideoPresenter *presenter)
+{
+ struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface);
+ HRESULT hr;
- LeaveCriticalSection(&renderer->cs);
+ TRACE("%p, %p, %p.\n", iface, mixer, presenter);
- IMFTransform_Release(mixer);
- IMFVideoPresenter_Release(presenter);
+ EnterCriticalSection(&renderer->cs);
+
+ if (renderer->flags & EVR_SHUT_DOWN)
+ hr = MF_E_SHUTDOWN;
+ else
+ {
+ video_renderer_uninitialize(renderer);
+
+ if (SUCCEEDED(hr = video_renderer_create_mixer_and_presenter(renderer, &mixer, &presenter)))
+ {
+ /* FIXME: check clock state */
+ /* FIXME: check that streams are not initialized */
+
+ hr = video_renderer_initialize(renderer, mixer, presenter);
+
+ IMFTransform_Release(mixer);
+ IMFVideoPresenter_Release(presenter);
+ }
+ }
+
+ LeaveCriticalSection(&renderer->cs);
return hr;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/372
More information about the wine-devel
mailing list