Module: wine Branch: master Commit: 5ae74bc812bd1cd794466fc48419734ccb4e3fea URL: https://gitlab.winehq.org/wine/wine/-/commit/5ae74bc812bd1cd794466fc48419734...
Author: Rémi Bernon rbernon@codeweavers.com Date: Fri May 20 22:19:00 2022 +0200
qasf: Wait for IWMReader_Open to complete in ASF Reader Load.
---
dlls/qasf/asfreader.c | 66 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 19 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 43a7a3534a8..d5b6483ada3 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -41,6 +41,11 @@ struct asf_reader AM_MEDIA_TYPE media_type; WCHAR *file_name;
+ HRESULT result; + WMT_STATUS status; + CRITICAL_SECTION status_cs; + CONDITION_VARIABLE status_cv; + IWMReaderCallback *callback; IWMReader *reader;
@@ -171,6 +176,10 @@ static void asf_reader_destroy(struct strmbase_filter *iface) IWMReader_Release(filter->reader);
strmbase_filter_cleanup(&filter->filter); + + filter->status_cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&filter->status_cs); + free(filter); }
@@ -269,18 +278,35 @@ static HRESULT WINAPI file_source_Load(IFileSourceFilter *iface, LPCOLESTR file_ if (!file_name) return E_POINTER;
- if (filter->file_name) + EnterCriticalSection(&filter->filter.filter_cs); + + if (filter->file_name || !(filter->file_name = wcsdup(file_name))) + { + LeaveCriticalSection(&filter->filter.filter_cs); return E_FAIL; + }
- if (!(filter->file_name = wcsdup(file_name))) - return E_OUTOFMEMORY; + if (media_type && FAILED(hr = CopyMediaType(&filter->media_type, media_type))) + { + LeaveCriticalSection(&filter->filter.filter_cs); + return hr; + }
- if (media_type) - CopyMediaType(&filter->media_type, media_type); + EnterCriticalSection(&filter->status_cs); + if (SUCCEEDED(hr = IWMReader_Open(filter->reader, filter->file_name, filter->callback, NULL))) + { + filter->status = -1; + while (filter->status != WMT_OPENED) + SleepConditionVariableCS(&filter->status_cv, &filter->status_cs, INFINITE); + hr = filter->result; + } + LeaveCriticalSection(&filter->status_cs);
- if (FAILED(hr = IWMReader_Open(filter->reader, filter->file_name, filter->callback, NULL))) + if (FAILED(hr)) WARN("Failed to open WM reader, hr %#lx.\n", hr);
+ LeaveCriticalSection(&filter->filter.filter_cs); + return S_OK; }
@@ -378,29 +404,25 @@ static ULONG WINAPI reader_callback_Release(IWMReaderCallback *iface) return ref; }
-static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS status, HRESULT hr, +static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS status, HRESULT result, WMT_ATTR_DATATYPE type, BYTE *value, void *context) { struct asf_reader *filter = impl_from_IWMReaderCallback(iface)->filter; - AM_MEDIA_TYPE stream_media_type = {0}; + AM_MEDIA_TYPE stream_media_type = {{0}}; DWORD i, stream_count; WCHAR name[MAX_PATH]; + HRESULT hr;
- TRACE("iface %p, status %d, hr %#lx, type %d, value %p, context %p.\n", - iface, status, hr, type, value, context); + TRACE("iface %p, status %d, result %#lx, type %d, value %p, context %p.\n", + iface, status, result, type, value, context);
switch (status) { case WMT_OPENED: - if (FAILED(hr)) - { - ERR("Failed to open WMReader, hr %#lx.\n", hr); - break; - } if (FAILED(hr = IWMReader_GetOutputCount(filter->reader, &stream_count))) { ERR("Failed to get WMReader output count, hr %#lx.\n", hr); - break; + stream_count = 0; } if (stream_count > ARRAY_SIZE(filter->streams)) { @@ -408,7 +430,6 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA stream_count = ARRAY_SIZE(filter->streams); }
- EnterCriticalSection(&filter->filter.filter_cs); for (i = 0; i < stream_count; ++i) { struct asf_stream *stream = filter->streams + i; @@ -424,9 +445,13 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA strmbase_source_init(&stream->source, &filter->filter, name, &source_ops); } filter->stream_count = stream_count; - LeaveCriticalSection(&filter->filter.filter_cs); - BaseFilterImpl_IncrementPinVersion(&filter->filter); + + EnterCriticalSection(&filter->status_cs); + filter->result = result; + filter->status = WMT_OPENED; + LeaveCriticalSection(&filter->status_cs); + WakeConditionVariable(&filter->status_cv); break;
default: @@ -494,6 +519,9 @@ HRESULT asf_reader_create(IUnknown *outer, IUnknown **out) strmbase_filter_init(&object->filter, outer, &CLSID_WMAsfReader, &filter_ops); object->IFileSourceFilter_iface.lpVtbl = &file_source_vtbl;
+ InitializeCriticalSection(&object->status_cs); + object->status_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": status_cs"); + TRACE("Created WM ASF reader %p.\n", object); *out = &object->filter.IUnknown_inner;