[PATCH v4 0/5] MR625: qasf: Configure, start and stop the WMReader in the ASF Reader filter.
-- v4: qasf: Configure WMReader stream selection in asf_reader_init_stream. qasf: Configure WMReader stream format in asf_reader_init_stream. qasf: Start/stop the WM reader in asf_reader_init/cleanup_stream. qasf: Implement ASF Reader filter init_stream and cleanup_stream. qasf: Wait for IWMReader_Open to complete in ASF Reader Load. https://gitlab.winehq.org/wine/wine/-/merge_requests/625
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/qasf/asfreader.c | 64 +++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 43a7a3534a8..cb2054da9fc 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}; 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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/625
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/qasf/asfreader.c | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index cb2054da9fc..2c7dc2ed7dd 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -197,11 +197,63 @@ static HRESULT asf_reader_query_interface(struct strmbase_filter *iface, REFIID return E_NOINTERFACE; } +static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) +{ + struct asf_reader *filter = impl_from_strmbase_filter(iface); + HRESULT hr = S_OK; + int i; + + TRACE("iface %p\n", iface); + + for (i = 0; i < filter->stream_count; ++i) + { + struct asf_stream *stream = filter->streams + i; + + if (!stream->source.pin.peer) + continue; + + if (FAILED(hr = IMemAllocator_Commit(stream->source.pAllocator))) + { + WARN("Failed to commit stream %u allocator, hr %#lx\n", i, hr); + break; + } + } + + return hr; +} + +static HRESULT asf_reader_cleanup_stream(struct strmbase_filter *iface) +{ + struct asf_reader *filter = impl_from_strmbase_filter(iface); + HRESULT hr = S_OK; + int i; + + TRACE("iface %p\n", iface); + + for (i = 0; i < filter->stream_count; ++i) + { + struct asf_stream *stream = filter->streams + i; + + if (!stream->source.pin.peer) + continue; + + if (FAILED(hr = IMemAllocator_Decommit(stream->source.pAllocator))) + { + WARN("Failed to decommit stream %u allocator, hr %#lx\n", i, hr); + break; + } + } + + return hr; +} + 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_init_stream = asf_reader_init_stream, + .filter_cleanup_stream = asf_reader_cleanup_stream, }; static HRESULT WINAPI asf_reader_DecideBufferSize(struct strmbase_source *iface, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/625
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/qasf/asfreader.c | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 2c7dc2ed7dd..2f61bbe8258 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -217,8 +217,30 @@ static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) WARN("Failed to commit stream %u allocator, hr %#lx\n", i, hr); break; } + + if (FAILED(hr = IPin_NewSegment(stream->source.pin.peer, 0, 0, 1))) + { + WARN("Failed to start stream %u new segment, hr %#lx\n", i, hr); + break; + } } + if (FAILED(hr)) + return hr; + + EnterCriticalSection(&filter->status_cs); + if (SUCCEEDED(hr = IWMReader_Start(filter->reader, 0, 0, 1, NULL))) + { + filter->status = -1; + while (filter->status != WMT_STARTED) + SleepConditionVariableCS(&filter->status_cv, &filter->status_cs, INFINITE); + hr = filter->result; + } + LeaveCriticalSection(&filter->status_cs); + + if (FAILED(hr)) + WARN("Failed to start WMReader %p, hr %#lx\n", filter->reader, hr); + return hr; } @@ -230,6 +252,19 @@ static HRESULT asf_reader_cleanup_stream(struct strmbase_filter *iface) TRACE("iface %p\n", iface); + EnterCriticalSection(&filter->status_cs); + if (SUCCEEDED(hr = IWMReader_Stop(filter->reader))) + { + filter->status = -1; + while (filter->status != WMT_STOPPED) + SleepConditionVariableCS(&filter->status_cv, &filter->status_cs, INFINITE); + hr = filter->result; + } + LeaveCriticalSection(&filter->status_cs); + + if (FAILED(hr)) + WARN("Failed to stop WMReader %p, hr %#lx\n", filter->reader, hr); + for (i = 0; i < filter->stream_count; ++i) { struct asf_stream *stream = filter->streams + i; @@ -506,6 +541,34 @@ static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STA WakeConditionVariable(&filter->status_cv); break; + case WMT_END_OF_STREAMING: + for (i = 0; i < filter->stream_count; ++i) + { + struct asf_stream *stream = filter->streams + i; + + if (!stream->source.pin.peer) + continue; + + IPin_EndOfStream(stream->source.pin.peer); + } + break; + + case WMT_STARTED: + EnterCriticalSection(&filter->status_cs); + filter->result = result; + filter->status = WMT_STARTED; + LeaveCriticalSection(&filter->status_cs); + WakeConditionVariable(&filter->status_cv); + break; + + case WMT_STOPPED: + EnterCriticalSection(&filter->status_cs); + filter->result = result; + filter->status = WMT_STOPPED; + LeaveCriticalSection(&filter->status_cs); + WakeConditionVariable(&filter->status_cv); + break; + default: WARN("Ignoring status %#x.\n", status); break; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/625
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/qasf/asfreader.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 2f61bbe8258..18442302511 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -208,6 +208,7 @@ static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) for (i = 0; i < filter->stream_count; ++i) { struct asf_stream *stream = filter->streams + i; + IWMOutputMediaProps *props; if (!stream->source.pin.peer) continue; @@ -218,6 +219,22 @@ static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) break; } + if (FAILED(hr = IWMReader_GetOutputFormat(filter->reader, stream->index, 0, &props))) + { + WARN("Failed to get stream %u output format, hr %#lx\n", i, hr); + break; + } + + hr = IWMOutputMediaProps_SetMediaType(props, (WM_MEDIA_TYPE *)&stream->source.pin.mt); + if (SUCCEEDED(hr)) + hr = IWMReader_SetOutputProps(filter->reader, stream->index, props); + IWMOutputMediaProps_Release(props); + if (FAILED(hr)) + { + WARN("Failed to set stream %u output format, hr %#lx\n", i, hr); + break; + } + if (FAILED(hr = IPin_NewSegment(stream->source.pin.peer, 0, 0, 1))) { WARN("Failed to start stream %u new segment, hr %#lx\n", i, hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/625
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/qasf/asfreader.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 18442302511..29c153941ee 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -200,16 +200,25 @@ static HRESULT asf_reader_query_interface(struct strmbase_filter *iface, REFIID static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) { struct asf_reader *filter = impl_from_strmbase_filter(iface); + WMT_STREAM_SELECTION selections[ARRAY_SIZE(filter->streams)]; + WORD stream_numbers[ARRAY_SIZE(filter->streams)]; + IWMReaderAdvanced *reader_advanced; HRESULT hr = S_OK; int i; TRACE("iface %p\n", iface); + if (FAILED(hr = IWMReader_QueryInterface(filter->reader, &IID_IWMReaderAdvanced, (void **)&reader_advanced))) + return hr; + for (i = 0; i < filter->stream_count; ++i) { struct asf_stream *stream = filter->streams + i; IWMOutputMediaProps *props; + stream_numbers[i] = i + 1; + selections[i] = WMT_OFF; + if (!stream->source.pin.peer) continue; @@ -240,8 +249,16 @@ static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) WARN("Failed to start stream %u new segment, hr %#lx\n", i, hr); break; } + + selections[i] = WMT_ON; } + if (SUCCEEDED(hr) && FAILED(hr = IWMReaderAdvanced_SetStreamsSelected(reader_advanced, + filter->stream_count, stream_numbers, selections))) + WARN("Failed to set reader %p stream selection, hr %#lx\n", filter->reader, hr); + + IWMReaderAdvanced_Release(reader_advanced); + if (FAILED(hr)) return hr; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/625
participants (1)
-
Rémi Bernon