summaryrefslogtreecommitdiff
path: root/gst/autodetect
diff options
context:
space:
mode:
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-08-03 17:18:31 +0000
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>2005-08-03 17:18:31 +0000
commit7e8df65cc2df0ddea9e943245c0ed0402306a50a (patch)
tree0a63e4d6c2a04496e89d11338d5c81838f78b7c8 /gst/autodetect
parent1b23cf61a855bd39ba822f1a179dcd479b0ef6b5 (diff)
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.
Diffstat (limited to 'gst/autodetect')
-rw-r--r--gst/autodetect/gstautoaudiosink.c93
-rw-r--r--gst/autodetect/gstautoaudiosink.h1
-rw-r--r--gst/autodetect/gstautovideosink.c90
-rw-r--r--gst/autodetect/gstautovideosink.h1
4 files changed, 101 insertions, 84 deletions
diff --git a/gst/autodetect/gstautoaudiosink.c b/gst/autodetect/gstautoaudiosink.c
index a77a541e..9d62c7de 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 3df3b944..50b6b47c 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 0a472eb3..ba22a21f 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 42885c54..06995ad8 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 {