Port auto/gconfsinks to 0.9. They actually appear to work here in

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.
This commit is contained in:
Ronald S. Bultje 2005-07-20 10:07:10 +00:00
parent bef986dba1
commit 961178077e
10 changed files with 135 additions and 218 deletions

View file

@ -1,3 +1,27 @@
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> 2005-07-20 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* ext/faad/Makefile.am: * ext/faad/Makefile.am:

View file

@ -302,6 +302,7 @@ dnl these are all the gst plug-ins, compilable without additional libs
GST_PLUGINS_ALL="\ GST_PLUGINS_ALL="\
videofilter \ videofilter \
alpha \ alpha \
autodetect \
avi \ avi \
effectv \ effectv \
fdsrc \ fdsrc \
@ -582,6 +583,7 @@ Makefile
gst-plugins.spec gst-plugins.spec
gst/Makefile gst/Makefile
gst/alpha/Makefile gst/alpha/Makefile
gst/autodetect/Makefile
gst/avi/Makefile gst/avi/Makefile
gst/effectv/Makefile gst/effectv/Makefile
gst/fdsrc/Makefile gst/fdsrc/Makefile
@ -602,6 +604,7 @@ sys/oss/Makefile
ext/Makefile ext/Makefile
ext/aalib/Makefile ext/aalib/Makefile
ext/dv/Makefile ext/dv/Makefile
ext/gconf/Makefile
ext/libcaca/Makefile ext/libcaca/Makefile
ext/mad/Makefile ext/mad/Makefile
ext/raw1394/Makefile ext/raw1394/Makefile

View file

@ -124,6 +124,12 @@ endif
FLAC_DIR= FLAC_DIR=
# endif # endif
if USE_GCONF
GCONF_DIR=gconf
else
GCONF_DIR=
endif
# if USE_GDK_PIXBUF # if USE_GDK_PIXBUF
# GDK_PIXBUF_DIR=gdk_pixbuf # GDK_PIXBUF_DIR=gdk_pixbuf
# else # else
@ -393,6 +399,7 @@ SUBDIRS=\
$(FAAC_DIR) \ $(FAAC_DIR) \
$(FAAD_DIR) \ $(FAAD_DIR) \
$(FLAC_DIR) \ $(FLAC_DIR) \
$(GCONF_DIR) \
$(GDK_PIXBUF_DIR) \ $(GDK_PIXBUF_DIR) \
$(GNOMEVFS_DIR) \ $(GNOMEVFS_DIR) \
$(GSM_DIR) \ $(GSM_DIR) \
@ -434,6 +441,7 @@ SUBDIRS=\
DIST_SUBDIRS=\ DIST_SUBDIRS=\
mad \ mad \
gconf \
shout2 \ shout2 \
sidplay \ sidplay \
aalib \ aalib \

View file

@ -3,15 +3,16 @@ plugin_LTLIBRARIES = libgstgconfelements.la
libgstgconfelements_la_SOURCES = \ libgstgconfelements_la_SOURCES = \
gstgconfaudiosink.c \ gstgconfaudiosink.c \
gstgconfelements.c \ gstgconfelements.c \
gstgconfvideosink.c gstgconfvideosink.c \
gconf.c
DIR_CFLAGS = -DGST_GCONF_DIR=\"/system/gstreamer/@GST_MAJORMINOR@\" DIR_CFLAGS = -DGST_GCONF_DIR=\"/system/gstreamer/@GST_MAJORMINOR@\"
libgstgconfelements_la_CFLAGS = $(GST_CFLAGS) $(GCONF_CFLAGS) $(DIR_CFLAGS) libgstgconfelements_la_CFLAGS = $(GST_CFLAGS) $(GCONF_CFLAGS) $(DIR_CFLAGS)
libgstgconfelements_la_LIBADD = $(GCONF_LIBS) \ libgstgconfelements_la_LIBADD = $(GCONF_LIBS)
$(top_builddir)/gst-libs/gst/gconf/libgstgconf-@GST_MAJORMINOR@.la
libgstgconfelements_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstgconfelements_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = \ noinst_HEADERS = \
gstgconfaudiosink.h \ gstgconfaudiosink.h \
gstgconfelements.h \ gstgconfelements.h \
gstgconfvideosink.h gstgconfvideosink.h \
gconf.h

View file

