From: R��mi Bernon rbernon@codeweavers.com
--- dlls/qasf/asfreader.c | 49 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 43a7a3534a8..f8114cdda26 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -41,6 +41,9 @@ struct asf_reader AM_MEDIA_TYPE media_type; WCHAR *file_name;
+ WMT_STATUS status; + CONDITION_VARIABLE status_cv; + IWMReaderCallback *callback; IWMReader *reader;
@@ -188,11 +191,27 @@ static HRESULT asf_reader_query_interface(struct strmbase_filter *iface, REFIID return E_NOINTERFACE; }
+static HRESULT asf_reader_wait_state(struct strmbase_filter *iface, DWORD timeout) +{ + struct asf_reader *filter = impl_from_strmbase_filter(iface); + DWORD time = GetTickCount(), end_time = time + timeout; + + while (filter->status == -1 && end_time - time <= timeout) + { + if (!SleepConditionVariableCS(&filter->status_cv, &filter->filter.filter_cs, end_time - time)) + break; + time = GetTickCount(); + } + + return filter->status == -1 ? VFW_S_STATE_INTERMEDIATE : S_OK; +} + static const struct strmbase_filter_ops filter_ops = { .filter_get_pin = asf_reader_get_pin, .filter_destroy = asf_reader_destroy, .filter_query_interface = asf_reader_query_interface, + .filter_wait_state = asf_reader_wait_state, };
static HRESULT WINAPI asf_reader_DecideBufferSize(struct strmbase_source *iface, @@ -269,17 +288,29 @@ static HRESULT WINAPI file_source_Load(IFileSourceFilter *iface, LPCOLESTR file_ if (!file_name) return E_POINTER;
- if (filter->file_name) - return E_FAIL; + EnterCriticalSection(&filter->filter.filter_cs);
- if (!(filter->file_name = wcsdup(file_name))) - return E_OUTOFMEMORY; + if (filter->file_name || !(filter->file_name = wcsdup(file_name))) + { + LeaveCriticalSection(&filter->filter.filter_cs); + return E_FAIL; + }
- if (media_type) - CopyMediaType(&filter->media_type, media_type); + if (media_type && FAILED(hr = CopyMediaType(&filter->media_type, media_type))) + { + LeaveCriticalSection(&filter->filter.filter_cs); + return hr; + }
if (FAILED(hr = IWMReader_Open(filter->reader, filter->file_name, filter->callback, NULL))) WARN("Failed to open WM reader, hr %#lx.\n", hr); + else + { + filter->status = -1; + asf_reader_wait_state(&filter->filter, INFINITE); + } + + LeaveCriticalSection(&filter->filter.filter_cs);
return S_OK; } @@ -424,9 +455,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); + + filter->status = WMT_OPENED; + WakeConditionVariable(&filter->status_cv);
BaseFilterImpl_IncrementPinVersion(&filter->filter); + + LeaveCriticalSection(&filter->filter.filter_cs); break;
default: