static gboolean do_toggle_element (GstGConfVideoSrc * src) { GstPad *targetpad; 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 && (strlen (new_gconf_str) == 0 || strcmp (src->gconf_str, new_gconf_str) == 0)) { g_free (new_gconf_str); GST_DEBUG_OBJECT (src, "GConf key was updated, but it didn't change"); return TRUE; } GST_OBJECT_LOCK (src); cur = GST_STATE (src); next = GST_STATE_PENDING (src); GST_OBJECT_UNLOCK (src); 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; } 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"); return TRUE; }
static gboolean do_change_child (GstGConfAudioSink * sink) { const gchar *key; gchar *new_gconf_str; GstElement *new_kid; if (sink->profile == GCONF_PROFILE_NONE) return FALSE; /* Can't switch to a 'NONE' sink */ key = gst_gconf_get_key_for_sink_profile (sink->profile); new_gconf_str = gst_gconf_get_string (key); GST_LOG_OBJECT (sink, "old gconf string: %s", GST_STR_NULL (sink->gconf_str)); GST_LOG_OBJECT (sink, "new gconf string: %s", GST_STR_NULL (new_gconf_str)); if (new_gconf_str != NULL && sink->gconf_str != NULL && (strlen (new_gconf_str) == 0 || strcmp (sink->gconf_str, new_gconf_str) == 0)) { g_free (new_gconf_str); GST_DEBUG_OBJECT (sink, "GConf key was updated, but it didn't change. Ignoring"); return TRUE; } GST_DEBUG_OBJECT (sink, "GConf key changed: '%s' to '%s'", GST_STR_NULL (sink->gconf_str), GST_STR_NULL (new_gconf_str)); GST_DEBUG_OBJECT (sink, "Creating new child for profile %d", sink->profile); new_kid = gst_gconf_render_bin_with_default (new_gconf_str, DEFAULT_AUDIOSINK); if (new_kid == NULL) { GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL), ("Failed to render audio sink from GConf")); goto fail; } if (!gst_switch_sink_set_child (GST_SWITCH_SINK (sink), new_kid)) { GST_WARNING_OBJECT (sink, "Failed to update child element"); goto fail; } g_free (sink->gconf_str); sink->gconf_str = new_gconf_str; GST_DEBUG_OBJECT (sink, "done changing gconf audio sink"); return TRUE; fail: g_free (new_gconf_str); return FALSE; }
static gboolean do_toggle_element (GstGConfVideoSink * sink) { GstPad *targetpad; gchar *new_gconf_str; GstState cur, next; new_gconf_str = gst_gconf_get_string (GST_GCONF_VIDEOSINK_KEY); if (new_gconf_str != NULL && sink->gconf_str != NULL && (strlen (new_gconf_str) == 0 || strcmp (sink->gconf_str, new_gconf_str) == 0)) { g_free (new_gconf_str); GST_DEBUG_OBJECT (sink, "GConf key was updated, but it didn't change"); return TRUE; } /* Sometime, it would be lovely to allow sink changes even when * already running, but this involves sending an appropriate new-segment * and possibly prerolling etc */ GST_OBJECT_LOCK (sink); cur = GST_STATE (sink); next = GST_STATE_PENDING (sink); GST_OBJECT_UNLOCK (sink); if (cur > GST_STATE_READY || next == GST_STATE_PAUSED) { GST_DEBUG_OBJECT (sink, "Auto-sink is already running. Ignoring GConf change"); g_free (new_gconf_str); return TRUE; } GST_DEBUG_OBJECT (sink, "GConf key changed: '%s' to '%s'", GST_STR_NULL (sink->gconf_str), GST_STR_NULL (new_gconf_str)); g_free (sink->gconf_str); sink->gconf_str = new_gconf_str; /* kill old element */ if (sink->kid) { GST_DEBUG_OBJECT (sink, "Removing old kid"); gst_element_set_state (sink->kid, GST_STATE_NULL); gst_bin_remove (GST_BIN (sink), sink->kid); sink->kid = NULL; } GST_DEBUG_OBJECT (sink, "Creating new kid"); if (!(sink->kid = gst_gconf_get_default_video_sink ())) { GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL), ("Failed to render video sink from GConf")); return FALSE; } gst_element_set_state (sink->kid, GST_STATE (sink)); gst_bin_add (GST_BIN (sink), sink->kid); /* re-attach ghostpad */ GST_DEBUG_OBJECT (sink, "Creating new ghostpad"); targetpad = gst_element_get_static_pad (sink->kid, "sink"); gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); GST_DEBUG_OBJECT (sink, "done changing gconf video sink"); return TRUE; }