[PATCH 1/3] winegstreamer: Introduce new wg_transform struct.

Rémi Bernon rbernon at codeweavers.com
Fri Feb 11 03:36:19 CST 2022


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

This would serve a simpler purpose than the full-fledged wg_parser, and
be used by synchronous transforms only (at least there's no thread on
the Wine side), which simply work on the push then pull loop model.

The wg_transform name is chosen to be generic and possibly cover both
decoder and encoders (and possibly converters), but maybe it's better
to keep it specific for now and only design it for decoders. This would
simplify the format question in the next patch.

 dlls/winegstreamer/Makefile.in    |  1 +
 dlls/winegstreamer/gst_private.h  |  3 ++
 dlls/winegstreamer/main.c         | 14 +++++++
 dlls/winegstreamer/unix_private.h | 31 ++++++++++++++
 dlls/winegstreamer/unixlib.h      |  8 ++++
 dlls/winegstreamer/wg_parser.c    | 20 +++++++--
 dlls/winegstreamer/wg_transform.c | 69 +++++++++++++++++++++++++++++++
 dlls/winegstreamer/wma_decoder.c  | 20 +++++++++
 8 files changed, 162 insertions(+), 4 deletions(-)
 create mode 100644 dlls/winegstreamer/unix_private.h
 create mode 100644 dlls/winegstreamer/wg_transform.c

diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index c53e914e246..52295418f0f 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -13,6 +13,7 @@ C_SRCS = \
 	mfplat.c \
 	quartz_parser.c \
 	wg_parser.c \
+	wg_transform.c \
 	wm_asyncreader.c \
 	wm_reader.c \
 	wm_syncreader.c \
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 222bce3b2c7..df82b229143 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -96,6 +96,9 @@ uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream) DECLSPEC
 void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate,
         uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags) DECLSPEC_HIDDEN;
 
+struct wg_transform *wg_transform_create(void) DECLSPEC_HIDDEN;
+void wg_transform_destroy(struct wg_transform *transform) DECLSPEC_HIDDEN;
+
 unsigned int wg_format_get_max_size(const struct wg_format *format);
 
 HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 260dd208e2f..f23fa3abcdf 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -254,6 +254,20 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate,
     __wine_unix_call(unix_handle, unix_wg_parser_stream_seek, &params);
 }
 
+struct wg_transform *wg_transform_create(void)
+{
+    struct wg_transform_create_params params = {0};
+
+    if (__wine_unix_call(unix_handle, unix_wg_transform_create, &params))
+        return NULL;
+    return params.transform;
+}
+
+void wg_transform_destroy(struct wg_transform *transform)
+{
+    __wine_unix_call(unix_handle, unix_wg_transform_destroy, transform);
+}
+
 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
 {
     if (reason == DLL_PROCESS_ATTACH)
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h
new file mode 100644
index 00000000000..375d33e7728
--- /dev/null
+++ b/dlls/winegstreamer/unix_private.h
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+#ifndef __WINE_WINEGSTREAMER_UNIX_PRIVATE_H
+#define __WINE_WINEGSTREAMER_UNIX_PRIVATE_H
+
+#include "unixlib.h"
+
+extern bool init_gstreamer(void) DECLSPEC_HIDDEN;
+
+extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN;
+extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN;
+
+#endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index 82bb534b938..c8b98da3a64 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -217,6 +217,11 @@ struct wg_parser_stream_seek_params
     DWORD start_flags, stop_flags;
 };
 
+struct wg_transform_create_params
+{
+    struct wg_transform *transform;
+};
+
 enum unix_funcs
 {
     unix_wg_parser_create,
@@ -245,6 +250,9 @@ enum unix_funcs
 
     unix_wg_parser_stream_get_duration,
     unix_wg_parser_stream_seek,
+
+    unix_wg_transform_create,
+    unix_wg_transform_destroy,
 };
 
 #endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index 013566b25e9..ac8c5a2b95c 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -37,7 +37,7 @@
 #include "winternl.h"
 #include "dshow.h"
 
