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