Commit 11b30ffc authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

winegstreamer: Append an audioconvert element to raw audio streams.

parent aa701751
...@@ -85,10 +85,7 @@ struct gstdemux_source ...@@ -85,10 +85,7 @@ struct gstdemux_source
struct strmbase_source pin; struct strmbase_source pin;
IQualityControl IQualityControl_iface; IQualityControl IQualityControl_iface;
GstElement *flipfilter; GstPad *their_src, *post_sink, *post_src, *my_sink;
GstPad *flip_sink, *flip_src;
GstPad *their_src;
GstPad *my_sink;
AM_MEDIA_TYPE mt; AM_MEDIA_TYPE mt;
HANDLE caps_event; HANDLE caps_event;
GstSegment *segment; GstSegment *segment;
...@@ -1004,11 +1001,10 @@ static void removed_decoded_pad(GstElement *bin, GstPad *pad, gpointer user) ...@@ -1004,11 +1001,10 @@ static void removed_decoded_pad(GstElement *bin, GstPad *pad, gpointer user)
if (pin->their_src == pad) if (pin->their_src == pad)
{ {
if(pin->flipfilter) if (pin->post_sink)
gst_pad_unlink(pin->their_src, pin->flip_sink); gst_pad_unlink(pin->their_src, pin->post_sink);
else else
gst_pad_unlink(pin->their_src, pin->my_sink); gst_pad_unlink(pin->their_src, pin->my_sink);
gst_object_unref(pin->their_src); gst_object_unref(pin->their_src);
pin->their_src = NULL; pin->their_src = NULL;
return; return;
...@@ -1052,85 +1048,91 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux * ...@@ -1052,85 +1048,91 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux *
if (!strcmp(typename, "video/x-raw")) if (!strcmp(typename, "video/x-raw"))
{ {
GstElement *vconv; GstElement *vconv, *flip;
TRACE("setting up videoflip filter for pin %p, my_sink: %p, their_src: %p\n",
pin, pin->my_sink, pad);
/* gstreamer outputs video top-down, but dshow expects bottom-up, so /* decodebin considers many YUV formats to be "raw", but some quartz
* make new transform filter to invert video */ * filters can't handle those. Also, videoflip can't handle all "raw"
vconv = gst_element_factory_make("videoconvert", NULL); * formats either. Add a videoconvert to swap color spaces. */
if(!vconv){ if (!(vconv = gst_element_factory_make("videoconvert", NULL)))
ERR("Missing videoconvert filter?\n"); {
ret = -1; ERR("Failed to create videoconvert, are %u-bit GStreamer \"base\" plugins installed?\n",
goto exit; 8 * (int)sizeof(void *));
return;
} }
pin->flipfilter = gst_element_factory_make("videoflip", NULL); /* GStreamer outputs video top-down, but DirectShow expects bottom-up. */
if(!pin->flipfilter){ if (!(flip = gst_element_factory_make("videoflip", NULL)))
ERR("Missing videoflip filter?\n"); {
ret = -1; ERR("Failed to create videoflip, are %u-bit GStreamer \"good\" plugins installed?\n",
goto exit; 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_bin_add(GST_BIN(This->container), vconv); /* bin takes ownership */
gst_element_sync_state_with_parent(vconv); gst_element_sync_state_with_parent(vconv);
gst_bin_add(GST_BIN(This->container), pin->flipfilter); /* bin takes ownership */ gst_bin_add(GST_BIN(This->container), flip); /* bin takes ownership */
gst_element_sync_state_with_parent(pin->flipfilter); gst_element_sync_state_with_parent(flip);
gst_element_link (vconv, pin->flipfilter);
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;
}
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;
}
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;
}
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;
}
} else
ret = gst_pad_link(pad, pin->my_sink);
gst_pad_set_active(pin->my_sink, 1); gst_element_link(vconv, flip);
exit: pin->post_sink = gst_element_get_static_pad(vconv, "sink");
TRACE("Linking: %i\n", ret); pin->post_src = gst_element_get_static_pad(flip, "src");
}
else if (!strcmp(typename, "audio/x-raw"))
{
GstElement *convert;
if (ret >= 0) { /* Currently our dsound can't handle 64-bit formats or all
pin->their_src = pad; * surround-sound configurations. Native dsound can't always handle
gst_object_ref(pin->their_src); * 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;
} }
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;
}
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 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);
gst_object_ref(pin->their_src = pad);
} }
static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user) 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) ...@@ -1156,8 +1158,8 @@ static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user)
if (!pin->their_src) { if (!pin->their_src) {
gst_segment_init(pin->segment, GST_FORMAT_TIME); gst_segment_init(pin->segment, GST_FORMAT_TIME);
if (pin->flipfilter) if (pin->post_sink)
ret = gst_pad_link(pad, pin->flip_sink); ret = gst_pad_link(pad, pin->post_sink);
else else
ret = gst_pad_link(pad, pin->my_sink); ret = gst_pad_link(pad, pin->my_sink);
...@@ -2136,14 +2138,13 @@ static void free_source_pin(struct gstdemux_source *pin) ...@@ -2136,14 +2138,13 @@ static void free_source_pin(struct gstdemux_source *pin)
if (pin->their_src) if (pin->their_src)
{ {
if (pin->flipfilter) if (pin->post_sink)
{ {
gst_pad_unlink(pin->their_src, pin->flip_sink); gst_pad_unlink(pin->their_src, pin->post_sink);
gst_pad_unlink(pin->flip_src, pin->my_sink); gst_pad_unlink(pin->post_src, pin->my_sink);
gst_object_unref(pin->flip_src); gst_object_unref(pin->post_src);
gst_object_unref(pin->flip_sink); gst_object_unref(pin->post_sink);
pin->flipfilter = NULL; pin->post_src = pin->post_sink = NULL;
pin->flip_src = pin->flip_sink = NULL;
} }
else else
gst_pad_unlink(pin->their_src, pin->my_sink); gst_pad_unlink(pin->their_src, pin->my_sink);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment