コード例 #1
0
GESTimeline *
testPatternTL (void)
{
  GESTimeline *timeline;
  GESLayer *layer;
  GESTestClip *srca, *srcb;

  timeline = ges_timeline_new_audio_video ();

  layer = ges_layer_new ();
  g_object_set (layer, "auto-transition", TRUE, NULL);

  ges_timeline_add_layer (timeline, layer);

  srca = ges_test_clip_new ();
  srcb = ges_test_clip_new ();

  g_object_set (srca,
      "vpattern", GES_VIDEO_TEST_PATTERN_SMPTE,
      "duration", 3 * GST_SECOND, "start", 0, NULL);

  g_object_set (srcb,
      "vpattern", GES_VIDEO_TEST_PATTERN_CIRCULAR,
      "duration", 3 * GST_SECOND, "start", 2 * GST_SECOND, NULL);
  ges_test_clip_set_frequency (srcb, 800);

  ges_layer_add_clip (layer, GES_CLIP (srca));
  ges_layer_add_clip (layer, GES_CLIP (srcb));


  ges_timeline_commit (timeline);

  return timeline;
}
コード例 #2
0
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;
}
コード例 #3
0
static void
extractable_set_asset (GESExtractable * self, GESAsset * asset)
{
  GEnumClass *enum_class;
  GESVideoStandardTransitionType value;
  GESTransitionClip *trans = GES_TRANSITION_CLIP (self);
  const gchar *vtype = ges_asset_get_id (asset);

  /* Update the transition type if we actually changed it */
  if (g_strcmp0 (vtype, trans->priv->vtype_name)) {
    guint index;

    value = GES_VIDEO_STANDARD_TRANSITION_TYPE_CROSSFADE;
    enum_class = g_type_class_peek (GES_VIDEO_STANDARD_TRANSITION_TYPE_TYPE);

    /* Find the in value in use */
    for (index = 0; index < enum_class->n_values; index++) {
      if (g_strcmp0 (enum_class->values[index].value_nick, vtype) == 0) {
        value = enum_class->values[index].value;
        break;
      }
    }
    ges_transition_clip_update_vtype_internal (GES_CLIP (self), value, FALSE);
  }
}
コード例 #4
0
ファイル: ges-uri-clip.c プロジェクト: vliaskov/PitiviGes
static void
extractable_set_asset (GESExtractable * self, GESAsset * asset)
{
  GESUriClip *uriclip = GES_URI_CLIP (self);
  GESUriClipAsset *filesource_asset = GES_URI_CLIP_ASSET (asset);
  GESClip *clip = GES_CLIP (self);

  if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_DURATION (clip)) == FALSE)
    _set_duration0 (GES_TIMELINE_ELEMENT (uriclip),
        ges_uri_clip_asset_get_duration (filesource_asset));

  ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (uriclip),
      ges_uri_clip_asset_get_duration (filesource_asset));
  ges_uri_clip_set_is_image (uriclip,
      ges_uri_clip_asset_is_image (filesource_asset));

  if (ges_clip_get_supported_formats (clip) == GES_TRACK_TYPE_UNKNOWN) {

    ges_clip_set_supported_formats (clip,
        ges_clip_asset_get_supported_formats
        (GES_CLIP_ASSET (filesource_asset)));
  }

  GES_TIMELINE_ELEMENT (uriclip)->asset = asset;
}
コード例 #5
0
ファイル: uriclip.c プロジェクト: lubosz/gst-editing-services
static void
asset_created_cb (GObject * source, GAsyncResult * res, gpointer udata)
{
  GList *tracks, *tmp;
  GESAsset *asset;
  GESLayer *layer;
  GESUriClip *tlfs;

  GError *error = NULL;

  asset = ges_asset_request_finish (res, &error);
  ASSERT_OBJECT_REFCOUNT (asset, "1 for us + for the cache + 1 taken "
      "by g_simple_async_result_complete_in_idle", 3);
  fail_unless (error == NULL);
  fail_if (asset == NULL);
  fail_if (g_strcmp0 (ges_asset_get_id (asset), av_uri));

  layer = GES_LAYER (g_async_result_get_user_data (res));
  tlfs = GES_URI_CLIP (ges_layer_add_asset (layer,
          asset, 0, 0, GST_CLOCK_TIME_NONE, GES_TRACK_TYPE_UNKNOWN));
  fail_unless (GES_IS_URI_CLIP (tlfs));
  fail_if (g_strcmp0 (ges_uri_clip_get_uri (tlfs), av_uri));
  assert_equals_uint64 (_DURATION (tlfs), GST_SECOND);

  fail_unless (ges_clip_get_supported_formats
      (GES_CLIP (tlfs)) & GES_TRACK_TYPE_VIDEO);
  fail_unless (ges_clip_get_supported_formats
      (GES_CLIP (tlfs)) & GES_TRACK_TYPE_AUDIO);

  tracks = ges_timeline_get_tracks (ges_layer_get_timeline (layer));
  for (tmp = tracks; tmp; tmp = tmp->next) {
    GList *trackelements = ges_track_get_elements (GES_TRACK (tmp->data));

    assert_equals_int (g_list_length (trackelements), 1);
    fail_unless (GES_IS_VIDEO_URI_SOURCE (trackelements->data)
        || GES_IS_AUDIO_URI_SOURCE (trackelements->data));
    g_list_free_full (trackelements, gst_object_unref);
  }
  g_list_free_full (tracks, gst_object_unref);

  gst_object_unref (asset);
  g_main_loop_quit (mainloop);
}
コード例 #6
0
/****************************************************
 *              Our listening of children           *
 ****************************************************/
