Commit 5981f2ed authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

mf/evr: Consistently check for shutdown flag within a lock.

parent d4bb82af
...@@ -1432,38 +1432,43 @@ static HRESULT WINAPI video_renderer_sink_GetPresentationClock(IMFMediaSink *ifa ...@@ -1432,38 +1432,43 @@ static HRESULT WINAPI video_renderer_sink_GetPresentationClock(IMFMediaSink *ifa
static HRESULT WINAPI video_renderer_sink_Shutdown(IMFMediaSink *iface) static HRESULT WINAPI video_renderer_sink_Shutdown(IMFMediaSink *iface)
{ {
struct video_renderer *renderer = impl_from_IMFMediaSink(iface); struct video_renderer *renderer = impl_from_IMFMediaSink(iface);
HRESULT hr = S_OK;
size_t i; size_t i;
TRACE("%p.\n", iface); TRACE("%p.\n", iface);
if (renderer->flags & EVR_SHUT_DOWN)
return MF_E_SHUTDOWN;
EnterCriticalSection(&renderer->cs); EnterCriticalSection(&renderer->cs);
renderer->flags |= EVR_SHUT_DOWN;
/* Detach streams from the sink. */ if (renderer->flags & EVR_SHUT_DOWN)
for (i = 0; i < renderer->stream_count; ++i) 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); EnterCriticalSection(&stream->cs);
stream->parent = NULL; stream->parent = NULL;
LeaveCriticalSection(&stream->cs); LeaveCriticalSection(&stream->cs);
IMFMediaEventQueue_Shutdown(stream->event_queue); IMFMediaEventQueue_Shutdown(stream->event_queue);
IMFStreamSink_Release(&stream->IMFStreamSink_iface); IMFStreamSink_Release(&stream->IMFStreamSink_iface);
IMFMediaSink_Release(iface); IMFMediaSink_Release(iface);
renderer->streams[i] = NULL; 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); LeaveCriticalSection(&renderer->cs);
return S_OK; return hr;
} }
static const IMFMediaSinkVtbl video_renderer_sink_vtbl = static const IMFMediaSinkVtbl video_renderer_sink_vtbl =
...@@ -1742,52 +1747,64 @@ static HRESULT video_renderer_initialize(struct video_renderer *renderer, IMFTra ...@@ -1742,52 +1747,64 @@ static HRESULT video_renderer_initialize(struct video_renderer *renderer, IMFTra
return hr; return hr;
} }
static HRESULT WINAPI video_renderer_InitializeRenderer(IMFVideoRenderer *iface, IMFTransform *mixer, static HRESULT video_renderer_create_mixer_and_presenter(struct video_renderer *renderer,
IMFVideoPresenter *presenter) IMFTransform **mixer, IMFVideoPresenter **presenter)
{ {
struct video_renderer *renderer = impl_from_IMFVideoRenderer(iface);
HRESULT hr; HRESULT hr;
TRACE("%p, %p, %p.\n", iface, mixer, presenter); if (*mixer)
EnterCriticalSection(&renderer->cs);
if (renderer->flags & EVR_SHUT_DOWN)
{ {
LeaveCriticalSection(&renderer->cs); IMFTransform_AddRef(*mixer);
return MF_E_SHUTDOWN;
} }
else if (FAILED(hr = video_renderer_create_mixer(NULL, mixer)))
video_renderer_uninitialize(renderer);
if (mixer)
IMFTransform_AddRef(mixer);
else if (FAILED(hr = video_renderer_create_mixer(NULL, &mixer)))
{ {
WARN("Failed to create default mixer object, hr %#lx.\n", hr); WARN("Failed to create default mixer object, hr %#lx.\n", hr);
LeaveCriticalSection(&renderer->cs);
return hr; return hr;
} }
if (presenter) if (*presenter)
IMFVideoPresenter_AddRef(presenter); {
else if (FAILED(hr = video_renderer_create_presenter(renderer, NULL, &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); WARN("Failed to create default presenter, hr %#lx.\n", hr);
LeaveCriticalSection(&renderer->cs); IMFTransform_Release(*mixer);
IMFTransform_Release(mixer);
return hr; return hr;
} }
/* FIXME: check clock state */ return S_OK;
/* FIXME: check that streams are not initialized */ }
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); EnterCriticalSection(&renderer->cs);
IMFVideoPresenter_Release(presenter);
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; return hr;
} }
......
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