-- v2: winegstreamer: Lookup stream handler result using a dedicated helper. winegstreamer: Rename winegstreamer_stream_handler to stream_handler. winegstreamer: Create and destroy result entries using dedicated helpers. winegstreamer: Lookup stream descriptors before starting streams. winegstreamer: Keep a reference on the media source start descriptor.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index d404662e5bb..558d7dd51f5 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -174,7 +174,10 @@ static ULONG WINAPI source_async_command_Release(IUnknown *iface) if (!refcount) { if (command->op == SOURCE_ASYNC_START) + { + IMFPresentationDescriptor_Release(command->u.start.descriptor); PropVariantClear(&command->u.start.position); + } else if (command->op == SOURCE_ASYNC_REQUEST_SAMPLE) { if (command->u.request_sample.token) @@ -1376,6 +1379,7 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD { struct source_async_command *command = impl_from_async_command_IUnknown(op); command->u.start.descriptor = descriptor; + IMFPresentationDescriptor_AddRef(descriptor); command->u.start.format = *time_format; PropVariantCopy(&command->u.start.position, position);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 78 ++++++++++++++++--------------- 1 file changed, 40 insertions(+), 38 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 558d7dd51f5..4de5b5ab608 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -272,30 +272,6 @@ static HRESULT wg_format_from_stream_descriptor(IMFStreamDescriptor *descriptor, return hr; }
-static IMFStreamDescriptor *stream_descriptor_from_id(IMFPresentationDescriptor *pres_desc, DWORD id, BOOL *selected) -{ - ULONG sd_count; - IMFStreamDescriptor *ret; - unsigned int i; - - if (FAILED(IMFPresentationDescriptor_GetStreamDescriptorCount(pres_desc, &sd_count))) - return NULL; - - for (i = 0; i < sd_count; i++) - { - DWORD stream_id; - - if (FAILED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(pres_desc, i, selected, &ret))) - return NULL; - - if (SUCCEEDED(IMFStreamDescriptor_GetStreamIdentifier(ret, &stream_id)) && stream_id == id) - return ret; - - IMFStreamDescriptor_Release(ret); - } - return NULL; -} - static HRESULT stream_descriptor_set_tag(IMFStreamDescriptor *descriptor, struct wg_parser_stream *stream, const GUID *attr, enum wg_parser_tag tag) { @@ -517,7 +493,8 @@ static HRESULT media_source_start(struct media_source *source, IMFPresentationDe GUID *format, PROPVARIANT *position) { BOOL starting = source->state == SOURCE_STOPPED, seek_message = !starting && position->vt != VT_EMPTY; - unsigned int i; + IMFStreamDescriptor **descriptors; + DWORD i, count; HRESULT hr;
TRACE("source %p, descriptor %p, format %s, position %s\n", source, descriptor, @@ -533,29 +510,54 @@ static HRESULT media_source_start(struct media_source *source, IMFPresentationDe position->hVal.QuadPart = 0; }
- for (i = 0; i < source->stream_count; i++) + if (!(descriptors = calloc(source->stream_count, sizeof(*descriptors)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = IMFPresentationDescriptor_GetStreamDescriptorCount(descriptor, &count))) + WARN("Failed to get presentation descriptor stream count, hr %#lx\n", hr); + + for (i = 0; i < count; i++) { - struct media_stream *stream; - BOOL was_active, selected; - IMFStreamDescriptor *sd; - DWORD stream_id; + IMFStreamDescriptor *stream_descriptor; + BOOL selected; + DWORD id;
- stream = source->streams[i]; - was_active = !starting && stream->active; + if (FAILED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, i, + &selected, &stream_descriptor))) + WARN("Failed to get presentation stream descriptor, hr %#lx\n", hr); + else + { + if (FAILED(hr = IMFStreamDescriptor_GetStreamIdentifier(stream_descriptor, &id))) + WARN("Failed to get stream descriptor id, hr %#lx\n", hr); + else if (id >= source->stream_count) + WARN("Invalid stream descriptor id %lu, hr %#lx\n", id, hr); + else if (selected) + IMFStreamDescriptor_AddRef((descriptors[id] = stream_descriptor)); + + IMFStreamDescriptor_Release(stream_descriptor); + } + }
- IMFStreamDescriptor_GetStreamIdentifier(stream->descriptor, &stream_id); - sd = stream_descriptor_from_id(descriptor, stream_id, &selected); - IMFStreamDescriptor_Release(sd); + for (i = 0; i < source->stream_count; i++) + { + struct media_stream *stream = source->streams[i]; + BOOL was_active = !starting && stream->active;
if (position->vt != VT_EMPTY) stream->eos = FALSE;
- if (!(stream->active = selected)) + if (!(stream->active = !!descriptors[i])) wg_parser_stream_disable(stream->wg_stream); - else if (FAILED(hr = media_stream_start(stream, was_active, seek_message, position))) - WARN("Failed to start media stream, hr %#lx\n", hr); + else + { + if (FAILED(hr = media_stream_start(stream, was_active, seek_message, position))) + WARN("Failed to start media stream, hr %#lx\n", hr); + IMFStreamDescriptor_Release(descriptors[i]); + } }
+ free(descriptors); + source->state = SOURCE_RUNNING;
if (position->vt == VT_I8)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 95 +++++++++++++++++-------------- 1 file changed, 53 insertions(+), 42 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 4de5b5ab608..eb16f4d3aa9 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1656,14 +1656,39 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ return hr; }
-struct winegstreamer_stream_handler_result +struct result_entry { struct list entry; IMFAsyncResult *result; - MF_OBJECT_TYPE obj_type; + MF_OBJECT_TYPE type; IUnknown *object; };
+static HRESULT result_entry_create(IMFAsyncResult *result, MF_OBJECT_TYPE type, + IUnknown *object, struct result_entry **out) +{ + struct result_entry *entry; + + if (!(entry = malloc(sizeof(*entry)))) + return E_OUTOFMEMORY; + + entry->result = result; + IMFAsyncResult_AddRef(entry->result); + entry->object = object; + IUnknown_AddRef(entry->object); + entry->type = type; + + *out = entry; + return S_OK; +} + +static void result_entry_destroy(struct result_entry *entry) +{ + IMFAsyncResult_Release(entry->result); + IUnknown_Release(entry->object); + free(entry); +} + struct winegstreamer_stream_handler { IMFByteStreamHandler IMFByteStreamHandler_iface; @@ -1714,20 +1739,14 @@ static ULONG WINAPI winegstreamer_stream_handler_Release(IMFByteStreamHandler *i { struct winegstreamer_stream_handler *handler = impl_from_IMFByteStreamHandler(iface); ULONG refcount = InterlockedDecrement(&handler->refcount); - struct winegstreamer_stream_handler_result *result, *next; + struct result_entry *result, *next;
TRACE("%p, refcount %lu.\n", iface, refcount);
if (!refcount) { - LIST_FOR_EACH_ENTRY_SAFE(result, next, &handler->results, struct winegstreamer_stream_handler_result, entry) - { - list_remove(&result->entry); - IMFAsyncResult_Release(result->result); - if (result->object) - IUnknown_Release(result->object); - free(result); - } + LIST_FOR_EACH_ENTRY_SAFE(result, next, &handler->results, struct result_entry, entry) + result_entry_destroy(result); DeleteCriticalSection(&handler->cs); free(handler); } @@ -1868,14 +1887,14 @@ static HRESULT WINAPI winegstreamer_stream_handler_EndCreateObject(IMFByteStream MF_OBJECT_TYPE *obj_type, IUnknown **object) { struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); - struct winegstreamer_stream_handler_result *found = NULL, *cur; + struct result_entry *found = NULL, *cur; HRESULT hr;
TRACE("%p, %p, %p, %p.\n", iface, result, obj_type, object);
EnterCriticalSection(&this->cs);
- LIST_FOR_EACH_ENTRY(cur, &this->results, struct winegstreamer_stream_handler_result, entry) + LIST_FOR_EACH_ENTRY(cur, &this->results, struct result_entry, entry) { if (result == cur->result) { @@ -1889,11 +1908,11 @@ static HRESULT WINAPI winegstreamer_stream_handler_EndCreateObject(IMFByteStream
if (found) { - *obj_type = found->obj_type; - *object = found->object; hr = IMFAsyncResult_GetStatus(found->result); - IMFAsyncResult_Release(found->result); - free(found); + *obj_type = found->type; + *object = found->object; + IUnknown_AddRef(*object); + result_entry_destroy(found); } else { @@ -1908,13 +1927,13 @@ static HRESULT WINAPI winegstreamer_stream_handler_EndCreateObject(IMFByteStream static HRESULT WINAPI winegstreamer_stream_handler_CancelObjectCreation(IMFByteStreamHandler *iface, IUnknown *cancel_cookie) { struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); - struct winegstreamer_stream_handler_result *found = NULL, *cur; + struct result_entry *found = NULL, *cur;
TRACE("%p, %p.\n", iface, cancel_cookie);
EnterCriticalSection(&this->cs);
- LIST_FOR_EACH_ENTRY(cur, &this->results, struct winegstreamer_stream_handler_result, entry) + LIST_FOR_EACH_ENTRY(cur, &this->results, struct result_entry, entry) { if (cancel_cookie == (IUnknown *)cur->result) { @@ -1927,12 +1946,7 @@ static HRESULT WINAPI winegstreamer_stream_handler_CancelObjectCreation(IMFByteS LeaveCriticalSection(&this->cs);
if (found) - { - IMFAsyncResult_Release(found->result); - if (found->object) - IUnknown_Release(found->object); - free(found); - } + result_entry_destroy(found);
return found ? S_OK : MF_E_UNEXPECTED; } @@ -2016,10 +2030,10 @@ static HRESULT winegstreamer_stream_handler_create_object(struct winegstreamer_s static HRESULT WINAPI winegstreamer_stream_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { struct winegstreamer_stream_handler *handler = impl_from_IMFAsyncCallback(iface); - struct winegstreamer_stream_handler_result *handler_result; MF_OBJECT_TYPE obj_type = MF_OBJECT_INVALID; IUnknown *object = NULL, *context_object; struct create_object_context *context; + struct result_entry *entry; IMFAsyncResult *caller; HRESULT hr;
@@ -2033,24 +2047,21 @@ static HRESULT WINAPI winegstreamer_stream_handler_callback_Invoke(IMFAsyncCallb
context = impl_from_IUnknown(context_object);
- hr = winegstreamer_stream_handler_create_object(handler, context->url, context->stream, context->flags, context->props, &object, &obj_type); - - if ((handler_result = malloc(sizeof(*handler_result)))) - { - handler_result->result = caller; - IMFAsyncResult_AddRef(handler_result->result); - handler_result->obj_type = obj_type; - handler_result->object = object; - - EnterCriticalSection(&handler->cs); - list_add_tail(&handler->results, &handler_result->entry); - LeaveCriticalSection(&handler->cs); - } + if (FAILED(hr = winegstreamer_stream_handler_create_object(handler, context->url, context->stream, + context->flags, context->props, &object, &obj_type))) + WARN("Failed to create object, hr %#lx\n", hr); else { - if (object) - IUnknown_Release(object); - hr = E_OUTOFMEMORY; + if (FAILED(hr = result_entry_create(caller, obj_type, object, &entry))) + WARN("Failed to create handler result, hr %#lx\n", hr); + else + { + EnterCriticalSection(&handler->cs); + list_add_tail(&handler->results, &entry->entry); + LeaveCriticalSection(&handler->cs); + } + + IUnknown_Release(object); }
IUnknown_Release(&context->IUnknown_iface);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/gst_private.h | 2 +- dlls/winegstreamer/media_source.c | 118 +++++++++++++++--------------- dlls/winegstreamer/mfplat.c | 2 +- 3 files changed, 61 insertions(+), 61 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index d397ab21ca0..d515d33bdb5 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -149,7 +149,7 @@ HRESULT wg_transform_read_mf(struct wg_transform *transform, IMFSample *sample, HRESULT wg_transform_read_quartz(struct wg_transform *transform, struct wg_sample *sample); HRESULT wg_transform_read_dmo(struct wg_transform *transform, DMO_OUTPUT_DATA_BUFFER *buffer);
-HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); +HRESULT gstreamer_byte_stream_handler_create(REFIID riid, void **obj);
unsigned int wg_format_get_stride(const struct wg_format *format);
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index eb16f4d3aa9..2a83abfb7a5 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1689,7 +1689,7 @@ static void result_entry_destroy(struct result_entry *entry) free(entry); }
-struct winegstreamer_stream_handler +struct stream_handler { IMFByteStreamHandler IMFByteStreamHandler_iface; IMFAsyncCallback IMFAsyncCallback_iface; @@ -1698,17 +1698,17 @@ struct winegstreamer_stream_handler CRITICAL_SECTION cs; };
-static struct winegstreamer_stream_handler *impl_from_IMFByteStreamHandler(IMFByteStreamHandler *iface) +static struct stream_handler *impl_from_IMFByteStreamHandler(IMFByteStreamHandler *iface) { - return CONTAINING_RECORD(iface, struct winegstreamer_stream_handler, IMFByteStreamHandler_iface); + return CONTAINING_RECORD(iface, struct stream_handler, IMFByteStreamHandler_iface); }
-static struct winegstreamer_stream_handler *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) +static struct stream_handler *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) { - return CONTAINING_RECORD(iface, struct winegstreamer_stream_handler, IMFAsyncCallback_iface); + return CONTAINING_RECORD(iface, struct stream_handler, IMFAsyncCallback_iface); }
-static HRESULT WINAPI winegstreamer_stream_handler_QueryInterface(IMFByteStreamHandler *iface, REFIID riid, void **obj) +static HRESULT WINAPI stream_handler_QueryInterface(IMFByteStreamHandler *iface, REFIID riid, void **obj) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
@@ -1725,9 +1725,9 @@ static HRESULT WINAPI winegstreamer_stream_handler_QueryInterface(IMFByteStreamH return E_NOINTERFACE; }
-static ULONG WINAPI winegstreamer_stream_handler_AddRef(IMFByteStreamHandler *iface) +static ULONG WINAPI stream_handler_AddRef(IMFByteStreamHandler *iface) { - struct winegstreamer_stream_handler *handler = impl_from_IMFByteStreamHandler(iface); + struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); ULONG refcount = InterlockedIncrement(&handler->refcount);
TRACE("%p, refcount %lu.\n", handler, refcount); @@ -1735,9 +1735,9 @@ static ULONG WINAPI winegstreamer_stream_handler_AddRef(IMFByteStreamHandler *if return refcount; }
-static ULONG WINAPI winegstreamer_stream_handler_Release(IMFByteStreamHandler *iface) +static ULONG WINAPI stream_handler_Release(IMFByteStreamHandler *iface) { - struct winegstreamer_stream_handler *handler = impl_from_IMFByteStreamHandler(iface); + struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); ULONG refcount = InterlockedDecrement(&handler->refcount); struct result_entry *result, *next;
@@ -1823,10 +1823,10 @@ static const IUnknownVtbl create_object_context_vtbl = create_object_context_Release, };
-static HRESULT WINAPI winegstreamer_stream_handler_BeginCreateObject(IMFByteStreamHandler *iface, IMFByteStream *stream, const WCHAR *url, DWORD flags, +static HRESULT WINAPI stream_handler_BeginCreateObject(IMFByteStreamHandler *iface, IMFByteStream *stream, const WCHAR *url, DWORD flags, IPropertyStore *props, IUnknown **cancel_cookie, IMFAsyncCallback *callback, IUnknown *state) { - struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); + struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); struct create_object_context *context; IMFAsyncResult *caller, *item; HRESULT hr; @@ -1863,7 +1863,7 @@ static HRESULT WINAPI winegstreamer_stream_handler_BeginCreateObject(IMFByteStre return E_OUTOFMEMORY; }
- hr = MFCreateAsyncResult(&context->IUnknown_iface, &this->IMFAsyncCallback_iface, (IUnknown *)caller, &item); + hr = MFCreateAsyncResult(&context->IUnknown_iface, &handler->IMFAsyncCallback_iface, (IUnknown *)caller, &item); IUnknown_Release(&context->IUnknown_iface); if (SUCCEEDED(hr)) { @@ -1883,18 +1883,18 @@ static HRESULT WINAPI winegstreamer_stream_handler_BeginCreateObject(IMFByteStre return hr; }
-static HRESULT WINAPI winegstreamer_stream_handler_EndCreateObject(IMFByteStreamHandler *iface, IMFAsyncResult *result, +static HRESULT WINAPI stream_handler_EndCreateObject(IMFByteStreamHandler *iface, IMFAsyncResult *result, MF_OBJECT_TYPE *obj_type, IUnknown **object) { - struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); + struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); struct result_entry *found = NULL, *cur; HRESULT hr;
TRACE("%p, %p, %p, %p.\n", iface, result, obj_type, object);
- EnterCriticalSection(&this->cs); + EnterCriticalSection(&handler->cs);
- LIST_FOR_EACH_ENTRY(cur, &this->results, struct result_entry, entry) + LIST_FOR_EACH_ENTRY(cur, &handler->results, struct result_entry, entry) { if (result == cur->result) { @@ -1904,7 +1904,7 @@ static HRESULT WINAPI winegstreamer_stream_handler_EndCreateObject(IMFByteStream } }
- LeaveCriticalSection(&this->cs); + LeaveCriticalSection(&handler->cs);
if (found) { @@ -1924,16 +1924,16 @@ static HRESULT WINAPI winegstreamer_stream_handler_EndCreateObject(IMFByteStream return hr; }
-static HRESULT WINAPI winegstreamer_stream_handler_CancelObjectCreation(IMFByteStreamHandler *iface, IUnknown *cancel_cookie) +static HRESULT WINAPI stream_handler_CancelObjectCreation(IMFByteStreamHandler *iface, IUnknown *cancel_cookie) { - struct winegstreamer_stream_handler *this = impl_from_IMFByteStreamHandler(iface); + struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); struct result_entry *found = NULL, *cur;
TRACE("%p, %p.\n", iface, cancel_cookie);
- EnterCriticalSection(&this->cs); + EnterCriticalSection(&handler->cs);
- LIST_FOR_EACH_ENTRY(cur, &this->results, struct result_entry, entry) + LIST_FOR_EACH_ENTRY(cur, &handler->results, struct result_entry, entry) { if (cancel_cookie == (IUnknown *)cur->result) { @@ -1943,7 +1943,7 @@ static HRESULT WINAPI winegstreamer_stream_handler_CancelObjectCreation(IMFByteS } }
- LeaveCriticalSection(&this->cs); + LeaveCriticalSection(&handler->cs);
if (found) result_entry_destroy(found); @@ -1951,24 +1951,24 @@ static HRESULT WINAPI winegstreamer_stream_handler_CancelObjectCreation(IMFByteS return found ? S_OK : MF_E_UNEXPECTED; }
-static HRESULT WINAPI winegstreamer_stream_handler_GetMaxNumberOfBytesRequiredForResolution(IMFByteStreamHandler *iface, QWORD *bytes) +static HRESULT WINAPI stream_handler_GetMaxNumberOfBytesRequiredForResolution(IMFByteStreamHandler *iface, QWORD *bytes) { FIXME("stub (%p %p)\n", iface, bytes); return E_NOTIMPL; }
-static const IMFByteStreamHandlerVtbl winegstreamer_stream_handler_vtbl = +static const IMFByteStreamHandlerVtbl stream_handler_vtbl = { - winegstreamer_stream_handler_QueryInterface, - winegstreamer_stream_handler_AddRef, - winegstreamer_stream_handler_Release, - winegstreamer_stream_handler_BeginCreateObject, - winegstreamer_stream_handler_EndCreateObject, - winegstreamer_stream_handler_CancelObjectCreation, - winegstreamer_stream_handler_GetMaxNumberOfBytesRequiredForResolution, + stream_handler_QueryInterface, + stream_handler_AddRef, + stream_handler_Release, + stream_handler_BeginCreateObject, + stream_handler_EndCreateObject, + stream_handler_CancelObjectCreation, + stream_handler_GetMaxNumberOfBytesRequiredForResolution, };
-static HRESULT WINAPI winegstreamer_stream_handler_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +static HRESULT WINAPI stream_handler_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IMFAsyncCallback) || IsEqualIID(riid, &IID_IUnknown)) @@ -1983,27 +1983,27 @@ static HRESULT WINAPI winegstreamer_stream_handler_callback_QueryInterface(IMFAs return E_NOINTERFACE; }
-static ULONG WINAPI winegstreamer_stream_handler_callback_AddRef(IMFAsyncCallback *iface) +static ULONG WINAPI stream_handler_callback_AddRef(IMFAsyncCallback *iface) { - struct winegstreamer_stream_handler *handler = impl_from_IMFAsyncCallback(iface); + struct stream_handler *handler = impl_from_IMFAsyncCallback(iface); return IMFByteStreamHandler_AddRef(&handler->IMFByteStreamHandler_iface); }
-static ULONG WINAPI winegstreamer_stream_handler_callback_Release(IMFAsyncCallback *iface) +static ULONG WINAPI stream_handler_callback_Release(IMFAsyncCallback *iface) { - struct winegstreamer_stream_handler *handler = impl_from_IMFAsyncCallback(iface); + struct stream_handler *handler = impl_from_IMFAsyncCallback(iface); return IMFByteStreamHandler_Release(&handler->IMFByteStreamHandler_iface); }
-static HRESULT WINAPI winegstreamer_stream_handler_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +static HRESULT WINAPI stream_handler_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) { return E_NOTIMPL; }
-static HRESULT winegstreamer_stream_handler_create_object(struct winegstreamer_stream_handler *This, WCHAR *url, IMFByteStream *stream, DWORD flags, +static HRESULT stream_handler_create_object(struct stream_handler *handler, WCHAR *url, IMFByteStream *stream, DWORD flags, IPropertyStore *props, IUnknown **out_object, MF_OBJECT_TYPE *out_obj_type) { - TRACE("%p, %s, %p, %#lx, %p, %p, %p.\n", This, debugstr_w(url), stream, flags, props, out_object, out_obj_type); + TRACE("%p, %s, %p, %#lx, %p, %p, %p.\n", handler, debugstr_w(url), stream, flags, props, out_object, out_obj_type);
if (flags & MF_RESOLUTION_MEDIASOURCE) { @@ -2027,9 +2027,9 @@ static HRESULT winegstreamer_stream_handler_create_object(struct winegstreamer_s } }
-static HRESULT WINAPI winegstreamer_stream_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI stream_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { - struct winegstreamer_stream_handler *handler = impl_from_IMFAsyncCallback(iface); + struct stream_handler *handler = impl_from_IMFAsyncCallback(iface); MF_OBJECT_TYPE obj_type = MF_OBJECT_INVALID; IUnknown *object = NULL, *context_object; struct create_object_context *context; @@ -2047,7 +2047,7 @@ static HRESULT WINAPI winegstreamer_stream_handler_callback_Invoke(IMFAsyncCallb
context = impl_from_IUnknown(context_object);
- if (FAILED(hr = winegstreamer_stream_handler_create_object(handler, context->url, context->stream, + if (FAILED(hr = stream_handler_create_object(handler, context->url, context->stream, context->flags, context->props, &object, &obj_type))) WARN("Failed to create object, hr %#lx\n", hr); else @@ -2072,34 +2072,34 @@ static HRESULT WINAPI winegstreamer_stream_handler_callback_Invoke(IMFAsyncCallb return S_OK; }
-static const IMFAsyncCallbackVtbl winegstreamer_stream_handler_callback_vtbl = +static const IMFAsyncCallbackVtbl stream_handler_callback_vtbl = { - winegstreamer_stream_handler_callback_QueryInterface, - winegstreamer_stream_handler_callback_AddRef, - winegstreamer_stream_handler_callback_Release, - winegstreamer_stream_handler_callback_GetParameters, - winegstreamer_stream_handler_callback_Invoke, + stream_handler_callback_QueryInterface, + stream_handler_callback_AddRef, + stream_handler_callback_Release, + stream_handler_callback_GetParameters, + stream_handler_callback_Invoke, };
-HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) +HRESULT gstreamer_byte_stream_handler_create(REFIID riid, void **obj) { - struct winegstreamer_stream_handler *this; + struct stream_handler *handler; HRESULT hr;
TRACE("%s, %p.\n", debugstr_guid(riid), obj);
- if (!(this = calloc(1, sizeof(*this)))) + if (!(handler = calloc(1, sizeof(*handler)))) return E_OUTOFMEMORY;
- list_init(&this->results); - InitializeCriticalSection(&this->cs); + list_init(&handler->results); + InitializeCriticalSection(&handler->cs);
- this->IMFByteStreamHandler_iface.lpVtbl = &winegstreamer_stream_handler_vtbl; - this->IMFAsyncCallback_iface.lpVtbl = &winegstreamer_stream_handler_callback_vtbl; - this->refcount = 1; + handler->IMFByteStreamHandler_iface.lpVtbl = &stream_handler_vtbl; + handler->IMFAsyncCallback_iface.lpVtbl = &stream_handler_callback_vtbl; + handler->refcount = 1;
- hr = IMFByteStreamHandler_QueryInterface(&this->IMFByteStreamHandler_iface, riid, obj); - IMFByteStreamHandler_Release(&this->IMFByteStreamHandler_iface); + hr = IMFByteStreamHandler_QueryInterface(&handler->IMFByteStreamHandler_iface, riid, obj); + IMFByteStreamHandler_Release(&handler->IMFByteStreamHandler_iface);
return hr; } diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index e740807101e..7a37f25fcb2 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -126,7 +126,7 @@ static const struct class_object class_objects[] = { { &CLSID_VideoProcessorMFT, &video_processor_create }, - { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, + { &CLSID_GStreamerByteStreamHandler, &gstreamer_byte_stream_handler_create }, { &CLSID_MSAACDecMFT, &aac_decoder_create }, { &CLSID_MSH264DecoderMFT, &h264_decoder_create }, };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 86 ++++++++++++++----------------- 1 file changed, 38 insertions(+), 48 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 2a83abfb7a5..9e75e82063d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1698,6 +1698,25 @@ struct stream_handler CRITICAL_SECTION cs; };
+static struct result_entry *handler_find_result_entry(struct stream_handler *handler, IMFAsyncResult *result) +{ + struct result_entry *entry; + + EnterCriticalSection(&handler->cs); + LIST_FOR_EACH_ENTRY(entry, &handler->results, struct result_entry, entry) + { + if (result == entry->result) + { + list_remove(&entry->entry); + LeaveCriticalSection(&handler->cs); + return entry; + } + } + LeaveCriticalSection(&handler->cs); + + return NULL; +} + static struct stream_handler *impl_from_IMFByteStreamHandler(IMFByteStreamHandler *iface) { return CONTAINING_RECORD(iface, struct stream_handler, IMFByteStreamHandler_iface); @@ -1884,71 +1903,42 @@ static HRESULT WINAPI stream_handler_BeginCreateObject(IMFByteStreamHandler *ifa }
static HRESULT WINAPI stream_handler_EndCreateObject(IMFByteStreamHandler *iface, IMFAsyncResult *result, - MF_OBJECT_TYPE *obj_type, IUnknown **object) + MF_OBJECT_TYPE *type, IUnknown **object) { struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); - struct result_entry *found = NULL, *cur; + struct result_entry *entry; HRESULT hr;
- TRACE("%p, %p, %p, %p.\n", iface, result, obj_type, object); - - EnterCriticalSection(&handler->cs); + TRACE("%p, %p, %p, %p.\n", iface, result, type, object);
- LIST_FOR_EACH_ENTRY(cur, &handler->results, struct result_entry, entry) + if (!(entry = handler_find_result_entry(handler, result))) { - if (result == cur->result) - { - list_remove(&cur->entry); - found = cur; - break; - } - } - - LeaveCriticalSection(&handler->cs); - - if (found) - { - hr = IMFAsyncResult_GetStatus(found->result); - *obj_type = found->type; - *object = found->object; - IUnknown_AddRef(*object); - result_entry_destroy(found); - } - else - { - *obj_type = MF_OBJECT_INVALID; + *type = MF_OBJECT_INVALID; *object = NULL; - hr = MF_E_UNEXPECTED; + return MF_E_UNEXPECTED; }
+ hr = IMFAsyncResult_GetStatus(entry->result); + *type = entry->type; + *object = entry->object; + IUnknown_AddRef(*object); + result_entry_destroy(entry); return hr; }
-static HRESULT WINAPI stream_handler_CancelObjectCreation(IMFByteStreamHandler *iface, IUnknown *cancel_cookie) +static HRESULT WINAPI stream_handler_CancelObjectCreation(IMFByteStreamHandler *iface, IUnknown *cookie) { struct stream_handler *handler = impl_from_IMFByteStreamHandler(iface); - struct result_entry *found = NULL, *cur; - - TRACE("%p, %p.\n", iface, cancel_cookie); - - EnterCriticalSection(&handler->cs); - - LIST_FOR_EACH_ENTRY(cur, &handler->results, struct result_entry, entry) - { - if (cancel_cookie == (IUnknown *)cur->result) - { - list_remove(&cur->entry); - found = cur; - break; - } - } + IMFAsyncResult *result = (IMFAsyncResult *)cookie; + struct result_entry *entry;
- LeaveCriticalSection(&handler->cs); + TRACE("%p, %p.\n", iface, cookie);
- if (found) - result_entry_destroy(found); + if (!(entry = handler_find_result_entry(handler, result))) + return MF_E_UNEXPECTED;
- return found ? S_OK : MF_E_UNEXPECTED; + result_entry_destroy(entry); + return S_OK; }
static HRESULT WINAPI stream_handler_GetMaxNumberOfBytesRequiredForResolution(IMFByteStreamHandler *iface, QWORD *bytes)
v2: Avoid leaking media source, don't hardcode object type (yet).