Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 7 ------- dlls/winegstreamer/wg_parser.c | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 49e06b31369..923bba25d38 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -36,13 +36,6 @@ #include "wine/debug.h" #include "wine/strmbase.h"
-typedef enum -{ - GST_AUTOPLUG_SELECT_TRY, - GST_AUTOPLUG_SELECT_EXPOSE, - GST_AUTOPLUG_SELECT_SKIP, -} GstAutoplugSelectResult; - static inline const char *debugstr_time(REFERENCE_TIME time) { ULONGLONG abstime = time >= 0 ? time : -time; diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index f0815e37689..dde137ef186 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -34,6 +34,13 @@ #include <gst/video/video.h> #include <gst/audio/audio.h>
+typedef enum +{ + GST_AUTOPLUG_SELECT_TRY, + GST_AUTOPLUG_SELECT_EXPOSE, + GST_AUTOPLUG_SELECT_SKIP, +} GstAutoplugSelectResult; + /* GStreamer callbacks may be called on threads not created by Wine, and * therefore cannot access the Wine TEB. This means that we must use GStreamer * debug logging instead of Wine debug logging. In order to be safe we forbid
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 13 ++++--- dlls/winegstreamer/media_source.c | 2 +- dlls/winegstreamer/quartz_parser.c | 8 ++--- dlls/winegstreamer/wg_parser.c | 56 ++++++++---------------------- 4 files changed, 28 insertions(+), 51 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 923bba25d38..9e5de174984 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -149,12 +149,17 @@ struct wg_parser_event }; C_ASSERT(sizeof(struct wg_parser_event) == 40);
+enum wg_parser_type +{ + WG_PARSER_DECODEBIN, + WG_PARSER_AVIDEMUX, + WG_PARSER_MPEGAUDIOPARSE, + WG_PARSER_WAVPARSE, +}; + struct unix_funcs { - struct wg_parser *(CDECL *wg_decodebin_parser_create)(void); - struct wg_parser *(CDECL *wg_avi_parser_create)(void); - struct wg_parser *(CDECL *wg_mpeg_audio_parser_create)(void); - struct wg_parser *(CDECL *wg_wave_parser_create)(void); + struct wg_parser *(CDECL *wg_parser_create)(enum wg_parser_type type); void (CDECL *wg_parser_destroy)(struct wg_parser *parser);
HRESULT (CDECL *wg_parser_connect)(struct wg_parser *parser, uint64_t file_size); diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 12ca14ca139..e1e6cdbceb1 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1421,7 +1421,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ if (FAILED(hr = MFAllocateWorkQueue(&object->async_commands_queue))) goto fail;
- if (!(parser = unix_funcs->wg_decodebin_parser_create())) + if (!(parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN))) { hr = E_OUTOFMEMORY; goto fail; diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index a8e7e3d979f..f532b8969de 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_decodebin_parser_create())) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_DECODEBIN))) { 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_wave_parser_create())) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_WAVPARSE))) { 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_avi_parser_create())) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_AVIDEMUX))) { 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_mpeg_audio_parser_create())) + if (!(object->wg_parser = unix_funcs->wg_parser_create(WG_PARSER_MPEGAUDIOPARSE))) { free(object); return E_OUTOFMEMORY; diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index dde137ef186..e1127b9a059 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -49,9 +49,11 @@ typedef enum GST_DEBUG_CATEGORY_STATIC(wine); #define GST_CAT_DEFAULT wine
+typedef BOOL (*init_gst_cb)(struct wg_parser *parser); + struct wg_parser { - BOOL (*init_gst)(struct wg_parser *parser); + init_gst_cb init_gst;
struct wg_parser_stream **streams; unsigned int stream_count; @@ -1844,8 +1846,16 @@ static BOOL wave_parser_init_gst(struct wg_parser *parser) return TRUE; }
-static struct wg_parser *wg_parser_create(void) +static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type) { + static const init_gst_cb init_funcs[] = + { + [WG_PARSER_DECODEBIN] = decodebin_parser_init_gst, + [WG_PARSER_AVIDEMUX] = avi_parser_init_gst, + [WG_PARSER_MPEGAUDIOPARSE] = mpeg_audio_parser_init_gst, + [WG_PARSER_WAVPARSE] = wave_parser_init_gst, + }; + struct wg_parser *parser;
if (!(parser = calloc(1, sizeof(*parser)))) @@ -1856,47 +1866,12 @@ static struct wg_parser *wg_parser_create(void) pthread_cond_init(&parser->read_cond, NULL); pthread_cond_init(&parser->read_done_cond, NULL); parser->flushing = true; + parser->init_gst = init_funcs[type];
GST_DEBUG("Created winegstreamer parser %p.\n", parser); return parser; }
-static struct wg_parser * CDECL wg_decodebin_parser_create(void) -{ - struct wg_parser *parser; - - if ((parser = wg_parser_create())) - parser->init_gst = decodebin_parser_init_gst; - return parser; -} - -static struct wg_parser * CDECL wg_avi_parser_create(void) -{ - struct wg_parser *parser; - - if ((parser = wg_parser_create())) - parser->init_gst = avi_parser_init_gst; - return parser; -} - -static struct wg_parser * CDECL wg_mpeg_audio_parser_create(void) -{ - struct wg_parser *parser; - - if ((parser = wg_parser_create())) - parser->init_gst = mpeg_audio_parser_init_gst; - return parser; -} - -static struct wg_parser * CDECL wg_wave_parser_create(void) -{ - struct wg_parser *parser; - - if ((parser = wg_parser_create())) - parser->init_gst = wave_parser_init_gst; - return parser; -} - static void CDECL wg_parser_destroy(struct wg_parser *parser) { if (parser->bus) @@ -1915,10 +1890,7 @@ static void CDECL wg_parser_destroy(struct wg_parser *parser)
static const struct unix_funcs funcs = { - wg_decodebin_parser_create, - wg_avi_parser_create, - wg_mpeg_audio_parser_create, - wg_wave_parser_create, + wg_parser_create, wg_parser_destroy,
wg_parser_connect,
This alleviates bug 51086.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/wg_parser.c | 47 +++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index e1127b9a059..f27ad84df17 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1846,6 +1846,28 @@ static BOOL wave_parser_init_gst(struct wg_parser *parser) return TRUE; }
+static void init_gstreamer_once(void) +{ + char arg0[] = "wine"; + char arg1[] = "--gst-disable-registry-fork"; + char *args[] = {arg0, arg1, NULL}; + int argc = ARRAY_SIZE(args) - 1; + char **argv = args; + GError *err; + + if (!gst_init_check(&argc, &argv, &err)) + { + fprintf(stderr, "winegstreamer: failed to initialize GStreamer: %s\n", debugstr_a(err->message)); + g_error_free(err); + return; + } + + GST_DEBUG_CATEGORY_INIT(wine, "WINE", GST_DEBUG_FG_RED, "Wine GStreamer support"); + + GST_INFO("GStreamer library version %s; wine built with %d.%d.%d.\n", + 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 const init_gst_cb init_funcs[] = @@ -1856,8 +1878,12 @@ static struct wg_parser * CDECL wg_parser_create(enum wg_parser_type type) [WG_PARSER_WAVPARSE] = wave_parser_init_gst, };
+ static pthread_once_t once = PTHREAD_ONCE_INIT; struct wg_parser *parser;
+ if (pthread_once(&once, init_gstreamer_once)) + return NULL; + if (!(parser = calloc(1, sizeof(*parser)))) return NULL;
@@ -1923,27 +1949,6 @@ static const struct unix_funcs funcs = NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out) { if (reason == DLL_PROCESS_ATTACH) - { - char arg0[] = "wine"; - char arg1[] = "--gst-disable-registry-fork"; - char *args[] = {arg0, arg1, NULL}; - int argc = ARRAY_SIZE(args) - 1; - char **argv = args; - GError *err; - - if (!gst_init_check(&argc, &argv, &err)) - { - fprintf(stderr, "winegstreamer: failed to initialize GStreamer: %s\n", debugstr_a(err->message)); - g_error_free(err); - return STATUS_UNSUCCESSFUL; - } - - GST_DEBUG_CATEGORY_INIT(wine, "WINE", GST_DEBUG_FG_RED, "Wine GStreamer support"); - - GST_INFO("GStreamer library version %s; wine built with %d.%d.%d.\n", - gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); - *(const struct unix_funcs **)ptr_out = &funcs; - } return STATUS_SUCCESS; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 4 +--- dlls/winegstreamer/media_source.c | 16 +++++++--------- dlls/winegstreamer/quartz_parser.c | 8 ++++---- dlls/winegstreamer/wg_parser.c | 21 +++++++++++---------- 4 files changed, 23 insertions(+), 26 deletions(-)
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,
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 3b477ba254a..3470f7870fa 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -203,8 +203,6 @@ HRESULT wave_parser_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
-void start_dispatch_thread(void) DECLSPEC_HIDDEN; - extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN; extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN;