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

Rémi Bernon rbernon at codeweavers.com
Mon Feb 14 04:19:44 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>
---

v2: Move the format helpers to a dedicated source, use a separate major
    format in the wg_format struct for WMA format.

 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