Port auto/gconfsinks to 0.9. They actually appear to work here in
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Wed, 20 Jul 2005 10:07:10 +0000 (10:07 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Wed, 20 Jul 2005 10:07:10 +0000 (10:07 +0000)
Original commit message from CVS:
* configure.ac:
* ext/Makefile.am:
* ext/gconf/Makefile.am:
* ext/gconf/gconf.c: (gst_bin_find_unconnected_pad),
(gst_gconf_render_bin_from_description),
(gst_gconf_get_default_video_sink):
* ext/gconf/gstgconfaudiosink.c: (gst_gconf_audio_sink_base_init),
(gst_gconf_audio_sink_class_init), (gst_gconf_audio_sink_dispose),
(cb_toggle_element), (gst_gconf_audio_sink_change_state):
* ext/gconf/gstgconfelements.h:
* ext/gconf/gstgconfvideosink.c: (gst_gconf_video_sink_base_init),
(gst_gconf_video_sink_class_init), (gst_gconf_video_sink_dispose),
(cb_toggle_element), (gst_gconf_video_sink_change_state):
* gst/autodetect/gstautoaudiosink.c:
(gst_auto_audio_sink_base_init), (gst_auto_audio_sink_class_init),
(gst_auto_audio_sink_detect), (gst_auto_audio_sink_change_state):
* gst/autodetect/gstautovideosink.c:
(gst_auto_video_sink_base_init), (gst_auto_video_sink_class_init),
(gst_auto_video_sink_find_best), (gst_auto_video_sink_detect):
Port auto/gconfsinks to 0.9. They actually appear to work here in
Totem as well, making them actually useful.

ChangeLog
configure.ac
ext/Makefile.am
ext/gconf/Makefile.am
ext/gconf/gconf.c
ext/gconf/gstgconfaudiosink.c
ext/gconf/gstgconfelements.h
ext/gconf/gstgconfvideosink.c
gst/autodetect/gstautoaudiosink.c
gst/autodetect/gstautovideosink.c

index b73fddb..cab12a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2005-07-20  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
+       * configure.ac:
+       * ext/Makefile.am:
+       * ext/gconf/Makefile.am:
+       * ext/gconf/gconf.c: (gst_bin_find_unconnected_pad),
+       (gst_gconf_render_bin_from_description),
+       (gst_gconf_get_default_video_sink):
+       * ext/gconf/gstgconfaudiosink.c: (gst_gconf_audio_sink_base_init),
+       (gst_gconf_audio_sink_class_init), (gst_gconf_audio_sink_dispose),
+       (cb_toggle_element), (gst_gconf_audio_sink_change_state):
+       * ext/gconf/gstgconfelements.h:
+       * ext/gconf/gstgconfvideosink.c: (gst_gconf_video_sink_base_init),
+       (gst_gconf_video_sink_class_init), (gst_gconf_video_sink_dispose),
+       (cb_toggle_element), (gst_gconf_video_sink_change_state):
+       * gst/autodetect/gstautoaudiosink.c:
+       (gst_auto_audio_sink_base_init), (gst_auto_audio_sink_class_init),
+       (gst_auto_audio_sink_detect), (gst_auto_audio_sink_change_state):
+       * gst/autodetect/gstautovideosink.c:
+       (gst_auto_video_sink_base_init), (gst_auto_video_sink_class_init),
+       (gst_auto_video_sink_find_best), (gst_auto_video_sink_detect):
+         Port auto/gconfsinks to 0.9. They actually appear to work here in
+         Totem as well, making them actually useful.
+
+2005-07-20  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
        * ext/faad/Makefile.am:
          Fix uninstalled build.
 
index 1c8288f..bac10af 100644 (file)
@@ -302,9 +302,10 @@ dnl these are all the gst plug-ins, compilable without additional libs
 GST_PLUGINS_ALL="\
                videofilter \
                alpha \
+               autodetect \
                avi \
                effectv \
-        fdsrc \
+               fdsrc \
                goom \
                law \
                level \
@@ -582,6 +583,7 @@ Makefile
 gst-plugins.spec
 gst/Makefile
 gst/alpha/Makefile
+gst/autodetect/Makefile
 gst/avi/Makefile
 gst/effectv/Makefile
 gst/fdsrc/Makefile
@@ -602,6 +604,7 @@ sys/oss/Makefile
 ext/Makefile
 ext/aalib/Makefile
 ext/dv/Makefile
+ext/gconf/Makefile
 ext/libcaca/Makefile
 ext/mad/Makefile
 ext/raw1394/Makefile
index 13e4843..0bfa012 100644 (file)
@@ -124,6 +124,12 @@ endif
 FLAC_DIR=
 # endif
 
+if USE_GCONF
+GCONF_DIR=gconf
+else
+GCONF_DIR=
+endif
+
 # if USE_GDK_PIXBUF
 # GDK_PIXBUF_DIR=gdk_pixbuf
 # else
@@ -393,6 +399,7 @@ SUBDIRS=\
        $(FAAC_DIR) \
        $(FAAD_DIR) \
        $(FLAC_DIR) \
+       $(GCONF_DIR) \
        $(GDK_PIXBUF_DIR) \
        $(GNOMEVFS_DIR) \
        $(GSM_DIR) \
@@ -434,6 +441,7 @@ SUBDIRS=\
 
 DIST_SUBDIRS=\
        mad \
+       gconf \
        shout2 \
        sidplay \
        aalib \
index 7f0052f..4e23b17 100644 (file)
@@ -3,15 +3,16 @@ plugin_LTLIBRARIES = libgstgconfelements.la
 libgstgconfelements_la_SOURCES = \
        gstgconfaudiosink.c \
        gstgconfelements.c \
-       gstgconfvideosink.c
+       gstgconfvideosink.c \
+       gconf.c
 
 DIR_CFLAGS = -DGST_GCONF_DIR=\"/system/gstreamer/@GST_MAJORMINOR@\"
 libgstgconfelements_la_CFLAGS = $(GST_CFLAGS) $(GCONF_CFLAGS) $(DIR_CFLAGS)
-libgstgconfelements_la_LIBADD = $(GCONF_LIBS) \
-       $(top_builddir)/gst-libs/gst/gconf/libgstgconf-@GST_MAJORMINOR@.la
+libgstgconfelements_la_LIBADD = $(GCONF_LIBS)
 libgstgconfelements_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 noinst_HEADERS = \
        gstgconfaudiosink.h \
        gstgconfelements.h \
-       gstgconfvideosink.h
+       gstgconfvideosink.h \
+       gconf.h
index 4c7509e..bbd327c 100644 (file)
@@ -55,25 +55,34 @@ gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
   const GList *pads = NULL;
   GstElement *element = NULL;
 
-  elements = (GList *) gst_bin_get_list (bin);
+  GST_LOCK (bin);
+  elements = bin->children;
   /* traverse all elements looking for unconnected pads */
   while (elements && pad == NULL) {
     element = GST_ELEMENT (elements->data);
-    pads = gst_element_get_pad_list (element);
+    GST_LOCK (element);
+    pads = element->pads;
     while (pads) {
+      GstPad *testpad = GST_PAD (pads->data);
+
       /* check if the direction matches */
-      if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction) {
-        if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL) {
+      if (GST_PAD_DIRECTION (testpad) == direction) {
+        GST_LOCK (testpad);
+        if (GST_PAD_PEER (testpad) == NULL) {
+          GST_UNLOCK (testpad);
           /* found it ! */
-          pad = GST_PAD (pads->data);
+          pad = testpad;
+          break;
         }
+        GST_UNLOCK (testpad);
       }
-      if (pad)
-        break;                  /* found one already */
       pads = g_list_next (pads);
     }
+    GST_UNLOCK (element);
     elements = g_list_next (elements);
   }
+  GST_UNLOCK (bin);
+
   return pad;
 }
 
