From 7e8df65cc2df0ddea9e943245c0ed0402306a50a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 3 Aug 2005 17:18:31 +0000 Subject: [PATCH] Use new ghostpad API; now they actually work in Totem, also. Original commit message from CVS: * ext/gconf/gstgconfaudiosink.c: (gst_gconf_audio_sink_reset), (gst_gconf_audio_sink_init), (do_toggle_element), (cb_toggle_element), (gst_gconf_audio_sink_change_state): * ext/gconf/gstgconfaudiosink.h: * ext/gconf/gstgconfvideosink.c: (gst_gconf_video_sink_reset), (gst_gconf_video_sink_init), (do_toggle_element), (cb_toggle_element), (gst_gconf_video_sink_change_state): * ext/gconf/gstgconfvideosink.h: * gst/autodetect/gstautoaudiosink.c: (gst_auto_audio_sink_reset), (gst_auto_audio_sink_init), (gst_auto_audio_sink_detect), (gst_auto_audio_sink_change_state): * gst/autodetect/gstautoaudiosink.h: * gst/autodetect/gstautovideosink.c: (gst_auto_video_sink_reset), (gst_auto_video_sink_init), (gst_auto_video_sink_detect), (gst_auto_video_sink_change_state): * gst/autodetect/gstautovideosink.h: Use new ghostpad API; now they actually work in Totem, also. --- ChangeLog | 20 +++++++++ ext/gconf/gstgconfaudiosink.c | 92 +++++++++++++++++++++----------------- ext/gconf/gstgconfaudiosink.h | 1 - ext/gconf/gstgconfvideosink.c | 92 +++++++++++++++++++++----------------- ext/gconf/gstgconfvideosink.h | 1 - gst/autodetect/gstautoaudiosink.c | 93 +++++++++++++++++++++------------------ gst/autodetect/gstautoaudiosink.h | 1 - gst/autodetect/gstautovideosink.c | 90 ++++++++++++++++++++----------------- gst/autodetect/gstautovideosink.h | 1 - 9 files changed, 223 insertions(+), 168 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ab458e..75c5df2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 2005-08-03 Ronald S. Bultje + * ext/gconf/gstgconfaudiosink.c: (gst_gconf_audio_sink_reset), + (gst_gconf_audio_sink_init), (do_toggle_element), + (cb_toggle_element), (gst_gconf_audio_sink_change_state): + * ext/gconf/gstgconfaudiosink.h: + * ext/gconf/gstgconfvideosink.c: (gst_gconf_video_sink_reset), + (gst_gconf_video_sink_init), (do_toggle_element), + (cb_toggle_element), (gst_gconf_video_sink_change_state): + * ext/gconf/gstgconfvideosink.h: + * gst/autodetect/gstautoaudiosink.c: (gst_auto_audio_sink_reset), + (gst_auto_audio_sink_init), (gst_auto_audio_sink_detect), + (gst_auto_audio_sink_change_state): + * gst/autodetect/gstautoaudiosink.h: + * gst/autodetect/gstautovideosink.c: (gst_auto_video_sink_reset), + (gst_auto_video_sink_init), (gst_auto_video_sink_detect), + (gst_auto_video_sink_change_state): + * gst/autodetect/gstautovideosink.h: + Use new ghostpad API; now they actually work in Totem, also. + +2005-08-03 Ronald S. Bultje + * ext/libpng/Makefile.am: Fix uninstalled build. diff --git a/ext/gconf/gstgconfaudiosink.c b/ext/gconf/gstgconfaudiosink.c index edca50a..256f569 100644 --- a/ext/gconf/gstgconfaudiosink.c +++ b/ext/gconf/gstgconfaudiosink.c @@ -62,20 +62,40 @@ gst_gconf_audio_sink_class_init (GstGConfAudioSinkClass * klass) eklass->change_state = gst_gconf_audio_sink_change_state; } +/* + * Hack to make negotiation work. + */ + +static void +gst_gconf_audio_sink_reset (GstGConfAudioSink * sink) +{ + GstPad *targetpad; + + /* fakesink */ + if (sink->kid) { + gst_bin_remove (GST_BIN (sink), sink->kid); + } + sink->kid = gst_element_factory_make ("fakesink", "testsink"); + gst_bin_add (GST_BIN (sink), sink->kid); + + targetpad = gst_element_get_pad (sink->kid, "sink"); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); + gst_object_unref (targetpad); +} + static void gst_gconf_audio_sink_init (GstGConfAudioSink * sink) { - sink->pad = NULL; - sink->kid = NULL; + sink->pad = gst_ghost_pad_new_notarget ("sink", GST_PAD_SINK); + gst_element_add_pad (GST_ELEMENT (sink), sink->pad); + + gst_gconf_audio_sink_reset (sink); sink->client = gconf_client_get_default (); gconf_client_add_dir (sink->client, GST_GCONF_DIR, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); gconf_client_notify_add (sink->client, GST_GCONF_DIR "/default/audiosink", cb_toggle_element, sink, NULL, NULL); - cb_toggle_element (sink->client, 0, NULL, sink); - - sink->init = FALSE; } static void @@ -91,23 +111,10 @@ gst_gconf_audio_sink_dispose (GObject * object) GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); } -static void -cb_toggle_element (GConfClient * client, - guint connection_id, GConfEntry * entry, gpointer data) +static gboolean +do_toggle_element (GstGConfAudioSink * sink) { - GstGConfAudioSink *sink = GST_GCONF_AUDIO_SINK (data); - GstPad *peer = NULL, *targetpad; - - /* save ghostpad */ - if (sink->pad) { - peer = GST_PAD_PEER (sink->pad); - if (peer) { - gst_pad_unlink (peer, sink->pad); - GST_DEBUG_OBJECT (sink, "Caching peer %p", peer); - } - gst_element_remove_pad (GST_ELEMENT (sink), sink->pad); - sink->pad = NULL; - } + GstPad *targetpad; /* kill old element */ if (sink->kid) { @@ -116,31 +123,30 @@ cb_toggle_element (GConfClient * client, sink->kid = NULL; } - GST_DEBUG_OBJECT (sink, "Creating new kid (%ssink)", - entry ? "audio" : "fake"); - sink->kid = entry ? gst_gconf_get_default_audio_sink () : - gst_element_factory_make ("fakesink", "temporary-element"); - if (!sink->kid) { + GST_DEBUG_OBJECT (sink, "Creating new kid"); + if (!(sink->kid = gst_gconf_get_default_audio_sink ())) { GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL), ("Failed to render audio sink from GConf")); - return; + return FALSE; } + gst_element_set_state (sink->kid, GST_STATE (sink)); gst_bin_add (GST_BIN (sink), sink->kid); /* re-attach ghostpad */ GST_DEBUG_OBJECT (sink, "Creating new ghostpad"); targetpad = gst_element_get_pad (sink->kid, "sink"); - sink->pad = gst_ghost_pad_new ("sink", targetpad); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); - gst_element_add_pad (GST_ELEMENT (sink), sink->pad); + GST_DEBUG_OBJECT (sink, "done changing gconf audio sink"); - if (peer) { - GST_DEBUG_OBJECT (sink, "Linking..."); - gst_pad_link (peer, sink->pad); - } + return TRUE; +} - GST_DEBUG_OBJECT (sink, "done changing gconf audio sink"); - sink->init = TRUE; +static void +cb_toggle_element (GConfClient * client, + guint connection_id, GConfEntry * entry, gpointer data) +{ + do_toggle_element (GST_GCONF_AUDIO_SINK (data)); } static GstElementStateReturn @@ -148,12 +154,16 @@ gst_gconf_audio_sink_change_state (GstElement * element) { GstGConfAudioSink *sink = GST_GCONF_AUDIO_SINK (element); - if (GST_STATE_TRANSITION (element) == GST_STATE_NULL_TO_READY && !sink->init) { - cb_toggle_element (sink->client, 0, - gconf_client_get_entry (sink->client, - GST_GCONF_DIR "/default/audiosink", NULL, TRUE, NULL), sink); - if (!sink->init) - return GST_STATE_FAILURE; + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + if (!do_toggle_element (sink)) + return GST_STATE_FAILURE; + break; + case GST_STATE_READY_TO_NULL: + gst_gconf_audio_sink_reset (sink); + break; + default: + break; } return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state, diff --git a/ext/gconf/gstgconfaudiosink.h b/ext/gconf/gstgconfaudiosink.h index 28f6d82..3029aec 100644 --- a/ext/gconf/gstgconfaudiosink.h +++ b/ext/gconf/gstgconfaudiosink.h @@ -45,7 +45,6 @@ typedef struct _GstGConfAudioSink { GConfClient *client; GstElement *kid; GstPad *pad; - gboolean init; } GstGConfAudioSink; typedef struct _GstGConfAudioSinkClass { diff --git a/ext/gconf/gstgconfvideosink.c b/ext/gconf/gstgconfvideosink.c index f8f6838..88b7644 100644 --- a/ext/gconf/gstgconfvideosink.c +++ b/ext/gconf/gstgconfvideosink.c @@ -62,20 +62,40 @@ gst_gconf_video_sink_class_init (GstGConfVideoSinkClass * klass) eklass->change_state = gst_gconf_video_sink_change_state; } +/* + * Hack to make negotiation work. + */ + +static void +gst_gconf_video_sink_reset (GstGConfVideoSink * sink) +{ + GstPad *targetpad; + + /* fakesink */ + if (sink->kid) { + gst_bin_remove (GST_BIN (sink), sink->kid); + } + sink->kid = gst_element_factory_make ("fakesink", "testsink"); + gst_bin_add (GST_BIN (sink), sink->kid); + + targetpad = gst_element_get_pad (sink->kid, "sink"); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); + gst_object_unref (targetpad); +} + static void gst_gconf_video_sink_init (GstGConfVideoSink * sink) { - sink->pad = NULL; - sink->kid = NULL; + sink->pad = gst_ghost_pad_new_notarget ("sink", GST_PAD_SINK); + gst_element_add_pad (GST_ELEMENT (sink), sink->pad); + + gst_gconf_video_sink_reset (sink); sink->client = gconf_client_get_default (); gconf_client_add_dir (sink->client, GST_GCONF_DIR, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); gconf_client_notify_add (sink->client, GST_GCONF_DIR "/default/videosink", cb_toggle_element, sink, NULL, NULL); - cb_toggle_element (sink->client, 0, NULL, sink); - - sink->init = FALSE; } static void @@ -91,23 +111,10 @@ gst_gconf_video_sink_dispose (GObject * object) GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); } -static void -cb_toggle_element (GConfClient * client, - guint connection_id, GConfEntry * entry, gpointer data) +static gboolean +do_toggle_element (GstGConfVideoSink * sink) { - GstGConfVideoSink *sink = GST_GCONF_VIDEO_SINK (data); - GstPad *peer = NULL, *targetpad; - - /* save ghostpad */ - if (sink->pad) { - peer = GST_PAD_PEER (sink->pad); - if (peer) { - gst_pad_unlink (peer, sink->pad); - GST_DEBUG_OBJECT (sink, "Caching peer %p", peer); - } - gst_element_remove_pad (GST_ELEMENT (sink), sink->pad); - sink->pad = NULL; - } + GstPad *targetpad; /* kill old element */ if (sink->kid) { @@ -116,31 +123,30 @@ cb_toggle_element (GConfClient * client, sink->kid = NULL; } - GST_DEBUG_OBJECT (sink, "Creating new kid (%ssink)", - entry ? "video" : "fake"); - sink->kid = entry ? gst_gconf_get_default_video_sink () : - gst_element_factory_make ("fakesink", "temporary-element"); - if (!sink->kid) { + GST_DEBUG_OBJECT (sink, "Creating new kid"); + if (!(sink->kid = gst_gconf_get_default_video_sink ())) { GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL), ("Failed to render video sink from GConf")); - return; + return FALSE; } + gst_element_set_state (sink->kid, GST_STATE (sink)); gst_bin_add (GST_BIN (sink), sink->kid); /* re-attach ghostpad */ GST_DEBUG_OBJECT (sink, "Creating new ghostpad"); targetpad = gst_element_get_pad (sink->kid, "sink"); - sink->pad = gst_ghost_pad_new ("sink", targetpad); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); - gst_element_add_pad (GST_ELEMENT (sink), sink->pad); + GST_DEBUG_OBJECT (sink, "done changing gconf video sink"); - if (peer) { - GST_DEBUG_OBJECT (sink, "Linking..."); - gst_pad_link (peer, sink->pad); - } + return TRUE; +} - GST_DEBUG_OBJECT (sink, "done changing gconf video sink"); - sink->init = TRUE; +static void +cb_toggle_element (GConfClient * client, + guint connection_id, GConfEntry * entry, gpointer data) +{ + do_toggle_element (GST_GCONF_VIDEO_SINK (data)); } static GstElementStateReturn @@ -148,12 +154,16 @@ gst_gconf_video_sink_change_state (GstElement * element) { GstGConfVideoSink *sink = GST_GCONF_VIDEO_SINK (element); - if (GST_STATE_TRANSITION (element) == GST_STATE_NULL_TO_READY && !sink->init) { - cb_toggle_element (sink->client, 0, - gconf_client_get_entry (sink->client, - GST_GCONF_DIR "/default/videosink", NULL, TRUE, NULL), sink); - if (!sink->init) - return GST_STATE_FAILURE; + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + if (!do_toggle_element (sink)) + return GST_STATE_FAILURE; + break; + case GST_STATE_READY_TO_NULL: + gst_gconf_video_sink_reset (sink); + break; + default: + break; } return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state, diff --git a/ext/gconf/gstgconfvideosink.h b/ext/gconf/gstgconfvideosink.h index 2aa4675..9bd0bfb 100644 --- a/ext/gconf/gstgconfvideosink.h +++ b/ext/gconf/gstgconfvideosink.h @@ -45,7 +45,6 @@ typedef struct _GstGConfVideoSink { GConfClient *client; GstElement *kid; GstPad *pad; - gboolean init; } GstGConfVideoSink; typedef struct _GstGConfVideoSinkClass { diff --git a/gst/autodetect/gstautoaudiosink.c b/gst/autodetect/gstautoaudiosink.c index a77a541..9d62c7d 100644 --- a/gst/autodetect/gstautoaudiosink.c +++ b/gst/autodetect/gstautoaudiosink.c @@ -26,7 +26,6 @@ #include "gstautoaudiosink.h" #include "gstautodetect.h" -static void gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake); static GstElementStateReturn gst_auto_audio_sink_change_state (GstElement * element); @@ -60,13 +59,36 @@ gst_auto_audio_sink_class_init (GstAutoAudioSinkClass * klass) eklass->change_state = gst_auto_audio_sink_change_state; } +/* + * Hack to make initial linking work; ideally, this'd work even when + * no target has been assigned to the ghostpad yet. + */ + +static void +gst_auto_audio_sink_reset (GstAutoAudioSink * sink) +{ + GstPad *targetpad; + + /* fakesink placeholder */ + if (sink->kid) { + gst_bin_remove (GST_BIN (sink), sink->kid); + } + sink->kid = gst_element_factory_make ("fakesink", "tempsink"); + gst_bin_add (GST_BIN (sink), sink->kid); + + /* pad */ + targetpad = gst_element_get_pad (sink->kid, "sink"); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); + gst_object_unref (targetpad); +} + static void gst_auto_audio_sink_init (GstAutoAudioSink * sink) { - sink->pad = NULL; - sink->kid = NULL; - gst_auto_audio_sink_detect (sink, TRUE); - sink->init = FALSE; + sink->pad = gst_ghost_pad_new_notarget ("sink", GST_PAD_SINK); + gst_element_add_pad (GST_ELEMENT (sink), sink->pad); + + gst_auto_audio_sink_reset (sink); } static gboolean @@ -171,56 +193,35 @@ done: return choice; } -static void -gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake) +static gboolean +gst_auto_audio_sink_detect (GstAutoAudioSink * sink) { GstElement *esink; - GstPad *targetpad, *peer = NULL; - - /* save ghostpad */ - if (sink->pad) { - peer = GST_PAD_PEER (sink->pad); - if (peer) { - gst_pad_unlink (peer, sink->pad); - GST_DEBUG_OBJECT (sink, "Element was linked, caching peer %p", peer); - } - gst_element_remove_pad (GST_ELEMENT (sink), sink->pad); - sink->pad = NULL; - } + GstPad *targetpad; - /* kill old element */ if (sink->kid) { - GST_DEBUG_OBJECT (sink, "Removing old kid"); gst_bin_remove (GST_BIN (sink), sink->kid); sink->kid = NULL; } /* find element */ - GST_DEBUG_OBJECT (sink, "Creating new kid (%ssink)", fake ? "fake" : "audio"); - if (fake) { - esink = gst_element_factory_make ("fakesink", "temporary-sink"); - } else if (!(esink = gst_auto_audio_sink_find_best (sink))) { + GST_DEBUG_OBJECT (sink, "Creating new kid"); + if (!(esink = gst_auto_audio_sink_find_best (sink))) { GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL), ("Failed to find a supported audio sink")); - return; + return FALSE; } sink->kid = esink; gst_bin_add (GST_BIN (sink), esink); /* attach ghost pad */ - GST_DEBUG_OBJECT (sink, "Creating new ghostpad"); + GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad"); targetpad = gst_element_get_pad (sink->kid, "sink"); - sink->pad = gst_ghost_pad_new ("sink", targetpad); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); - gst_element_add_pad (GST_ELEMENT (sink), sink->pad); - - if (peer) { - GST_DEBUG_OBJECT (sink, "Linking..."); - gst_pad_link (peer, sink->pad); - } - GST_DEBUG_OBJECT (sink, "done changing auto audio sink"); - sink->init = TRUE; + + return TRUE; } static GstElementStateReturn @@ -228,12 +229,20 @@ gst_auto_audio_sink_change_state (GstElement * element) { GstAutoAudioSink *sink = GST_AUTO_AUDIO_SINK (element); - if (GST_STATE_TRANSITION (element) == GST_STATE_NULL_TO_READY && !sink->init) { - gst_auto_audio_sink_detect (sink, FALSE); - if (!sink->init) - return GST_STATE_FAILURE; + GST_DEBUG_OBJECT (element, "Change state 0x%x", + GST_STATE_TRANSITION (element)); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + if (!gst_auto_audio_sink_detect (sink)) + return GST_STATE_FAILURE; + break; + case GST_STATE_READY_TO_NULL: + gst_auto_audio_sink_reset (sink); + break; + default: + break; } - return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state, - (element), GST_STATE_SUCCESS); + return GST_ELEMENT_CLASS (parent_class)->change_state (element); } diff --git a/gst/autodetect/gstautoaudiosink.h b/gst/autodetect/gstautoaudiosink.h index 3df3b94..50b6b47 100644 --- a/gst/autodetect/gstautoaudiosink.h +++ b/gst/autodetect/gstautoaudiosink.h @@ -43,7 +43,6 @@ typedef struct _GstAutoAudioSink { /* explicit pointers to stuff used */ GstPad *pad; GstElement *kid; - gboolean init; } GstAutoAudioSink; typedef struct _GstAutoAudioSinkClass { diff --git a/gst/autodetect/gstautovideosink.c b/gst/autodetect/gstautovideosink.c index 0a472eb..ba22a21 100644 --- a/gst/autodetect/gstautovideosink.c +++ b/gst/autodetect/gstautovideosink.c @@ -26,7 +26,6 @@ #include "gstautovideosink.h" #include "gstautodetect.h" -static void gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake); static GstElementStateReturn gst_auto_video_sink_change_state (GstElement * element); @@ -60,13 +59,36 @@ gst_auto_video_sink_class_init (GstAutoVideoSinkClass * klass) eklass->change_state = gst_auto_video_sink_change_state; } +/* + * Hack to make initial linking work; ideally, this'd work even when + * no target has been assigned to the ghostpad yet. + */ + +static void +gst_auto_video_sink_reset (GstAutoVideoSink * sink) +{ + GstPad *targetpad; + + /* fakesink placeholder */ + if (sink->kid) { + gst_bin_remove (GST_BIN (sink), sink->kid); + } + sink->kid = gst_element_factory_make ("fakesink", "tempsink"); + gst_bin_add (GST_BIN (sink), sink->kid); + + /* pad */ + targetpad = gst_element_get_pad (sink->kid, "sink"); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); + gst_object_unref (targetpad); +} + static void gst_auto_video_sink_init (GstAutoVideoSink * sink) { - sink->pad = NULL; - sink->kid = NULL; - gst_auto_video_sink_detect (sink, TRUE); - sink->init = FALSE; + sink->pad = gst_ghost_pad_new_notarget ("sink", GST_PAD_SINK); + gst_element_add_pad (GST_ELEMENT (sink), sink->pad); + + gst_auto_video_sink_reset (sink); } static gboolean @@ -132,56 +154,35 @@ gst_auto_video_sink_find_best (GstAutoVideoSink * sink) return NULL; } -static void -gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake) +static gboolean +gst_auto_video_sink_detect (GstAutoVideoSink * sink) { GstElement *esink; - GstPad *targetpad, *peer = NULL; - - /* save ghostpad */ - if (sink->pad) { - peer = GST_PAD_PEER (sink->pad); - if (peer) { - gst_pad_unlink (peer, sink->pad); - GST_DEBUG_OBJECT (sink, "Element was linked, caching peer %p", peer); - } - gst_element_remove_pad (GST_ELEMENT (sink), sink->pad); - sink->pad = NULL; - } + GstPad *targetpad; - /* kill old element */ if (sink->kid) { - GST_DEBUG_OBJECT (sink, "Removing old kid"); gst_bin_remove (GST_BIN (sink), sink->kid); sink->kid = NULL; } /* find element */ - GST_DEBUG_OBJECT (sink, "Creating new kid (%ssink)", fake ? "fake" : "video"); - if (fake) { - esink = gst_element_factory_make ("fakesink", "temporary-sink"); - } else if (!(esink = gst_auto_video_sink_find_best (sink))) { + GST_DEBUG_OBJECT (sink, "Creating new kid"); + if (!(esink = gst_auto_video_sink_find_best (sink))) { GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL), ("Failed to find a supported video sink")); - return; + return FALSE; } sink->kid = esink; gst_bin_add (GST_BIN (sink), esink); /* attach ghost pad */ - GST_DEBUG_OBJECT (sink, "Creating new ghostpad"); + GST_DEBUG_OBJECT (sink, "Re-assigning ghostpad"); targetpad = gst_element_get_pad (sink->kid, "sink"); - sink->pad = gst_ghost_pad_new ("sink", targetpad); + gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); - gst_element_add_pad (GST_ELEMENT (sink), sink->pad); - - if (peer) { - GST_DEBUG_OBJECT (sink, "Linking..."); - gst_pad_link (peer, sink->pad); - } - GST_DEBUG_OBJECT (sink, "done changing auto video sink"); - sink->init = TRUE; + + return TRUE; } static GstElementStateReturn @@ -189,10 +190,19 @@ gst_auto_video_sink_change_state (GstElement * element) { GstAutoVideoSink *sink = GST_AUTO_VIDEO_SINK (element); - if (GST_STATE_TRANSITION (element) == GST_STATE_NULL_TO_READY && !sink->init) { - gst_auto_video_sink_detect (sink, FALSE); - if (!sink->init) - return GST_STATE_FAILURE; + GST_DEBUG_OBJECT (element, "Change state 0x%x", + GST_STATE_TRANSITION (element)); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + if (!gst_auto_video_sink_detect (sink)) + return GST_STATE_FAILURE; + break; + case GST_STATE_READY_TO_NULL: + gst_auto_video_sink_reset (sink); + break; + default: + break; } return GST_ELEMENT_CLASS (parent_class)->change_state (element); diff --git a/gst/autodetect/gstautovideosink.h b/gst/autodetect/gstautovideosink.h index 42885c5..06995ad 100644 --- a/gst/autodetect/gstautovideosink.h +++ b/gst/autodetect/gstautovideosink.h @@ -43,7 +43,6 @@ typedef struct _GstAutoVideoSink { /* explicit pointers to stuff used */ GstPad *pad; GstElement *kid; - gboolean init; } GstAutoVideoSink; typedef struct _GstAutoVideoSinkClass { -- 2.7.4