From 2df0b96008edded542b60dbeb3803d16c3a1ca30 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Bernon?= Date: Wed, 15 Mar 2023 10:11:13 +0100 Subject: [PATCH] winegstreamer: Introduce a new wg_init_gstreamer unixlib entry. --- dlls/winegstreamer/Makefile.in | 1 + dlls/winegstreamer/main.c | 3 ++ dlls/winegstreamer/quartz_parser.c | 3 -- dlls/winegstreamer/unix_private.h | 16 ++++++++- dlls/winegstreamer/unixlib.c | 71 ++++++++++++++++++++++++++++++++++++++ dlls/winegstreamer/unixlib.h | 2 ++ dlls/winegstreamer/wg_allocator.c | 3 -- dlls/winegstreamer/wg_format.c | 3 -- dlls/winegstreamer/wg_parser.c | 42 ++-------------------- dlls/winegstreamer/wg_transform.c | 6 ---- dlls/winegstreamer/wm_reader.c | 3 ++ 11 files changed, 97 insertions(+), 56 deletions(-) create mode 100644 dlls/winegstreamer/unixlib.c diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index ae6420bad84..1c701bfa9f6 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -16,6 +16,7 @@ C_SRCS = \ quartz_parser.c \ quartz_transform.c \ resampler.c \ + unixlib.c \ video_decoder.c \ video_processor.c \ wg_allocator.c \ diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index ce59baaab3b..1e54edb2015 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -616,6 +616,9 @@ static BOOL CALLBACK init_gstreamer_proc(INIT_ONCE *once, void *param, void **ct { HINSTANCE handle; + if (WINE_UNIX_CALL(unix_wg_init_gstreamer, NULL)) + return FALSE; + /* Unloading glib is a bad idea.. it installs atexit handlers, * so never unload the dll after loading */ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index a5eb939fcbb..590ef48fef4 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -1392,9 +1392,6 @@ static HRESULT parser_create(enum wg_parser_type type, struct parser **parser) { struct parser *object; - if (!init_gstreamer()) - return E_FAIL; - if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index ce67134af16..7ae3002ac0b 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -25,13 +25,25 @@ #include -extern bool init_gstreamer(void) DECLSPEC_HIDDEN; +/* unixlib.c */ + +GST_DEBUG_CATEGORY_EXTERN(wine) DECLSPEC_HIDDEN; +#define GST_CAT_DEFAULT wine + +extern NTSTATUS wg_init_gstreamer(void *args) DECLSPEC_HIDDEN; + +/* wg_parser.c */ + extern GstElement *create_element(const char *name, const char *plugin_set) DECLSPEC_HIDDEN; +/* wg_format.c */ + extern void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) DECLSPEC_HIDDEN; extern bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) DECLSPEC_HIDDEN; extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDEN; +/* wg_transform.c */ + extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_set_output_format(void *args) DECLSPEC_HIDDEN; @@ -39,6 +51,8 @@ extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_get_status(void *args) DECLSPEC_HIDDEN; +/* wg_allocator.c */ + /* wg_allocator_release_sample can be used to release any sample that was requested. */ typedef struct wg_sample *(*wg_allocator_request_sample_cb)(gsize size, void *context); extern GstAllocator *wg_allocator_create(wg_allocator_request_sample_cb request_sample, diff --git a/dlls/winegstreamer/unixlib.c b/dlls/winegstreamer/unixlib.c new file mode 100644 index 00000000000..a1799f8043d --- /dev/null +++ b/dlls/winegstreamer/unixlib.c @@ -0,0 +1,71 @@ +/* + * winegstreamer Unix library interface + * + * Copyright 2020-2021 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" +#include "dshow.h" + +#include "unix_private.h" + +/* 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 + * any use of Wine debug logging in this entire file. */ + +GST_DEBUG_CATEGORY(wine); + +NTSTATUS wg_init_gstreamer(void *arg) +{ + 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", 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.", + gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); + return STATUS_SUCCESS; +} diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index d7bc7c65f0d..a01efb934f8 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -335,6 +335,8 @@ struct wg_transform_get_status_params enum unix_funcs { + unix_wg_init_gstreamer, + unix_wg_parser_create, unix_wg_parser_destroy, diff --git a/dlls/winegstreamer/wg_allocator.c b/dlls/winegstreamer/wg_allocator.c index 784677e2b2d..14550ad8bcc 100644 --- a/dlls/winegstreamer/wg_allocator.c +++ b/dlls/winegstreamer/wg_allocator.c @@ -35,9 +35,6 @@ #include "wine/list.h" -GST_DEBUG_CATEGORY_EXTERN(wine); -#define GST_CAT_DEFAULT wine - typedef struct { GstMemory parent; diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index ac21b0af94f..6317a69edee 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -40,9 +40,6 @@ #include "unix_private.h" -GST_DEBUG_CATEGORY_EXTERN(wine); -#define GST_CAT_DEFAULT wine - static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format) { switch (format) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index a8da149e7be..f371fc3b336 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -49,14 +49,6 @@ typedef enum 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 - * any use of Wine debug logging in this entire file. */ - -GST_DEBUG_CATEGORY(wine); -#define GST_CAT_DEFAULT wine - typedef BOOL (*init_gst_cb)(struct wg_parser *parser); struct wg_parser @@ -1680,35 +1672,6 @@ 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", 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.", - gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); -} - -bool init_gstreamer(void) -{ - static pthread_once_t init_once = PTHREAD_ONCE_INIT; - - return !pthread_once(&init_once, init_gstreamer_once); -} - static NTSTATUS wg_parser_create(void *args) { static const init_gst_cb init_funcs[] = @@ -1722,9 +1685,6 @@ static NTSTATUS wg_parser_create(void *args) struct wg_parser_create_params *params = args; struct wg_parser *parser; - if (!init_gstreamer()) - return E_FAIL; - if (!(parser = calloc(1, sizeof(*parser)))) return E_OUTOFMEMORY; @@ -1763,6 +1723,8 @@ static NTSTATUS wg_parser_destroy(void *args) const unixlib_entry_t __wine_unix_call_funcs[] = { #define X(name) [unix_ ## name] = name + X(wg_init_gstreamer), + X(wg_parser_create), X(wg_parser_destroy), diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index ccdd90361fc..ca89c883f62 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -39,9 +39,6 @@ #include "unix_private.h" -GST_DEBUG_CATEGORY_EXTERN(wine); -#define GST_CAT_DEFAULT wine - #define GST_SAMPLE_FLAG_WG_CAPS_CHANGED (GST_MINI_OBJECT_FLAG_LAST << 0) struct wg_transform @@ -360,9 +357,6 @@ NTSTATUS wg_transform_create(void *args) const gchar *media_type; GstEvent *event; - if (!init_gstreamer()) - return STATUS_UNSUCCESSFUL; - if (!(transform = calloc(1, sizeof(*transform)))) return STATUS_NO_MEMORY; if (!(transform->container = gst_bin_new("wg_transform"))) diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 2e0badba5db..764774d505b 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -2541,6 +2541,9 @@ HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out) TRACE("out %p.\n", out); + if (!init_gstreamer()) + return E_FAIL; + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; -- 2.11.4.GIT