This fixes media replay for BlazeBlue.
-- v2: qasf: Add asf_reader_start_stream helper. qasf: Add asf_reader_stop_stream helper. qasf: Implement seeking for asf reader.
From: Ziqing Hui zhui@codeweavers.com
This fixes media replay for BlazeBlue. --- dlls/qasf/asfreader.c | 50 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 91fdc6fbb34..5e438f59d7e 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -286,8 +286,54 @@ 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); + struct SourceSeeking *seek = &stream->seek; + HRESULT hr; + UINT i; + + TRACE("iface %p.\n", iface); + + /* Send begin flush commands downstream. */ + 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); + } + + /* Stop the reader. */ + 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); + + /* Send end flush commands downstream. */ + 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); + } + + /* Start the reader. */ + if (hr == S_OK) + { + EnterCriticalSection(&filter->status_cs); + if (SUCCEEDED(hr = IWMReader_Start(filter->reader, seek->llCurrent, seek->llDuration, seek->dRate, NULL))) + { + filter->status = -1; + while (filter->status != WMT_STARTED) + SleepConditionVariableCS(&filter->status_cv, &filter->status_cs, INFINITE); + hr = filter->result; + } + LeaveCriticalSection(&filter->status_cs); + } + + return hr; }
static HRESULT WINAPI media_seeking_ChangeStop(IMediaSeeking *iface)
From: Ziqing Hui zhui@codeweavers.com
--- dlls/qasf/asfreader.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 5e438f59d7e..6b82553c33f 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -279,6 +279,25 @@ static HRESULT asf_stream_query_interface(struct strmbase_pin *iface, REFIID iid return S_OK; }
+static HRESULT asf_reader_stop_stream(struct asf_reader *filter) +{ + HRESULT hr; + + 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); + + return hr; +} + static inline struct asf_stream *impl_from_IMediaSeeking(IMediaSeeking *iface) { return CONTAINING_RECORD(iface, struct asf_stream, seek.IMediaSeeking_iface); @@ -302,15 +321,7 @@ static HRESULT WINAPI media_seeking_ChangeCurrent(IMediaSeeking *iface) }
/* Stop the reader. */ - 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); + hr = asf_reader_stop_stream(filter);
/* Send end flush commands downstream. */ for (i = 0; i < filter->stream_count; ++i) @@ -553,17 +564,7 @@ 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)) + if (FAILED(hr = asf_reader_stop_stream(filter))) WARN("Failed to stop WMReader %p, hr %#lx\n", filter->reader, hr);
for (i = 0; i < filter->stream_count; ++i)
From: Ziqing Hui zhui@codeweavers.com
--- dlls/qasf/asfreader.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index 6b82553c33f..ec7a0310e0a 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -279,6 +279,25 @@ static HRESULT asf_stream_query_interface(struct strmbase_pin *iface, REFIID iid return S_OK; }
+static HRESULT asf_reader_start_stream(struct asf_reader *filter, LONGLONG start, LONGLONG duration, float rate) +{ + HRESULT hr; + + EnterCriticalSection(&filter->status_cs); + + if (SUCCEEDED(hr = IWMReader_Start(filter->reader, start, duration, rate, NULL))) + { + filter->status = -1; + while (filter->status != WMT_STARTED) + SleepConditionVariableCS(&filter->status_cv, &filter->status_cs, INFINITE); + hr = filter->result; + } + + LeaveCriticalSection(&filter->status_cs); + + return hr; +} + static HRESULT asf_reader_stop_stream(struct asf_reader *filter) { HRESULT hr; @@ -332,17 +351,7 @@ static HRESULT WINAPI media_seeking_ChangeCurrent(IMediaSeeking *iface)
/* Start the reader. */ if (hr == S_OK) - { - EnterCriticalSection(&filter->status_cs); - if (SUCCEEDED(hr = IWMReader_Start(filter->reader, seek->llCurrent, seek->llDuration, seek->dRate, NULL))) - { - filter->status = -1; - while (filter->status != WMT_STARTED) - SleepConditionVariableCS(&filter->status_cv, &filter->status_cs, INFINITE); - hr = filter->result; - } - LeaveCriticalSection(&filter->status_cs); - } + hr = asf_reader_start_stream(filter, seek->llCurrent, seek->llDuration, seek->dRate);
return hr; } @@ -540,17 +549,7 @@ static HRESULT asf_reader_init_stream(struct strmbase_filter *iface) 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)) + if (FAILED(hr = asf_reader_start_stream(filter, 0, 0, 1.0))) WARN("Failed to start WMReader %p, hr %#lx\n", filter->reader, hr);
return hr;
v2: Instead of stopping the filter, we now stop the reader.