This MR is splitted from !3810
-- v2: winegstreamer: Implement wg_muxer_add_stream. winegstreamer: Introduce factory_create_element. winegstreamer: Introduce find_element_factories.
From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/main.c | 8 ++++++-- dlls/winegstreamer/wg_muxer.c | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 853907e1825..beb48fa3731 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -466,13 +466,17 @@ HRESULT wg_muxer_create(const char *format, wg_muxer_t *muxer)
TRACE("format %p, muxer %p.\n", format, muxer);
- if (SUCCEEDED(status = WINE_UNIX_CALL(unix_wg_muxer_create, ¶ms))) + if (!(status = WINE_UNIX_CALL(unix_wg_muxer_create, ¶ms))) { *muxer = params.muxer; TRACE("Created wg_muxer %#I64x.\n", params.muxer); } + else + { + WARN("Failed to create muxer, status %#lx.\n", status); + }
- return status; + return HRESULT_FROM_NT(status); }
void wg_muxer_destroy(wg_muxer_t muxer) diff --git a/dlls/winegstreamer/wg_muxer.c b/dlls/winegstreamer/wg_muxer.c index 6887bc015ba..601c5f03d31 100644 --- a/dlls/winegstreamer/wg_muxer.c +++ b/dlls/winegstreamer/wg_muxer.c @@ -61,14 +61,14 @@ NTSTATUS wg_muxer_create(void *args) { struct wg_muxer_create_params *params = args; GstElement *first = NULL, *last = NULL; + NTSTATUS status = STATUS_UNSUCCESSFUL; GstPadTemplate *template = NULL; GstCaps *sink_caps = NULL; - NTSTATUS status = E_FAIL; struct wg_muxer *muxer;
/* Create wg_muxer object. */ if (!(muxer = calloc(1, sizeof(*muxer)))) - return E_OUTOFMEMORY; + return STATUS_NO_MEMORY; if (!(muxer->container = gst_bin_new("wg_muxer"))) goto out;
@@ -110,7 +110,7 @@ NTSTATUS wg_muxer_create(void *args) GST_INFO("Created winegstreamer muxer %p.", muxer); params->muxer = (wg_transform_t)(ULONG_PTR)muxer;
- return S_OK; + return STATUS_SUCCESS;
out: if (muxer->my_sink)
From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/unix_private.h | 1 + dlls/winegstreamer/unixlib.c | 34 ++++++++++++++++--------------- dlls/winegstreamer/wg_parser.c | 7 ++----- 3 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index 305d69c12a8..eefd3cdb259 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -37,6 +37,7 @@ extern GstStreamType stream_type_from_caps(GstCaps *caps) DECLSPEC_HIDDEN; extern GstElement *create_element(const char *name, const char *plugin_set) DECLSPEC_HIDDEN; extern GstElement *find_element(GstElementFactoryListType type, GstCaps *src_caps, GstCaps *sink_caps) DECLSPEC_HIDDEN; extern bool append_element(GstElement *container, GstElement *element, GstElement **first, GstElement **last) DECLSPEC_HIDDEN; +extern bool link_src_to_sink(GstPad *src_pad, GstPad *sink_pad) DECLSPEC_HIDDEN; extern bool link_src_to_element(GstPad *src_pad, GstElement *element) DECLSPEC_HIDDEN; extern bool link_element_to_sink(GstElement *element, GstPad *sink_pad) DECLSPEC_HIDDEN; extern bool push_event(GstPad *pad, GstEvent *event) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/unixlib.c b/dlls/winegstreamer/unixlib.c index 513ece95a90..4a204478ade 100644 --- a/dlls/winegstreamer/unixlib.c +++ b/dlls/winegstreamer/unixlib.c @@ -162,6 +162,20 @@ bool append_element(GstElement *container, GstElement *element, GstElement **fir return success; }
+bool link_src_to_sink(GstPad *src_pad, GstPad *sink_pad) +{ + GstPadLinkReturn ret; + + if ((ret = gst_pad_link(src_pad, sink_pad)) != GST_PAD_LINK_OK) + { + GST_ERROR("Failed to link src pad %"GST_PTR_FORMAT" to sink pad %"GST_PTR_FORMAT", reason: %s", + src_pad, sink_pad, gst_pad_link_get_name(ret)); + return false; + } + + return true; +} + bool link_src_to_element(GstPad *src_pad, GstElement *element) { GstPadLinkReturn ret; @@ -174,15 +188,9 @@ bool link_src_to_element(GstPad *src_pad, GstElement *element) g_free(name); return false; } - if ((ret = gst_pad_link(src_pad, sink_pad))) - { - gchar *src_name = gst_pad_get_name(src_pad), *sink_name = gst_pad_get_name(sink_pad); - GST_ERROR("Failed to link element pad %s with pad %s", src_name, sink_name); - g_free(sink_name); - g_free(src_name); - } + ret = link_src_to_sink(src_pad, sink_pad); gst_object_unref(sink_pad); - return !ret; + return ret; }
bool link_element_to_sink(GstElement *element, GstPad *sink_pad) @@ -197,15 +205,9 @@ bool link_element_to_sink(GstElement *element, GstPad *sink_pad) g_free(name); return false; } - if ((ret = gst_pad_link(src_pad, sink_pad))) - { - gchar *src_name = gst_pad_get_name(src_pad), *sink_name = gst_pad_get_name(sink_pad); - GST_ERROR("Failed to link pad %s with element pad %s", src_name, sink_name); - g_free(sink_name); - g_free(src_name); - } + ret = link_src_to_sink(src_pad, sink_pad); gst_object_unref(src_pad); - return !ret; + return ret; }
bool push_event(GstPad *pad, GstEvent *event) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 299eea09c90..ebdefb6a7f9 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -849,7 +849,6 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser struct wg_parser *parser = stream->parser; const char *name; GstCaps *caps; - int ret;
caps = gst_pad_query_caps(pad, NULL); name = gst_structure_get_name(gst_caps_get_structure(caps, 0)); @@ -898,11 +897,9 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser if (!link_src_to_element(pad, first) || !link_element_to_sink(last, stream->my_sink)) return false; } - else if ((ret = gst_pad_link(pad, stream->my_sink)) < 0) + else { - GST_ERROR("Failed to link decodebin source pad to our sink pad, error %s.", - gst_pad_link_get_name(ret)); - return false; + return link_src_to_sink(pad, stream->my_sink); }
return true;
From: Ziqing Hui zhui@codeweavers.com
gst_element_get_compatible_pad supports request pad. --- dlls/winegstreamer/unixlib.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/dlls/winegstreamer/unixlib.c b/dlls/winegstreamer/unixlib.c index 4a204478ade..d0d50b34004 100644 --- a/dlls/winegstreamer/unixlib.c +++ b/dlls/winegstreamer/unixlib.c @@ -181,11 +181,10 @@ bool link_src_to_element(GstPad *src_pad, GstElement *element) GstPadLinkReturn ret; GstPad *sink_pad;
- if (!(sink_pad = gst_element_get_static_pad(element, "sink"))) + if (!(sink_pad = gst_element_get_compatible_pad(element, src_pad, NULL))) { - gchar *name = gst_element_get_name(element); - GST_ERROR("Failed to find sink pad on %s", name); - g_free(name); + GST_ERROR("Failed to find sink pad compatible to %"GST_PTR_FORMAT" on %"GST_PTR_FORMAT".", + src_pad, element); return false; } ret = link_src_to_sink(src_pad, sink_pad); @@ -198,11 +197,10 @@ bool link_element_to_sink(GstElement *element, GstPad *sink_pad) GstPadLinkReturn ret; GstPad *src_pad;
- if (!(src_pad = gst_element_get_static_pad(element, "src"))) + if (!(src_pad = gst_element_get_compatible_pad(element, sink_pad, NULL))) { - gchar *name = gst_element_get_name(element); - GST_ERROR("Failed to find src pad on %s", name); - g_free(name); + GST_ERROR("Failed to find src pad compatible to %"GST_PTR_FORMAT" on %"GST_PTR_FORMAT".", + sink_pad, element); return false; } ret = link_src_to_sink(src_pad, sink_pad);
From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/unix_private.h | 5 ++- dlls/winegstreamer/unixlib.c | 58 +++++++++++++++++++------------ 2 files changed, 39 insertions(+), 24 deletions(-)
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index eefd3cdb259..ea9803e6003 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -35,7 +35,10 @@ extern NTSTATUS wg_init_gstreamer(void *args) DECLSPEC_HIDDEN;
extern GstStreamType stream_type_from_caps(GstCaps *caps) DECLSPEC_HIDDEN; extern GstElement *create_element(const char *name, const char *plugin_set) DECLSPEC_HIDDEN; -extern GstElement *find_element(GstElementFactoryListType type, GstCaps *src_caps, GstCaps *sink_caps) DECLSPEC_HIDDEN; +extern GList *find_element_factories(GstElementFactoryListType type, GstRank min_rank, + GstCaps *element_sink_caps, GstCaps *element_src_caps) DECLSPEC_HIDDEN; +extern GstElement *find_element(GstElementFactoryListType type, + GstCaps *element_sink_caps, GstCaps *element_src_caps) DECLSPEC_HIDDEN; extern bool append_element(GstElement *container, GstElement *element, GstElement **first, GstElement **last) DECLSPEC_HIDDEN; extern bool link_src_to_sink(GstPad *src_pad, GstPad *sink_pad) DECLSPEC_HIDDEN; extern bool link_src_to_element(GstPad *src_pad, GstElement *element) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/unixlib.c b/dlls/winegstreamer/unixlib.c index d0d50b34004..ad92ff230f8 100644 --- a/dlls/winegstreamer/unixlib.c +++ b/dlls/winegstreamer/unixlib.c @@ -78,32 +78,50 @@ GstElement *create_element(const char *name, const char *plugin_set) return element; }
-GstElement *find_element(GstElementFactoryListType type, GstCaps *src_caps, GstCaps *sink_caps) +GList *find_element_factories(GstElementFactoryListType type, GstRank min_rank, + GstCaps *element_sink_caps, GstCaps *element_src_caps) { - GstElement *element = NULL; - GList *tmp, *transforms; - const gchar *name; + GList *tmp, *factories = NULL;
- if (!(transforms = gst_element_factory_list_get_elements(type, GST_RANK_MARGINAL))) + if (!(factories = gst_element_factory_list_get_elements(type, min_rank))) goto done;
- if (src_caps) + if (element_sink_caps) { - tmp = gst_element_factory_list_filter(transforms, src_caps, GST_PAD_SINK, FALSE); - gst_plugin_feature_list_free(transforms); - if (!(transforms = tmp)) + tmp = gst_element_factory_list_filter(factories, element_sink_caps, GST_PAD_SINK, FALSE); + gst_plugin_feature_list_free(factories); + if (!(factories = tmp)) goto done; }
- if (sink_caps) + if (element_src_caps) { - tmp = gst_element_factory_list_filter(transforms, sink_caps, GST_PAD_SRC, FALSE); - gst_plugin_feature_list_free(transforms); - if (!(transforms = tmp)) + tmp = gst_element_factory_list_filter(factories, element_src_caps, GST_PAD_SRC, FALSE); + gst_plugin_feature_list_free(factories); + if (!(factories = tmp)) goto done; }
- transforms = g_list_sort(transforms, gst_plugin_feature_rank_compare_func); + factories = g_list_sort(factories, gst_plugin_feature_rank_compare_func); + +done: + if (!factories) + GST_WARNING("Failed to find any element factory matching " + "type %"G_GUINT64_FORMAT"x, caps %"GST_PTR_FORMAT" / %"GST_PTR_FORMAT".", + type, element_sink_caps, element_src_caps); + + return factories; +} + +GstElement *find_element(GstElementFactoryListType type, GstCaps *element_sink_caps, GstCaps *element_src_caps) +{ + GstElement *element = NULL; + GList *tmp, *transforms; + const gchar *name; + + if (!(transforms = find_element_factories(type, GST_RANK_MARGINAL, element_sink_caps, element_src_caps))) + return NULL; + for (tmp = transforms; tmp != NULL && element == NULL; tmp = tmp->next) { name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(tmp->data)); @@ -120,20 +138,14 @@ GstElement *find_element(GstElementFactoryListType type, GstCaps *src_caps, GstC if (!(element = gst_element_factory_create(GST_ELEMENT_FACTORY(tmp->data), NULL))) GST_WARNING("Failed to create %s element.", name); } + gst_plugin_feature_list_free(transforms);
-done: if (element) - { GST_DEBUG("Created %s element %p.", name, element); - } else - { - gchar *src_str = gst_caps_to_string(src_caps), *sink_str = gst_caps_to_string(sink_caps); - GST_WARNING("Failed to create element matching caps %s / %s.", src_str, sink_str); - g_free(sink_str); - g_free(src_str); - } + GST_WARNING("Failed to create element matching caps %"GST_PTR_FORMAT" / %"GST_PTR_FORMAT".", + element_sink_caps, element_src_caps);
return element; }
From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/unix_private.h | 1 + dlls/winegstreamer/unixlib.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index ea9803e6003..823fab908be 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -35,6 +35,7 @@ extern NTSTATUS wg_init_gstreamer(void *args) DECLSPEC_HIDDEN;
extern GstStreamType stream_type_from_caps(GstCaps *caps) DECLSPEC_HIDDEN; extern GstElement *create_element(const char *name, const char *plugin_set) DECLSPEC_HIDDEN; +GstElement *factory_create_element(GstElementFactory *factory) DECLSPEC_HIDDEN; extern GList *find_element_factories(GstElementFactoryListType type, GstRank min_rank, GstCaps *element_sink_caps, GstCaps *element_src_caps) DECLSPEC_HIDDEN; extern GstElement *find_element(GstElementFactoryListType type, diff --git a/dlls/winegstreamer/unixlib.c b/dlls/winegstreamer/unixlib.c index ad92ff230f8..db9d1eb114f 100644 --- a/dlls/winegstreamer/unixlib.c +++ b/dlls/winegstreamer/unixlib.c @@ -78,6 +78,19 @@ GstElement *create_element(const char *name, const char *plugin_set) return element; }
+GstElement *factory_create_element(GstElementFactory *factory) +{ + GstElement *element; + + if ((element = gst_element_factory_create(factory, NULL))) + GST_INFO("Created element %"GST_PTR_FORMAT" from factory %"GST_PTR_FORMAT".", + element, factory); + else + GST_WARNING("Failed to create element from factory %"GST_PTR_FORMAT".", factory); + + return element; +} + GList *find_element_factories(GstElementFactoryListType type, GstRank min_rank, GstCaps *element_sink_caps, GstCaps *element_src_caps) { @@ -135,15 +148,12 @@ GstElement *find_element(GstElementFactoryListType type, GstCaps *element_sink_c continue; }
- if (!(element = gst_element_factory_create(GST_ELEMENT_FACTORY(tmp->data), NULL))) - GST_WARNING("Failed to create %s element.", name); + element = factory_create_element(GST_ELEMENT_FACTORY(tmp->data)); }
gst_plugin_feature_list_free(transforms);
- if (element) - GST_DEBUG("Created %s element %p.", name, element); - else + if (!element) GST_WARNING("Failed to create element matching caps %"GST_PTR_FORMAT" / %"GST_PTR_FORMAT".", element_sink_caps, element_src_caps);
From: Ziqing Hui zhui@codeweavers.com
--- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/main.c | 21 ++++++++ dlls/winegstreamer/media_sink.c | 9 ++++ dlls/winegstreamer/unix_private.h | 1 + dlls/winegstreamer/unixlib.h | 8 ++++ dlls/winegstreamer/wg_muxer.c | 80 +++++++++++++++++++++++++++++++ dlls/winegstreamer/wg_parser.c | 19 ++++++++ 7 files changed, 139 insertions(+)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 8cfadd10bfc..23b59766d0c 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -112,6 +112,7 @@ HRESULT wg_transform_flush(wg_transform_t transform);
HRESULT wg_muxer_create(const char *format, wg_muxer_t *muxer); void wg_muxer_destroy(wg_muxer_t muxer); +HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_format *format);
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 beb48fa3731..55817922e9b 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -486,6 +486,27 @@ void wg_muxer_destroy(wg_muxer_t muxer) WINE_UNIX_CALL(unix_wg_muxer_destroy, &muxer); }
+HRESULT wg_muxer_add_stream(wg_muxer_t muxer, UINT32 stream_id, const struct wg_format *format) +{ + struct wg_muxer_add_stream_params params = + { + .muxer = muxer, + .stream_id = stream_id, + .format = format, + }; + NTSTATUS status; + + TRACE("muxer %#I64x, stream_id %u, format %p.\n", muxer, stream_id, format); + + if ((status = WINE_UNIX_CALL(unix_wg_muxer_add_stream, ¶ms))) + { + WARN("Failed to add stream, status %#lx.\n", status); + return HRESULT_FROM_NT(status); + } + + return S_OK; +} + #define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
unsigned int wg_format_get_stride(const struct wg_format *format) diff --git a/dlls/winegstreamer/media_sink.c b/dlls/winegstreamer/media_sink.c index 6bd9fdcfb7d..344134d1633 100644 --- a/dlls/winegstreamer/media_sink.c +++ b/dlls/winegstreamer/media_sink.c @@ -588,6 +588,7 @@ static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, D { struct media_sink *media_sink = impl_from_IMFFinalizableMediaSink(iface); struct stream_sink *object; + struct wg_format format; HRESULT hr;
TRACE("iface %p, stream_sink_id %#lx, media_type %p, stream_sink %p.\n", @@ -608,6 +609,14 @@ static HRESULT WINAPI media_sink_AddStreamSink(IMFFinalizableMediaSink *iface, D return hr; }
+ mf_media_type_to_wg_format(media_type, &format); + if (FAILED(hr = wg_muxer_add_stream(media_sink->muxer, stream_sink_id, &format))) + { + LeaveCriticalSection(&media_sink->cs); + IMFStreamSink_Release(&object->IMFStreamSink_iface); + return hr; + } + list_add_tail(&media_sink->stream_sinks, &object->entry);
LeaveCriticalSection(&media_sink->cs); diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index 823fab908be..cf4a293c863 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -67,6 +67,7 @@ extern NTSTATUS wg_transform_flush(void *args) DECLSPEC_HIDDEN;
extern NTSTATUS wg_muxer_create(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_muxer_destroy(void *args) DECLSPEC_HIDDEN; +extern NTSTATUS wg_muxer_add_stream(void *args) DECLSPEC_HIDDEN;
/* wg_allocator.c */
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index a3131e9f789..d00790c6b05 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -372,6 +372,13 @@ struct wg_muxer_create_params const char *format; };
+struct wg_muxer_add_stream_params +{ + wg_muxer_t muxer; + UINT32 stream_id; + const struct wg_format *format; +}; + enum unix_funcs { unix_wg_init_gstreamer, @@ -414,6 +421,7 @@ enum unix_funcs
unix_wg_muxer_create, unix_wg_muxer_destroy, + unix_wg_muxer_add_stream,
unix_wg_funcs_count, }; diff --git a/dlls/winegstreamer/wg_muxer.c b/dlls/winegstreamer/wg_muxer.c index 601c5f03d31..793444ad243 100644 --- a/dlls/winegstreamer/wg_muxer.c +++ b/dlls/winegstreamer/wg_muxer.c @@ -22,16 +22,33 @@ #pragma makedep unix #endif
+#include <stdio.h> + #include "ntstatus.h" #define WIN32_NO_STATUS #include "winternl.h"
#include "unix_private.h"
+#include "wine/list.h" + struct wg_muxer { GstElement *container, *muxer; GstPad *my_sink; + struct list streams; +}; + +struct wg_muxer_stream +{ + struct wg_muxer *muxer; + struct wg_format format; + uint32_t id; + + GstPad *my_src; + GstCaps *my_src_caps; + + struct list entry; };
static struct wg_muxer *get_muxer(wg_muxer_t muxer) @@ -57,6 +74,13 @@ static gboolean muxer_sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *qu } }
+static void stream_free(struct wg_muxer_stream *stream) +{ + gst_object_unref(stream->my_src); + gst_caps_unref(stream->my_src_caps); + free(stream); +} + NTSTATUS wg_muxer_create(void *args) { struct wg_muxer_create_params *params = args; @@ -69,6 +93,7 @@ NTSTATUS wg_muxer_create(void *args) /* Create wg_muxer object. */ if (!(muxer = calloc(1, sizeof(*muxer)))) return STATUS_NO_MEMORY; + list_init(&muxer->streams); if (!(muxer->container = gst_bin_new("wg_muxer"))) goto out;
@@ -132,7 +157,13 @@ out: NTSTATUS wg_muxer_destroy(void *args) { struct wg_muxer *muxer = get_muxer(*(wg_muxer_t *)args); + struct wg_muxer_stream *stream, *next;
+ LIST_FOR_EACH_ENTRY_SAFE(stream, next, &muxer->streams, struct wg_muxer_stream, entry) + { + list_remove(&stream->entry); + stream_free(stream); + } gst_object_unref(muxer->my_sink); gst_element_set_state(muxer->container, GST_STATE_NULL); gst_object_unref(muxer->container); @@ -140,3 +171,52 @@ NTSTATUS wg_muxer_destroy(void *args)
return S_OK; } + +NTSTATUS wg_muxer_add_stream(void *args) +{ + struct wg_muxer_add_stream_params *params = args; + struct wg_muxer *muxer = get_muxer(params->muxer); + NTSTATUS status = STATUS_UNSUCCESSFUL; + GstPadTemplate *template = NULL; + struct wg_muxer_stream *stream; + char src_pad_name[64]; + + GST_DEBUG("muxer %p, stream_id %u, format %p.", muxer, params->stream_id, params->format); + + /* Create stream object. */ + if (!(stream = calloc(1, sizeof(*stream)))) + return STATUS_NO_MEMORY; + stream->muxer = muxer; + stream->format = *params->format; + stream->id = params->stream_id; + + /* Create stream my_src pad. */ + if (!(stream->my_src_caps = wg_format_to_caps(params->format))) + goto out; + if (!(template = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, stream->my_src_caps))) + goto out; + sprintf(src_pad_name, "wg_muxer_stream_src_%u", stream->id); + if (!(stream->my_src = gst_pad_new_from_template(template, src_pad_name))) + goto out; + gst_pad_set_element_private(stream->my_src, stream); + + /* Add to muxer stream list. */ + list_add_tail(&muxer->streams, &stream->entry); + + gst_object_unref(template); + + GST_INFO("Created winegstreamer muxer stream %p.", stream); + + return STATUS_SUCCESS; + +out: + if (stream->my_src) + gst_object_unref(stream->my_src); + if (template) + gst_object_unref(template); + if (stream->my_src_caps) + gst_caps_unref(stream->my_src_caps); + free(stream); + + return status; +} diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index ebdefb6a7f9..2d2e3450ccb 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1945,6 +1945,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_muxer_create), X(wg_muxer_destroy), + X(wg_muxer_add_stream), };
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == unix_wg_funcs_count); @@ -2171,6 +2172,23 @@ NTSTATUS wow64_wg_muxer_create(void *args) return ret; }
+NTSTATUS wow64_wg_muxer_add_stream(void *args) +{ + struct + { + wg_muxer_t muxer; + UINT32 stream_id; + PTR32 format; + } *params32 = args; + struct wg_muxer_add_stream_params params = + { + .muxer = params32->muxer, + .stream_id = params32->stream_id, + .format = ULongToPtr(params32->format), + }; + return wg_muxer_add_stream(¶ms); +} + const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { #define X64(name) [unix_ ## name] = wow64_ ## name @@ -2214,6 +2232,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
X64(wg_muxer_create), X(wg_muxer_destroy), + X64(wg_muxer_add_stream), };
C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_wg_funcs_count);
This merge request was approved by Zebediah Figura.