From 27eb6555d19ab2496cc35273bc54e89dfc0b9977 Mon Sep 17 00:00:00 2001 From: "Joshua M. Doe" Date: Thu, 18 Sep 2014 16:13:58 -0400 Subject: [PATCH] dshowsrcwrapper: avoid error when set_caps called twice If set_caps is called in a running state, return immediately if the caps haven't changed. If the pins are already connected, disconnect them. https://bugzilla.gnome.org/show_bug.cgi?id=736926 --- sys/dshowsrcwrapper/gstdshow.cpp | 16 ++++++++++++++++ sys/dshowsrcwrapper/gstdshow.h | 3 +++ sys/dshowsrcwrapper/gstdshowaudiosrc.cpp | 19 +++++++++++++++++++ sys/dshowsrcwrapper/gstdshowvideosrc.cpp | 17 +++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/sys/dshowsrcwrapper/gstdshow.cpp b/sys/dshowsrcwrapper/gstdshow.cpp index 7d8fe7a46c..de700aa734 100644 --- a/sys/dshowsrcwrapper/gstdshow.cpp +++ b/sys/dshowsrcwrapper/gstdshow.cpp @@ -413,6 +413,22 @@ gst_dshow_guid_to_gst_video_format (AM_MEDIA_TYPE *mediatype) return GST_VIDEO_FORMAT_UNKNOWN; } +gboolean +gst_dshow_is_pin_connected (IPin * pin) +{ + IPin *tmp_pin = NULL; + gboolean res; + HRESULT hres; + + g_assert (pin); + hres = pin->ConnectedTo (&tmp_pin); + res = (hres != VFW_E_NOT_CONNECTED); + if (tmp_pin) + tmp_pin->Release (); + + return res; +} + GstCaps * gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar * name, GstCapturePinMediaType * pin_mediatype) diff --git a/sys/dshowsrcwrapper/gstdshow.h b/sys/dshowsrcwrapper/gstdshow.h index 92220b65c5..4c75f354af 100644 --- a/sys/dshowsrcwrapper/gstdshow.h +++ b/sys/dshowsrcwrapper/gstdshow.h @@ -92,6 +92,9 @@ gboolean gst_dshow_show_propertypage (IBaseFilter * base_filter); /* translate GUID format to gsteamer video format */ GstVideoFormat gst_dshow_guid_to_gst_video_format (AM_MEDIA_TYPE *mediatype); +/* check if IPin is connected */ +gboolean gst_dshow_is_pin_connected (IPin *pin); + /* transform a dshow video caps to a gstreamer video caps */ GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar * name, GstCapturePinMediaType * pin_mediatype); diff --git a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp index 7d21c7e08a..d5a77b4039 100644 --- a/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp +++ b/sys/dshowsrcwrapper/gstdshowaudiosrc.cpp @@ -452,6 +452,13 @@ gst_dshowaudiosrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) HRESULT hres; IPin *input_pin = NULL; GstDshowAudioSrc *src = GST_DSHOWAUDIOSRC (asrc); + GstCaps *current_caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (asrc)); + + if (gst_caps_is_equal (spec->caps, current_caps)) { + gst_caps_unref (current_caps); + return TRUE; + } + gst_caps_unref (current_caps); /* In 1.0, prepare() seems to be called in the PLAYING state. Most of the time you can't do much on a running graph. */ @@ -511,6 +518,18 @@ gst_dshowaudiosrc_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec) spec->segtotal = 2; }; GST_INFO ("Configuring with segsize:%d segtotal:%d", spec->segsize, spec->segtotal); + + if (gst_dshow_is_pin_connected (pin_mediatype->capture_pin)) { + GST_DEBUG_OBJECT (src, + "capture_pin already connected, disconnecting"); + src->filter_graph->Disconnect (pin_mediatype->capture_pin); + } + + if (gst_dshow_is_pin_connected (input_pin)) { + GST_DEBUG_OBJECT (src, "input_pin already connected, disconnecting"); + src->filter_graph->Disconnect (input_pin); + } + hres = src->filter_graph->ConnectDirect (pin_mediatype->capture_pin, input_pin, NULL); input_pin->Release (); diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp index bea1d1c5ca..c254f0c805 100644 --- a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp +++ b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp @@ -576,6 +576,13 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) IPin *input_pin = NULL; GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (bsrc); GstStructure *s = gst_caps_get_structure (caps, 0); + GstCaps *current_caps = gst_pad_get_current_caps (GST_BASE_SRC_PAD (bsrc)); + + if (gst_caps_is_equal (caps, current_caps)) { + gst_caps_unref (current_caps); + return TRUE; + } + gst_caps_unref (current_caps); /* Same remark as in gstdshowaudiosrc. */ gboolean was_running = src->is_running; @@ -654,6 +661,16 @@ gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) goto error; } + if (gst_dshow_is_pin_connected (pin_mediatype->capture_pin)) { + GST_DEBUG_OBJECT (src, + "capture_pin already connected, disconnecting"); + src->filter_graph->Disconnect (pin_mediatype->capture_pin); + } + + if (gst_dshow_is_pin_connected (input_pin)) { + GST_DEBUG_OBJECT (src, "input_pin already connected, disconnecting"); + src->filter_graph->Disconnect (input_pin); + } hres = src->filter_graph->ConnectDirect (pin_mediatype->capture_pin, input_pin, pin_mediatype->mediatype);