From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/winegstreamer/media_source.c | 60 +++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 11 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 9bb7a441a8f..a9f0eb70902 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -92,6 +92,8 @@ struct media_source IMFMediaEventQueue *event_queue; IMFByteStream *byte_stream;
+ CRITICAL_SECTION cs; + struct wg_parser *wg_parser;
struct media_stream **streams; @@ -1114,7 +1116,9 @@ static HRESULT WINAPI media_source_rate_control_SetRate(IMFRateControl *iface, B if (FAILED(hr = IMFRateSupport_IsRateSupported(&source->IMFRateSupport_iface, thin, rate, NULL))) return hr;
+ EnterCriticalSection(&source->cs); source->rate = rate; + LeaveCriticalSection(&source->cs);
return IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceRateChanged, &GUID_NULL, S_OK, NULL); } @@ -1128,7 +1132,9 @@ static HRESULT WINAPI media_source_rate_control_GetRate(IMFRateControl *iface, B if (thin) *thin = FALSE;
+ EnterCriticalSection(&source->cs); *rate = source->rate; + LeaveCriticalSection(&source->cs);
return S_OK; } @@ -1190,6 +1196,7 @@ static ULONG WINAPI media_source_Release(IMFMediaSource *iface) { IMFMediaSource_Shutdown(&source->IMFMediaSource_iface); IMFMediaEventQueue_Release(source->event_queue); + DeleteCriticalSection(&source->cs); free(source); }
@@ -1236,10 +1243,15 @@ static HRESULT WINAPI media_source_QueueEvent(IMFMediaSource *iface, MediaEventT static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWORD *characteristics) { struct media_source *source = impl_from_IMFMediaSource(iface); + BOOL is_shutdown;
TRACE("%p, %p.\n", iface, characteristics);
- if (source->state == SOURCE_SHUTDOWN) + EnterCriticalSection(&source->cs); + is_shutdown = source->state == SOURCE_SHUTDOWN; + LeaveCriticalSection(&source->cs); + + if (is_shutdown) return MF_E_SHUTDOWN;
*characteristics = MFMEDIASOURCE_CAN_SEEK | MFMEDIASOURCE_CAN_PAUSE; @@ -1250,10 +1262,15 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor) { struct media_source *source = impl_from_IMFMediaSource(iface); + BOOL is_shutdown;
TRACE("%p, %p.\n", iface, descriptor);
- if (source->state == SOURCE_SHUTDOWN) + EnterCriticalSection(&source->cs); + is_shutdown = source->state == SOURCE_SHUTDOWN; + LeaveCriticalSection(&source->cs); + + if (is_shutdown) return MF_E_SHUTDOWN;
return IMFPresentationDescriptor_Clone(source->pres_desc, descriptor); @@ -1264,11 +1281,16 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD { struct media_source *source = impl_from_IMFMediaSource(iface); struct source_async_command *command; + BOOL is_shutdown; HRESULT hr;
TRACE("%p, %p, %p, %p.\n", iface, descriptor, time_format, position);
- if (source->state == SOURCE_SHUTDOWN) + EnterCriticalSection(&source->cs); + is_shutdown = source->state == SOURCE_SHUTDOWN; + LeaveCriticalSection(&source->cs); + + if (is_shutdown) return MF_E_SHUTDOWN;
if (!(IsEqualIID(time_format, &GUID_NULL))) @@ -1290,11 +1312,16 @@ static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface) { struct media_source *source = impl_from_IMFMediaSource(iface); struct source_async_command *command; + BOOL is_shutdown; HRESULT hr;
TRACE("%p.\n", iface);
- if (source->state == SOURCE_SHUTDOWN) + EnterCriticalSection(&source->cs); + is_shutdown = source->state == SOURCE_SHUTDOWN; + LeaveCriticalSection(&source->cs); + + if (is_shutdown) return MF_E_SHUTDOWN;
if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_STOP, &command))) @@ -1307,14 +1334,20 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) { struct media_source *source = impl_from_IMFMediaSource(iface); struct source_async_command *command; + BOOL is_shutdown, is_running; HRESULT hr;
TRACE("%p.\n", iface);
- if (source->state == SOURCE_SHUTDOWN) + EnterCriticalSection(&source->cs); + is_shutdown = source->state == SOURCE_SHUTDOWN; + is_running = source->state == SOURCE_RUNNING; + LeaveCriticalSection(&source->cs); + + if (is_shutdown) return MF_E_SHUTDOWN;
- if (source->state != SOURCE_RUNNING) + if (!is_running) return MF_E_INVALID_STATE_TRANSITION;
if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_PAUSE, &command))) @@ -1327,14 +1360,20 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) { struct media_source *source = impl_from_IMFMediaSource(iface); + BOOL is_shutdown; unsigned int i;
TRACE("%p.\n", iface);
- if (source->state == SOURCE_SHUTDOWN) - return MF_E_SHUTDOWN; - + EnterCriticalSection(&source->cs); + is_shutdown = source->state == SOURCE_SHUTDOWN; source->state = SOURCE_SHUTDOWN; + for (i = 0; i < source->stream_count; i++) + source->streams[i]->state = STREAM_SHUTDOWN; + LeaveCriticalSection(&source->cs); + + if (is_shutdown) + return MF_E_SHUTDOWN;
wg_parser_disconnect(source->wg_parser);
@@ -1350,8 +1389,6 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) { struct media_stream *stream = source->streams[i];
- stream->state = STREAM_SHUTDOWN; - IMFMediaEventQueue_Shutdown(stream->event_queue); IMFStreamDescriptor_Release(stream->descriptor); IMFMediaSource_Release(&stream->parent_source->IMFMediaSource_iface); @@ -1424,6 +1461,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ object->byte_stream = bytestream; IMFByteStream_AddRef(bytestream); object->rate = 1.0f; + InitializeCriticalSection(&object->cs);
if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) goto fail;