[PATCH 1/5] winegstreamer: Link the container pads and activate ours.

Rémi Bernon rbernon at codeweavers.com
Tue Feb 22 16:48:15 CST 2022


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>
---

This series introduces a new wg_sample structure, which is used to pass
media buffers from PE to unix and back, as well as their metadata.

Initially the buffers are copied to GStreamer buffer, but the last patch
of the series introduces a zero-copy mechanism, which is used for input
buffers only for now.

Testing shows that IMFTransform are usually keeping a reference on their
input samples, and this makes it easier to keep the IMFSample alive as
long as the unix side has a reference on them, reaping them on specific
occasion to retrieve released samples and release their PE-side objects.

For output buffers, zero-copy is also possible, using the same structure
and mapping mechanism, but is a little trickier as transforms aren't
apparently keeping a reference on the output samples they are passed
across calls to ProcessOutput.

They can also optionally allocate and provide samples themselves to the
caller, instead of depending on their samples, but it's not how native
transforms are working, and to keep the behavior and compatibility close
we cannot safely rely on it.

The idea, which will be proposed later, and for the H264 transform (as
video buffers may be large, it makes most sense there), will be to
decouple GStreamer decoding using a queue, and a buffer pool which will
wait on ProcessOutput calls to provide output buffers to the pipeline.

 dlls/winegstreamer/wg_transform.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index d316071cf60..7160fd087b6 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -46,6 +46,7 @@ struct wg_transform
 {
     GstElement *container;
     GstPad *my_src, *my_sink;
+    GstPad *their_sink, *their_src;
 };
 
 static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer)
@@ -64,6 +65,10 @@ NTSTATUS wg_transform_destroy(void *args)
     struct wg_transform *transform = args;
 
     gst_element_set_state(transform->container, GST_STATE_NULL);
+    gst_pad_unlink(transform->their_src, transform->my_sink);
+    gst_pad_unlink(transform->my_src, transform->their_sink);
+    g_object_unref(transform->their_sink);
+    g_object_unref(transform->their_src);
     g_object_unref(transform->container);
     g_object_unref(transform->my_sink);
     g_object_unref(transform->my_src);
@@ -237,9 +242,22 @@ NTSTATUS wg_transform_create(void *args)
             goto out_free_sink_pad;
     }
 
+    if (!(transform->their_sink = gst_element_get_static_pad(first, "sink")))
+        goto out_free_sink_pad;
+    if (!(transform->their_src = gst_element_get_static_pad(last, "src")))
+        goto out_free_their_sink;
+    if (gst_pad_link(transform->my_src, transform->their_sink) < 0)
+        goto out_free_their_src;
+    if (gst_pad_link(transform->their_src, transform->my_sink) < 0)
+        goto out_unlink_src_pad;
+    if (!gst_pad_set_active(transform->my_sink, 1))
+        goto out_unlink_sink_pad;
+    if (!gst_pad_set_active(transform->my_src, 1))
+        goto out_unlink_sink_pad;
+
     gst_element_set_state(transform->container, GST_STATE_PAUSED);
     if (!gst_element_get_state(transform->container, NULL, NULL, -1))
-        goto out_free_sink_pad;
+        goto out_unlink_sink_pad;
 
     gst_caps_unref(sink_caps);
     gst_caps_unref(src_caps);
@@ -248,6 +266,14 @@ NTSTATUS wg_transform_create(void *args)
     params->transform = transform;
     return STATUS_SUCCESS;
 
+out_unlink_sink_pad:
+    gst_pad_unlink(transform->their_src, transform->my_sink);
+out_unlink_src_pad:
+    gst_pad_unlink(transform->my_src, transform->their_sink);
+out_free_their_src:
+    g_object_unref(transform->their_src);
+out_free_their_sink:
+    g_object_unref(transform->their_sink);
 out_free_sink_pad:
     gst_object_unref(transform->my_sink);
 out_free_sink_caps:
-- 
2.34.1




More information about the wine-devel mailing list