winegstreamer: Remove support for flushing the wg_parser object.

Aside from EOS logic, which is now handled entirely on the client side,
wg_parser_stream_get_event() now only waits for data processing—that is,
demuxing, decoding, and format conversion. While unblocking waits in
wg_parser_stream_get_event() does allow that function to return immediately, a
subsequent seek request in GStreamer will still have to wait for that data
processing to complete and for the stream thread to return to the demuxer's main
loop. In essence, wg_parser_begin_flush() is only moving costs around.

In theory we could force the GStreamer pipeline to complete faster by actually
flushing it. In practice this isn't really true. Individual elements do check
whether they are flushing before processing, but even elements which take a
relatively long time (i.e. multiple milliseconds) to process data don't
periodically check whether they are flushing while doing so. Although there is
arguably a benefit to skipping some elements by flushing the GStreamer pipeline,
it does not seem worth the added code complexity in Wine.

The real point of flushing in DirectShow or GStreamer is to unblock long or
unbounded waits in sink elements (i.e. waits for PTS, or waits for running state
while rendering preroll frames). None of these waits apply here. Waits for
actual sample processing complete in bounded time, and should ideally take less
than the sample DTS to complete (or we are already in trouble).

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:47 -06:00 committed by Alexandre Julliard
parent 7da1828c49
commit 5144b27661
7 changed files with 8 additions and 83 deletions

View File

@ -70,9 +70,6 @@ void wg_parser_destroy(struct wg_parser *parser);
HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size);
void wg_parser_disconnect(struct wg_parser *parser);
void wg_parser_begin_flush(struct wg_parser *parser);
void wg_parser_end_flush(struct wg_parser *parser);
bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset, uint32_t *size);
void wg_parser_push_data(struct wg_parser *parser, const void *data, uint32_t size);
@ -83,7 +80,7 @@ void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, stru
void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format);
void wg_parser_stream_disable(struct wg_parser_stream *stream);
bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event);
void wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event);
bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
void *data, uint32_t offset, uint32_t size);
void wg_parser_stream_release_buffer(struct wg_parser_stream *stream);

View File

@ -96,16 +96,6 @@ void wg_parser_disconnect(struct wg_parser *parser)
__wine_unix_call(unix_handle, unix_wg_parser_disconnect, parser);
}
void wg_parser_begin_flush(struct wg_parser *parser)
{
__wine_unix_call(unix_handle, unix_wg_parser_begin_flush, parser);
}
void wg_parser_end_flush(struct wg_parser *parser)
{
__wine_unix_call(unix_handle, unix_wg_parser_end_flush, parser);
}
bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset, uint32_t *size)
{
struct wg_parser_get_next_read_offset_params params =
@ -182,7 +172,7 @@ void wg_parser_stream_disable(struct wg_parser_stream *stream)
__wine_unix_call(unix_handle, unix_wg_parser_stream_disable, stream);
}
bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event)
void wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event)
{
struct wg_parser_stream_get_event_params params =
{
@ -190,7 +180,7 @@ bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parse
.event = event,
};
return !__wine_unix_call(unix_handle, unix_wg_parser_stream_get_event, &params);
__wine_unix_call(unix_handle, unix_wg_parser_stream_get_event, &params);
}
bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,

View File