@@ -158,10 +167,10 @@ gst_gconf_render_bin_from_description (const gchar * description)
 
   /* find pads and ghost them if necessary */
   if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC))) {
-    gst_element_add_ghost_pad (bin, pad, "src");
+    gst_element_add_pad (bin, gst_ghost_pad_new ("src", pad));
   }
   if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SINK))) {
-    gst_element_add_ghost_pad (bin, pad, "sink");
+    gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
   }
   return bin;
 }
@@ -217,8 +226,8 @@ gst_gconf_get_default_audio_sink (void)
  * gst_gconf_get_default_video_sink:
  *
  * Render video output bin from GStreamer GConf key : "default/videosink".
- * If key is invalid, the default video sink for the platform is used,
- * and this is detected by the autodetection bin autovideosink.
+ * If key is invalid, the default video sink for the platform is used
+ * (typically xvimagesink or ximagesink).
  *
  * Returns: a #GstElement containing the video output bin, or NULL if
  * everything failed.
@@ -229,7 +238,7 @@ gst_gconf_get_default_video_sink (void)
   GstElement *ret = gst_gconf_render_bin_from_key ("default/videosink");
 
   if (!ret) {
-    ret = gst_element_factory_make ("xvimagesink", NULL);
+    ret = gst_element_factory_make (DEFAULT_VIDEOSINK, NULL);
 
     if (!ret)
       g_warning ("No GConf default video sink key and %s doesn't work",
@@ -243,7 +252,7 @@ gst_gconf_get_default_video_sink (void)
  * gst_gconf_get_default_audio_src:
  *
  * Render audio acquisition bin from GStreamer GConf key : "default/audiosrc".
- * If key is invalid, the default audio source for the plaform is used
+ * If key is invalid, the default audio source for the plaform is used.
  * (typically osssrc or sunaudiosrc).
  *
  * Returns: a #GstElement containing the audio source bin, or NULL if
index 1db9a13..edca50a 100644 (file)
 #include "gstgconfelements.h"
 #include "gstgconfaudiosink.h"
 
-static void gst_gconf_audio_sink_base_init (GstGConfAudioSinkClass * klass);
-static void gst_gconf_audio_sink_class_init (GstGConfAudioSinkClass * klass);
-static void gst_gconf_audio_sink_init (GstGConfAudioSink * sink);
 static void gst_gconf_audio_sink_dispose (GObject * object);
-
 static void cb_toggle_element (GConfClient * client,
     guint connection_id, GConfEntry * entry, gpointer data);
-
 static GstElementStateReturn
 gst_gconf_audio_sink_change_state (GstElement * element);
 
-static GstBinClass *parent_class = NULL;
-
-GType
-gst_gconf_audio_sink_get_type (void)
-{
-  static GType gst_gconf_audio_sink_type = 0;
-
-  if (!gst_gconf_audio_sink_type) {
-    static const GTypeInfo gst_gconf_audio_sink_info = {
-      sizeof (GstGConfAudioSinkClass),
-      (GBaseInitFunc) gst_gconf_audio_sink_base_init,
-      NULL,
-      (GClassInitFunc) gst_gconf_audio_sink_class_init,
-      NULL,
-      NULL,
-      sizeof (GstGConfAudioSink),
-      0,
-      (GInstanceInitFunc) gst_gconf_audio_sink_init,
-    };
-
-    gst_gconf_audio_sink_type = g_type_register_static (GST_TYPE_BIN,
-        "GstGConfAudioSink", &gst_gconf_audio_sink_info, 0);
-  }
-
-  return gst_gconf_audio_sink_type;
-}
+GST_BOILERPLATE (GstGConfAudioSink, gst_gconf_audio_sink, GstBin, GST_TYPE_BIN);
 
 static void
-gst_gconf_audio_sink_base_init (GstGConfAudioSinkClass * klass)
+gst_gconf_audio_sink_base_init (gpointer klass)
 {
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
   GstElementDetails gst_gconf_audio_sink_details = {
@@ -88,8 +58,6 @@ gst_gconf_audio_sink_class_init (GstGConfAudioSinkClass * klass)
   GObjectClass *oklass = G_OBJECT_CLASS (klass);
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_BIN);
-
   oklass->dispose = gst_gconf_audio_sink_dispose;
   eklass->change_state = gst_gconf_audio_sink_change_state;
 }
@@ -120,7 +88,7 @@ gst_gconf_audio_sink_dispose (GObject * object)
     sink->client = NULL;
   }
 
-  G_OBJECT_CLASS (parent_class)->dispose (object);
+  GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
 }
 
 static void
