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;
}
Beispiel #3
0
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;
}