[PATCH 3/3] winegstreamer: Create static pads on wg_transform struct.

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


With caps created from the input / output formats.

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>
---
 dlls/winegstreamer/gst_private.h  |  3 +-
 dlls/winegstreamer/main.c         |  9 ++-
 dlls/winegstreamer/unix_private.h |  1 +
 dlls/winegstreamer/unixlib.h      |  2 +
 dlls/winegstreamer/wg_parser.c    |  2 +-
 dlls/winegstreamer/wg_transform.c | 93 +++++++++++++++++++++++++++++++
 dlls/winegstreamer/wma_decoder.c  |  2 +-
 7 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index cec52e976ec..5d198f57dc7 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -96,7 +96,8 @@ 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;
+struct wg_transform *wg_transform_create(const struct wg_encoded_format *input_format,
+                const struct wg_format *output_format) DECLSPEC_HIDDEN;
 void wg_transform_destroy(struct wg_transform *transform) DECLSPEC_HIDDEN;
 
 unsigned int wg_format_get_max_size(const struct wg_format *format);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index f23fa3abcdf..6dfa9eb5c82 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -254,9 +254,14 @@ 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 *wg_transform_create(const struct wg_encoded_format *input_format,
+        const struct wg_format *output_format)
 {
-    struct wg_transform_create_params params = {0};
+    struct wg_transform_create_params params =
+    {
+        .input_format = input_format,
+        .output_format = output_format,
+    };
 
     if (__wine_unix_call(unix_handle, unix_wg_transform_create, &params))
         return NULL;
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h
index 375d33e7728..38349eb5e8d 100644
--- a/dlls/winegstreamer/unix_private.h
+++ b/dlls/winegstreamer/unix_private.h
@@ -24,6 +24,7 @@
 #include "unixlib.h"
 
 extern bool init_gstreamer(void) 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;
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index ea46de4cce1..96cda2e25aa 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -245,6 +245,8 @@ struct wg_parser_stream_seek_params
 struct wg_transform_create_params
 {
     struct wg_transform *transform;
+    const struct wg_encoded_format *input_format;
+    const struct wg_format *output_format;
 };
 
 enum unix_funcs
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index ac8c5a2b95c..e7e80ecfddf 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -463,7 +463,7 @@ static GstCaps *wg_format_to_caps_video(const struct wg_format *format)
     return caps;
 }
 
-static GstCaps *wg_format_to_caps(const struct wg_format *format)
+GstCaps *wg_format_to_caps(const struct wg_format *format)
 {
     switch (format->major_type)
     {
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index 822740da0d7..146cdd87ae7 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -42,12 +42,77 @@ GST_DEBUG_CATEGORY_EXTERN(wine);
 
 struct wg_transform
 {
+    GstPad *my_src, *my_sink;
 };
 
+static GstCaps *wg_format_to_caps_xwma(const struct wg_encoded_format *format)
+{
+    GstBuffer *buffer;
+    GstCaps *caps;
+
+    if (format->encoded_type == WG_ENCODED_TYPE_WMA)
+        caps = gst_caps_new_empty_simple("audio/x-wma");
+    else
+        caps = gst_caps_new_empty_simple("audio/x-xma");
+
+    if (format->u.xwma.version)
+        gst_caps_set_simple(caps, "wmaversion", G_TYPE_INT, format->u.xwma.version, NULL);
+    if (format->u.xwma.bitrate)
+        gst_caps_set_simple(caps, "bitrate", G_TYPE_INT, format->u.xwma.bitrate, NULL);
+    if (format->u.xwma.rate)
+        gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.xwma.rate, NULL);
+    if (format->u.xwma.depth)
+        gst_caps_set_simple(caps, "depth", G_TYPE_INT, format->u.xwma.depth, NULL);
+    if (format->u.xwma.channels)
+        gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.xwma.channels, NULL);
+    if (format->u.xwma.block_align)
+        gst_caps_set_simple(caps, "block_align", G_TYPE_INT, format->u.xwma.block_align, NULL);
+
+    if (format->u.xwma.codec_data_len)
+    {
+        buffer = gst_buffer_new_and_alloc(format->u.xwma.codec_data_len);
+        gst_buffer_fill(buffer, 0, format->u.xwma.codec_data, format->u.xwma.codec_data_len);
+        gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL);
+        gst_buffer_unref(buffer);
+    }
+
+    return caps;
+}
+
+static GstCaps *wg_encoded_format_to_caps(const struct wg_encoded_format *format)
+{
+    switch (format->encoded_type)
+    {
+        case WG_ENCODED_TYPE_UNKNOWN:
+            return NULL;
+        case WG_ENCODED_TYPE_WMA:
+        case WG_ENCODED_TYPE_XMA:
+            return wg_format_to_caps_xwma(format);
+    }
+    assert(0);
+    return NULL;
+}
+
+static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer)
+{
+    struct wg_transform *transform = gst_pad_get_element_private(pad);
+
+    GST_INFO("transform %p, buffer %p.", transform, buffer);
+
+    gst_buffer_unref(buffer);
+
+    return GST_FLOW_OK;
+}
+
 NTSTATUS wg_transform_destroy(void *args)
 {
     struct wg_transform *transform = args;
 
+    if (transform->my_sink)
+        g_object_unref(transform->my_sink);
+    if (transform->my_src)
+        g_object_unref(transform->my_src);
+
     free(transform);
     return S_OK;
 }
@@ -55,7 +120,11 @@ NTSTATUS wg_transform_destroy(void *args)
 NTSTATUS wg_transform_create(void *args)
 {
     struct wg_transform_create_params *params = args;
+    struct wg_encoded_format input_format = *params->input_format;
+    struct wg_format output_format = *params->output_format;
+    GstCaps *src_caps, *sink_caps;
     struct wg_transform *transform;
+    GstPadTemplate *template;
 
     if (!init_gstreamer())
         return E_FAIL;
@@ -63,7 +132,31 @@ NTSTATUS wg_transform_create(void *args)
     if (!(transform = calloc(1, sizeof(*transform))))
         return E_OUTOFMEMORY;
 
+    src_caps = wg_encoded_format_to_caps(&input_format);
+    assert(src_caps);
+    sink_caps = wg_format_to_caps(&output_format);
+    assert(sink_caps);
+
+    template = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps);
+    assert(template);
+    transform->my_src = gst_pad_new_from_template(template, "src");
+    g_object_unref(template);
+    assert(transform->my_src);
+
+    template = gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps);
+    assert(template);
+    transform->my_sink = gst_pad_new_from_template(template, "sink");
+    g_object_unref(template);
+    assert(transform->my_sink);
+
+    gst_pad_set_element_private(transform->my_sink, transform);
+    gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_cb);
+
     GST_INFO("Created winegstreamer transform %p.", transform);
     params->transform = transform;
+
+    gst_caps_unref(src_caps);
+    gst_caps_unref(sink_caps);
+
     return S_OK;
 }
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index b037795fc78..4183df43fed 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -79,7 +79,7 @@ static HRESULT try_create_wg_transform(struct wma_decoder *decoder)
     if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN)
         return MF_E_INVALIDMEDIATYPE;
 
-    decoder->wg_transform = wg_transform_create();
+    decoder->wg_transform = wg_transform_create(&input_format, &output_format);
     if (decoder->wg_transform)
         return S_OK;
 
-- 
2.34.1




More information about the wine-devel mailing list