@ -388,7 +388,6 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
if (position->vt == VT_I8)
wg_parser_stream_seek(source->streams[0]->wg_stream, 1.0, position->hVal.QuadPart, 0,
AM_SEEKING_AbsolutePositioning, AM_SEEKING_NoPositioning);
wg_parser_end_flush(source->wg_parser);
for (i = 0; i < source->stream_count; i++)
flush_token_queue(source->streams[i], position->vt == VT_EMPTY);
@ -416,8 +415,6 @@ static void stop_pipeline(struct media_source *source)
{
unsigned int i;
wg_parser_begin_flush(source->wg_parser);
for (i = 0; i < source->stream_count; i++)
{
struct media_stream *stream = source->streams[i];
@ -543,8 +540,7 @@ static void wait_on_sample(struct media_stream *stream, IUnknown *token)
for (;;)
{
if (!wg_parser_stream_get_event(stream->wg_stream, &event))
return;
wg_parser_stream_get_event(stream->wg_stream, &event);
TRACE("Got event of type %#x.\n", event.type);

View File

@ -833,11 +833,7 @@ static DWORD CALLBACK stream_thread(void *arg)
continue;
}
if (!wg_parser_stream_get_event(pin->wg_stream, &event))
{
LeaveCriticalSection(&pin->flushing_cs);
continue;
}
wg_parser_stream_get_event(pin->wg_stream, &event);
TRACE("Got event of type %#x.\n", event.type);
@ -971,7 +967,6 @@ static HRESULT parser_init_stream(struct strmbase_filter *iface)
return S_OK;
filter->streaming = true;
wg_parser_end_flush(filter->wg_parser);
/* DirectShow retains the old seek positions, but resets to them every time
* it transitions from stopped -> paused. */
@ -1011,7 +1006,6 @@ static HRESULT parser_cleanup_stream(struct strmbase_filter *iface)
return S_OK;
filter->streaming = false;
wg_parser_begin_flush(filter->wg_parser);
for (i = 0; i < filter->source_count; ++i)
{
@ -1336,8 +1330,6 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
if (!(current_flags & AM_SEEKING_NoFlush))
{
wg_parser_begin_flush(filter->wg_parser);
for (i = 0; i < filter->source_count; ++i)
{
if (filter->sources[i]->pin.pin.peer)
@ -1365,8 +1357,6 @@ static HRESULT WINAPI GST_Seeking_SetPositions(IMediaSeeking *iface,
if (!(current_flags & AM_SEEKING_NoFlush))
{
wg_parser_end_flush(filter->wg_parser);
for (i = 0; i < filter->source_count; ++i)
{
struct parser_source *flush_pin = filter->sources[i];

View File

@ -238,9 +238,6 @@ enum unix_funcs
unix_wg_parser_connect,
unix_wg_parser_disconnect,
unix_wg_parser_begin_flush,
unix_wg_parser_end_flush,
unix_wg_parser_get_next_read_offset,
unix_wg_parser_push_data,

View File

@ -87,7 +87,7 @@ struct wg_parser
GstFlowReturn ret;
} read_request;
bool flushing, sink_connected;
bool sink_connected;
bool unlimited_buffering;
};
@ -127,35 +127,6 @@ static NTSTATUS wg_parser_get_stream(void *args)
return S_OK;
}
static NTSTATUS wg_parser_begin_flush(void *args)
{
struct wg_parser *parser = args;
unsigned int i;
pthread_mutex_lock(&parser->mutex);
parser->flushing = true;
pthread_mutex_unlock(&parser->mutex);
for (i = 0; i < parser->stream_count; ++i)
{
if (parser->streams[i]->enabled)
pthread_cond_signal(&parser->streams[i]->event_cond);
}
return S_OK;
}
static NTSTATUS wg_parser_end_flush(void *args)
{
struct wg_parser *parser = args;
pthread_mutex_lock(&parser->mutex);
parser->flushing = false;
pthread_mutex_unlock(&parser->mutex);
return S_OK;
}
static NTSTATUS wg_parser_get_next_read_offset(void *args)
{
struct wg_parser_get_next_read_offset_params *params = args;
@ -288,16 +259,9 @@ static NTSTATUS wg_parser_stream_get_event(void *args)
pthread_mutex_lock(&parser->mutex);
while (!parser->flushing && stream->event.type == WG_PARSER_EVENT_NONE)
while (stream->event.type == WG_PARSER_EVENT_NONE)
pthread_cond_wait(&stream->event_cond, &parser->mutex);
if (parser->flushing)
{
pthread_mutex_unlock(&parser->mutex);
GST_DEBUG("Filter is flushing.\n");
return VFW_E_WRONG_STATE;
}
*params->event = stream->event;
if (stream->event.type != WG_PARSER_EVENT_BUFFER)
@ -1593,7 +1557,6 @@ static NTSTATUS wg_parser_create(void *args)
pthread_cond_init(&parser->init_cond, NULL);
pthread_cond_init(&parser->read_cond, NULL);
pthread_cond_init(&parser->read_done_cond, NULL);
parser->flushing = true;
parser->init_gst = init_funcs[params->type];
parser->unlimited_buffering = params->unlimited_buffering;
@ -1630,9 +1593,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_parser_connect),
X(wg_parser_disconnect),
X(wg_parser_begin_flush),
X(wg_parser_end_flush),
X(wg_parser_get_next_read_offset),
X(wg_parser_push_data),

View File

@ -1512,7 +1512,6 @@ static HRESULT init_stream(struct wm_reader *reader, QWORD file_size)
wg_parser_stream_enable(stream->wg_stream, &stream->format);
}
wg_parser_end_flush(reader->wg_parser);
/* We probably discarded events because streams weren't enabled yet.
* Now that they're all enabled seek back to the start again. */
wg_parser_stream_seek(reader->streams[0].wg_stream, 1.0, 0, 0,
@ -1836,11 +1835,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
for (;;)
{
if (!wg_parser_stream_get_event(wg_stream, &event))
{
FIXME("Stream is flushing.\n");
return E_NOTIMPL;
}
wg_parser_stream_get_event(wg_stream, &event);
TRACE("Got event of type %#x for %s stream %p.\n", event.type,
get_major_type_string(stream->format.major_type), stream);