/* GESAsset vmethod implementation */
static GESExtractable *
ges_project_extract (GESAsset * project, GError ** error)
{
  GESTimeline *timeline = g_object_new (GES_TYPE_TIMELINE, NULL);

  ges_extractable_set_asset (GES_EXTRACTABLE (timeline), GES_ASSET (project));
  if (_load_project (GES_PROJECT (project), timeline, error))
    return GES_EXTRACTABLE (timeline);

  gst_object_unref (timeline);
  return NULL;
}
/**
 * ges_timeline_element_copy:
 * @self: The #GESTimelineElement to copy
 * @deep: whether we want to create the elements @self contains or not
 *
 * Copies @self
 *
 * Returns: (transfer floating): The newly create #GESTimelineElement, copied from @self
 */
GESTimelineElement *
ges_timeline_element_copy (GESTimelineElement * self, gboolean deep)
{
  GESAsset *asset;
  GParameter *params;
  GParamSpec **specs;
  GESTimelineElementClass *klass;
  guint n, n_specs, n_params;

  GESTimelineElement *ret = NULL;

  g_return_val_if_fail (GES_IS_TIMELINE_ELEMENT (self), FALSE);

  klass = GES_TIMELINE_ELEMENT_GET_CLASS (self);

  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_specs);
  params = g_new0 (GParameter, n_specs);
  n_params = 0;

  for (n = 0; n < n_specs; ++n) {
    /* We do not want the timeline or the name to be copied */
    if (g_strcmp0 (specs[n]->name, "parent") &&
        g_strcmp0 (specs[n]->name, "timeline") &&
        g_strcmp0 (specs[n]->name, "name") &&
        (specs[n]->flags & G_PARAM_READWRITE) == G_PARAM_READWRITE) {
      params[n_params].name = g_intern_string (specs[n]->name);
      g_value_init (&params[n_params].value, specs[n]->value_type);
      g_object_get_property (G_OBJECT (self), specs[n]->name,
          &params[n_params].value);
      ++n_params;
    }
  }

  ret = g_object_newv (G_OBJECT_TYPE (self), n_params, params);

  g_free (specs);
  g_free (params);


  asset = ges_extractable_get_asset (GES_EXTRACTABLE (self));
  if (asset)
    ges_extractable_set_asset (GES_EXTRACTABLE (ret), asset);
  if (deep) {
    if (klass->deep_copy)
      klass->deep_copy (self, ret);
    else
      GST_WARNING_OBJECT (self, "No deep_copy virtual method implementation"
          " on class %s. Can not finish the copy", G_OBJECT_CLASS_NAME (klass));
  }

  return ret;
}
/**
 * ges_project_load:
 * @project: A #GESProject that has an @uri set already
 * @timeline: A blank timeline to load @project into
 * @error: (out) (allow-none): An error to be set in case something wrong happens or %NULL
 *
 * Loads @project into @timeline
 *
 * Returns: %TRUE if the project could be loaded %FALSE otherwize.
 */
