static gboolean
_set_child_property (GstValidateScenario * scenario, GstValidateAction * action)
{
  const GValue *value;
  GESTimeline *timeline;
  GESTimelineElement *element;
  const gchar *property_name, *element_name;

  element_name = gst_structure_get_string (action->structure, "element-name");

  timeline = get_timeline (scenario);
  g_return_val_if_fail (timeline, FALSE);

  element = ges_timeline_get_element (timeline, element_name);
  g_return_val_if_fail (GES_IS_TRACK_ELEMENT (element), FALSE);

  property_name = gst_structure_get_string (action->structure, "property");
  value = gst_structure_get_value (action->structure, "value");

  GST_DEBUG ("%s Setting %s property to %p",
      element->name, property_name, value);
  ges_track_element_set_child_property (GES_TRACK_ELEMENT (element),
      property_name, (GValue *) value);

  g_object_unref(timeline);

  return TRUE;
}
static gboolean
_remove_clip(GstValidateScenario *scenario, GstValidateAction * action)
{
  GESTimeline *timeline = get_timeline(scenario);
  GESTimelineElement *clip;
  GESLayer *layer;
  const gchar *name;
  gboolean res = FALSE;

  name = gst_structure_get_string (action->structure, "name");
  clip = ges_timeline_get_element (timeline, name);
  g_return_val_if_fail (GES_IS_CLIP (clip), FALSE);
  
  layer = ges_clip_get_layer(GES_CLIP(clip));

  if (layer) {
    res = ges_layer_remove_clip(layer, GES_CLIP(clip));
    gst_object_unref(layer);
  } else {
    GST_ERROR("No layer for clip %s", ges_timeline_element_get_name(clip));
  }

  g_object_unref(timeline);
  return res;
}
/**
 * ges_timeline_element_set_name:
 * @self: a #GESTimelineElement
 * @name: (allow-none): The name @self should take (if avalaible<)
 *
 *
 * Sets the name of object, or gives @self a guaranteed unique name (if name is NULL).
 * This function makes a copy of the provided name, so the caller retains ownership
 * of the name it sent.
 */
gboolean
ges_timeline_element_set_name (GESTimelineElement * self, const gchar * name)
{
  gboolean result = TRUE, readd_to_timeline = FALSE;

  g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);

  if (name != NULL && !g_strcmp0 (name, self->name)) {
    GST_DEBUG_OBJECT (self, "Same name!");
    return TRUE;
  }

  /* parented objects cannot be renamed */
  if (self->timeline != NULL && name) {
    GESTimelineElement *tmp = ges_timeline_get_element (self->timeline, name);

    if (tmp) {
      gst_object_unref (tmp);
      goto had_timeline;
    }

    timeline_remove_element (self->timeline, self);
    readd_to_timeline = TRUE;
  }

  _set_name (self, name);

  if (readd_to_timeline)
    timeline_add_element (self->timeline, self);

  return result;

  /* error */
had_timeline:
  {
    GST_WARNING ("Objects already in a timeline can't be renamed");
    return FALSE;
  }
}
static gboolean
_edit_clip (GstValidateScenario * scenario, GstValidateAction * action)
{
  gint64 cpos;
  gdouble rate;
  GList *layers = NULL;
  GESTimeline *timeline;
  GstQuery *query_segment;
  GESTimelineElement *clip;
  GstClockTime position;
  gint64 stop_value;
  gboolean res = FALSE;

  gint new_layer_priority = -1;
  GESEditMode edge = GES_EDGE_NONE;
  GESEditMode mode = GES_EDIT_MODE_NORMAL;

  const gchar *edit_mode_str = NULL, *edge_str = NULL;
  const gchar *clip_name;

  clip_name = gst_structure_get_string (action->structure, "clip-name");

  timeline = get_timeline (scenario);
  g_return_val_if_fail (timeline, FALSE);

  clip = ges_timeline_get_element (timeline, clip_name);
  g_return_val_if_fail (GES_IS_CLIP (clip), FALSE);

  if (!gst_validate_action_get_clocktime (scenario, action,
          "position", &position)) {
    GST_WARNING ("Could not get position");
    goto beach;
  }

  if ((edit_mode_str =
          gst_structure_get_string (action->structure, "edit-mode")))
    g_return_val_if_fail (gst_validate_utils_enum_from_str (GES_TYPE_EDIT_MODE,
            edit_mode_str, &mode), FALSE);

  if ((edge_str = gst_structure_get_string (action->structure, "edge")))
    g_return_val_if_fail (gst_validate_utils_enum_from_str (GES_TYPE_EDGE,
            edge_str, &edge), FALSE);

  gst_structure_get_int (action->structure, "new-layer-priority",
      &new_layer_priority);

  gst_validate_printf (action, "Editing %s to %" GST_TIME_FORMAT
      " in %s mode, edge: %s "
      "with new layer prio: %d \n\n",
      clip_name, GST_TIME_ARGS (position),
      edit_mode_str ? edit_mode_str : "normal",
      edge_str ? edge_str : "None", new_layer_priority);

  if (!ges_container_edit (GES_CONTAINER (clip), layers, new_layer_priority,
          mode, edge, position)) {
    gst_object_unref (clip);
    goto beach;
  }
  gst_object_unref (clip);

  query_segment = gst_query_new_segment (GST_FORMAT_TIME);
  if (!gst_element_query (scenario->pipeline, query_segment)) {
    GST_ERROR_OBJECT (scenario, "Could not query segment");
    goto beach;
  }

  if (!gst_element_query_position (scenario->pipeline, GST_FORMAT_TIME, &cpos)) {
    GST_ERROR_OBJECT (scenario, "Could not query position");
    goto beach;
  }

  if (!ges_timeline_commit (timeline)) {
    GST_DEBUG_OBJECT (scenario, "nothing changed, no need to seek");
    res = TRUE;
    goto beach;
  }


  gst_query_parse_segment (query_segment, &rate, NULL, NULL, &stop_value);

  res = gst_validate_scenario_execute_seek (scenario, action,
      rate, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
      GST_SEEK_TYPE_SET, cpos, GST_SEEK_TYPE_SET, stop_value);

beach:
  g_object_unref(timeline);
  return res;
}