Mostly a refresh of https://gitlab.winehq.org/wine/wine/-/merge_requests/1278, with a bit of cleanup. More to come.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index e9db8dcc0a2..cbd78b17118 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -821,13 +821,16 @@ static const IMFMediaStreamVtbl media_stream_vtbl = media_stream_RequestSample };
-static HRESULT new_media_stream(struct media_source *source, - struct wg_parser_stream *wg_stream, DWORD stream_id, struct media_stream **out_stream) +static HRESULT media_stream_create(struct media_source *source, DWORD id, + struct media_stream **out) { - struct media_stream *object = calloc(1, sizeof(*object)); + struct media_stream *object; HRESULT hr;
- TRACE("source %p, wg_stream %p, stream_id %lu.\n", source, wg_stream, stream_id); + TRACE("source %p, id %lu.\n", source, id); + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY;
object->IMFMediaStream_iface.lpVtbl = &media_stream_vtbl; object->ref = 1; @@ -840,16 +843,15 @@ static HRESULT new_media_stream(struct media_source *source,
IMFMediaSource_AddRef(&source->IMFMediaSource_iface); object->parent_source = source; - object->stream_id = stream_id; + object->stream_id = id;
object->state = STREAM_INACTIVE; object->eos = FALSE; - object->wg_stream = wg_stream; + object->wg_stream = wg_parser_get_stream(source->wg_parser, id);
TRACE("Created stream object %p.\n", object);
- *out_stream = object; - + *out = object; return S_OK; }
@@ -1473,7 +1475,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
for (i = 0; i < stream_count; ++i) { - if (FAILED(hr = new_media_stream(object, wg_parser_get_stream(parser, i), i, &object->streams[i]))) + if (FAILED(hr = media_stream_create(object, i, &object->streams[i]))) goto fail;
if (FAILED(hr = media_stream_init_desc(object->streams[i])))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 42 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 19 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index cbd78b17118..c9fdbdcf703 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -31,7 +31,8 @@ struct media_stream { IMFMediaStream IMFMediaStream_iface; LONG ref; - struct media_source *parent_source; + + IMFMediaSource *media_source; IMFMediaEventQueue *event_queue; IMFStreamDescriptor *descriptor;
@@ -288,6 +289,7 @@ static BOOL enqueue_token(struct media_stream *stream, IUnknown *token)
static void flush_token_queue(struct media_stream *stream, BOOL send) { + struct media_source *source = impl_from_IMFMediaSource(stream->media_source); LONG i;
for (i = 0; i < stream->token_queue_count; i++) @@ -301,8 +303,8 @@ static void flush_token_queue(struct media_stream *stream, BOOL send) command->u.request_sample.stream = stream; command->u.request_sample.token = stream->token_queue[i];
- hr = MFPutWorkItem(stream->parent_source->async_commands_queue, - &stream->parent_source->async_commands_callback, &command->IUnknown_iface); + hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, + &command->IUnknown_iface); } if (FAILED(hr)) WARN("Could not enqueue sample request, hr %#lx\n", hr); @@ -528,7 +530,7 @@ out:
static void wait_on_sample(struct media_stream *stream, IUnknown *token) { - struct media_source *source = stream->parent_source; + struct media_source *source = impl_from_IMFMediaSource(stream->media_source); PROPVARIANT empty_var = {.vt = VT_EMPTY}; struct wg_parser_buffer buffer;
@@ -542,7 +544,7 @@ static void wait_on_sample(struct media_stream *stream, IUnknown *token) { stream->eos = TRUE; IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEEndOfStream, &GUID_NULL, S_OK, &empty_var); - dispatch_end_of_presentation(stream->parent_source); + dispatch_end_of_presentation(source); } }
@@ -741,17 +743,18 @@ static HRESULT WINAPI media_stream_QueueEvent(IMFMediaStream *iface, MediaEventT return IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, event_type, ext_type, hr, value); }
-static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMediaSource **source) +static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMediaSource **out) { struct media_stream *stream = impl_from_IMFMediaStream(iface); + struct media_source *source = impl_from_IMFMediaSource(stream->media_source);
- TRACE("%p, %p.\n", iface, source); + TRACE("%p, %p.\n", iface, out);
if (stream->state == STREAM_SHUTDOWN) return MF_E_SHUTDOWN;
- IMFMediaSource_AddRef(&stream->parent_source->IMFMediaSource_iface); - *source = &stream->parent_source->IMFMediaSource_iface; + IMFMediaSource_AddRef(&source->IMFMediaSource_iface); + *out = &source->IMFMediaSource_iface;
return S_OK; } @@ -774,6 +777,7 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token) { struct media_stream *stream = impl_from_IMFMediaStream(iface); + struct media_source *source = impl_from_IMFMediaSource(stream->media_source); struct source_async_command *command; HRESULT hr;
@@ -800,8 +804,7 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown IUnknown_AddRef(token); command->u.request_sample.token = token;
- hr = MFPutWorkItem(stream->parent_source->async_commands_queue, - &stream->parent_source->async_commands_callback, &command->IUnknown_iface); + hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, &command->IUnknown_iface); }
return hr; @@ -821,9 +824,10 @@ static const IMFMediaStreamVtbl media_stream_vtbl = media_stream_RequestSample };
-static HRESULT media_stream_create(struct media_source *source, DWORD id, +static HRESULT media_stream_create(IMFMediaSource *source, DWORD id, struct media_stream **out) { + struct wg_parser *wg_parser = impl_from_IMFMediaSource(source)->wg_parser; struct media_stream *object; HRESULT hr;
@@ -841,13 +845,13 @@ static HRESULT media_stream_create(struct media_source *source, DWORD id, return hr; }
- IMFMediaSource_AddRef(&source->IMFMediaSource_iface); - object->parent_source = source; + IMFMediaSource_AddRef(source); + object->media_source = source; object->stream_id = id;
object->state = STREAM_INACTIVE; object->eos = FALSE; - object->wg_stream = wg_parser_get_stream(source->wg_parser, id); + object->wg_stream = wg_parser_get_stream(wg_parser, id);
TRACE("Created stream object %p.\n", object);
@@ -1368,7 +1372,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
IMFMediaEventQueue_Shutdown(stream->event_queue); IMFStreamDescriptor_Release(stream->descriptor); - IMFMediaSource_Release(&stream->parent_source->IMFMediaSource_iface); + IMFMediaSource_Release(stream->media_source);
IMFMediaStream_Release(&stream->IMFMediaStream_iface); } @@ -1475,13 +1479,13 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
for (i = 0; i < stream_count; ++i) { - if (FAILED(hr = media_stream_create(object, i, &object->streams[i]))) + if (FAILED(hr = media_stream_create(&object->IMFMediaSource_iface, i, &object->streams[i]))) goto fail;
if (FAILED(hr = media_stream_init_desc(object->streams[i]))) { ERR("Failed to finish initialization of media stream %p, hr %#lx.\n", object->streams[i], hr); - IMFMediaSource_Release(&object->streams[i]->parent_source->IMFMediaSource_iface); + IMFMediaSource_Release(object->streams[i]->media_source); IMFMediaEventQueue_Release(object->streams[i]->event_queue); free(object->streams[i]); goto fail; @@ -1567,7 +1571,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
IMFMediaEventQueue_Release(stream->event_queue); IMFStreamDescriptor_Release(stream->descriptor); - IMFMediaSource_Release(&stream->parent_source->IMFMediaSource_iface); + IMFMediaSource_Release(stream->media_source);
free(stream); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 38 ++++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index c9fdbdcf703..5221668b10c 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -697,8 +697,9 @@ static ULONG WINAPI media_stream_Release(IMFMediaStream *iface)
if (!ref) { - if (stream->event_queue) - IMFMediaEventQueue_Release(stream->event_queue); + IMFMediaSource_Release(stream->media_source); + IMFStreamDescriptor_Release(stream->descriptor); + IMFMediaEventQueue_Release(stream->event_queue); flush_token_queue(stream, FALSE); free(stream); } @@ -1205,8 +1206,11 @@ static ULONG WINAPI media_source_Release(IMFMediaSource *iface)
if (!ref) { - IMFMediaSource_Shutdown(&source->IMFMediaSource_iface); + IMFMediaSource_Shutdown(iface); + IMFPresentationDescriptor_Release(source->pres_desc); IMFMediaEventQueue_Release(source->event_queue); + IMFByteStream_Release(source->byte_stream); + wg_parser_destroy(source->wg_parser); free(source); }
@@ -1344,7 +1348,6 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) { struct media_source *source = impl_from_IMFMediaSource(iface); - unsigned int i;
TRACE("%p.\n", iface);
@@ -1359,26 +1362,16 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) WaitForSingleObject(source->read_thread, INFINITE); CloseHandle(source->read_thread);
- IMFPresentationDescriptor_Release(source->pres_desc); IMFMediaEventQueue_Shutdown(source->event_queue); IMFByteStream_Close(source->byte_stream); - IMFByteStream_Release(source->byte_stream);
- for (i = 0; i < source->stream_count; i++) + while (source->stream_count--) { - struct media_stream *stream = source->streams[i]; - + struct media_stream *stream = source->streams[source->stream_count]; stream->state = STREAM_SHUTDOWN; - IMFMediaEventQueue_Shutdown(stream->event_queue); - IMFStreamDescriptor_Release(stream->descriptor); - IMFMediaSource_Release(stream->media_source); - IMFMediaStream_Release(&stream->IMFMediaStream_iface); } - - wg_parser_destroy(source->wg_parser); - free(source->streams);
MFUnlockWorkQueue(source->async_commands_queue); @@ -1565,17 +1558,14 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ IMFStreamDescriptor_Release(descriptors[i]); free(descriptors); } - for (i = 0; i < object->stream_count; i++) - { - struct media_stream *stream = object->streams[i];
- IMFMediaEventQueue_Release(stream->event_queue); - IMFStreamDescriptor_Release(stream->descriptor); - IMFMediaSource_Release(stream->media_source); - - free(stream); + while (object->streams && object->stream_count--) + { + struct media_stream *stream = object->streams[object->stream_count]; + IMFMediaStream_Release(&stream->IMFMediaStream_iface); } free(object->streams); + if (stream_count != UINT_MAX) wg_parser_disconnect(object->wg_parser); if (object->read_thread)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 4 ++-- dlls/winegstreamer/wg_parser.c | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 5221668b10c..1b1745d70e3 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1351,13 +1351,13 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
TRACE("%p.\n", iface);
+ wg_parser_disconnect(source->wg_parser); + if (source->state == SOURCE_SHUTDOWN) return MF_E_SHUTDOWN;
source->state = SOURCE_SHUTDOWN;
- wg_parser_disconnect(source->wg_parser); - source->read_thread_shutdown = true; WaitForSingleObject(source->read_thread, INFINITE); CloseHandle(source->read_thread); diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index dfb3da9a4ab..6730b7cf78c 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1695,10 +1695,19 @@ out: static NTSTATUS wg_parser_disconnect(void *args) { struct wg_parser *parser = args; + GstElement *container; unsigned int i;
- /* Unblock all of our streams. */ pthread_mutex_lock(&parser->mutex); + + if (!(container = parser->container)) + { + pthread_mutex_unlock(&parser->mutex); + return S_OK; + } + parser->container = NULL; + + /* Unblock all of our streams. */ for (i = 0; i < parser->stream_count; ++i) { parser->streams[i]->flushing = true; @@ -1706,7 +1715,7 @@ static NTSTATUS wg_parser_disconnect(void *args) } pthread_mutex_unlock(&parser->mutex);
- gst_element_set_state(parser->container, GST_STATE_NULL); + gst_element_set_state(container, GST_STATE_NULL); gst_object_unref(parser->my_src); gst_object_unref(parser->their_sink); parser->my_src = parser->their_sink = NULL; @@ -1723,9 +1732,8 @@ static NTSTATUS wg_parser_disconnect(void *args) free(parser->streams); parser->streams = NULL;
- gst_element_set_bus(parser->container, NULL); - gst_object_unref(parser->container); - parser->container = NULL; + gst_element_set_bus(container, NULL); + gst_object_unref(container);
g_free(parser->sink_caps); parser->sink_caps = NULL;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/wg_parser.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 6730b7cf78c..6bf8bd997a5 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1711,7 +1711,9 @@ static NTSTATUS wg_parser_disconnect(void *args) for (i = 0; i < parser->stream_count; ++i) { parser->streams[i]->flushing = true; + parser->streams[i]->enabled = false; pthread_cond_signal(&parser->streams[i]->event_empty_cond); + pthread_cond_signal(&parser->streams[i]->event_cond); } pthread_mutex_unlock(&parser->mutex);
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/winegstreamer/media_source.c | 76 +++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 20 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 1b1745d70e3..7bf4a7ed483 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -93,6 +93,8 @@ struct media_source IMFMediaEventQueue *event_queue; IMFByteStream *byte_stream;
+ CRITICAL_SECTION cs; + struct wg_parser *wg_parser;
struct media_stream **streams; @@ -1132,7 +1134,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); } @@ -1146,7 +1150,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; } @@ -1211,6 +1217,8 @@ static ULONG WINAPI media_source_Release(IMFMediaSource *iface) IMFMediaEventQueue_Release(source->event_queue); IMFByteStream_Release(source->byte_stream); wg_parser_destroy(source->wg_parser); + source->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&source->cs); free(source); }
@@ -1257,27 +1265,39 @@ 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); + HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, characteristics);
+ EnterCriticalSection(&source->cs); + if (source->state == SOURCE_SHUTDOWN) - return MF_E_SHUTDOWN; + hr = MF_E_SHUTDOWN; + else + *characteristics = MFMEDIASOURCE_CAN_SEEK | MFMEDIASOURCE_CAN_PAUSE;
- *characteristics = MFMEDIASOURCE_CAN_SEEK | MFMEDIASOURCE_CAN_PAUSE; + LeaveCriticalSection(&source->cs);
- return S_OK; + return hr; }
static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor) { struct media_source *source = impl_from_IMFMediaSource(iface); + HRESULT hr;
TRACE("%p, %p.\n", iface, descriptor);
+ EnterCriticalSection(&source->cs); + if (source->state == SOURCE_SHUTDOWN) - return MF_E_SHUTDOWN; + hr = MF_E_SHUTDOWN; + else + hr = IMFPresentationDescriptor_Clone(source->pres_desc, descriptor); + + LeaveCriticalSection(&source->cs);
- return IMFPresentationDescriptor_Clone(source->pres_desc, descriptor); + return hr; }
static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor, @@ -1289,13 +1309,13 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD
TRACE("%p, %p, %p, %p.\n", iface, descriptor, time_format, position);
- if (source->state == SOURCE_SHUTDOWN) - return MF_E_SHUTDOWN; - - if (!(IsEqualIID(time_format, &GUID_NULL))) - return MF_E_UNSUPPORTED_TIME_FORMAT; + EnterCriticalSection(&source->cs);
- if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_START, &command))) + if (source->state == SOURCE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else if (!(IsEqualIID(time_format, &GUID_NULL))) + hr = MF_E_UNSUPPORTED_TIME_FORMAT; + else if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_START, &command))) { command->u.start.descriptor = descriptor; command->u.start.format = *time_format; @@ -1304,6 +1324,8 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, &command->IUnknown_iface); }
+ LeaveCriticalSection(&source->cs); + return hr; }
@@ -1315,12 +1337,15 @@ static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface)
TRACE("%p.\n", iface);
- if (source->state == SOURCE_SHUTDOWN) - return MF_E_SHUTDOWN; + EnterCriticalSection(&source->cs);
- if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_STOP, &command))) + if (source->state == SOURCE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_STOP, &command))) hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, &command->IUnknown_iface);
+ LeaveCriticalSection(&source->cs); + return hr; }
@@ -1332,16 +1357,18 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface)
TRACE("%p.\n", iface);
- if (source->state == SOURCE_SHUTDOWN) - return MF_E_SHUTDOWN; + EnterCriticalSection(&source->cs);
- if (source->state != SOURCE_RUNNING) - return MF_E_INVALID_STATE_TRANSITION; - - if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_PAUSE, &command))) + if (source->state == SOURCE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else if (source->state != SOURCE_RUNNING) + hr = MF_E_INVALID_STATE_TRANSITION; + else if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_PAUSE, &command))) hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, &command->IUnknown_iface);
+ LeaveCriticalSection(&source->cs); + return S_OK; }
@@ -1353,8 +1380,13 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
wg_parser_disconnect(source->wg_parser);
+ EnterCriticalSection(&source->cs); + if (source->state == SOURCE_SHUTDOWN) + { + LeaveCriticalSection(&source->cs); return MF_E_SHUTDOWN; + }
source->state = SOURCE_SHUTDOWN;
@@ -1376,6 +1408,8 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
MFUnlockWorkQueue(source->async_commands_queue);
+ LeaveCriticalSection(&source->cs); + return S_OK; }
@@ -1435,6 +1469,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ object->byte_stream = bytestream; IMFByteStream_AddRef(bytestream); object->rate = 1.0f; + InitializeCriticalSection(&object->cs); + object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) goto fail;
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/winegstreamer/media_source.c | 55 ++++++++++++++++++------------- 1 file changed, 33 insertions(+), 22 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 7bf4a7ed483..0d93597e467 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -750,31 +750,46 @@ static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMedi { struct media_stream *stream = impl_from_IMFMediaStream(iface); struct media_source *source = impl_from_IMFMediaSource(stream->media_source); + HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, out);
+ EnterCriticalSection(&source->cs); + if (stream->state == STREAM_SHUTDOWN) - return MF_E_SHUTDOWN; + hr = MF_E_SHUTDOWN; + else + { + IMFMediaSource_AddRef(&source->IMFMediaSource_iface); + *out = &source->IMFMediaSource_iface; + }
- IMFMediaSource_AddRef(&source->IMFMediaSource_iface); - *out = &source->IMFMediaSource_iface; + LeaveCriticalSection(&source->cs);
- return S_OK; + return hr; }
static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IMFStreamDescriptor **descriptor) { struct media_stream *stream = impl_from_IMFMediaStream(iface); + struct media_source *source = impl_from_IMFMediaSource(stream->media_source); + HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, descriptor);
+ EnterCriticalSection(&source->cs); + if (stream->state == STREAM_SHUTDOWN) - return MF_E_SHUTDOWN; + hr = MF_E_SHUTDOWN; + else + { + IMFStreamDescriptor_AddRef(stream->descriptor); + *descriptor = stream->descriptor; + }
- IMFStreamDescriptor_AddRef(stream->descriptor); - *descriptor = stream->descriptor; + LeaveCriticalSection(&source->cs);
- return S_OK; + return hr; }
static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token) @@ -786,21 +801,15 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown
TRACE("%p, %p.\n", iface, token);
- if (stream->state == STREAM_SHUTDOWN) - return MF_E_SHUTDOWN; - - if (stream->state == STREAM_INACTIVE) - { - WARN("Stream isn't active\n"); - return MF_E_MEDIA_SOURCE_WRONGSTATE; - } - - if (stream->eos) - { - return MF_E_END_OF_STREAM; - } + EnterCriticalSection(&source->cs);
- if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_REQUEST_SAMPLE, &command))) + if (stream->state == STREAM_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else if (stream->state == STREAM_INACTIVE) + hr = MF_E_MEDIA_SOURCE_WRONGSTATE; + else if (stream->eos) + hr = MF_E_END_OF_STREAM; + else if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_REQUEST_SAMPLE, &command))) { command->u.request_sample.stream = stream; if (token) @@ -810,6 +819,8 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown hr = MFPutWorkItem(source->async_commands_queue, &source->async_commands_callback, &command->IUnknown_iface); }
+ LeaveCriticalSection(&source->cs); + return hr; }
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/winegstreamer/media_source.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 0d93597e467..918eda51059 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -557,32 +557,36 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA IUnknown *state; HRESULT hr;
- if (source->state == SOURCE_SHUTDOWN) - return S_OK; - if (FAILED(hr = IMFAsyncResult_GetState(result, &state))) return hr;
+ EnterCriticalSection(&source->cs); + command = impl_from_async_command_IUnknown(state); switch (command->op) { case SOURCE_ASYNC_START: - start_pipeline(source, command); + if (source->state != SOURCE_SHUTDOWN) + start_pipeline(source, command); break; case SOURCE_ASYNC_PAUSE: - pause_pipeline(source); + if (source->state != SOURCE_SHUTDOWN) + pause_pipeline(source); break; case SOURCE_ASYNC_STOP: - stop_pipeline(source); + if (source->state != SOURCE_SHUTDOWN) + stop_pipeline(source); break; case SOURCE_ASYNC_REQUEST_SAMPLE: if (source->state == SOURCE_PAUSED) enqueue_token(command->u.request_sample.stream, command->u.request_sample.token); - else + else if (source->state == SOURCE_RUNNING) wait_on_sample(command->u.request_sample.stream, command->u.request_sample.token); break; }
+ LeaveCriticalSection(&source->cs); + IUnknown_Release(state);
return S_OK;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 40 +++++++++++++------------------ 1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 918eda51059..b50ed3e0229 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -42,13 +42,8 @@ struct media_stream LONG token_queue_count; LONG token_queue_cap;
- enum - { - STREAM_INACTIVE, - STREAM_SHUTDOWN, - STREAM_RUNNING, - } state; DWORD stream_id; + BOOL active; BOOL eos; };
@@ -350,9 +345,8 @@ static void start_pipeline(struct media_source *source, struct source_async_comm sd = stream_descriptor_from_id(command->u.start.descriptor, stream_id, &selected); IMFStreamDescriptor_Release(sd);
- was_active = stream->state != STREAM_INACTIVE; - - stream->state = selected ? STREAM_RUNNING : STREAM_INACTIVE; + was_active = stream->active; + stream->active = selected;
if (selected) { @@ -404,14 +398,14 @@ static void start_pipeline(struct media_source *source, struct source_async_comm static void pause_pipeline(struct media_source *source) { unsigned int i; + HRESULT hr;
for (i = 0; i < source->stream_count; i++) { struct media_stream *stream = source->streams[i]; - if (stream->state != STREAM_INACTIVE) - { - IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamPaused, &GUID_NULL, S_OK, NULL); - } + if (stream->active && FAILED(hr = IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamPaused, + &GUID_NULL, S_OK, NULL))) + WARN("Failed to queue MEStreamPaused event, hr %#lx\n", hr); }
IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourcePaused, &GUID_NULL, S_OK, NULL); @@ -422,12 +416,14 @@ static void pause_pipeline(struct media_source *source) static void stop_pipeline(struct media_source *source) { unsigned int i; + HRESULT hr;
for (i = 0; i < source->stream_count; i++) { struct media_stream *stream = source->streams[i]; - if (stream->state != STREAM_INACTIVE) - IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamStopped, &GUID_NULL, S_OK, NULL); + if (stream->active && FAILED(hr = IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEStreamStopped, + &GUID_NULL, S_OK, NULL))) + WARN("Failed to queue MEStreamStopped event, hr %#lx\n", hr); }
IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MESourceStopped, &GUID_NULL, S_OK, NULL); @@ -447,8 +443,7 @@ static void dispatch_end_of_presentation(struct media_source *source) for (i = 0; i < source->stream_count; i++) { struct media_stream *stream = source->streams[i]; - - if (stream->state != STREAM_INACTIVE && !stream->eos) + if (stream->active && !stream->eos) return; }
@@ -760,7 +755,7 @@ static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMedi
EnterCriticalSection(&source->cs);
- if (stream->state == STREAM_SHUTDOWN) + if (source->state == SOURCE_SHUTDOWN) hr = MF_E_SHUTDOWN; else { @@ -783,7 +778,7 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM
EnterCriticalSection(&source->cs);
- if (stream->state == STREAM_SHUTDOWN) + if (source->state == SOURCE_SHUTDOWN) hr = MF_E_SHUTDOWN; else { @@ -807,9 +802,9 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown
EnterCriticalSection(&source->cs);
- if (stream->state == STREAM_SHUTDOWN) + if (source->state == SOURCE_SHUTDOWN) hr = MF_E_SHUTDOWN; - else if (stream->state == STREAM_INACTIVE) + else if (!stream->active) hr = MF_E_MEDIA_SOURCE_WRONGSTATE; else if (stream->eos) hr = MF_E_END_OF_STREAM; @@ -867,7 +862,7 @@ static HRESULT media_stream_create(IMFMediaSource *source, DWORD id, object->media_source = source; object->stream_id = id;
- object->state = STREAM_INACTIVE; + object->active = FALSE; object->eos = FALSE; object->wg_stream = wg_parser_get_stream(wg_parser, id);
@@ -1415,7 +1410,6 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) while (source->stream_count--) { struct media_stream *stream = source->streams[source->stream_count]; - stream->state = STREAM_SHUTDOWN; IMFMediaEventQueue_Shutdown(stream->event_queue); IMFMediaStream_Release(&stream->IMFMediaStream_iface); }
This merge request was approved by Rémi Bernon.
Patch 4/9 seems underdocumented at least. It's not how wmvcore or quartz operate, and it's not immediately clear just from reading the patch why it's necessary or an improvement.
Patch 5/9 is a bit suspicious. Those calls to wg_parser_stream_get_buffer() will eventually exit anyway, where "eventually" should in practice never be more than 30 ms or so. Interrupting that might seem like it'll help the parser exit faster (although it's not clear just from reading the patch whether that's your goal or not), but in actuality that delay will just get pushed to when the GStreamer element is destroyed.
This is a bit of a large series to review all at once, so I haven't reviewed patches 6-9 yet. I'll try to get to them quickly...