gboolean
ges_project_load (GESProject * project, GESTimeline * timeline, GError ** error)
{
  g_return_val_if_fail (GES_IS_TIMELINE (timeline), FALSE);
  g_return_val_if_fail (GES_IS_PROJECT (project), FALSE);
  g_return_val_if_fail (ges_project_get_uri (project), FALSE);
  g_return_val_if_fail (
      (ges_extractable_get_asset (GES_EXTRACTABLE (timeline)) == NULL), FALSE);

  if (!_load_project (project, timeline, error))
    return FALSE;

  ges_extractable_set_asset (GES_EXTRACTABLE (timeline), GES_ASSET (project));

  return TRUE;
}
static void
new_asset_cb (GESAsset * source, GAsyncResult * res, NewAssetUData * udata)
{
  GError *error = NULL;

  GESAsset *asset = ges_asset_request_finish (res, &error);

  GST_DEBUG_OBJECT (udata->layer, "%" GST_PTR_FORMAT " Asset loaded, "
      "setting its asset", udata->clip);

  if (error) {
    GESProject *project = udata->layer->timeline ?
        GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE
            (udata->layer->timeline))) : NULL;
    if (project) {
      gchar *possible_id;

      possible_id = ges_project_try_updating_id (project, source, error);
      if (possible_id) {
        ges_asset_request_async (ges_asset_get_extractable_type (source),
            possible_id, NULL, (GAsyncReadyCallback) new_asset_cb, udata);
        g_free (possible_id);
        return;
      }
    }

    GST_ERROR ("Asset could not be created for uri %s, error: %s",
        ges_asset_get_id (asset), error->message);

  } else {
    GESProject *project = udata->layer->timeline ?
        GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE
            (udata->layer->timeline))) : NULL;
    ges_extractable_set_asset (GES_EXTRACTABLE (udata->clip), asset);

    ges_project_add_asset (project, asset);
    ges_layer_add_clip (udata->layer, udata->clip);
  }

  gst_object_unref (asset);
  g_slice_free (NewAssetUData, udata);
}
Esempio n. 5
0
/* GESAsset vmethod implementation */
static GESExtractable *
ges_project_extract (GESAsset * project, GError ** error)
{
  GESTimeline *timeline = ges_timeline_new ();

  if (_load_project (GES_PROJECT (project), timeline, error))
    return GES_EXTRACTABLE (timeline);

  gst_object_unref (timeline);
  return NULL;
}
static GstElement *
ges_multi_file_source_create_source (GESTrackElement * track_element)
{
  GESMultiFileSource *self;
  GstElement *bin, *src, *decodebin;
  GstCaps *disc_caps;
  GstDiscovererStreamInfo *stream_info;
  GValue fps = G_VALUE_INIT;
  GstCaps *caps;
  GESUriSourceAsset *asset;
  GESMultiFileURI *uri_data;

  self = (GESMultiFileSource *) track_element;

  asset =
      GES_URI_SOURCE_ASSET (ges_extractable_get_asset (GES_EXTRACTABLE (self)));

  if (asset != NULL) {
    stream_info = ges_uri_source_asset_get_stream_info (asset);
    g_assert (stream_info);
    disc_caps = gst_discoverer_stream_info_get_caps (stream_info);
    caps = gst_caps_copy (disc_caps);
    GST_DEBUG ("Got some nice caps %s", gst_caps_to_string (disc_caps));
    gst_object_unref (stream_info);
    gst_caps_unref (disc_caps);
  } else {
    caps = gst_caps_new_empty ();
    GST_WARNING ("Could not extract asset.");
  }

  g_value_init (&fps, GST_TYPE_FRACTION);
  gst_value_set_fraction (&fps, 25, 1);
  gst_caps_set_value (caps, "framerate", &fps);

  bin = GST_ELEMENT (gst_bin_new ("multi-image-bin"));
  src = gst_element_factory_make ("multifilesrc", NULL);

  uri_data = ges_multi_file_uri_new (self->uri);
  g_object_set (src, "start-index", uri_data->start, "stop-index",
      uri_data->end, "caps", caps, "location", uri_data->location, NULL);
  g_free (uri_data);

  decodebin = gst_element_factory_make ("decodebin", NULL);

  gst_bin_add_many (GST_BIN (bin), src, decodebin, NULL);
  gst_element_link_pads_full (src, "src", decodebin, "sink",
      GST_PAD_LINK_CHECK_NOTHING);

  g_signal_connect (G_OBJECT (decodebin), "pad-added",
      G_CALLBACK (pad_added_cb), bin);

  return bin;
}
Esempio n. 7
0
GESTimeline *
compTL (void)
{
  GESTimeline *timeline;
  GESTrack *trackv;

  timeline = ges_timeline_new ();
  trackv = GES_TRACK (ges_video_track_new ());
  ges_timeline_add_track (timeline, trackv);

  const gchar *assets[] = { "image/vieh.png",
    "image/PNG_transparency_demonstration_1.png",
    "image/Ice_Cream.png",
    "image/Fish.png"
  };

  guint asset_count = 4;

  for (int i = 1; i <= asset_count; i++) {
    GESLayer *layer = ges_layer_new ();
    ges_timeline_add_layer (timeline, layer);
    g_object_set (layer, "priority", i - 1, NULL);

    GESClip *vieh = ges_clip_from_rel_path (assets[i - 1], layer, 0, 0, 10,
        GES_TRACK_TYPE_VIDEO);

    GESTrackElement *elem =
        ges_clip_find_track_element (vieh, trackv, G_TYPE_NONE);

    GESUriClipAsset *asset =
        GES_URI_CLIP_ASSET (ges_extractable_get_asset (GES_EXTRACTABLE (vieh)));

    guint width = ges_asset_get_width (asset);
    guint height = ges_asset_get_height (asset);

    g_print ("%s: %dx%d\n", assets[i - 1], width, height);

    ges_track_element_set_child_properties (elem,
        "posx", i * 100, "posy", i * 100,
        "width", i * 100 * width / height, "height", (i * 100) - 1, NULL);
  }

  GESLayer *backgroud_layer = ges_layer_new ();
  ges_timeline_add_layer (timeline, backgroud_layer);
  g_object_set (backgroud_layer, "priority", asset_count, NULL);
  ges_clip_from_rel_path ("image/wallpaper-2597248.jpg", backgroud_layer, 0, 0,
      10, GES_TRACK_TYPE_VIDEO);

  ges_timeline_commit (timeline);

  return timeline;
}
/* Internal methods */
static void
ges_transition_clip_update_vtype_internal (GESClip *
    self, GESVideoStandardTransitionType value, gboolean set_asset)
{
  GSList *tmp;
  guint index;
  GEnumClass *enum_class;
  const gchar *asset_id = NULL;
  GESTransitionClip *trself = GES_TRANSITION_CLIP (self);

  enum_class = g_type_class_peek (GES_VIDEO_STANDARD_TRANSITION_TYPE_TYPE);
  for (index = 0; index < enum_class->n_values; index++) {
    if (enum_class->values[index].value == value) {
      asset_id = enum_class->values[index].value_nick;
      break;
    }
  }

  if (asset_id == NULL) {
    GST_WARNING_OBJECT (self, "Wrong transition type value: %i can not set it",
        value);

    return;
  }

  for (tmp = trself->priv->video_transitions; tmp; tmp = tmp->next) {
    if (!ges_video_transition_set_transition_type
        (GES_VIDEO_TRANSITION (tmp->data), value))
      return;
  }

  trself->vtype = value;
  trself->priv->vtype_name = asset_id;

  if (set_asset) {
    /* We already checked the value, so we can be sure no error will accured */
    ges_extractable_set_asset (GES_EXTRACTABLE (self),
        ges_asset_request (GES_TYPE_TRANSITION_CLIP, asset_id, NULL));
  }
}
/**
 * ges_project_save:
 * @project: A #GESProject to save
 * @timeline: The #GESTimeline to save, it must have been extracted from @project
 * @uri: The uri where to save @project and @timeline
 * @formatter_asset: (allow-none): The formatter asset to use or %NULL. If %NULL,
 * will try to save in the same format as the one from which the timeline as been loaded
 * or default to the formatter with highest rank
 * @overwrite: %TRUE to overwrite file if it exists
 * @error: (out) (allow-none): An error to be set in case something wrong happens or %NULL
 *
 * Save the timeline of @project to @uri. You should make sure that @timeline
 * is one of the timelines that have been extracted from @project
 * (using ges_asset_extract (@project);)
 *
 * Returns: %TRUE if the project could be save, %FALSE otherwize
 */
