winegstreamer: Explicitly sleep in the DirectShow streaming thread after receiving EOS.

Instead of waiting for another event from the wg_parser object.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2022-02-23 15:46:46 -06:00 committed by Alexandre Julliard
parent 680d7e4846
commit 7da1828c49
1 changed files with 23 additions and 4 deletions

View File

@ -74,6 +74,7 @@ struct parser_source
SourceSeeking seek; SourceSeeking seek;
CRITICAL_SECTION flushing_cs; CRITICAL_SECTION flushing_cs;
CONDITION_VARIABLE eos_cv;
HANDLE thread; HANDLE thread;
/* This variable is read and written by both the streaming thread and /* This variable is read and written by both the streaming thread and
@ -81,6 +82,8 @@ struct parser_source
* thread when the streaming thread is not running, or when it is blocked * thread when the streaming thread is not running, or when it is blocked
* by flushing_cs. */ * by flushing_cs. */
bool need_segment; bool need_segment;
bool eos;
}; };
static inline struct parser *impl_from_strmbase_filter(struct strmbase_filter *iface) static inline struct parser *impl_from_strmbase_filter(struct strmbase_filter *iface)
@ -823,6 +826,13 @@ static DWORD CALLBACK stream_thread(void *arg)
EnterCriticalSection(&pin->flushing_cs); EnterCriticalSection(&pin->flushing_cs);
if (pin->eos)
{
SleepConditionVariableCS(&pin->eos_cv, &pin->flushing_cs, INFINITE);
LeaveCriticalSection(&pin->flushing_cs);
continue;
}
if (!wg_parser_stream_get_event(pin->wg_stream, &event)) if (!wg_parser_stream_get_event(pin->wg_stream, &event))
{ {
LeaveCriticalSection(&pin->flushing_cs); LeaveCriticalSection(&pin->flushing_cs);
@ -839,6 +849,7 @@ static DWORD CALLBACK stream_thread(void *arg)
case WG_PARSER_EVENT_EOS: case WG_PARSER_EVENT_EOS:
IPin_EndOfStream(pin->pin.pin.peer); IPin_EndOfStream(pin->pin.pin.peer);
pin->eos = true;
break; break;
case WG_PARSER_EVENT_NONE: case WG_PARSER_EVENT_NONE:
@ -973,17 +984,19 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface)
for (i = 0; i < filter->source_count; ++i) for (i = 0; i < filter->source_count; ++i)
{ {
struct parser_source *pin = filter->sources[i];
HRESULT hr; HRESULT hr;
if (!filter->sources[i]->pin.pin.peer) if (!pin->pin.pin.peer)
continue; continue;
if (FAILED(hr = IMemAllocator_Commit(filter->sources[i]->pin.pAllocator))) if (FAILED(hr = IMemAllocator_Commit(pin->pin.pAllocator)))
ERR("Failed to commit allocator, hr %#lx.\n", hr); ERR("Failed to commit allocator, hr %#lx.\n", hr);
filter->sources[i]->need_segment = true; pin->need_segment = true;
pin->eos = false;
filter->sources[i]->thread = CreateThread(NULL, 0, stream_thread, filter->sources[i], 0, NULL); pin->thread = CreateThread(NULL, 0, stream_thread, pin, 0, NULL);
} }
return S_OK; return S_OK;
@ -1009,6 +1022,7 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface)
IMemAllocator_Decommit(pin->pin.pAllocator); IMemAllocator_Decommit(pin->pin.pAllocator);
WakeConditionVariable(&pin->eos_cv);
WaitForSingleObject(pin->thread, INFINITE); WaitForSingleObject(pin->thread, INFINITE);
CloseHandle(pin->thread); CloseHandle(pin->thread);
pin->thread = NULL; pin->thread = NULL;
@ -1371,9 +1385,13 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
struct parser_source *flush_pin = filter->sources[i]; struct parser_source *flush_pin = filter->sources[i];
flush_pin->need_segment = true; flush_pin->need_segment = true;
flush_pin->eos = false;
if (flush_pin->pin.pin.peer) if (flush_pin->pin.pin.peer)
{
LeaveCriticalSection(&flush_pin->flushing_cs); LeaveCriticalSection(&flush_pin->flushing_cs);
WakeConditionVariable(&flush_pin->eos_cv);
}
} }
return S_OK; return S_OK;
@ -1613,6 +1631,7 @@ static struct parser_source *create_pin(struct parser *filter,
InitializeCriticalSection(&pin->flushing_cs); InitializeCriticalSection(&pin->flushing_cs);
pin->flushing_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": pin.flushing_cs"); pin->flushing_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": pin.flushing_cs");
InitializeConditionVariable(&pin->eos_cv);
filter->sources[filter->source_count++] = pin; filter->sources[filter->source_count++] = pin;
return pin; return pin;