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