[PATCH v2 4/4] winegstreamer: Create static pads on wg_transform struct.
Rémi Bernon
rbernon at codeweavers.com
Mon Feb 14 04:19:47 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/unixlib.h | 2 ++
dlls/winegstreamer/wg_format.c | 34 +++++++++++++++++++++--
dlls/winegstreamer/wg_transform.c | 45 +++++++++++++++++++++++++++++++
dlls/winegstreamer/wma_decoder.c | 2 +-
6 files changed, 89 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index df82b229143..c1fe34373ce 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_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..f85e9995525 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, ¶ms);
}
-struct wg_transform *wg_transform_create(void)
+struct wg_transform *wg_transform_create(const struct wg_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, ¶ms))
return NULL;
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index 8e3f5e84bfb..4adbb694766 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -232,6 +232,8 @@ struct wg_parser_stream_seek_params
struct wg_transform_create_params
{
struct wg_transform *transform;
+ const struct wg_format *input_format;
+ const struct wg_format *output_format;
};
enum unix_funcs
diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c
index 8f771bb8abd..9d3d7808180 100644
--- a/dlls/winegstreamer/wg_format.c
+++ b/dlls/winegstreamer/wg_format.c
@@ -394,6 +394,37 @@ static GstCaps *wg_format_to_caps_video(const struct wg_format *format)
return caps;
}
+static GstCaps *wg_format_to_caps_wma(const struct wg_format *format)
+{
+ GstBuffer *buffer;
+ GstCaps *caps;
+
+ caps = gst_caps_new_empty_simple("audio/x-wma");
+ if (format->u.wma.version)
+ gst_caps_set_simple(caps, "wmaversion", G_TYPE_INT, format->u.wma.version, NULL);
+
+ if (format->u.wma.bitrate)
+ gst_caps_set_simple(caps, "bitrate", G_TYPE_INT, format->u.wma.bitrate, NULL);
+ if (format->u.wma.rate)
+ gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.wma.rate, NULL);
+ if (format->u.wma.depth)
+ gst_caps_set_simple(caps, "depth", G_TYPE_INT, format->u.wma.depth, NULL);
+ if (format->u.wma.channels)
+ gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.wma.channels, NULL);
+ if (format->u.wma.block_align)
+ gst_caps_set_simple(caps, "block_align", G_TYPE_INT, format->u.wma.block_align, NULL);
+
+ if (format->u.wma.codec_data_len)
+ {
+ buffer = gst_buffer_new_and_alloc(format->u.wma.codec_data_len);
+ gst_buffer_fill(buffer, 0, format->u.wma.codec_data, format->u.wma.codec_data_len);
+ gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL);
+ gst_buffer_unref(buffer);
+ }
+
+ return caps;
+}
+
GstCaps *wg_format_to_caps(const struct wg_format *format)
{
switch (format->major_type)
@@ -401,8 +432,7 @@ GstCaps *wg_format_to_caps(const struct wg_format *format)
case WG_MAJOR_TYPE_UNKNOWN:
return NULL;
case WG_MAJOR_TYPE_WMA:
- GST_FIXME("WMA format not implemented!\n");
- return NULL;
+ return wg_format_to_caps_wma(format);
case WG_MAJOR_TYPE_AUDIO:
return wg_format_to_caps_audio(format);
case WG_MAJOR_TYPE_VIDEO:
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index 822740da0d7..5debac87e4c 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -42,12 +42,29 @@ GST_DEBUG_CATEGORY_EXTERN(wine);
struct wg_transform
{
+ GstPad *my_src, *my_sink;
};
+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 +72,11 @@ NTSTATUS wg_transform_destroy(void *args)
NTSTATUS wg_transform_create(void *args)
{
struct wg_transform_create_params *params = args;
+ struct wg_format output_format = *params->output_format;
+ struct wg_format input_format = *params->input_format;
+ GstCaps *src_caps, *sink_caps;
struct wg_transform *transform;
+ GstPadTemplate *template;
if (!init_gstreamer())
return E_FAIL;
@@ -63,7 +84,31 @@ NTSTATUS wg_transform_create(void *args)
if (!(transform = calloc(1, sizeof(*transform))))
return E_OUTOFMEMORY;
+ src_caps = wg_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 b209ffc2e77..e8b47cc9bde 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -78,7 +78,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