@@ -128,15 +96,17 @@ cb_toggle_element (GConfClient * client,
     guint connection_id, GConfEntry * entry, gpointer data)
 {
   GstGConfAudioSink *sink = GST_GCONF_AUDIO_SINK (data);
-  GstPad *peer = NULL;
-  GstElementState state = GST_STATE (sink);
+  GstPad *peer = NULL, *targetpad;
 
   /* save ghostpad */
   if (sink->pad) {
-    gst_object_ref (GST_OBJECT (sink->pad));
-    peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad));
-    if (peer)
+    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;
   }
 
   /* kill old element */
@@ -158,21 +128,16 @@ cb_toggle_element (GConfClient * client,
   gst_bin_add (GST_BIN (sink), sink->kid);
 
   /* re-attach ghostpad */
-  if (sink->pad) {
-    GST_DEBUG_OBJECT (sink, "Re-doing existing ghostpad");
-    gst_pad_add_ghost_pad (gst_element_get_pad (sink->kid, "sink"), sink->pad);
-  } else {
-    GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
-    sink->pad = gst_ghost_pad_new ("sink",
-        gst_element_get_pad (sink->kid, "sink"));
-    gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
-  }
+  GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
+  targetpad = gst_element_get_pad (sink->kid, "sink");
+  sink->pad = gst_ghost_pad_new ("sink", 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, "Syncing state");
-  gst_element_set_state (GST_ELEMENT (sink), state);
 
   GST_DEBUG_OBJECT (sink, "done changing gconf audio sink");
   sink->init = TRUE;
@@ -191,5 +156,6 @@ gst_gconf_audio_sink_change_state (GstElement * element)
       return GST_STATE_FAILURE;
   }
 
