This fixes media replay for BlazeBlue.
From: Ziqing Hui zhui@codeweavers.com
This fixes media replay for BlazeBlue. --- dlls/qasf/asfreader.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 91fdc6fbb34..6aa04453f27 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -286,8 +286,32 @@ static inline struct asf_stream *impl_from_IMediaSeeking(IMediaSeeking *iface)
static HRESULT WINAPI media_seeking_ChangeCurrent(IMediaSeeking *iface) { - FIXME("iface %p stub!\n", iface); - return S_OK; + struct asf_stream *stream = impl_from_IMediaSeeking(iface); + struct asf_reader *filter = asf_reader_from_asf_stream(stream); + SourceSeeking *seek = &stream->seek; + HRESULT hr; + UINT i; + + TRACE("iface %p.\n", iface); + + for (i = 0; i < filter->stream_count; ++i) + { + if (FAILED(IPin_BeginFlush(stream->source.pin.peer))) + WARN("Failed to BeginFlush for stream %u.\n", i); + } + + hr = IBaseFilter_Stop(&filter->filter.IBaseFilter_iface); + + for (i = 0; i < filter->stream_count; ++i) + { + if (FAILED(IPin_EndFlush(stream->source.pin.peer))) + WARN("Failed to EndFlush for stream %u.\n", i); + } + + if (hr == S_OK) + hr = IWMReader_Start(filter->reader, seek->llCurrent, seek->llDuration, seek->dRate, NULL); + + return hr; }
static HRESULT WINAPI media_seeking_ChangeStop(IMediaSeeking *iface)
Do I need to add a test patch for this?
As if it's that easy. I wasted 2 weeks on this 😂😭
On Wed Sep 24 12:57:37 2025 +0000, Bernhard Kölbl wrote:
As if it's that easy. I wasted 2 weeks on this 😂😭
The patch is easy, but figuring out how to easily do this is not too easy.
* We should be respecting the AM_SEEKING_NoFlush flags.
* We should check for stopped state; we don't want to flush anything if not stopped.
* Stopping the filter seems wrong. Did you mean to stop the IWMReader? I don't think even that's necessary, though.
Do I need to add a test patch for this?
I'm not sure that there's a way to reliably test.
- We should be respecting the AM_SEEKING_NoFlush flags.
OK, I'll add this in new version.
- We should check for stopped state; we don't want to flush anything if not stopped.
- Stopping the filter seems wrong. Did you mean to stop the IWMReader? I don't think even that's necessary, though.
I don't think so. See https://learn.microsoft.com/en-us/windows/win32/directshow/supporting-seekin....
The document talks about seeking on condition of streaming thread running, so I don't think we should only send flush command downstream in stop state. If not in stop state, we drop the pending buffers by flushing, downstream filters chould handle this.
Stopping the filter is necessary, it finally calls asf_reader_cleanup_stream() to decommit the allocator to prevent futher buffer allocating. Buffer allocating failure makes upstream filters unable to send more buffers downstream, which is what we expected when we are seeking. If we don't, there may be race conditions, although I can not precisely says what condition it is.
I don't think so. See https://learn.microsoft.com/en-us/windows/win32/directshow/supporting-seekin....
Okay, I'm surprised it recommends actually calling Stop() [though note that you also have to put it back in paused state afterward, which this patch is missing]. Stop() is a bit of a heavy hammer, though, and I don't think we need it here.
The document talks about seeking on condition of streaming thread running, so I don't think we should only send flush command downstream in stop state. If not in stop state, we drop the pending buffers by flushing, downstream filters chould handle this.
Stopping the filter is necessary, it finally calls asf_reader_cleanup_stream() to decommit the allocator to prevent futher buffer allocating. Buffer allocating failure makes upstream filters unable to send more buffers downstream, which is what we expected when we are seeking. If we don't, there may be race conditions, although I can not precisely says what condition it is.
You don't need to stop the filter to prevent that. In fact, that's exactly what flushing is for.