The qasf change is a hack, but it solves the regressions and I don't think there's a good way to fix them otherwise. The proper fix is to implement wmvcore threading as in https://gitlab.winehq.org/wine/wine/-/merge_requests/1311, but that will be much more changes and is unsuitable for the code freeze.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53640 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53748
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53640 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53748 --- dlls/qasf/asfreader.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 4cf077e9dd3..538b4b5b377 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -451,6 +451,7 @@ static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) { struct asf_stream *stream = filter->streams + i; IWMOutputMediaProps *props; + IMediaSample *sample;
stream_numbers[i] = i + 1; selections[i] = WMT_OFF; @@ -493,6 +494,17 @@ static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) }
selections[i] = WMT_ON; + + /* Push a preroll sample to unblock DSoundRender filter and avoid a deadlock with renderers waiting on each other. + * FIXME: This should instead be done with WM Reader delivery threads. + */ + if (wcsstr(stream->source.pin.name, L"Raw Audio") + && SUCCEEDED(hr = IMemAllocator_GetBuffer(stream->source.pAllocator, &sample, NULL, NULL, 0))) + { + IMediaSample_SetPreroll(sample, TRUE); + IMemInputPin_Receive(stream->source.pMemInputPin, sample); + IMediaSample_Release(sample); + } }
if (SUCCEEDED(hr) && FAILED(hr = IWMReaderAdvanced_SetStreamsSelected(reader_advanced,
I don't think we want a hack like this upstream. If we want to fix the regression, I think it would be better to just revert 4608e1e12 for now, on the grounds that the ASF reader isn't quite ready yet.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53748 --- dlls/amstream/multimedia.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/dlls/amstream/multimedia.c b/dlls/amstream/multimedia.c index dc855901c77..90c0b0a54b5 100644 --- a/dlls/amstream/multimedia.c +++ b/dlls/amstream/multimedia.c @@ -38,6 +38,7 @@ struct multimedia_stream IMediaSeeking* media_seeking; IMediaControl* media_control; IMediaStreamFilter *filter; + IBaseFilter *source; IPin* ipin; BOOL initialized; STREAM_TYPE type; @@ -90,6 +91,8 @@ static ULONG WINAPI multimedia_stream_Release(IAMMultiMediaStream *iface)
if (!ref) { + if (This->source) + IBaseFilter_Release(This->source); if (This->ipin) IPin_Release(This->ipin); IMediaStreamFilter_Release(This->filter); @@ -431,7 +434,6 @@ static HRESULT WINAPI multimedia_stream_OpenFile(IAMMultiMediaStream *iface, { struct multimedia_stream *This = impl_from_IAMMultiMediaStream(iface); HRESULT ret = S_OK; - IBaseFilter *BaseFilter = NULL; IEnumPins *EnumPins = NULL; IPin *ipin; PIN_DIRECTION pin_direction; @@ -449,11 +451,17 @@ static HRESULT WINAPI multimedia_stream_OpenFile(IAMMultiMediaStream *iface, ret = create_graph(This, NULL); }
+ if (This->source) + { + IBaseFilter_Release(This->source); + This->source = NULL; + } + if (SUCCEEDED(ret)) - ret = IGraphBuilder_AddSourceFilter(This->graph, filename, L"Source", &BaseFilter); + ret = IGraphBuilder_AddSourceFilter(This->graph, filename, L"Source", &This->source);
if (SUCCEEDED(ret)) - ret = IBaseFilter_EnumPins(BaseFilter, &EnumPins); + ret = IBaseFilter_EnumPins(This->source, &EnumPins);
if (SUCCEEDED(ret)) ret = IEnumPins_Next(EnumPins, 1, &ipin, NULL); @@ -504,8 +512,6 @@ static HRESULT WINAPI multimedia_stream_OpenFile(IAMMultiMediaStream *iface,
if (EnumPins) IEnumPins_Release(EnumPins); - if (BaseFilter) - IBaseFilter_Release(BaseFilter); return ret; }
From: Rémi Bernon rbernon@codeweavers.com
Instead of the first one.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53748 --- dlls/amstream/multimedia.c | 90 ++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 42 deletions(-)
diff --git a/dlls/amstream/multimedia.c b/dlls/amstream/multimedia.c index 90c0b0a54b5..607cf6f0d03 100644 --- a/dlls/amstream/multimedia.c +++ b/dlls/amstream/multimedia.c @@ -39,7 +39,6 @@ struct multimedia_stream IMediaControl* media_control; IMediaStreamFilter *filter; IBaseFilter *source; - IPin* ipin; BOOL initialized; STREAM_TYPE type; OAEVENT event; @@ -93,8 +92,6 @@ static ULONG WINAPI multimedia_stream_Release(IAMMultiMediaStream *iface) { if (This->source) IBaseFilter_Release(This->source); - if (This->ipin) - IPin_Release(This->ipin); IMediaStreamFilter_Release(This->filter); IMediaStreamFilter_Release(This->filter); if (This->media_seeking) @@ -434,9 +431,6 @@ static HRESULT WINAPI multimedia_stream_OpenFile(IAMMultiMediaStream *iface, { struct multimedia_stream *This = impl_from_IAMMultiMediaStream(iface); HRESULT ret = S_OK; - IEnumPins *EnumPins = NULL; - IPin *ipin; - PIN_DIRECTION pin_direction;
TRACE("(%p/%p)->(%s,%lx)\n", This, iface, debugstr_w(filename), flags);
@@ -460,39 +454,8 @@ static HRESULT WINAPI multimedia_stream_OpenFile(IAMMultiMediaStream *iface, if (SUCCEEDED(ret)) ret = IGraphBuilder_AddSourceFilter(This->graph, filename, L"Source", &This->source);
- if (SUCCEEDED(ret)) - ret = IBaseFilter_EnumPins(This->source, &EnumPins); - - if (SUCCEEDED(ret)) - ret = IEnumPins_Next(EnumPins, 1, &ipin, NULL); - - if (SUCCEEDED(ret)) - { - ret = IPin_QueryDirection(ipin, &pin_direction); - if (ret == S_OK && pin_direction == PINDIR_OUTPUT) - This->ipin = ipin; - } - if (SUCCEEDED(ret) && !(flags & AMMSF_NORENDER)) - { - IFilterGraph2 *graph; - - if (SUCCEEDED(ret = IGraphBuilder_QueryInterface(This->graph, &IID_IFilterGraph2, (void **)&graph))) - { - DWORD renderflags = (flags & AMMSF_RENDERALLSTREAMS) ? 0 : AM_RENDEREX_RENDERTOEXISTINGRENDERERS; - - ret = IFilterGraph2_RenderEx(graph, This->ipin, renderflags, NULL); - if (ret == VFW_E_CANNOT_RENDER) ret = VFW_E_CANNOT_CONNECT; - else if (ret == VFW_S_PARTIAL_RENDER) ret = S_OK; - - IFilterGraph2_Release(graph); - } - else - { - FIXME("Failed to get IFilterGraph2 interface, hr %#lx.\n", ret); - ret = IGraphBuilder_Render(This->graph, This->ipin); - } - } + ret = IAMMultiMediaStream_Render(iface, flags | AMMSF_NOCLOCK);
if (SUCCEEDED(ret) && (flags & AMMSF_NOCLOCK)) { @@ -510,8 +473,6 @@ static HRESULT WINAPI multimedia_stream_OpenFile(IAMMultiMediaStream *iface, if (SUCCEEDED(ret) && (flags & AMMSF_RUN)) ret = IAMMultiMediaStream_SetState(iface, STREAMSTATE_RUN);
- if (EnumPins) - IEnumPins_Release(EnumPins); return ret; }
@@ -528,13 +489,58 @@ static HRESULT WINAPI multimedia_stream_OpenMoniker(IAMMultiMediaStream *iface, static HRESULT WINAPI multimedia_stream_Render(IAMMultiMediaStream *iface, DWORD dwFlags) { struct multimedia_stream *This = impl_from_IAMMultiMediaStream(iface); + IFilterGraph2 *graph; + IEnumPins *pins; + HRESULT ret; + IPin *pin;
FIXME("(%p/%p)->(%lx) partial stub!\n", This, iface, dwFlags);
- if(dwFlags != AMMSF_NOCLOCK) + if(!(dwFlags & AMMSF_NOCLOCK)) return E_INVALIDARG;
- return IGraphBuilder_Render(This->graph, This->ipin); + ret = IBaseFilter_EnumPins(This->source, &pins); + if (FAILED(ret)) + return ret; + + if (FAILED(IGraphBuilder_QueryInterface(This->graph, &IID_IFilterGraph2, (void **)&graph))) + { + FIXME("Failed to get IFilterGraph2 interface.\n"); + graph = NULL; + } + + while (!(ret = IEnumPins_Next(pins, 1, &pin, NULL))) + { + PIN_DIRECTION dir; + + ret = IPin_QueryDirection(pin, &dir); + if (ret != S_OK || dir != PINDIR_OUTPUT) + { + IPin_Release(pin); + continue; + } + + if (!graph) + ret = IGraphBuilder_Render(This->graph, pin); + else + { + DWORD renderflags = (dwFlags & AMMSF_RENDERALLSTREAMS) ? 0 : AM_RENDEREX_RENDERTOEXISTINGRENDERERS; + + ret = IFilterGraph2_RenderEx(graph, pin, renderflags, NULL); + if (ret == VFW_E_CANNOT_RENDER) ret = VFW_E_CANNOT_CONNECT; + else if (ret == VFW_S_PARTIAL_RENDER) ret = S_OK; + } + + IPin_Release(pin); + if (FAILED(ret)) + break; + } + + if (graph) + IFilterGraph2_Release(graph); + + IEnumPins_Release(pins); + return SUCCEEDED(ret) ? S_OK : ret; }
static const IAMMultiMediaStreamVtbl multimedia_stream_vtbl =
This merge request was closed by Rémi Bernon.