[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, ¶ms);
}
+struct wg_transform *wg_transform_create(void)
+{
+ struct wg_transform_create_params params = {0};
+
+ if (__wine_unix_call(unix_handle, unix_wg_transform_create, ¶ms))
+ 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