gboolean
ges_project_save (GESProject * project, GESTimeline * timeline,
    const gchar * uri, GESAsset * formatter_asset, gboolean overwrite,
    GError ** error)
{
  GESAsset *tl_asset;
  gboolean ret = TRUE;
  GESFormatter *formatter = NULL;

  g_return_val_if_fail (GES_IS_PROJECT (project), FALSE);
  g_return_val_if_fail (formatter_asset == NULL ||
      g_type_is_a (ges_asset_get_extractable_type (formatter_asset),
          GES_TYPE_FORMATTER), FALSE);
  g_return_val_if_fail ((error == NULL || *error == NULL), FALSE);

  tl_asset = ges_extractable_get_asset (GES_EXTRACTABLE (timeline));
  if (tl_asset == NULL && project->priv->uri == NULL) {
    GESAsset *asset = ges_asset_cache_lookup (GES_TYPE_PROJECT, uri);

    if (asset) {
      GST_WARNING_OBJECT (project, "Trying to save project to %s but we already"
          "have %" GST_PTR_FORMAT " for that uri, can not save", uri, asset);
      goto out;
    }

    GST_DEBUG_OBJECT (project, "Timeline %" GST_PTR_FORMAT " has no asset"
        " we have no uri set, so setting ourself as asset", timeline);

    ges_extractable_set_asset (GES_EXTRACTABLE (timeline), GES_ASSET (project));
  } else if (tl_asset != GES_ASSET (project)) {
    GST_WARNING_OBJECT (project, "Timeline %" GST_PTR_FORMAT
        " not created by this project can not save", timeline);

    ret = FALSE;
    goto out;
  }

  if (formatter_asset == NULL)
    formatter_asset = gst_object_ref (ges_formatter_get_default ());

  formatter = GES_FORMATTER (ges_asset_extract (formatter_asset, error));
  if (formatter == NULL) {
    GST_WARNING_OBJECT (project, "Could not create the formatter %p %s: %s",
        formatter_asset, ges_asset_get_id (formatter_asset),
        (error && *error) ? (*error)->message : "Unknown Error");

    ret = FALSE;
    goto out;
  }

  ges_project_add_formatter (project, formatter);
  ret = ges_formatter_save_to_uri (formatter, timeline, uri, overwrite, error);
  if (ret && project->priv->uri == NULL)
    ges_project_set_uri (project, uri);

out:
  if (formatter_asset)
    gst_object_unref (formatter_asset);
  ges_project_remove_formatter (project, formatter);

  return ret;
}
Esempio n. 10
0
/**
 * ges_layer_add_clip:
 * @layer: a #GESLayer
 * @clip: (transfer full): the #GESClip to add.
 *
 * Adds the given clip to the layer. Sets the clip's parent, and thus
 * takes ownership of the clip.
 *
 * An clip can only be added to one layer.
 *
 * Calling this method will construct and properly set all the media related
 * elements on @clip. If you need to know when those objects (actually #GESTrackElement)
 * are constructed, you should connect to the container::child-added signal which
 * is emited right after those elements are ready to be used.
 *
 * Returns: TRUE if the clip was properly added to the layer, or FALSE
 * if the @layer refuses to add the clip.
 */
