diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 9e5de174984..3b477ba254a 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -159,7 +159,7 @@ enum wg_parser_type struct unix_funcs { - struct wg_parser *(CDECL *wg_parser_create)(enum wg_parser_type type); + struct wg_parser *(CDECL *wg_parser_create)(enum wg_parser_type type, bool unlimited_buffering); void (CDECL *wg_parser_destroy)(struct wg_parser *parser); HRESULT (CDECL *wg_parser_connect)(struct wg_parser *parser, uint64_t file_size); @@ -173,8 +173,6 @@ struct unix_funcs void (CDECL *wg_parser_push_data)(struct wg_parser *parser, const void *data, uint32_t size); - void (CDECL *wg_parser_set_unlimited_buffering)(struct wg_parser *parser); - uint32_t (CDECL *wg_parser_get_stream_count)(struct wg_parser *parser); struct wg_parser_stream *(CDECL *wg_parser_get_stream)(struct wg_parser *parser, uint32_t index); diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index e1e6cdbceb1..18bffca1362 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1421,7 +1421,13 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (FAILED(hr = MFAllocateWorkQueue(&object->async_commands_queue))) goto fail; - if (!(parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN))) + /* In Media Foundation, sources may read from any media source stream + * without fear of blocking due to buffering limits on another. Trailmakers, + * a Unity3D Engine game, only reads one sample from the audio stream (and + * never deselects it). Remove buffering limits from decodebin in order to + * account for this. Note that this does leak memory, but the same memory + * leak occurs with native. */ + if (!(parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN, true))) { hr = E_OUTOFMEMORY; goto fail; @@ -1435,14 +1441,6 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (FAILED(hr = unix_funcs->wg_parser_connect(parser, file_size))) goto fail; - /* In Media Foundation, sources may read from any media source stream - * without fear of blocking due to buffering limits on another. Trailmakers, - * a Unity3D Engine game, only reads one sample from the audio stream (and - * never deselects it). Remove buffering limits from decodebin in order to - * account for this. Note that this does leak memory, but the same memory - * leak occurs with native. */ - unix_funcs->wg_parser_set_unlimited_buffering(parser); - stream_count = unix_funcs->wg_parser_get_stream_count(parser); if (!(object->streams = calloc(stream_count, sizeof(*object->streams)))) diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index f532b8969de..a1fa7daec6f 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -1115,7 +1115,7 @@ HRESULT decodebin_parser_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN))) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN, false))) { free(object); return E_OUTOFMEMORY; @@ -1646,7 +1646,7 @@ HRESULT wave_parser_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_WAVPARSE))) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_WAVPARSE, false))) { free(object); return E_OUTOFMEMORY; @@ -1732,7 +1732,7 @@ HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_AVIDEMUX))) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_AVIDEMUX, false))) { free(object); return E_OUTOFMEMORY; @@ -1839,7 +1839,7 @@ HRESULT mpeg_splitter_create(IUnknown *outer, IUnknown **out) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_MPEGAUDIOPARSE))) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_MPEGAUDIOPARSE, false))) { free(object); return E_OUTOFMEMORY; diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index f27ad84df17..21278682318 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -83,6 +83,8 @@ struct wg_parser } read_request; bool flushing, sink_connected; + + bool unlimited_buffering; }; struct wg_parser_stream @@ -561,13 +563,6 @@ static void CDECL wg_parser_push_data(struct wg_parser *parser, pthread_cond_signal(&parser->read_done_cond); } -static void CDECL wg_parser_set_unlimited_buffering(struct wg_parser *parser) -{ - g_object_set(parser->decodebin, "max-size-buffers", G_MAXUINT, NULL); - g_object_set(parser->decodebin, "max-size-time", G_MAXUINT64, NULL); - g_object_set(parser->decodebin, "max-size-bytes", G_MAXUINT, NULL); -} - static void CDECL wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, struct wg_format *format) { *format = stream->preferred_format; @@ -1728,6 +1723,13 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser) gst_bin_add(GST_BIN(parser->container), element); parser->decodebin = element; + if (parser->unlimited_buffering) + { + g_object_set(parser->decodebin, "max-size-buffers", G_MAXUINT, NULL); + g_object_set(parser->decodebin, "max-size-time", G_MAXUINT64, NULL); + g_object_set(parser->decodebin, "max-size-bytes", G_MAXUINT, NULL); + } + g_signal_connect(element, "pad-added", G_CALLBACK(pad_added_cb), parser); g_signal_connect(element, "pad-removed", G_CALLBACK(pad_removed_cb), parser); g_signal_connect(element, "autoplug-select", G_CALLBACK(autoplug_select_cb), parser); @@ -1868,7 +1870,7 @@ static void init_gstreamer_once(void) gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); } -static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type) +static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type, bool unlimited_buffering) { static const init_gst_cb init_funcs[] = { @@ -1893,6 +1895,7 @@ static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type) pthread_cond_init(&parser->read_done_cond, NULL); parser->flushing = true; parser->init_gst = init_funcs[type]; + parser->unlimited_buffering = unlimited_buffering; GST_DEBUG("Created winegstreamer parser %p.\n", parser); return parser; @@ -1928,8 +1931,6 @@ static const struct unix_funcs funcs = wg_parser_get_next_read_offset, wg_parser_push_data, - wg_parser_set_unlimited_buffering, - wg_parser_get_stream_count, wg_parser_get_stream,