@ -55,25 +55,34 @@ gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
const GList *pads = NULL; const GList *pads = NULL;
GstElement *element = NULL; GstElement *element = NULL;
elements = (GList *) gst_bin_get_list (bin); GST_LOCK (bin);
elements = bin->children;
/* traverse all elements looking for unconnected pads */ /* traverse all elements looking for unconnected pads */
while (elements && pad == NULL) { while (elements && pad == NULL) {
element = GST_ELEMENT (elements->data); element = GST_ELEMENT (elements->data);
pads = gst_element_get_pad_list (element); GST_LOCK (element);
pads = element->pads;
while (pads) { while (pads) {
GstPad *testpad = GST_PAD (pads->data);
/* check if the direction matches */ /* check if the direction matches */
if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == direction) { if (GST_PAD_DIRECTION (testpad) == direction) {
if (GST_PAD_PEER (GST_PAD (pads->data)) == NULL) { GST_LOCK (testpad);
if (GST_PAD_PEER (testpad) == NULL) {
GST_UNLOCK (testpad);
/* found it ! */ /* found it ! */
pad = GST_PAD (pads->data); pad = testpad;
break;
} }
GST_UNLOCK (testpad);
} }
if (pad)
break; /* found one already */
pads = g_list_next (pads); pads = g_list_next (pads);
} }
GST_UNLOCK (element);
elements = g_list_next (elements); elements = g_list_next (elements);
} }
GST_UNLOCK (bin);
return pad; return pad;
} }
@ -158,10 +167,10 @@ gst_gconf_render_bin_from_description (const gchar * description)
/* find pads and ghost them if necessary */ /* find pads and ghost them if necessary */
if ((pad = gst_bin_find_unconnected_pad (GST_BIN (bin), GST_PAD_SRC))) { 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))) { 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; return bin;
} }
@ -217,8 +226,8 @@ gst_gconf_get_default_audio_sink (void)
* gst_gconf_get_default_video_sink: * gst_gconf_get_default_video_sink:
* *
* Render video output bin from GStreamer GConf key : "default/videosink". * Render video output bin from GStreamer GConf key : "default/videosink".
* If key is invalid, the default video sink for the platform is used, * If key is invalid, the default video sink for the platform is used
* and this is detected by the autodetection bin autovideosink. * (typically xvimagesink or ximagesink).
* *
* Returns: a #GstElement containing the video output bin, or NULL if * Returns: a #GstElement containing the video output bin, or NULL if
* everything failed. * everything failed.
@ -229,7 +238,7 @@ gst_gconf_get_default_video_sink (void)
GstElement *ret = gst_gconf_render_bin_from_key ("default/videosink"); GstElement *ret = gst_gconf_render_bin_from_key ("default/videosink");
if (!ret) { if (!ret) {
ret = gst_element_factory_make ("xvimagesink", NULL); ret = gst_element_factory_make (DEFAULT_VIDEOSINK, NULL);
if (!ret) if (!ret)
g_warning ("No GConf default video sink key and %s doesn't work", 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: * gst_gconf_get_default_audio_src:
* *
* Render audio acquisition bin from GStreamer GConf key : "default/audiosrc". * 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). * (typically osssrc or sunaudiosrc).
* *
* Returns: a #GstElement containing the audio source bin, or NULL if * Returns: a #GstElement containing the audio source bin, or NULL if

View file

@ -24,46 +24,16 @@
#include "gstgconfelements.h" #include "gstgconfelements.h"
#include "gstgconfaudiosink.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 gst_gconf_audio_sink_dispose (GObject * object);
static void cb_toggle_element (GConfClient * client, static void cb_toggle_element (GConfClient * client,
guint connection_id, GConfEntry * entry, gpointer data); guint connection_id, GConfEntry * entry, gpointer data);
static GstElementStateReturn static GstElementStateReturn
gst_gconf_audio_sink_change_state (GstElement * element); gst_gconf_audio_sink_change_state (GstElement * element);
static GstBinClass *parent_class = NULL; GST_BOILERPLATE (GstGConfAudioSink, gst_gconf_audio_sink, GstBin, GST_TYPE_BIN);
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;
}
static void static void
gst_gconf_audio_sink_base_init (GstGConfAudioSinkClass * klass) gst_gconf_audio_sink_base_init (gpointer klass)
{ {
GstElementClass *eklass = GST_ELEMENT_CLASS (klass); GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
GstElementDetails gst_gconf_audio_sink_details = { GstElementDetails gst_gconf_audio_sink_details = {
@ -88,8 +58,6 @@ gst_gconf_audio_sink_class_init (GstGConfAudioSinkClass * klass)
GObjectClass *oklass = G_OBJECT_CLASS (klass); GObjectClass *oklass = G_OBJECT_CLASS (klass);
GstElementClass *eklass = GST_ELEMENT_CLASS (klass); GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
parent_class = g_type_class_ref (GST_TYPE_BIN);
oklass->dispose = gst_gconf_audio_sink_dispose; oklass->dispose = gst_gconf_audio_sink_dispose;
eklass->change_state = gst_gconf_audio_sink_change_state; eklass->change_state = gst_gconf_audio_sink_change_state;
} }
@ -120,7 +88,7 @@ gst_gconf_audio_sink_dispose (GObject * object)
sink->client = NULL; sink->client = NULL;
} }
G_OBJECT_CLASS (parent_class)->dispose (object); GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
} }
static void static void
@ -128,15 +96,17 @@ cb_toggle_element (GConfClient * client,
guint connection_id, GConfEntry * entry, gpointer data) guint connection_id, GConfEntry * entry, gpointer data)
{ {
GstGConfAudioSink *sink = GST_GCONF_AUDIO_SINK (data); GstGConfAudioSink *sink = GST_GCONF_AUDIO_SINK (data);
GstPad *peer = NULL; GstPad *peer = NULL, *targetpad;
GstElementState state = GST_STATE (sink);
/* save ghostpad */ /* save ghostpad */
if (sink->pad) { if (sink->pad) {
gst_object_ref (GST_OBJECT (sink->pad)); peer = GST_PAD_PEER (sink->pad);
peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad)); if (peer) {
if (peer)
gst_pad_unlink (peer, sink->pad); 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 */ /* kill old element */
@ -158,21 +128,16 @@ cb_toggle_element (GConfClient * client,
gst_bin_add (GST_BIN (sink), sink->kid); gst_bin_add (GST_BIN (sink), sink->kid);
/* re-attach ghostpad */ /* 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"); GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
sink->pad = gst_ghost_pad_new ("sink", targetpad = gst_element_get_pad (sink->kid, "sink");
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); gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
}
if (peer) { if (peer) {
GST_DEBUG_OBJECT (sink, "Linking..."); GST_DEBUG_OBJECT (sink, "Linking...");
gst_pad_link (peer, sink->pad); 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"); GST_DEBUG_OBJECT (sink, "done changing gconf audio sink");
sink->init = TRUE; sink->init = TRUE;
@ -191,5 +156,6 @@ gst_gconf_audio_sink_change_state (GstElement * element)
return GST_STATE_FAILURE; 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);
} }

View file

@ -20,7 +20,7 @@
#ifndef __GST_GCONF_ELEMENTS_H__ #ifndef __GST_GCONF_ELEMENTS_H__
#define __GST_GCONF_ELEMENTS_H__ #define __GST_GCONF_ELEMENTS_H__
#include <gst/gconf/gconf.h> #include <gconf.h>
GST_DEBUG_CATEGORY_EXTERN (gconf_debug); GST_DEBUG_CATEGORY_EXTERN (gconf_debug);
#define GST_CAT_DEFAULT gconf_debug #define GST_CAT_DEFAULT gconf_debug

View file

@ -24,46 +24,16 @@
#include "gstgconfelements.h" #include "gstgconfelements.h"
#include "gstgconfvideosink.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 gst_gconf_video_sink_dispose (GObject * object);
static void cb_toggle_element (GConfClient * client, static void cb_toggle_element (GConfClient * client,
guint connection_id, GConfEntry * entry, gpointer data); guint connection_id, GConfEntry * entry, gpointer data);
static GstElementStateReturn static GstElementStateReturn
gst_gconf_video_sink_change_state (GstElement * element); gst_gconf_video_sink_change_state (GstElement * element);
static GstBinClass *parent_class = NULL; GST_BOILERPLATE (GstGConfVideoSink, gst_gconf_video_sink, GstBin, GST_TYPE_BIN);
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;
}
static void static void
gst_gconf_video_sink_base_init (GstGConfVideoSinkClass * klass) gst_gconf_video_sink_base_init (gpointer klass)
{ {
GstElementClass *eklass = GST_ELEMENT_CLASS (klass); GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
GstElementDetails gst_gconf_video_sink_details = { GstElementDetails gst_gconf_video_sink_details = {
@ -88,8 +58,6 @@ gst_gconf_video_sink_class_init (GstGConfVideoSinkClass * klass)
GObjectClass *oklass = G_OBJECT_CLASS (klass); GObjectClass *oklass = G_OBJECT_CLASS (klass);
GstElementClass *eklass = GST_ELEMENT_CLASS (klass); GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
parent_class = g_type_class_ref (GST_TYPE_BIN);
oklass->dispose = gst_gconf_video_sink_dispose; oklass->dispose = gst_gconf_video_sink_dispose;
eklass->change_state = gst_gconf_video_sink_change_state; eklass->change_state = gst_gconf_video_sink_change_state;
} }
@ -120,7 +88,7 @@ gst_gconf_video_sink_dispose (GObject * object)
sink->client = NULL; sink->client = NULL;
} }
G_OBJECT_CLASS (parent_class)->dispose (object); GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
} }
static void static void
@ -128,15 +96,17 @@ cb_toggle_element (GConfClient * client,
guint connection_id, GConfEntry * entry, gpointer data) guint connection_id, GConfEntry * entry, gpointer data)
{ {
GstGConfVideoSink *sink = GST_GCONF_VIDEO_SINK (data); GstGConfVideoSink *sink = GST_GCONF_VIDEO_SINK (data);
GstPad *peer = NULL; GstPad *peer = NULL, *targetpad;
GstElementState state = GST_STATE (sink);
/* save ghostpad */ /* save ghostpad */
if (sink->pad) { if (sink->pad) {
gst_object_ref (GST_OBJECT (sink->pad)); peer = GST_PAD_PEER (sink->pad);
peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad)); if (peer) {
if (peer)
gst_pad_unlink (peer, sink->pad); 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 */ /* kill old element */
@ -158,21 +128,16 @@ cb_toggle_element (GConfClient * client,
gst_bin_add (GST_BIN (sink), sink->kid); gst_bin_add (GST_BIN (sink), sink->kid);
/* re-attach ghostpad */ /* 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"); GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
sink->pad = gst_ghost_pad_new ("sink", targetpad = gst_element_get_pad (sink->kid, "sink");
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); gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
}
if (peer) { if (peer) {
GST_DEBUG_OBJECT (sink, "Linking..."); GST_DEBUG_OBJECT (sink, "Linking...");
gst_pad_link (peer, sink->pad); 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"); GST_DEBUG_OBJECT (sink, "done changing gconf video sink");
sink->init = TRUE; sink->init = TRUE;
@ -191,5 +156,6 @@ gst_gconf_video_sink_change_state (GstElement * element)
return GST_STATE_FAILURE; 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);
} }

View file

@ -26,42 +26,14 @@
#include "gstautoaudiosink.h" #include "gstautoaudiosink.h"
#include "gstautodetect.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 void gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake);
static GstElementStateReturn static GstElementStateReturn
gst_auto_audio_sink_change_state (GstElement * element); gst_auto_audio_sink_change_state (GstElement * element);
static GstBinClass *parent_class = NULL; GST_BOILERPLATE (GstAutoAudioSink, gst_auto_audio_sink, GstBin, GST_TYPE_BIN);
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;
}
static void static void
gst_auto_audio_sink_base_init (GstAutoAudioSinkClass * klass) gst_auto_audio_sink_base_init (gpointer klass)
{ {
GstElementClass *eklass = GST_ELEMENT_CLASS (klass); GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
GstElementDetails gst_auto_audio_sink_details = { GstElementDetails gst_auto_audio_sink_details = {
@ -85,8 +57,6 @@ gst_auto_audio_sink_class_init (GstAutoAudioSinkClass * klass)
{ {
GstElementClass *eklass = GST_ELEMENT_CLASS (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; eklass->change_state = gst_auto_audio_sink_change_state;
} }
@ -205,14 +175,17 @@ static void
gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake) gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake)
{ {
GstElement *esink; GstElement *esink;
GstPad *peer = NULL; GstPad *targetpad, *peer = NULL;
/* save ghostpad */ /* save ghostpad */
if (sink->pad) { if (sink->pad) {
gst_object_ref (GST_OBJECT (sink->pad)); peer = GST_PAD_PEER (sink->pad);
peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad)); if (peer) {
if (peer)
gst_pad_unlink (peer, sink->pad); 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 */ /* kill old element */
@ -235,17 +208,12 @@ gst_auto_audio_sink_detect (GstAutoAudioSink * sink, gboolean fake)
gst_bin_add (GST_BIN (sink), esink); gst_bin_add (GST_BIN (sink), esink);
/* attach ghost pad */ /* 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"); GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
sink->pad = gst_ghost_pad_new ("sink", targetpad = gst_element_get_pad (sink->kid, "sink");
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); gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
}
if (peer) { if (peer) {
GST_DEBUG_OBJECT (sink, "Linking..."); GST_DEBUG_OBJECT (sink, "Linking...");
gst_pad_link (peer, sink->pad); gst_pad_link (peer, sink->pad);
@ -266,5 +234,6 @@ gst_auto_audio_sink_change_state (GstElement * element)
return GST_STATE_FAILURE; 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);
} }

View file

@ -26,42 +26,14 @@
#include "gstautovideosink.h" #include "gstautovideosink.h"
#include "gstautodetect.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 void gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake);
static GstElementStateReturn static GstElementStateReturn
gst_auto_video_sink_change_state (GstElement * element); gst_auto_video_sink_change_state (GstElement * element);
static GstBinClass *parent_class = NULL; GST_BOILERPLATE (GstAutoVideoSink, gst_auto_video_sink, GstBin, GST_TYPE_BIN);
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;
}
static void static void
gst_auto_video_sink_base_init (GstAutoVideoSinkClass * klass) gst_auto_video_sink_base_init (gpointer klass)
{ {
GstElementClass *eklass = GST_ELEMENT_CLASS (klass); GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
GstElementDetails gst_auto_video_sink_details = { GstElementDetails gst_auto_video_sink_details = {
@ -85,8 +57,6 @@ gst_auto_video_sink_class_init (GstAutoVideoSinkClass * klass)
{ {
GstElementClass *eklass = GST_ELEMENT_CLASS (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; 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); GstElementFactory *f = GST_ELEMENT_FACTORY (list->data);
GstElement *el; GstElement *el;
GST_DEBUG_OBJECT (sink, "Trying %s", GST_PLUGIN_FEATURE (f)->name);
if ((el = gst_element_factory_create (f, "actual-sink"))) { 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) { 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; return el;
} }
@ -164,14 +136,17 @@ static void
gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake) gst_auto_video_sink_detect (GstAutoVideoSink * sink, gboolean fake)
{ {
GstElement *esink; GstElement *esink;
GstPad *peer = NULL; GstPad *targetpad, *peer = NULL;
/* save ghostpad */ /* save ghostpad */
if (sink->pad) { if (sink->pad) {
gst_object_ref (GST_OBJECT (sink->pad)); peer = GST_PAD_PEER (sink->pad);
peer = GST_PAD_PEER (GST_PAD_REALIZE (sink->pad)); if (peer) {
if (peer)
gst_pad_unlink (peer, sink->pad); 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 */ /* 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"); GST_DEBUG_OBJECT (sink, "Creating new kid (%ssink)", fake ? "fake" : "video");
if (fake) { if (fake) {
esink = gst_element_factory_make ("fakesink", "temporary-sink"); esink = gst_element_factory_make ("fakesink", "temporary-sink");
g_return_if_fail (esink);
} else if (!(esink = gst_auto_video_sink_find_best (sink))) { } else if (!(esink = gst_auto_video_sink_find_best (sink))) {
GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL), GST_ELEMENT_ERROR (sink, LIBRARY, INIT, (NULL),
("Failed to find a supported video sink")); ("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); gst_bin_add (GST_BIN (sink), esink);
/* attach ghost pad */ /* 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"); GST_DEBUG_OBJECT (sink, "Creating new ghostpad");
sink->pad = gst_ghost_pad_new ("sink", targetpad = gst_element_get_pad (sink->kid, "sink");
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); gst_element_add_pad (GST_ELEMENT (sink), sink->pad);
}
if (peer) { if (peer) {
GST_DEBUG_OBJECT (sink, "Linking..."); GST_DEBUG_OBJECT (sink, "Linking...");
gst_pad_link (peer, sink->pad); gst_pad_link (peer, sink->pad);