Zebediah Figura : winegstreamer: Append an audioconvert element to raw audio streams.

Alexandre Julliard julliard at winehq.org
Tue Jan 28 15:35:25 CST 2020


Module: wine
Branch: master
Commit: 11b30ffc076126c6e75cb2c4bd026a9d468c18da
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=11b30ffc076126c6e75cb2c4bd026a9d468c18da

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Mon Jan 27 19:06:55 2020 -0600

winegstreamer: Append an audioconvert element to raw audio streams.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winegstreamer/gstdemux.c | 155 +++++++++++++++++++++---------------------
 1 file changed, 78 insertions(+), 77 deletions(-)

diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 66557b63a5..8e36644030 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -85,10 +85,7 @@ struct gstdemux_source
     struct strmbase_source pin;
     IQualityControl IQualityControl_iface;
 
-    GstElement *flipfilter;
-    GstPad *flip_sink, *flip_src;
-    GstPad *their_src;
-    GstPad *my_sink;
+    GstPad *their_src, *post_sink, *post_src, *my_sink;
     AM_MEDIA_TYPE mt;
     HANDLE caps_event;
     GstSegment *segment;
@@ -1004,11 +1001,10 @@ static void removed_decoded_pad(GstElement *bin, GstPad *pad, gpointer user)
 
         if (pin->their_src == pad)
         {
-            if(pin->flipfilter)
-                gst_pad_unlink(pin->their_src, pin->flip_sink);
+            if (pin->post_sink)
+                gst_pad_unlink(pin->their_src, pin->post_sink);
             else
                 gst_pad_unlink(pin->their_src, pin->my_sink);
-
             gst_object_unref(pin->their_src);
             pin->their_src = NULL;
             return;
@@ -1052,85 +1048,91 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux *
 
     if (!strcmp(typename, "video/x-raw"))
     {
-        GstElement *vconv;
-
-        TRACE("setting up videoflip filter for pin %p, my_sink: %p, their_src: %p\n",
-                pin, pin->my_sink, pad);
+        GstElement *vconv, *flip;
 
-        /* gstreamer outputs video top-down, but dshow expects bottom-up, so
-         * make new transform filter to invert video */
-        vconv = gst_element_factory_make("videoconvert", NULL);
-        if(!vconv){
-            ERR("Missing videoconvert filter?\n");
-            ret = -1;
-            goto exit;
+        /* decodebin considers many YUV formats to be "raw", but some quartz
+         * filters can't handle those. Also, videoflip can't handle all "raw"
+         * formats either. Add a videoconvert to swap color spaces. */
+        if (!(vconv = gst_element_factory_make("videoconvert", NULL)))
+        {
+            ERR("Failed to create videoconvert, are %u-bit GStreamer \"base\" plugins installed?\n",
+                    8 * (int)sizeof(void *));
+            return;
         }
 
-        pin->flipfilter = gst_element_factory_make("videoflip", NULL);
-        if(!pin->flipfilter){
-            ERR("Missing videoflip filter?\n");
-            ret = -1;
-            goto exit;
+        /* GStreamer outputs video top-down, but DirectShow expects bottom-up. */
+        if (!(flip = gst_element_factory_make("videoflip", NULL)))
+        {
+            ERR("Failed to create videoflip, are %u-bit GStreamer \"good\" plugins installed?\n",
+                    8 * (int)sizeof(void *));
+            return;
         }
 
-        gst_util_set_object_arg(G_OBJECT(pin->flipfilter), "method", "vertical-flip");
+        gst_util_set_object_arg(G_OBJECT(flip), "method", "vertical-flip");
 
         gst_bin_add(GST_BIN(This->container), vconv); /* bin takes ownership */
         gst_element_sync_state_with_parent(vconv);
-        gst_bin_add(GST_BIN(This->container), pin->flipfilter); /* bin takes ownership */
-        gst_element_sync_state_with_parent(pin->flipfilter);
+        gst_bin_add(GST_BIN(This->container), flip); /* bin takes ownership */
+        gst_element_sync_state_with_parent(flip);
 
-        gst_element_link (vconv, pin->flipfilter);
+        gst_element_link(vconv, flip);
 
-        pin->flip_sink = gst_element_get_static_pad(vconv, "sink");
-        if(!pin->flip_sink){
-            WARN("Couldn't find sink on flip filter\n");
-            pin->flipfilter = NULL;
-            ret = -1;
-            goto exit;
-        }
+        pin->post_sink = gst_element_get_static_pad(vconv, "sink");
+        pin->post_src = gst_element_get_static_pad(flip, "src");
+    }
+    else if (!strcmp(typename, "audio/x-raw"))
+    {
+        GstElement *convert;
 
-        ret = gst_pad_link(pad, pin->flip_sink);
-        if(ret < 0){
-            WARN("gst_pad_link failed: %d\n", ret);
-            gst_object_unref(pin->flip_sink);
-            pin->flip_sink = NULL;
-            pin->flipfilter = NULL;
-            goto exit;
+        /* Currently our dsound can't handle 64-bit formats or all
+         * surround-sound configurations. Native dsound can't always handle
+         * 64-bit formats either. Add an audioconvert to allow changing bit
+         * depth and channel count. */
+        if (!(convert = gst_element_factory_make("audioconvert", NULL)))
+        {
+            ERR("Failed to create audioconvert, are %u-bit GStreamer \"base\" plugins installed?\n",
+                    8 * (int)sizeof(void *));
+            return;
         }
 
-        pin->flip_src = gst_element_get_static_pad(pin->flipfilter, "src");
-        if(!pin->flip_src){
-            WARN("Couldn't find src on flip filter\n");
-            gst_object_unref(pin->flip_sink);
-            pin->flip_sink = NULL;
-            pin->flipfilter = NULL;
-            ret = -1;
-            goto exit;
+        gst_bin_add(GST_BIN(This->container), convert);
+        gst_element_sync_state_with_parent(convert);
+
+        pin->post_sink = gst_element_get_static_pad(convert, "sink");
+        pin->post_src = gst_element_get_static_pad(convert, "src");
+    }
+
+    if (pin->post_sink)
+    {
+        if ((ret = gst_pad_link(pad, pin->post_sink)) < 0)
+        {
+            ERR("Failed to link decodebin source pad to post-processing elements, error %s.\n",
+                    gst_pad_link_get_name(ret));
+            gst_object_unref(pin->post_sink);
+            pin->post_sink = NULL;
+            return;
         }
 
-        ret = gst_pad_link(pin->flip_src, pin->my_sink);
-        if(ret < 0){
-            WARN("gst_pad_link failed: %d\n", ret);
-            gst_object_unref(pin->flip_src);
-            pin->flip_src = NULL;
-            gst_object_unref(pin->flip_sink);
-            pin->flip_sink = NULL;
-            pin->flipfilter = NULL;
-            goto exit;
+        if ((ret = gst_pad_link(pin->post_src, pin->my_sink)) < 0)
+        {
+            ERR("Failed to link post-processing elements to our sink pad, error %s.\n",
+                    gst_pad_link_get_name(ret));
+            gst_object_unref(pin->post_src);
+            pin->post_src = NULL;
+            gst_object_unref(pin->post_sink);
+            pin->post_sink = NULL;
+            return;
         }
-    } else
-        ret = gst_pad_link(pad, pin->my_sink);
+    }
+    else if ((ret = gst_pad_link(pad, pin->my_sink)) < 0)
+    {
+        ERR("Failed to link decodebin source pad to our sink pad, error %s.\n",
+                gst_pad_link_get_name(ret));
+        return;
+    }
 
     gst_pad_set_active(pin->my_sink, 1);
-
-exit:
-    TRACE("Linking: %i\n", ret);
-
-    if (ret >= 0) {
-        pin->their_src = pad;
-        gst_object_ref(pin->their_src);
-    }
+    gst_object_ref(pin->their_src = pad);
 }
 
 static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user)
@@ -1156,8 +1158,8 @@ static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user)
         if (!pin->their_src) {
             gst_segment_init(pin->segment, GST_FORMAT_TIME);
 
-            if (pin->flipfilter)
-                ret = gst_pad_link(pad, pin->flip_sink);
+            if (pin->post_sink)
+                ret = gst_pad_link(pad, pin->post_sink);
             else
                 ret = gst_pad_link(pad, pin->my_sink);
 
@@ -2136,14 +2138,13 @@ static void free_source_pin(struct gstdemux_source *pin)
 
     if (pin->their_src)
     {
-        if (pin->flipfilter)
+        if (pin->post_sink)
         {
-            gst_pad_unlink(pin->their_src, pin->flip_sink);
-            gst_pad_unlink(pin->flip_src, pin->my_sink);
-            gst_object_unref(pin->flip_src);
-            gst_object_unref(pin->flip_sink);
-            pin->flipfilter = NULL;
-            pin->flip_src = pin->flip_sink = NULL;
+            gst_pad_unlink(pin->their_src, pin->post_sink);
+            gst_pad_unlink(pin->post_src, pin->my_sink);
+            gst_object_unref(pin->post_src);
+            gst_object_unref(pin->post_sink);
+            pin->post_src = pin->post_sink = NULL;
         }
         else
             gst_pad_unlink(pin->their_src, pin->my_sink);




More information about the wine-cvs mailing list