diff --git a/ChangeLog b/ChangeLog index b73fddb831..cab12a92f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2005-07-20 Ronald S. Bultje + + * 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 * ext/faad/Makefile.am: diff --git a/configure.ac b/configure.ac index 1c8288fd4c..bac10af74d 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/ext/Makefile.am b/ext/Makefile.am index 13e4843506..0bfa012c54 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -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 \ diff --git a/ext/gconf/Makefile.am b/ext/gconf/Makefile.am index 7f0052fbd0..4e23b174c5 100644 --- a/ext/gconf/Makefile.am +++ b/ext/gconf/Makefile.am @@ -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 diff --git a/ext/gconf/gconf.c b/ext/gconf/gconf.c index 4c7509e23c..bbd327ccd6 100644 --- a/ext/gconf/gconf.c +++ b/ext/gconf/gconf.c @@ -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 diff --git a/ext/gconf/gstgconfaudiosink.c b/ext/gconf/gstgconfaudiosink.c index 1db9a138ce..edca50ac17 100644 --- a/ext/gconf/gstgconfaudiosink.c +++ b/ext/gconf/gstgconfaudiosink.c @@ -24,46 +24,16 @@ #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); } diff --git a/ext/gconf/gstgconfelements.h b/ext/gconf/gstgconfelements.h index c49ab5352e..1b3efe3cbc 100644 --- a/ext/gconf/gstgconfelements.h +++ b/ext/gconf/gstgconfelements.h @@ -20,7 +20,7 @@ #ifndef __GST_GCONF_ELEMENTS_H__ #define __GST_GCONF_ELEMENTS_H__ -#include +#include GST_DEBUG_CATEGORY_EXTERN (gconf_debug); #define GST_CAT_DEFAULT gconf_debug diff --git a/ext/gconf/gstgconfvideosink.c b/ext/gconf/gstgconfvideosink.c index ce20bf7152..f8f6838907 100644 --- a/ext/gconf/gstgconfvideosink.c +++ b/ext/gconf/gstgconfvideosink.c @@ -24,46 +24,16 @@ #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); } diff --git a/gst/autodetect/gstautoaudiosink.c b/gst/autodetect/gstautoaudiosink.c index b2593b661b..a77a541e1c 100644 --- a/gst/autodetect/gstautoaudiosink.c +++ b/gst/autodetect/gstautoaudiosink.c @@ -26,42 +26,14 @@ #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); } diff --git a/gst/autodetect/gstautovideosink.c b/gst/autodetect/gstautovideosink.c index 0ae2eccace..0a472eb3d7 100644 --- a/gst/autodetect/gstautovideosink.c +++ b/gst/autodetect/gstautovideosink.c @@ -26,42 +26,14 @@ #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);