-#include "unixlib.h"
+#include "unix_private.h"
 
 typedef enum
 {
@@ -51,7 +51,7 @@ typedef enum
  * 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_STATIC(wine);
+GST_DEBUG_CATEGORY(wine);
 #define GST_CAT_DEFAULT wine
 
 typedef BOOL (*init_gst_cb)(struct wg_parser *parser);
@@ -1963,6 +1963,16 @@ static void init_gstreamer_once(void)
             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;
+
+    if (pthread_once(&init_once, init_gstreamer_once))
+        return false;
+
+    return true;
+}
+
 static NTSTATUS wg_parser_create(void *args)
 {
     static const init_gst_cb init_funcs[] =
@@ -1973,11 +1983,10 @@ static NTSTATUS wg_parser_create(void *args)
         [WG_PARSER_WAVPARSE] = wave_parser_init_gst,
     };
 
-    static pthread_once_t once = PTHREAD_ONCE_INIT;
     struct wg_parser_create_params *params = args;
     struct wg_parser *parser;
 
-    if (pthread_once(&once, init_gstreamer_once))
+    if (!init_gstreamer())
         return E_FAIL;
 
     if (!(parser = calloc(1, sizeof(*parser))))
@@ -2044,4 +2053,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
 
     X(wg_parser_stream_get_duration),
     X(wg_parser_stream_seek),
+
+    X(wg_transform_create),
+    X(wg_transform_destroy),
 };
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
new file mode 100644
index 00000000000..822740da0d7
--- /dev/null
+++ b/dlls/winegstreamer/wg_transform.c
@@ -0,0 +1,69 @@
+/*
+ * GStreamer transform backend
+ *
+ * Copyright 2022 Rémi Bernon 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 <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/audio/audio.h>
+
+#include "winternl.h"
+#include "dshow.h"
+
+#include "unix_private.h"
+
+GST_DEBUG_CATEGORY_EXTERN(wine);
+#define GST_CAT_DEFAULT wine
+
+struct wg_transform
+{
+};
+
+NTSTATUS wg_transform_destroy(void *args)
+{
+    struct wg_transform *transform = args;
+
+    free(transform);
+    return S_OK;
+}
+
+NTSTATUS wg_transform_create(void *args)
+{
+    struct wg_transform_create_params *params = args;
+    struct wg_transform *transform;
+
+    if (!init_gstreamer())
+        return E_FAIL;
+
+    if (!(transform = calloc(1, sizeof(*transform))))
+        return E_OUTOFMEMORY;
+
+    GST_INFO("Created winegstreamer transform %p.", transform);
+    params->transform = transform;
+    return S_OK;
+}
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 78316059052..3b051230a9e 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -53,6 +53,8 @@ struct wma_decoder
     LONG refcount;
     IMFMediaType *input_type;
     IMFMediaType *output_type;
+
+    struct wg_transform *wg_transform;
 };
 
 static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface)
@@ -60,6 +62,19 @@ static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface)
     return CONTAINING_RECORD(iface, struct wma_decoder, IUnknown_inner);
 }
 
+static HRESULT try_create_wg_transform(struct wma_decoder *decoder)
+{
+    if (decoder->wg_transform)
+        wg_transform_destroy(decoder->wg_transform);
+
+    decoder->wg_transform = wg_transform_create();
+    if (decoder->wg_transform)
+        return S_OK;
+
+    WARN("Failed to create wg_transform.\n");
+    return E_FAIL;
+}
+
 static HRESULT WINAPI unknown_QueryInterface(IUnknown *iface, REFIID iid, void **out)
 {
     struct wma_decoder *decoder = impl_from_IUnknown(iface);
@@ -104,6 +119,8 @@ static ULONG WINAPI unknown_Release(IUnknown *iface)
 
     if (!refcount)
     {
+        if (decoder->wg_transform)
+            wg_transform_destroy(decoder->wg_transform);
         if (decoder->input_type)
             IMFMediaType_Release(decoder->input_type);
         if (decoder->output_type)
@@ -438,6 +455,9 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
     if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)decoder->output_type)))
         goto failed;
 
+    if (FAILED(hr = try_create_wg_transform(decoder)))
+        goto failed;
+
     return S_OK;
 
 failed:
-- 
2.34.1




More information about the wine-devel mailing list