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:
parent
7da1828c49
commit
5144b27661
|
@ -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);
|
||||
|
|
|
@ -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, ¶ms);
|
||||
__wine_unix_call(unix_handle, unix_wg_parser_stream_get_event, ¶ms);
|
||||
}
|
||||
|
||||
bool wg_parser_stream_copy_buffer(struct wg_parser_stream *stream,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue