The default behaviour for gstreamer is to use the URI to create the stream-id. Without this, gstreamer creates a random stream-id per pad which can cause inconsistent ordering on the decodebin src pads.
This in turn can cause issues, for example, with audio stream selection.
The first commit is a partial cherry-pick of eda34f74c6ad from Proton.
From: Brendan McGrath bmcgrath@codeweavers.com
This is a partial cherry-pick of eda34f74c6ad from Proton. --- dlls/winegstreamer/gst_private.h | 2 +- dlls/winegstreamer/main.c | 3 ++- dlls/winegstreamer/media_source.c | 2 +- dlls/winegstreamer/quartz_parser.c | 2 +- dlls/winegstreamer/unixlib.h | 1 + dlls/winegstreamer/wg_parser.c | 12 ++++++++++++ dlls/winegstreamer/wm_reader.c | 4 ++-- 7 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index e03c779f750..4bdef90e045 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -52,7 +52,7 @@ void wg_sample_queue_flush(struct wg_sample_queue *queue, bool all); wg_parser_t wg_parser_create(bool output_compressed); void wg_parser_destroy(wg_parser_t parser);
-HRESULT wg_parser_connect(wg_parser_t parser, uint64_t file_size); +HRESULT wg_parser_connect(wg_parser_t parser, uint64_t file_size, const WCHAR *uri); void wg_parser_disconnect(wg_parser_t parser);
bool wg_parser_get_next_read_offset(wg_parser_t parser, uint64_t *offset, uint32_t *size); diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 671d011424e..dc948be3883 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -94,12 +94,13 @@ void wg_parser_destroy(wg_parser_t parser) WINE_UNIX_CALL(unix_wg_parser_destroy, &parser); }
-HRESULT wg_parser_connect(wg_parser_t parser, uint64_t file_size) +HRESULT wg_parser_connect(wg_parser_t parser, uint64_t file_size, const WCHAR *uri) { struct wg_parser_connect_params params = { .parser = parser, .file_size = file_size, + .uri = uri, };
TRACE("parser %#I64x, file_size %I64u.\n", parser, file_size); diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 8acfa75f335..d4b7e9a0051 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1654,7 +1654,7 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc
object->state = SOURCE_OPENING;
- if (FAILED(hr = wg_parser_connect(parser, object->file_size))) + if (FAILED(hr = wg_parser_connect(parser, object->file_size, context->url))) goto fail;
stream_count = wg_parser_get_stream_count(parser); diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 9b17b0afddd..bad86d7d017 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -1527,7 +1527,7 @@ static HRESULT parser_sink_connect(struct strmbase_sink *iface, IPin *peer, cons filter->sink_connected = true; filter->read_thread = CreateThread(NULL, 0, read_thread, filter, 0, NULL);
- if (FAILED(hr = wg_parser_connect(filter->wg_parser, file_size))) + if (FAILED(hr = wg_parser_connect(filter->wg_parser, file_size, NULL))) goto err;
if (!filter->init_gst(filter)) diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index d77a0346d46..2758be1da6b 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -220,6 +220,7 @@ struct wg_parser_create_params struct wg_parser_connect_params { wg_parser_t parser; + const WCHAR *uri; UINT64 file_size; };
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 31538624ef6..db16971cd4f 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -70,6 +70,7 @@ struct wg_parser
guint64 file_size, start_offset, next_offset, stop_offset; guint64 next_pull_offset; + gchar *uri;
pthread_t push_thread;
@@ -1548,11 +1549,21 @@ static NTSTATUS wg_parser_connect(void *args) GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); const struct wg_parser_connect_params *params = args; struct wg_parser *parser = get_parser(params->parser); + const WCHAR *uri = params->uri; unsigned int i; int ret;
parser->file_size = params->file_size; parser->sink_connected = true; + if (uri) + { + parser->uri = malloc(wcslen(uri) * 3 + 1); + ntdll_wcstoumbs(uri, wcslen(uri) + 1, parser->uri, wcslen(uri) * 3 + 1, FALSE); + } + else + { + parser->uri = NULL; + }
if (!parser->bus) { @@ -1818,6 +1829,7 @@ static NTSTATUS wg_parser_destroy(void *args) pthread_cond_destroy(&parser->read_cond); pthread_cond_destroy(&parser->read_done_cond);
+ free(parser->uri); free(parser); return S_OK; } diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 0cf0dd0ac9f..1eb9d2a245f 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -1464,7 +1464,7 @@ static HRESULT init_stream(struct wm_reader *reader) goto out_destroy_parser; }
- if (FAILED(hr = wg_parser_connect(reader->wg_parser, reader->file_size))) + if (FAILED(hr = wg_parser_connect(reader->wg_parser, reader->file_size, NULL))) { ERR("Failed to connect parser, hr %#lx.\n", hr); goto out_shutdown_thread; @@ -1569,7 +1569,7 @@ static HRESULT reinit_stream(struct wm_reader *reader, bool read_compressed) goto out_destroy_parser; }
- if (FAILED(hr = wg_parser_connect(reader->wg_parser, reader->file_size))) + if (FAILED(hr = wg_parser_connect(reader->wg_parser, reader->file_size, NULL))) { ERR("Failed to connect parser, hr %#lx.\n", hr); goto out_shutdown_thread;
From: Brendan McGrath bmcgrath@codeweavers.com
The default behaviour for gstreamer is to use the URI to create the stream-id. Without this, gstreamer creates a random stream-id per pad which can cause inconsistent ordering on the decodebin src pads.
This in turn can cause issues, for example, with audio stream selection. --- dlls/winegstreamer/wg_parser.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index db16971cd4f..679500b617e 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1244,6 +1244,15 @@ static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) gst_query_add_scheduling_mode(query, GST_PAD_MODE_PULL); return TRUE;
+ case GST_QUERY_URI: + if (parser->uri) + { + GST_LOG_OBJECT(pad, "Responding with %" GST_PTR_FORMAT, query); + gst_query_set_uri(query, parser->uri); + return TRUE; + } + return FALSE; + default: GST_WARNING("Unhandled query type %s.", GST_QUERY_TYPE_NAME(query)); return FALSE;
Another benefit, mentioned in 3606, is that this speeds up media type resolution by providing more of a hint to typefind.
This merge request was approved by Elizabeth Figura.