-  return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+  return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state,
+      (element), GST_STATE_SUCCESS);
 }
index c49ab53..1b3efe3 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef __GST_GCONF_ELEMENTS_H__
 #define __GST_GCONF_ELEMENTS_H__
 
-#include <gst/gconf/gconf.h>
+#include <gconf.h>
 
 GST_DEBUG_CATEGORY_EXTERN (gconf_debug);
 #define GST_CAT_DEFAULT gconf_debug
index ce20bf7..f8f6838 100644 (file)
 #include "gstgconfelements.h"
 #include "gstgconfvideosink.h"
 
-static void gst_gconf_video_sink_base_init (GstGConfVideoSinkClass * klass);
-static void gst_gconf_video_sink_class_init (GstGConfVideoSinkClass * klass);
-static void gst_gconf_video_sink_init (GstGConfVideoSink * sink);
 static void gst_gconf_video_sink_dispose (GObject * object);
-
 static void cb_toggle_element (GConfClient * client,
     guint connection_id, GConfEntry * entry, gpointer data);
-
 static GstElementStateReturn
 gst_gconf_video_sink_change_state (GstElement * element);
 
-static GstBinClass *parent_class = NULL;
-
-GType
-gst_gconf_video_sink_get_type (void)
-{
-  static GType gst_gconf_video_sink_type = 0;
-
-  if (!gst_gconf_video_sink_type) {
-    static const GTypeInfo gst_gconf_video_sink_info = {
-      sizeof (GstGConfVideoSinkClass),
-      (GBaseInitFunc) gst_gconf_video_sink_base_init,
-      NULL,
-      (GClassInitFunc) gst_gconf_video_sink_class_init,
-      NULL,
-      NULL,
-      sizeof (GstGConfVideoSink),
-      0,
-      (GInstanceInitFunc) gst_gconf_video_sink_init,
-    };
-
-    gst_gconf_video_sink_type = g_type_register_static (GST_TYPE_BIN,
-        "GstGConfVideoSink", &gst_gconf_video_sink_info, 0);
-  }
-
-  return gst_gconf_video_sink_type;
-}
+GST_BOILERPLATE (GstGConfVideoSink, gst_gconf_video_sink, GstBin, GST_TYPE_BIN);
 
 static void
-gst_gconf_video_sink_base_init (GstGConfVideoSinkClass * klass)
+gst_gconf_video_sink_base_init (gpointer klass)
 {
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
   GstElementDetails gst_gconf_video_sink_details = {
@@ -88,8 +58,6 @@ gst_gconf_video_sink_class_init (GstGConfVideoSinkClass * klass)
   GObjectClass *oklass = G_OBJECT_CLASS (klass);
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_BIN);
-
   oklass->dispose = gst_gconf_video_sink_dispose;
   eklass->change_state = gst_gconf_video_sink_change_state;
 }
@@ -120,7 +88,7 @@ gst_gconf_video_sink_dispose (GObject * object)
     sink->client = NULL;
   }
 
-  G_OBJECT_CLASS (parent_class)->dispose (object);
+  GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
 }
 
 static void
@@ -128,15 +96,17 @@ cb_toggle_element (GConfClient * client,
     guint connection_id, GConfEntry * entry, gpointer data)
 {
   GstGConfVideoSink *sink = GST_GCONF_VIDEO_SINK (data);
-  GstPad *peer = NULL;
-  GstElementState state = GST_STATE (sink);
+  GstPad *peer = NULL, *targetpad;
 
   /* save ghostpad */
   if (sink->pad) {
-    gst_object_ref (GST_OBJECT (sink->pad));
-    peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad));
-    if (peer)
+    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;
   }
 
   /* kill old element */
