gconf: Port gconfvideosrc to GstSwitchSrc

This commit is contained in:
Sebastian Dröge 2010-07-03 14:12:12 +02:00
parent cb5c185804
commit b7900161f2
2 changed files with 27 additions and 68 deletions

View file

@ -49,20 +49,14 @@ static GstStateChangeReturn
gst_gconf_video_src_change_state (GstElement * element,
GstStateChange transition);
GST_BOILERPLATE (GstGConfVideoSrc, gst_gconf_video_src, GstBin, GST_TYPE_BIN);
GST_BOILERPLATE (GstGConfVideoSrc, gst_gconf_video_src, GstSwitchSrc,
GST_TYPE_SWITCH_SRC);
static void
gst_gconf_video_src_base_init (gpointer klass)
{
GstElementClass *eklass = GST_ELEMENT_CLASS (klass);
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
gst_element_class_add_pad_template (eklass,
gst_static_pad_template_get (&src_template));
gst_element_class_set_details_simple (eklass, "GConf video source",
"Source/Video",
"Video source embedding the GConf-settings for video input",
@ -87,23 +81,7 @@ gst_gconf_video_src_class_init (GstGConfVideoSrcClass * klass)
static gboolean
gst_gconf_video_src_reset (GstGConfVideoSrc * src)
{
GstPad *targetpad;
/* fakesrc */
if (src->kid) {
gst_element_set_state (src->kid, GST_STATE_NULL);
gst_bin_remove (GST_BIN (src), src->kid);
}
src->kid = gst_element_factory_make ("fakesrc", "testsrc");
if (!src->kid) {
GST_ERROR_OBJECT (src, "Failed to create fakesrc");
return FALSE;
}
gst_bin_add (GST_BIN (src), src->kid);
targetpad = gst_element_get_static_pad (src->kid, "src");
gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad);
gst_object_unref (targetpad);
gst_switch_src_set_child (GST_SWITCH_SRC (src), NULL);
g_free (src->gconf_str);
src->gconf_str = NULL;
@ -115,9 +93,6 @@ static void
gst_gconf_video_src_init (GstGConfVideoSrc * src,
GstGConfVideoSrcClass * g_class)
{
src->pad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
gst_element_add_pad (GST_ELEMENT (src), src->pad);
gst_gconf_video_src_reset (src);
src->client = gconf_client_get_default ();
@ -155,9 +130,8 @@ gst_gconf_video_src_finalize (GstGConfVideoSrc * src)
static gboolean
do_toggle_element (GstGConfVideoSrc * src)
{
GstPad *targetpad;
GstElement *new_kid;
gchar *new_gconf_str;
GstState cur, next;
new_gconf_str = gst_gconf_get_string (GST_GCONF_AUDIOSRC_KEY);
if (new_gconf_str != NULL && src->gconf_str != NULL &&
@ -168,47 +142,30 @@ do_toggle_element (GstGConfVideoSrc * src)
return TRUE;
}
GST_OBJECT_LOCK (src);
cur = GST_STATE (src);
next = GST_STATE_PENDING (src);
GST_OBJECT_UNLOCK (src);
GST_DEBUG_OBJECT (src, "GConf key changed: '%s' to '%s'",
GST_STR_NULL (src->gconf_str), GST_STR_NULL (new_gconf_str));
if (cur >= GST_STATE_READY || next == GST_STATE_PAUSED) {
GST_DEBUG_OBJECT (src, "already running, ignoring GConf change");
g_free (new_gconf_str);
return TRUE;
GST_DEBUG_OBJECT (src, "Creating new kid");
if (!(new_kid = gst_gconf_get_default_video_src ())) {
GST_ELEMENT_ERROR (src, LIBRARY, SETTINGS, (NULL),
("Failed to render video src from GConf"));
return FALSE;
}
if (!gst_switch_src_set_child (GST_SWITCH_SRC (src), new_kid)) {
GST_WARNING_OBJECT (src, "Failed to update child element");
goto fail;
}
g_free (src->gconf_str);
src->gconf_str = new_gconf_str;
/* kill old element */
if (src->kid) {
GST_DEBUG_OBJECT (src, "Removing old kid");
gst_element_set_state (src->kid, GST_STATE_NULL);
gst_bin_remove (GST_BIN (src), src->kid);
src->kid = NULL;
}
GST_DEBUG_OBJECT (src, "Creating new kid");
if (!(src->kid = gst_gconf_get_default_video_src ())) {
GST_ELEMENT_ERROR (src, LIBRARY, SETTINGS, (NULL),
("Failed to render video source from GConf"));
g_free (src->gconf_str);
src->gconf_str = NULL;
return FALSE;
}
gst_element_set_state (src->kid, GST_STATE (src));
gst_bin_add (GST_BIN (src), src->kid);
/* re-attach ghostpad */
GST_DEBUG_OBJECT (src, "Creating new ghostpad");
targetpad = gst_element_get_static_pad (src->kid, "src");
gst_ghost_pad_set_target (GST_GHOST_PAD (src->pad), targetpad);
gst_object_unref (targetpad);
GST_DEBUG_OBJECT (src, "done changing gconf video source");
GST_DEBUG_OBJECT (src, "done changing gconf video src");
return TRUE;
fail:
g_free (new_gconf_str);
return FALSE;
}
static void
@ -227,8 +184,10 @@ gst_gconf_video_src_change_state (GstElement * element,
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
if (!do_toggle_element (src))
if (!do_toggle_element (src)) {
gst_gconf_video_src_reset (src);
return GST_STATE_CHANGE_FAILURE;
}
break;
default:
break;

View file

@ -24,6 +24,8 @@
#include <gst/gst.h>
#include <gconf/gconf-client.h>
#include "gstswitchsrc.h"
G_BEGIN_DECLS
#define GST_TYPE_GCONF_VIDEO_SRC (gst_gconf_video_src_get_type ())
@ -33,12 +35,10 @@ G_BEGIN_DECLS
#define GST_IS_GCONF_VIDEO_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GCONF_VIDEO_SRC))
typedef struct _GstGConfVideoSrc {
GstBin parent;
GstSwitchSrc parent;
/* explicit pointers to stuff used */
GConfClient *client;
GstElement *kid;
GstPad *pad;
/* gconf key notification id */
guint notify_id;
@ -48,7 +48,7 @@ typedef struct _GstGConfVideoSrc {
} GstGConfVideoSrc;
typedef struct _GstGConfVideoSrcClass {
GstBinClass parent_class;
GstSwitchSrcClass parent_class;
} GstGConfVideoSrcClass;
GType gst_gconf_video_src_get_type (void);