Rémi Bernon : winegstreamer: Introduce new wg_transform struct.
Alexandre Julliard
julliard at winehq.org
Thu Feb 17 15:33:57 CST 2022
Module: wine
Branch: master
Commit: 51a262d368afca3ec1edf50a850dbd5339194280
URL: https://source.winehq.org/git/wine.git/?a=commit;h=51a262d368afca3ec1edf50a850dbd5339194280
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Wed Feb 16 12:19:08 2022 +0100
winegstreamer: Introduce new wg_transform struct.
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>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winegstreamer/Makefile.in | 1 +
dlls/winegstreamer/gst_private.h | 3 ++
dlls/winegstreamer/main.c | 14 +++++++
dlls/winegstreamer/unix_private.h | 5 +++
dlls/winegstreamer/unixlib.h | 8 ++++
dlls/winegstreamer/wg_parser.c | 13 +++++-
dlls/winegstreamer/wg_transform.c | 88 +++++++++++++++++++++++++++++++++++++++
dlls/winegstreamer/wma_decoder.c | 11 +++++
8 files changed, 141 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index d9805e3d797..0bcdb3eec65 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -14,6 +14,7 @@ C_SRCS = \
quartz_parser.c \
wg_format.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 3584f465218..8bc9f838d29 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);
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);
+struct wg_transform *wg_transform_create(void);
+void wg_transform_destroy(struct wg_transform *transform);
+
unsigned int wg_format_get_max_size(const struct wg_format *format);
HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out);
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
index b483638403d..f9c4da2f6ea 100644
--- a/dlls/winegstreamer/unix_private.h
+++ b/dlls/winegstreamer/unix_private.h
@@ -25,8 +25,13 @@
#include <gst/gst.h>
+extern bool init_gstreamer(void) DECLSPEC_HIDDEN;
+
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;
+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 45ec606fc6a..8e3f5e84bfb 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -229,6 +229,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,
@@ -257,6 +262,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 a73685a2e69..5a2e970a4dd 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -1570,6 +1570,13 @@ 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;
+
+ return !pthread_once(&init_once, init_gstreamer_once);
+}
+
static NTSTATUS wg_parser_create(void *args)
{
static const init_gst_cb init_funcs[] =
@@ -1580,11 +1587,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))))
@@ -1651,4 +1657,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..2f225e5bc55
--- /dev/null
+++ b/dlls/winegstreamer/wg_transform.c
@@ -0,0 +1,88 @@
+/*
+ * 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 "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+#include "dshow.h"
+
+#include "unix_private.h"
+
+GST_DEBUG_CATEGORY_EXTERN(wine);
+#define GST_CAT_DEFAULT wine
+
+struct wg_transform
+{
+ int dummy;
+};
+
+NTSTATUS wg_transform_destroy(void *args)
+{
+ struct wg_transform *transform = args;
+
+ free(transform);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS wg_transform_create(void *args)
+{
+ struct wg_transform_create_params *params = args;
+ struct wg_transform *transform;
+ NTSTATUS status;
+
+ if (!init_gstreamer())
+ return STATUS_UNSUCCESSFUL;
+
+ status = STATUS_NO_MEMORY;
+
+ if (!(transform = calloc(1, sizeof(*transform))))
+ goto done;
+
+ status = STATUS_SUCCESS;
+
+done:
+ if (status)
+ {
+ GST_ERROR("Failed to create winegstreamer transform.");
+ if (transform)
+ wg_transform_destroy(transform);
+ }
+ else
+ {
+ GST_INFO("Created winegstreamer transform %p.", transform);
+ params->transform = transform;
+ }
+
+ return status;
+}
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 31f735a5b1d..b14261706a7 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)
@@ -64,6 +66,10 @@ static HRESULT try_create_wg_transform(struct wma_decoder *decoder)
{
struct wg_format input_format, output_format;
+ if (decoder->wg_transform)
+ wg_transform_destroy(decoder->wg_transform);
+ decoder->wg_transform = NULL;
+
mf_media_type_to_wg_format(decoder->input_type, &input_format);
if (input_format.major_type == WG_MAJOR_TYPE_UNKNOWN)
return MF_E_INVALIDMEDIATYPE;
@@ -72,6 +78,9 @@ static HRESULT try_create_wg_transform(struct wma_decoder *decoder)
if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN)
return MF_E_INVALIDMEDIATYPE;
+ if (!(decoder->wg_transform = wg_transform_create()))
+ return E_FAIL;
+
return S_OK;
}
@@ -119,6 +128,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)
More information about the wine-cvs
mailing list