@@ -158,21 +128,16 @@ cb_toggle_element (GConfClient * client,
   gst_bin_add (GST_BIN (sink), sink->kid);
 
   /* re-attach ghostpad */
-  if (sink->pad) {
-    GST_DEBUG_OBJECT (sink, "Re-doing existing ghostpad");
-    gst_pad_add_ghost_pad (gst_element_get_pad (sink->kid, "sink"), sink->pad);
-  } else {
-    GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
-    sink->pad = gst_ghost_pad_new ("sink",
-        gst_element_get_pad (sink->kid, "sink"));
-    gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
-  }
+  GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
+  targetpad = gst_element_get_pad (sink->kid, "sink");
+  sink->pad = gst_ghost_pad_new ("sink", 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, "Syncing state");
-  gst_element_set_state (GST_ELEMENT (sink), state);
 
   GST_DEBUG_OBJECT (sink, "done changing gconf video sink");
   sink->init = TRUE;
@@ -191,5 +156,6 @@ gst_gconf_video_sink_change_state (GstElement * element)
       return GST_STATE_FAILURE;
   }
 
-  return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+  return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state,
+      (element), GST_STATE_SUCCESS);
 }
index b2593b6..a77a541 100644 (file)
 #include "gstautoaudiosink.h"
 #include "gstautodetect.h"
 
-static void gst_auto_audio_sink_base_init (GstAutoAudioSinkClass * klass);
-static void gst_auto_audio_sink_class_init (GstAutoAudioSinkClass * klass);
-static void gst_auto_audio_sink_init (GstAutoAudioSink * sink);
 static void gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake);
 static GstElementStateReturn
 gst_auto_audio_sink_change_state (GstElement * element);
 
-static GstBinClass *parent_class = NULL;
-
-GType
-gst_auto_audio_sink_get_type (void)
-{
-  static GType gst_auto_audio_sink_type = 0;
-
-  if (!gst_auto_audio_sink_type) {
-    static const GTypeInfo gst_auto_audio_sink_info = {
-      sizeof (GstAutoAudioSinkClass),
-      (GBaseInitFunc) gst_auto_audio_sink_base_init,
-      NULL,
-      (GClassInitFunc) gst_auto_audio_sink_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAutoAudioSink),
-      0,
-      (GInstanceInitFunc) gst_auto_audio_sink_init,
-    };
-
-    gst_auto_audio_sink_type = g_type_register_static (GST_TYPE_BIN,
-        "GstAutoAudioSink", &gst_auto_audio_sink_info, 0);
-  }
-
-  return gst_auto_audio_sink_type;
-}
+GST_BOILERPLATE (GstAutoAudioSink, gst_auto_audio_sink, GstBin, GST_TYPE_BIN);
 
 static void
-gst_auto_audio_sink_base_init (GstAutoAudioSinkClass * klass)
+gst_auto_audio_sink_base_init (gpointer klass)
 {
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
   GstElementDetails gst_auto_audio_sink_details = {
@@ -85,8 +57,6 @@ gst_auto_audio_sink_class_init (GstAutoAudioSinkClass * klass)
 {
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_BIN);
-
   eklass->change_state = gst_auto_audio_sink_change_state;
 }
 
@@ -205,14 +175,17 @@ static void
 gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake)
 {
   GstElement *esink;
-  GstPad *peer = NULL;
+  GstPad *targetpad, *peer = NULL;
 
   /* save ghostpad */
   if (sink->pad) {
-    gst_object_ref (GST_OBJECT (sink->pad));
-    peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad));
-    if (peer)
+    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;
   }
 
   /* kill old element */
@@ -235,17 +208,12 @@ gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake)
   gst_bin_add (GST_BIN (sink), esink);
 
   /* attach ghost pad */
-  if (sink->pad) {
-    GST_DEBUG_OBJECT (sink, "Re-doing existing ghostpad");
-    gst_pad_add_ghost_pad (gst_element_get_pad (sink->kid, "sink"), sink->pad);
-    if (GST_ELEMENT (sink)->pads == NULL)
-      gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
-  } else {
-    GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
-    sink->pad = gst_ghost_pad_new ("sink",
-        gst_element_get_pad (sink->kid, "sink"));
-    gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
-  }
+  GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
+  targetpad = gst_element_get_pad (sink->kid, "sink");
+  sink->pad = gst_ghost_pad_new ("sink", 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);
@@ -266,5 +234,6 @@ gst_auto_audio_sink_change_state (GstElement * element)
       return GST_STATE_FAILURE;
   }
 