static void
_update_our_values (GESGroup * group)
{
  GList *tmp;
  GESContainer *container = GES_CONTAINER (group);
  guint32 min_layer_prio = G_MAXINT32, max_layer_prio = 0;

  for (tmp = GES_CONTAINER_CHILDREN (group); tmp; tmp = tmp->next) {
    GESContainer *child = tmp->data;

    if (GES_IS_CLIP (child)) {
      GESLayer *layer = ges_clip_get_layer (GES_CLIP (child));
      gint32 prio = ges_layer_get_priority (layer);

      min_layer_prio = MIN (prio, min_layer_prio);
      max_layer_prio = MAX (prio, max_layer_prio);
    } else if (GES_IS_GROUP (child)) {
      gint32 prio = _PRIORITY (child), height = GES_CONTAINER_HEIGHT (child);

      min_layer_prio = MIN (prio, min_layer_prio);
      max_layer_prio = MAX ((prio + height), max_layer_prio);
    }
  }

  if (min_layer_prio != _PRIORITY (group)) {
    group->priv->setting_value = TRUE;
    _set_priority0 (GES_TIMELINE_ELEMENT (group), min_layer_prio);
    group->priv->setting_value = FALSE;
    for (tmp = GES_CONTAINER_CHILDREN (group); tmp; tmp = tmp->next) {
      GESTimelineElement *child = tmp->data;
      guint32 child_prio = GES_IS_CLIP (child) ?
          ges_clip_get_layer_priority (GES_CLIP (child)) : _PRIORITY (child);

      _ges_container_set_priority_offset (container,
          child, min_layer_prio - child_prio);
    }
  }

  group->priv->max_layer_prio = max_layer_prio;
  _ges_container_set_height (GES_CONTAINER (group),
      max_layer_prio - min_layer_prio + 1);
}
コード例 #7
0
ファイル: ges-clip.c プロジェクト: aleb/gst-editing-services
static void
_get_priority_range (GESContainer * container, guint32 * min_priority,
    guint32 * max_priority)
{
  GESLayer *layer = GES_CLIP (container)->priv->layer;

  if (layer) {
    *min_priority = layer->min_nle_priority;
    *max_priority = layer->max_nle_priority;
  } else {
    *min_priority = MIN_NLE_PRIO;
    *max_priority = G_MAXUINT32;
  }
}
コード例 #8
0
static GESPipeline *
create_timeline (void)
{
  GESPipeline *pipeline;
  GESLayer *layer;
  GESTrack *tracka, *trackv;
  GESTimeline *timeline;
  GESClip *src;

  timeline = ges_timeline_new ();

  tracka = GES_TRACK (ges_audio_track_new ());
  trackv = GES_TRACK (ges_video_track_new ());

  layer = (GESLayer *) ges_simple_layer_new ();

  /* Add the tracks and the layer to the timeline */
  if (!ges_timeline_add_layer (timeline, layer) ||
      !ges_timeline_add_track (timeline, tracka) ||
      !ges_timeline_add_track (timeline, trackv))
    return NULL;

  /* Add the main audio/video file */
  src = GES_CLIP (ges_test_clip_new ());
  g_object_set (src,
      "vpattern", GES_VIDEO_TEST_PATTERN_SNOW,
      "duration", 10 * GST_SECOND, NULL);

  ges_simple_layer_add_object ((GESSimpleLayer *) layer, GES_CLIP (src), 0);

  pipeline = ges_pipeline_new ();

  if (!ges_pipeline_add_timeline (pipeline, timeline))
    return NULL;

  return pipeline;
}
コード例 #9
0
static void
ges_transition_clip_set_property (GObject * object,
    guint property_id, const GValue * value, GParamSpec * pspec)
{
  GESClip *self = GES_CLIP (object);

  switch (property_id) {
    case PROP_VTYPE:
      ges_transition_clip_update_vtype_internal (self,
          g_value_get_enum (value), TRUE);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}
コード例 #10
0
GESClip *
make_source (char *path, guint64 start, guint64 duration, gint priority)
{
  gchar *uri = gst_filename_to_uri (path, NULL);

  GESClip *ret = GES_CLIP (ges_uri_clip_new (uri));

  g_object_set (ret,
      "start", (guint64) start,
      "duration", (guint64) duration,
      "priority", (guint32) priority, "in-point", (guint64) 0, NULL);

  g_free (uri);

  return ret;
}
コード例 #11
0
GESClip *
make_overlay (char *text, guint64 start, guint64 duration, gint priority,
    guint32 color, gdouble xpos, gdouble ypos)
{
  GESClip *ret = GES_CLIP (ges_text_overlay_clip_new ());

  g_object_set (ret,
      "text", (gchar *) text,
      "start", (guint64) start,
      "duration", (guint64) duration,
      "priority", (guint32) priority,
      "in-point", (guint64) 0,
      "color", (guint32) color,
      "valignment", (gint) GES_TEXT_VALIGN_POSITION,
      "halignment", (gint) GES_TEXT_HALIGN_POSITION,
      "xpos", (gdouble) xpos, "ypos", (gdouble) ypos, NULL);

  return ret;
}
コード例 #12
0
/**
 * ges_layer_add_asset:
 * @layer: a #GESLayer
 * @asset: The asset to add to
 * @start: The start value to set on the new #GESClip
 * @inpoint: The inpoint value to set on the new #GESClip
 * @duration: The duration value to set on the new #GESClip
 * @track_types: The #GESTrackType to set on the the new #GESClip
 *
 * Creates Clip from asset, adds it to layer and
 * returns a reference to it.
 *
 * Returns: (transfer none): Created #GESClip
 */
GESClip *
ges_layer_add_asset (GESLayer * layer,
    GESAsset * asset, GstClockTime start, GstClockTime inpoint,
    GstClockTime duration, GESTrackType track_types)
{
  GESClip *clip;

  g_return_val_if_fail (GES_IS_LAYER (layer), NULL);
  g_return_val_if_fail (GES_IS_ASSET (asset), NULL);
  g_return_val_if_fail (g_type_is_a (ges_asset_get_extractable_type
          (asset), GES_TYPE_CLIP), NULL);

  GST_DEBUG_OBJECT (layer, "Adding asset %s with: start: %" GST_TIME_FORMAT
      " inpoint: %" GST_TIME_FORMAT " duration: %" GST_TIME_FORMAT
      " track types: %d (%s)", ges_asset_get_id (asset), GST_TIME_ARGS (start),
      GST_TIME_ARGS (inpoint), GST_TIME_ARGS (duration), track_types,
      ges_track_type_name (track_types));

  clip = GES_CLIP (ges_asset_extract (asset, NULL));
  _set_start0 (GES_TIMELINE_ELEMENT (clip), start);
  _set_inpoint0 (GES_TIMELINE_ELEMENT (clip), inpoint);
  if (track_types != GES_TRACK_TYPE_UNKNOWN)
    ges_clip_set_supported_formats (clip, track_types);

  if (GST_CLOCK_TIME_IS_VALID (duration)) {
    _set_duration0 (GES_TIMELINE_ELEMENT (clip), duration);
  }

  if (!ges_layer_add_clip (layer, clip)) {
    gst_object_unref (clip);

    return NULL;
  }

  return clip;
}
コード例 #13
0
static void
ges_uri_clip_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GESUriClipPrivate *priv = GES_URI_CLIP (object)->priv;

  switch (property_id) {
    case PROP_URI:
      g_value_set_string (value, priv->uri);
      break;
    case PROP_MUTE:
      g_value_set_boolean (value, priv->mute);
      break;
    case PROP_IS_IMAGE:
      g_value_set_boolean (value, priv->is_image);
      break;
    case PROP_SUPPORTED_FORMATS:
      g_value_set_flags (value,
          ges_clip_get_supported_formats (GES_CLIP (object)));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}
コード例 #14
0
static void
ges_uri_clip_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GESUriClip *uriclip = GES_URI_CLIP (object);

  switch (property_id) {
    case PROP_URI:
      ges_uri_clip_set_uri (uriclip, g_value_dup_string (value));
      break;
    case PROP_MUTE:
      ges_uri_clip_set_mute (uriclip, g_value_get_boolean (value));
      break;
    case PROP_IS_IMAGE:
      ges_uri_clip_set_is_image (uriclip, g_value_get_boolean (value));
      break;
    case PROP_SUPPORTED_FORMATS:
      ges_clip_set_supported_formats (GES_CLIP (uriclip),
          g_value_get_flags (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  }
}
コード例 #15
0
static gboolean
extractable_set_asset (GESExtractable * self, GESAsset * asset)
{
  gboolean res = TRUE;
  GESUriClip *uriclip = GES_URI_CLIP (self);
  GESUriClipAsset *uri_clip_asset;
  GESClip *clip = GES_CLIP (self);
  GESLayer *layer = ges_clip_get_layer (clip);
  GList *tmp;
  GESTimelineElement *audio_source = NULL, *video_source = NULL;

  g_return_val_if_fail (GES_IS_URI_CLIP_ASSET (asset), FALSE);

  uri_clip_asset = GES_URI_CLIP_ASSET (asset);
  if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_DURATION (clip)) == FALSE)
    _set_duration0 (GES_TIMELINE_ELEMENT (uriclip),
        ges_uri_clip_asset_get_duration (uri_clip_asset));

  ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (uriclip),
      ges_uri_clip_asset_get_duration (uri_clip_asset));
  ges_uri_clip_set_is_image (uriclip,
      ges_uri_clip_asset_is_image (uri_clip_asset));

  if (ges_clip_get_supported_formats (clip) == GES_TRACK_TYPE_UNKNOWN) {
    ges_clip_set_supported_formats (clip,
        ges_clip_asset_get_supported_formats (GES_CLIP_ASSET (uri_clip_asset)));
  }

  GES_TIMELINE_ELEMENT (uriclip)->asset = asset;

  if (layer) {
    GList *children = ges_container_get_children (GES_CONTAINER (self), TRUE);

    for (tmp = children; tmp; tmp = tmp->next) {
      if (GES_IS_SOURCE (tmp->data)) {
        GESTrack *track = ges_track_element_get_track (tmp->data);

        if (track->type == GES_TRACK_TYPE_AUDIO)
          audio_source = gst_object_ref (tmp->data);
        else if (track->type == GES_TRACK_TYPE_VIDEO)
          video_source = gst_object_ref (tmp->data);

        ges_track_remove_element (track, tmp->data);
        ges_container_remove (GES_CONTAINER (self), tmp->data);
      }
    }
    g_list_free_full (children, g_object_unref);

    gst_object_ref (clip);

    ges_layer_remove_clip (layer, clip);
    res = ges_layer_add_clip (layer, clip);

    for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
      if (GES_IS_SOURCE (tmp->data)) {
        GESTrack *track = ges_track_element_get_track (tmp->data);

        if (track->type == GES_TRACK_TYPE_AUDIO && audio_source)
          ges_track_element_copy_properties (audio_source, tmp->data);
        else if (track->type == GES_TRACK_TYPE_VIDEO && video_source)
          ges_track_element_copy_properties (video_source, tmp->data);
      }
    }

    g_clear_object (&audio_source);
    g_clear_object (&video_source);
    gst_object_unref (clip);
    gst_object_unref (layer);
  }

  if (res) {
    g_free (uriclip->priv->uri);
    uriclip->priv->uri = g_strdup (ges_asset_get_id (asset));
  }

  return res;
}
コード例 #16
0
int
main (int argc, gchar ** argv)
{
  GError *err = NULL;
  GOptionContext *ctx;
  GESPipeline *pipeline;
  GESTimeline *timeline;
  GESTrack *tracka, *trackv;
  GESLayer *layer1, *layer2;
  GESUriClip *src;
  GMainLoop *mainloop;

  gint inpoint = 0, duration = 10;
  gboolean mute = FALSE;
  gchar *audiofile = NULL;
  GOptionEntry options[] = {
    {"inpoint", 'i', 0, G_OPTION_ARG_INT, &inpoint,
        "in-point in the file (in seconds, default:0s)", "seconds"},
    {"duration", 'd', 0, G_OPTION_ARG_INT, &duration,
        "duration to use from the file (in seconds, default:10s)", "seconds"},
    {"mute", 'm', 0, G_OPTION_ARG_NONE, &mute,
        "Whether to mute the audio from the file",},
    {"audiofile", 'a', 0, G_OPTION_ARG_FILENAME, &audiofile,
          "Use this audiofile instead of the original audio from the file",
        "audiofile"},
    {NULL}
  };

  ctx =
      g_option_context_new
      ("- Plays an video file with sound (origin/muted/replaced)");
  g_option_context_add_main_entries (ctx, options, NULL);
  g_option_context_add_group (ctx, gst_init_get_option_group ());

  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
    g_print ("Error initializing %s\n", err->message);
    exit (1);
  }

  if (argc == 1) {
    g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL));
    exit (0);
  }
  g_option_context_free (ctx);

  ges_init ();

  /* Create an Audio/Video pipeline with two layers */
  pipeline = ges_pipeline_new ();

  timeline = ges_timeline_new ();

  tracka = GES_TRACK (ges_audio_track_new ());
  trackv = GES_TRACK (ges_video_track_new ());

  layer1 = ges_layer_new ();
  layer2 = ges_layer_new ();
  g_object_set (layer2, "priority", 1, NULL);

  if (!ges_timeline_add_layer (timeline, layer1) ||
      !ges_timeline_add_layer (timeline, layer2) ||
      !ges_timeline_add_track (timeline, tracka) ||
      !ges_timeline_add_track (timeline, trackv) ||
      !ges_pipeline_set_timeline (pipeline, timeline))
    return -1;

  if (1) {
    gchar *uri = gst_filename_to_uri (argv[1], NULL);
    /* Add the main audio/video file */
    src = ges_uri_clip_new (uri);
    g_free (uri);
    g_object_set (src, "start", 0, "in-point", inpoint * GST_SECOND,
        "duration", duration * GST_SECOND, "mute", mute, NULL);
    ges_layer_add_clip (layer1, GES_CLIP (src));
  }

  /* Play the pipeline */
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
  mainloop = g_main_loop_new (NULL, FALSE);
  g_timeout_add_seconds (duration + 1, (GSourceFunc) g_main_loop_quit,
      mainloop);
  g_main_loop_run (mainloop);

  return 0;
}
コード例 #17
0
ファイル: timelineedition.c プロジェクト: vliaskov/PitiviGes
static inline GESClip *
create_custom_clip (void)
{
  return GES_CLIP (ges_custom_source_clip_new (my_fill_track_func, NULL));
}
コード例 #18
0
ファイル: ges-pitivi-formatter.c プロジェクト: cfoch/ges
static void
make_source (GESFormatter * self, GList * reflist, GHashTable * source_table)
{
  GHashTable *props_table, *effect_table;
  gchar **prio_array;
  GESLayer *layer;
  GESPitiviFormatterPrivate *priv = GES_PITIVI_FORMATTER (self)->priv;

  gchar *fac_ref = NULL, *media_type = NULL, *filename = NULL, *prio_str;
  GList *tmp = NULL, *keys, *tmp_key;
  GESUriClip *src = NULL;
  gint prio;
  gboolean a_avail = FALSE, v_avail = FALSE, video;
  GHashTable *trackelement_table = priv->track_elements_table;

  for (tmp = reflist; tmp; tmp = tmp->next) {

    /* Get the layer */
    props_table = g_hash_table_lookup (trackelement_table, (gchar *) tmp->data);
    prio_str = (gchar *) g_hash_table_lookup (props_table, "priority");
    prio_array = g_strsplit (prio_str, ")", 0);
    prio = (gint) g_ascii_strtod (prio_array[1], NULL);
    g_strfreev (prio_array);

    /* If we do not have any layer with this priority, create it */
    if (!(layer = g_hash_table_lookup (priv->layers_table, &prio))) {
      layer = ges_layer_new ();
      g_object_set (layer, "auto-transition", TRUE, "priority", prio, NULL);
      ges_timeline_add_layer (self->timeline, layer);
      g_hash_table_insert (priv->layers_table, g_memdup (&prio,
              sizeof (guint64)), layer);
    }

    fac_ref = (gchar *) g_hash_table_lookup (props_table, "fac_ref");
    media_type = (gchar *) g_hash_table_lookup (props_table, "media_type");

    if (!g_strcmp0 (media_type, "pitivi.stream.VideoStream"))
      video = TRUE;
    else
      video = FALSE;

    /* FIXME I am sure we could reimplement this whole part
     * in a simpler way */

    if (g_strcmp0 (fac_ref, (gchar *) "effect")) {
      /* FIXME this is a hack to get a ref to the formatter when receiving
       * child-added */
      g_hash_table_insert (props_table, (gchar *) "current-formatter", self);
      if (a_avail && (!video)) {
        a_avail = FALSE;
      } else if (v_avail && (video)) {
        v_avail = FALSE;
      } else {

        /* If we only have audio or only video in the previous source,
         * set it has such */
        if (a_avail) {
          ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_VIDEO);
        } else if (v_avail) {
          ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_AUDIO);
        }

        filename = (gchar *) g_hash_table_lookup (source_table, "filename");

        src = ges_uri_clip_new (filename);

        if (!video) {
          v_avail = TRUE;
          a_avail = FALSE;
        } else {
          a_avail = TRUE;
          v_avail = FALSE;
        }

        set_properties (G_OBJECT (src), props_table);
        ges_layer_add_clip (layer, GES_CLIP (src));

        g_signal_connect (src, "child-added",
            G_CALLBACK (track_element_added_cb), props_table);

        priv->sources_to_load = g_list_prepend (priv->sources_to_load, src);
      }

    } else {
      GESEffect *effect;
      gchar *active = (gchar *) g_hash_table_lookup (props_table, "active");

      effect = ges_effect_new ((gchar *)
          g_hash_table_lookup (props_table, (gchar *) "effect_name"));
      ges_track_element_set_track_type (GES_TRACK_ELEMENT (effect),
          (video ? GES_TRACK_TYPE_VIDEO : GES_TRACK_TYPE_AUDIO));
      effect_table =
          g_hash_table_lookup (props_table, (gchar *) "effect_props");

      ges_container_add (GES_CONTAINER (src), GES_TIMELINE_ELEMENT (effect));

      if (!g_strcmp0 (active, (gchar *) "(bool)False"))
        ges_track_element_set_active (GES_TRACK_ELEMENT (effect), FALSE);

      /* Set effect properties */
      keys = g_hash_table_get_keys (effect_table);
      for (tmp_key = keys; tmp_key; tmp_key = tmp_key->next) {
        GstStructure *structure;
        const GValue *value;
        GParamSpec *spec;
        GstCaps *caps;
        gchar *prop_val;

        prop_val = (gchar *) g_hash_table_lookup (effect_table,
            (gchar *) tmp_key->data);

        if (g_strstr_len (prop_val, -1, "(GEnum)")) {
          gchar **val = g_strsplit (prop_val, ")", 2);

          ges_track_element_set_child_properties (GES_TRACK_ELEMENT (effect),
              (gchar *) tmp_key->data, atoi (val[1]), NULL);
          g_strfreev (val);

        } else if (ges_track_element_lookup_child (GES_TRACK_ELEMENT (effect),
                (gchar *) tmp->data, NULL, &spec)) {
          gchar *caps_str = g_strdup_printf ("structure1, property1=%s;",
              prop_val);

          caps = gst_caps_from_string (caps_str);
          g_free (caps_str);
          structure = gst_caps_get_structure (caps, 0);
          value = gst_structure_get_value (structure, "property1");

          ges_track_element_set_child_property_by_pspec (GES_TRACK_ELEMENT
              (effect), spec, (GValue *) value);
          gst_caps_unref (caps);
        }
      }
    }
  }

  if (a_avail) {
    ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_VIDEO);
  } else if (v_avail) {
    ges_clip_set_supported_formats (GES_CLIP (src), GES_TRACK_TYPE_AUDIO);
  }
}