gboolean
ges_layer_add_clip (GESLayer * layer, GESClip * clip)
{
  GESAsset *asset;
  GESLayerPrivate *priv;
  GESLayer *current_layer;

  g_return_val_if_fail (GES_IS_LAYER (layer), FALSE);
  g_return_val_if_fail (GES_IS_CLIP (clip), FALSE);

  GST_DEBUG_OBJECT (layer, "adding clip:%p", clip);

  priv = layer->priv;
  current_layer = ges_clip_get_layer (clip);
  if (G_UNLIKELY (current_layer)) {
    GST_WARNING ("Clip %p already belongs to another layer", clip);
    gst_object_unref (current_layer);

    return FALSE;
  }

  asset = ges_extractable_get_asset (GES_EXTRACTABLE (clip));
  if (asset == NULL) {
    gchar *id;
    NewAssetUData *mudata = g_slice_new (NewAssetUData);

    mudata->clip = clip;
    mudata->layer = layer;

    GST_DEBUG_OBJECT (layer, "%" GST_PTR_FORMAT " as no reference to any "
        "assets creating a asset... trying sync", clip);

    id = ges_extractable_get_id (GES_EXTRACTABLE (clip));
    asset = ges_asset_request (G_OBJECT_TYPE (clip), id, NULL);
    if (asset == NULL) {
      GESProject *project = layer->timeline ?
          GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE
              (layer->timeline))) : NULL;

      ges_asset_request_async (G_OBJECT_TYPE (clip),
          id, NULL, (GAsyncReadyCallback) new_asset_cb, mudata);

      if (project)
        ges_project_add_loading_asset (project, G_OBJECT_TYPE (clip), id);
      g_free (id);

      GST_LOG_OBJECT (layer, "Object added async");
      return TRUE;
    }
    g_free (id);

    ges_extractable_set_asset (GES_EXTRACTABLE (clip), asset);

    g_slice_free (NewAssetUData, mudata);
  }


  gst_object_ref_sink (clip);

  /* Take a reference to the clip and store it stored by start/priority */
  priv->clips_start = g_list_insert_sorted (priv->clips_start, clip,
      (GCompareFunc) element_start_compare);

  /* Inform the clip it's now in this layer */
  ges_clip_set_layer (clip, layer);

  GST_DEBUG ("current clip priority : %d, Height: %d", _PRIORITY (clip),
      LAYER_HEIGHT);

  /* Set the priority. */
  if (_PRIORITY (clip) > LAYER_HEIGHT) {
    GST_WARNING_OBJECT (layer,
        "%p is out of the layer space, setting its priority to "
        "%d, setting it to the maximum priority of the layer: %d", clip,
        _PRIORITY (clip), LAYER_HEIGHT - 1);
    _set_priority0 (GES_TIMELINE_ELEMENT (clip), LAYER_HEIGHT - 1);
  }

  /* If the clip has an acceptable priority, we just let it with its current
   * priority */
  ges_layer_resync_priorities (layer);
  ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (clip),
      layer->timeline);

  /* emit 'clip-added' */
  g_signal_emit (layer, ges_layer_signals[OBJECT_ADDED], 0, clip);

  return TRUE;
}
Esempio n. 11
0
void
getClips (JsonReader * reader, GESLayer * layer, GESTrackType type,
    gboolean absolute_paths)
{
  int i;
  json_reader_read_member (reader, "clips");

  g_print ("= clips =\n");

  for (i = 0; i < json_reader_count_elements (reader); i++) {
    json_reader_read_element (reader, i);
    const char *src = getString (reader, "src");
    int start = getInt (reader, "start");
    int in = getInt (reader, "in");
    int dur = getInt (reader, "dur");
    g_print ("Clip: %s (start: %d, in: %d, dur: %d)\n", src, start, in, dur);

    GESClip *clip;

    if (is_in_members (reader, "multi") && getBool (reader, "multi")) {
      g_print ("multi on.\n");
      clip =
          ges_multi_clip_from_path (src, layer, start, in, dur, absolute_paths);
    } else {
      const char *path;
      if (absolute_paths == TRUE) {
        path = src;
      } else {
        path = ges_renderer_get_absolute_path (src);
      }
      clip = ges_clip_from_path (path, layer, start, in, dur, type);
    }

    GESTimeline *tl = ges_layer_get_timeline (layer);
    GList *tracks = ges_timeline_get_tracks (tl);
    GESTrack *trackv = g_list_first (tracks)->data;
    GESTrack *tracka = g_list_last (tracks)->data;

    if (is_in_members (reader, "volume")) {
      double volume = getDouble (reader, "volume");
      GESTrackElement *audioElement =
          ges_clip_find_track_element (clip, tracka, G_TYPE_NONE);
      if (audioElement != NULL) {
        ges_track_element_set_child_properties (audioElement, "volume", volume,
            NULL);
      }
    }

    GESTrackElement *videoElement =
        ges_clip_find_track_element (clip, trackv, G_TYPE_NONE);

    if (videoElement != NULL) {
      if (is_in_members (reader, "x")) {
        int x = getInt (reader, "x");
        ges_track_element_set_child_properties (videoElement, "posx", x, NULL);
      }
      if (is_in_members (reader, "y")) {
        int y = getInt (reader, "y");
        ges_track_element_set_child_properties (videoElement, "posy", y, NULL);
      }
      if (is_in_members (reader, "alpha")) {
        gdouble alpha = getDouble (reader, "alpha");
        ges_track_element_set_child_properties (videoElement, "alpha", alpha,
            NULL);
      }

      if (is_in_members (reader, "size")) {
        gdouble size = getDouble (reader, "size");
        GESUriClipAsset *asset =
            GES_URI_CLIP_ASSET (ges_extractable_get_asset (GES_EXTRACTABLE
                (clip)));
        guint width = ges_asset_get_width (asset);
        guint height = ges_asset_get_height (asset);

        if (width != 0 && height != 0) {
          double dw = width * size;
          double dh = height * size;
          g_print ("%dx%d => * %f => %dx%d\n", width, height, size, (int) dw,
              (int) dh);
          ges_track_element_set_child_properties (videoElement,
              "width", (int) dw, "height", (int) dh, NULL);
        }
      }

      if (is_in_members (reader, "effect")) {
        const char *effect_str = getString (reader, "effect");
        if (strcmp (effect_str, "") != 0) {
          g_print ("Using effect %s", effect_str);
          GESEffect *effect = ges_effect_new (effect_str);
          ges_container_add (GES_CONTAINER (clip),
              GES_TIMELINE_ELEMENT (effect));
        }
      }
    }

    json_reader_end_element (reader);
  }
  json_reader_end_member (reader);
}