-  return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+  return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, change_state,
+      (element), GST_STATE_SUCCESS);
 }
index 0ae2ecc..0a472eb 100644 (file)
 #include "gstautovideosink.h"
 #include "gstautodetect.h"
 
-static void gst_auto_video_sink_base_init (GstAutoVideoSinkClass * klass);
-static void gst_auto_video_sink_class_init (GstAutoVideoSinkClass * klass);
-static void gst_auto_video_sink_init (GstAutoVideoSink * sink);
 static void gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake);
 static GstElementStateReturn
 gst_auto_video_sink_change_state (GstElement * element);
 
-static GstBinClass *parent_class = NULL;
-
-GType
-gst_auto_video_sink_get_type (void)
-{
-  static GType gst_auto_video_sink_type = 0;
-
-  if (!gst_auto_video_sink_type) {
-    static const GTypeInfo gst_auto_video_sink_info = {
-      sizeof (GstAutoVideoSinkClass),
-      (GBaseInitFunc) gst_auto_video_sink_base_init,
-      NULL,
-      (GClassInitFunc) gst_auto_video_sink_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAutoVideoSink),
-      0,
-      (GInstanceInitFunc) gst_auto_video_sink_init,
-    };
-
-    gst_auto_video_sink_type = g_type_register_static (GST_TYPE_BIN,
-        "GstAutoVideoSink", &gst_auto_video_sink_info, 0);
-  }
-
-  return gst_auto_video_sink_type;
-}
+GST_BOILERPLATE (GstAutoVideoSink, gst_auto_video_sink, GstBin, GST_TYPE_BIN);
 
 static void
-gst_auto_video_sink_base_init (GstAutoVideoSinkClass * klass)
+gst_auto_video_sink_base_init (gpointer klass)
 {
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
   GstElementDetails gst_auto_video_sink_details = {
@@ -85,8 +57,6 @@ gst_auto_video_sink_class_init (GstAutoVideoSinkClass * klass)
 {
   GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_BIN);
-
   eklass->change_state = gst_auto_video_sink_change_state;
 }
 
@@ -147,9 +117,11 @@ gst_auto_video_sink_find_best (GstAutoVideoSink * sink)
     GstElementFactory *f = GST_ELEMENT_FACTORY (list->data);
     GstElement *el;
 
+    GST_DEBUG_OBJECT (sink, "Trying %s", GST_PLUGIN_FEATURE (f)->name);
     if ((el = gst_element_factory_create (f, "actual-sink"))) {
+      GST_DEBUG_OBJECT (sink, "Changing state to READY");
       if (gst_element_set_state (el, GST_STATE_READY) == GST_STATE_SUCCESS) {
-        gst_element_set_state (el, GST_STATE_NULL);
+        GST_DEBUG_OBJECT (sink, "success");
         return el;
       }
 
@@ -164,14 +136,17 @@ static void
 gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake)
 {
   GstElement *esink;
-  GstPad *peer = NULL;
+  GstPad *targetpad, *peer = NULL;
 
   /* save ghostpad */
   if (sink->pad) {
-    gst_object_ref (GST_OBJECT (sink->pad));
-    peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad));
-    if (peer)
+    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;
   }
 
   /* kill old element */
@@ -185,7 +160,6 @@ gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake)
   GST_DEBUG_OBJECT (sink, "Creating new kid (%ssink)", fake ? "fake" : "video");
   if (fake) {
     esink = gst_element_factory_make ("fakesink", "temporary-sink");
-    g_return_if_fail (esink);
   } else if (!(esink = gst_auto_video_sink_find_best (sink))) {
     GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
         ("Failed to find a supported video sink"));
@@ -195,15 +169,12 @@ gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake)
   gst_bin_add (GST_BIN (sink), esink);
 
   /* attach ghost pad */
-  if (sink->pad) {
-    GST_DEBUG_OBJECT (sink, "Re-doing existing ghostpad");
-    gst_pad_add_ghost_pad (gst_element_get_pad (sink->kid, "sink"), sink->pad);
-  } else {
-    GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
-    sink->pad = gst_ghost_pad_new ("sink",
-        gst_element_get_pad (sink->kid, "sink"));
-    gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
-  }
+  GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
+  targetpad = gst_element_get_pad (sink->kid, "sink");
+  sink->pad = gst_ghost_pad_new ("sink", 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);