Rémi Bernon : qasf: Wait for IWMReader_Open to complete in ASF Reader Load.
Alexandre Julliard
julliard at winehq.org
Sat Aug 13 14:20:31 CDT 2022
Module: wine
Branch: master
Commit: 5ae74bc812bd1cd794466fc48419734ccb4e3fea
URL: https://gitlab.winehq.org/wine/wine/-/commit/5ae74bc812bd1cd794466fc48419734ccb4e3fea
Author: Rémi Bernon <rbernon at 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;
More information about the wine-cvs
mailing list