From: Zhiyi Zhang zzhang@codeweavers.com
The streaming threads and GST_Seeking_SetPositions() contend for the same flushing locks. GST_Seeking_SetPositions() needs to acquire all the flushing locks before doing the actual stream seeking, having the streaming threads fighting for the same locks will make GST_Seeking_SetPositions() wait for a unusually long time.
This reduces PowerPoint 2016 video seeking time from ~5s to almost an instant and fixes a regression for Fallout 3.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53403 --- dlls/winegstreamer/quartz_parser.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 9369b529642..3f6b4e11385 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -84,6 +84,11 @@ struct parser_source bool need_segment;
bool eos; + + /* When is_seeking is true, the code is in GST_Seeking_SetPositions() and is trying to change + * positions. In this case, pause the streaming thread until seeking is completed. Otherwise, + * GST_Seeking_SetPositions() may take a long time acquiring all the flushing locks. */ + bool is_seeking; };
static inline struct parser *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -929,6 +934,9 @@ static DWORD CALLBACK stream_thread(void *arg) { struct wg_parser_buffer buffer;
+ while (pin->is_seeking) + Sleep(1); + EnterCriticalSection(&pin->flushing_cs);
if (pin->eos) @@ -1462,7 +1470,10 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface, struct parser_source *flush_pin = filter->sources[i];
if (flush_pin->pin.pin.peer) + { + flush_pin->is_seeking = true; EnterCriticalSection(&flush_pin->flushing_cs); + } }
SourceSeekingImpl_SetPositions(iface, current, current_flags, stop, stop_flags); @@ -1494,6 +1505,7 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
if (flush_pin->pin.pin.peer) { + flush_pin->is_seeking = false; LeaveCriticalSection(&flush_pin->flushing_cs); WakeConditionVariable(&flush_pin->eos_cv); }