This MR is splitted from !3810
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 | 57 ++++++++++++++++++------------- 2 files changed, 38 insertions(+), 24 deletions(-)
diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index eefd3cdb259..7034750d7d2 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, + 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..4ee7fc25d4d 100644 --- a/dlls/winegstreamer/unixlib.c +++ b/dlls/winegstreamer/unixlib.c @@ -78,32 +78,49 @@ 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, 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, GST_RANK_NONE))) 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, 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 +137,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 7034750d7d2..f8c7abb2aef 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, 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 4ee7fc25d4d..7ade13d6aae 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, GstCaps *element_sink_caps, GstCaps *element_src_caps) { GList *tmp, *factories = NULL; @@ -134,15 +147,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 f8c7abb2aef..78d3da6e07e 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 Rémi Bernon.
Zebediah Figura (@zfigura) commented about dlls/winegstreamer/unixlib.c:
return element;
}
-GstElement *find_element(GstElementFactoryListType type, GstCaps *src_caps, GstCaps *sink_caps) +GList *find_element_factories(GstElementFactoryListType type, 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, GST_RANK_NONE)))
I don't think we want to do this. NONE factories are NONE for a reason (and if that reason is no longer applicable, it should be fixed on the GStreamer side).
Note that this also changes behaviour in a (nontrivial) way that's not called out by the patch subject. Patches should ideally change either behaviour or organization, and if they do both that should be spelled out explicitly.
On Sat Oct 28 18:45:08 2023 +0000, Zebediah Figura wrote:
I don't think we want to do this. NONE factories are NONE for a reason (and if that reason is no longer applicable, it should be fixed on the GStreamer side). Note that this also changes behaviour in a (nontrivial) way that's not called out by the patch subject. Patches should ideally change either behaviour or organization, and if they do both that should be spelled out explicitly.
NONE is only there for plugins to be chosen in last resort, there is no other meaning.
I agree it should be done in a separate change though.
On Sun Oct 29 08:11:51 2023 +0000, Rémi Bernon wrote:
NONE is only there for plugins to be chosen in last resort, there is no other meaning. I agree it should be done in a separate change though.
NONE plugins are not chosen by builtin autopluggers. By the same logic I don't think we should choose them either.
The documentation is unfortunately vague about this, but it does state that NONE plugins "will be chosen last **or not at all**" (emphasis mine).
The documentation is unfortunately vague about this, but it does state that NONE plugins "will be chosen last **or not at all**"
We could very well emphasis the other side of the or.
I don't see any reason not to chose them, there's several seemingly useful plugins that have rank none: all Intel MSDK encoder / decoder plugins, VA-API hardware decoders (not the higher level vaapidecodebin), `avenc_aac`, and of course multiple `avmux` plugins which can be useful here, have rank none.
If rank none was meant for plugins not to be used, `gst_element_factory_list_get_elements` should not return them.
On Sun Oct 29 17:36:54 2023 +0000, Rémi Bernon wrote:
The documentation is unfortunately vague about this, but it does state
that NONE plugins "will be chosen last **or not at all**" We could very well emphasis the other side of the or. I don't see any reason not to chose them, there's several seemingly useful plugins that have rank none: all Intel MSDK encoder / decoder plugins, VA-API hardware decoders (not the higher level vaapidecodebin), `avenc_aac`, and of course multiple `avmux` plugins which can be useful here, have rank none. If rank none was meant for plugins not to be used, `gst_element_factory_list_get_elements` should not return them.
I'll make this MR become a "safe version" to get it merged, which means it doens't change the rank to NONE. If we think we think we should change the rank for some reason, we can submit a new MR later.