/**
 * ges_text_overlay_clip_new:
 *
 * Creates a new #GESTextOverlayClip
 *
 * Returns: (transfer floating) (nullable): The newly created
 * #GESTextOverlayClip, or %NULL if there was an error.
 */
GESTextOverlayClip *
ges_text_overlay_clip_new (void)
{
  GESTextOverlayClip *new_clip;
  GESAsset *asset = ges_asset_request (GES_TYPE_OVERLAY_TEXT_CLIP, NULL, NULL);

  new_clip = GES_OVERLAY_TEXT_CLIP (ges_asset_extract (asset, NULL));
  gst_object_unref (asset);

  return new_clip;
}
Пример #2
0
/**
 * ges_test_clip_new:
 *
 * Creates a new #GESTestClip.
 *
 * Returns: The newly created #GESTestClip, or NULL if there was an
 * error.
 */
GESTestClip *
ges_test_clip_new (void)
{
  GESTestClip *new_clip;
  GESAsset *asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL);

  new_clip = GES_TEST_CLIP (ges_asset_extract (asset, NULL));
  gst_object_unref (asset);

  return new_clip;
}
void
ges_base_xml_formatter_add_layer (GESBaseXmlFormatter * self,
    GType extractable_type, guint priority, GstStructure * properties,
    const gchar * metadatas, GError ** error)
{
  LayerEntry *entry;
  GESAsset *asset;
  GESLayer *layer;
  gboolean auto_transition = FALSE;
  GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);

  if (priv->check_only)
    return;

  if (extractable_type == G_TYPE_NONE)
    layer = ges_layer_new ();
  else {
    asset = ges_asset_request (extractable_type, NULL, error);
    if (asset == NULL) {
      if (error && *error == NULL) {
        g_set_error (error, G_MARKUP_ERROR,
            G_MARKUP_ERROR_INVALID_CONTENT,
            "Layer type %s could not be created'",
            g_type_name (extractable_type));
        return;
      }
    }
    layer = GES_LAYER (ges_asset_extract (asset, error));
  }

  ges_layer_set_priority (layer, priority);
  ges_timeline_add_layer (GES_FORMATTER (self)->timeline, layer);
  if (properties) {
    if (gst_structure_get_boolean (properties, "auto-transition",
            &auto_transition))
      gst_structure_remove_field (properties, "auto-transition");

    gst_structure_foreach (properties,
        (GstStructureForeachFunc) set_property_foreach, layer);
  }

  if (metadatas)
    ges_meta_container_add_metas_from_string (GES_META_CONTAINER (layer),
        metadatas);

  entry = g_slice_new0 (LayerEntry);
  entry->layer = gst_object_ref (layer);
  entry->auto_trans = auto_transition;

  g_hash_table_insert (priv->layers, GINT_TO_POINTER (priority), entry);
}
/**
 * ges_asset_custom_source_clip_new:
 * @func: (scope notified): The #GESFillTrackElementUserFunc that will be used to fill the track
 * objects.
 * @user_data: (closure): a gpointer that will be used when @func is called.
 *
 * Helper constructor to instanciate a new #GESAsset from which you can
 * extract #GESCustomSourceClip-s
 *
 * Returns: The new #GESAsset
 */
GESAsset *
ges_asset_custom_source_clip_new (GESFillTrackElementUserFunc func,
    gpointer user_data)
{
  GESAsset *asset;
  gchar *id = g_strdup_printf ("%i!%i", GPOINTER_TO_INT (func),
      GPOINTER_TO_INT (user_data));

  asset = ges_asset_request (GES_TYPE_CUSTOM_SOURCE_CLIP, id, NULL);

  g_free (id);

  return asset;
}
GESTransitionClip *
ges_transition_clip_new_for_nick (gchar * nick)
{
  GESTransitionClip *ret = NULL;
  GESAsset *asset = ges_asset_request (GES_TYPE_TRANSITION_CLIP, nick, NULL);

  if (asset != NULL) {
    ret = GES_TRANSITION_CLIP (ges_asset_extract (asset, NULL));

    gst_object_unref (asset);
  } else
    GST_WARNING ("No asset found for nick: %s", nick);

  return ret;
}
Пример #6
0
/**
 * ges_effect_new:
 * @bin_description: The gst-launch like bin description of the effect
 *
 * Creates a new #GESEffect from the description of the bin.
 *
 * Returns: a newly created #GESEffect, or %NULL if something went
 * wrong.
 */
GESEffect *
ges_effect_new (const gchar * bin_description)
{
  GESEffect *effect;
  GESAsset *asset = ges_asset_request (GES_TYPE_EFFECT,
      bin_description, NULL);

  g_return_val_if_fail (asset, NULL);

  effect = GES_EFFECT (ges_asset_extract (asset, NULL));

  gst_object_unref (asset);

  return effect;
}
Пример #7
0
void
_init_standard_transition_assets (void)
{
    guint i;

    for (i = 1; i < G_N_ELEMENTS (transition_types) - 1; i++) {
        GESAsset *asset = ges_asset_request (GES_TYPE_TRANSITION_CLIP,
                                             transition_types[i].value_nick, NULL);

        ges_meta_container_register_meta_string (GES_META_CONTAINER (asset),
                GES_META_READABLE, GES_META_DESCRIPTION,
                transition_types[i].value_name);
    }

}
Пример #8
0
/**
 * ges_project_new:
 * @uri: (allow-none): The uri to be set after creating the project.
 *
 * Creates a new #GESProject and sets its uri to @uri if provided. Note that
 * if @uri is not valid or %NULL, the uri of the project will then be set
 * the first time you save the project. If you then save the project to
 * other locations, it will never be updated again and the first valid URI is
 * the URI it will keep refering to.
 *
 * Returns: A newly created #GESProject
 */
GESProject *
ges_project_new (const gchar * uri)
{
  gchar *id = (gchar *) uri;
  GESProject *project;

  if (uri == NULL)
    id = g_strdup_printf ("project-%i", nb_projects++);

  project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, id, NULL));

  if (project && uri)
    ges_project_set_uri (project, uri);

  return project;
}
Пример #9
0
static gboolean
_add_asset (GstValidateScenario *scenario, GstValidateAction *action)
{
  const gchar *id = NULL;
  const gchar *type_string = NULL;
  GType type;
  GESTimeline *timeline = get_timeline(scenario);
  GESProject *project = ges_timeline_get_project(timeline);
  GESAsset *asset;
  GError *error = NULL;
  gboolean res = FALSE;

  id = gst_structure_get_string (action->structure, "id");
  type_string = gst_structure_get_string (action->structure, "type");

  if (!type_string || !id) {
    GST_ERROR("Missing parameters, we got type %s and id %s", type_string, id);
    goto beach;
  }

  if (!(type = g_type_from_name(type_string))) {
    GST_ERROR("This type doesn't exist : %s", type_string);
    goto beach;
  }

  if (type == GES_TYPE_URI_CLIP)
    asset = (GESAsset *) ges_uri_clip_asset_request_sync(id, &error);
  else
    asset = ges_asset_request(type, id, &error);

  if (!asset || error) {
    GST_ERROR("There was an error requesting the asset with id %s and type %s", id, type_string);
    goto beach;
  }

  res = ges_project_add_asset(project, asset);

beach:
  g_object_unref(timeline);
  return res;
}
/* 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));
  }
}
void
ges_base_xml_formatter_add_clip (GESBaseXmlFormatter * self,
    const gchar * id, const char *asset_id, GType type, GstClockTime start,
    GstClockTime inpoint, GstClockTime duration,
    guint layer_prio, GESTrackType track_types, GstStructure * properties,
    const gchar * metadatas, GError ** error)
{
  GESAsset *asset;
  GESClip *nclip;
  LayerEntry *entry;
  GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);

  if (priv->check_only)
    return;

  entry = g_hash_table_lookup (priv->layers, GINT_TO_POINTER (layer_prio));
  if (entry == NULL) {
    g_set_error (error, GES_ERROR, GES_ERROR_FORMATTER_MALFORMED_INPUT_FILE,
        "We got a Clip in a layer"
        " that does not exist, something is wrong either in the project file or"
        " in %s", g_type_name (G_OBJECT_TYPE (self)));
    return;
  }

  /* We do not want the properties that are passed to layer-add_asset to be reset */
  if (properties)
    gst_structure_remove_fields (properties, "supported-formats",
        "inpoint", "start", "duration", NULL);

  asset = ges_asset_request (type, asset_id, NULL);
  if (asset == NULL) {
    gchar *real_id;
    PendingClip *pclip;
    GList *pendings;

    real_id = ges_extractable_type_check_id (type, asset_id, error);
    if (real_id == NULL) {
      if (*error == NULL)
        g_set_error (error, G_MARKUP_ERROR,
            G_MARKUP_ERROR_INVALID_CONTENT,
            "Object type '%s' with Asset id: %s not be created'",
            g_type_name (type), asset_id);

      return;
    }

    pendings = g_hash_table_lookup (priv->assetid_pendingclips, asset_id);

    pclip = g_slice_new0 (PendingClip);
    GST_DEBUG_OBJECT (self, "Adding pending %p for %s, currently: %i",
        pclip, asset_id, g_list_length (pendings));

    pclip->id = g_strdup (id);
    pclip->track_types = track_types;
    pclip->duration = duration;
    pclip->inpoint = inpoint;
    pclip->start = start;
    pclip->layer = gst_object_ref (entry->layer);

    pclip->properties = properties ? gst_structure_copy (properties) : NULL;
    pclip->metadatas = g_strdup (metadatas);

    /* Add the new pending object to the hashtable */
    g_hash_table_insert (priv->assetid_pendingclips, real_id,
        g_list_append (pendings, pclip));
    g_hash_table_insert (priv->clipid_pendings, g_strdup (id), pclip);

    priv->current_clip = NULL;
    priv->current_pending_clip = pclip;

    return;
  }

  nclip = _add_object_to_layer (priv, id, entry->layer,
      asset, start, inpoint, duration, track_types, metadatas, properties);

  if (!nclip)
    return;

  priv->current_clip = nclip;
}
void
ges_base_xml_formatter_add_track_element (GESBaseXmlFormatter * self,
    GType track_element_type, const gchar * asset_id, const gchar * track_id,
    const gchar * timeline_obj_id, GstStructure * children_properties,
    GstStructure * properties, const gchar * metadatas, GError ** error)
{
  GESTrackElement *trackelement;

  GError *err = NULL;
  GESAsset *asset = NULL;
  GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);

  if (priv->check_only)
    return;

  if (g_type_is_a (track_element_type, GES_TYPE_TRACK_ELEMENT) == FALSE) {
    GST_DEBUG_OBJECT (self, "%s is not a TrackElement, can not create it",
        g_type_name (track_element_type));
    goto out;
  }

  if (g_type_is_a (track_element_type, GES_TYPE_BASE_EFFECT) == FALSE) {
    GST_FIXME_OBJECT (self, "%s currently not supported",
        g_type_name (track_element_type));
    goto out;
  }

  asset = ges_asset_request (track_element_type, asset_id, &err);
  if (asset == NULL) {
    GST_DEBUG_OBJECT (self, "Can not create trackelement %s", asset_id);
    GST_FIXME_OBJECT (self, "Check if missing plugins etc %s",
        err ? err->message : "");

    goto out;
  }

  trackelement = GES_TRACK_ELEMENT (ges_asset_extract (asset, NULL));
  if (trackelement) {
    GESClip *clip;
    if (metadatas)
      ges_meta_container_add_metas_from_string (GES_META_CONTAINER
          (trackelement), metadatas);

    clip = g_hash_table_lookup (priv->containers, timeline_obj_id);
    if (clip) {
      _add_track_element (GES_FORMATTER (self), clip, trackelement, track_id,
          children_properties, properties);
    } else {
      PendingEffects *peffect;
      PendingClip *pend = g_hash_table_lookup (priv->clipid_pendings,
          timeline_obj_id);
      if (pend == NULL) {
        GST_WARNING_OBJECT (self, "No Clip with id: %s can not "
            "add TrackElement", timeline_obj_id);
        goto out;
      }

      peffect = g_slice_new0 (PendingEffects);

      peffect->trackelement = trackelement;
      peffect->track_id = g_strdup (track_id);
      peffect->properties = properties ? gst_structure_copy (properties) : NULL;
      peffect->children_properties = children_properties ?
          gst_structure_copy (children_properties) : NULL;

      pend->effects = g_list_append (pend->effects, peffect);
    }
    priv->current_track_element = trackelement;
  }

  ges_project_add_asset (GES_FORMATTER (self)->project, asset);

out:
  if (asset)
    gst_object_unref (asset);
  if (err)
    g_error_free (err);

  return;
}
Пример #13
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;
}
Пример #14
0
static gboolean
_add_clip(GstValidateScenario *scenario, GstValidateAction * action)
{
  GESTimeline *timeline = get_timeline(scenario);
  GESAsset *asset;
  GESLayer *layer;
  GESClip *clip;
  GError *error = NULL;
  gint layer_priority;
  const gchar *name;
  const gchar *asset_id;
  const gchar *type_string;
  GType type;
  gboolean res = FALSE;
  GstClockTime duration = 1 * GST_SECOND;

  gst_structure_get_int(action->structure, "layer-priority", &layer_priority);
  name = gst_structure_get_string(action->structure, "name");
  asset_id = gst_structure_get_string(action->structure, "asset-id");
  type_string = gst_structure_get_string(action->structure, "type");

  if (!(type = g_type_from_name(type_string))) {
    GST_ERROR("This type doesn't exist : %s", type_string);
    goto beach;
  }

  asset = ges_asset_request(type, asset_id, &error);

  if (!asset || error) {
    GST_ERROR("There was an error requesting the asset with id %s and type %s (%s)",
        asset_id, type_string, error->message);
    goto beach;
  }

  layer = _get_layer_by_priority(timeline, layer_priority);

  if (!layer) {
    GST_ERROR("No layer with priority %d", layer_priority);
    goto beach;
  }

  if (type == GES_TYPE_URI_CLIP) {
    duration = GST_CLOCK_TIME_NONE;
  }

  clip = ges_layer_add_asset(layer, asset, GST_CLOCK_TIME_NONE, 0, duration,
      GES_TRACK_TYPE_UNKNOWN);

  if (clip) {
    res = TRUE;
    if (!ges_timeline_element_set_name(GES_TIMELINE_ELEMENT(clip), name)) {
      res = FALSE;
      GST_ERROR("couldn't set name %s on clip with id %s", name, asset_id);
    }
  } else {
    GST_ERROR("Couldn't add clip with id %s to layer with priority %d", asset_id, layer_priority);
  }

  gst_object_unref (layer); 

  ges_timeline_commit(timeline);

beach:
  g_object_unref(timeline);
  return res;
}
Пример #15
0
/* A simple timeline with 3 audio/video sources */
int
main (int argc, gchar ** argv)
{
  GESAsset *src_asset;
  GESTimelinePipeline *pipeline;
  GESTimeline *timeline;
  GESClip *source;
  GESTimelineLayer *layer;
  GMainLoop *mainloop;

  /* Initialize GStreamer (this will parse environment variables and commandline
   * arguments. */
  gst_init (&argc, &argv);

  /* Initialize the GStreamer Editing Services */
  ges_init ();

  /* Setup of a A/V timeline */

  /* This is our main GESTimeline */
  timeline = ges_timeline_new_audio_video ();

  /* We are only going to be doing one layer of clips */
  layer = ges_timeline_layer_new ();

  /* Add the tracks and the layer to the timeline */
  if (!ges_timeline_add_layer (timeline, layer))
    return -1;

  /* We create a simple asset able to extract GESTestClip */
  src_asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL);

  /* Add sources to our layer */
  ges_timeline_layer_add_asset (layer, src_asset, 0, 0, GST_SECOND, 1,
      GES_TRACK_TYPE_UNKNOWN);
  source = ges_timeline_layer_add_asset (layer, src_asset, GST_SECOND, 0,
      GST_SECOND, 1, GES_TRACK_TYPE_UNKNOWN);
  g_object_set (source, "freq", 480.0, "vpattern", 2, NULL);
  ges_timeline_layer_add_asset (layer, src_asset, 2 * GST_SECOND, 0,
      GST_SECOND, 1, GES_TRACK_TYPE_UNKNOWN);


  /* In order to view our timeline, let's grab a convenience pipeline to put
   * our timeline in. */
  pipeline = ges_timeline_pipeline_new ();

  /* Add the timeline to that pipeline */
  if (!ges_timeline_pipeline_add_timeline (pipeline, timeline))
    return -1;

  /* The following is standard usage of a GStreamer pipeline (note how you haven't
   * had to care about GStreamer so far ?).
   *
   * We set the pipeline to playing ... */
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

  /* .. and we start a GMainLoop. GES **REQUIRES** a GMainLoop to be running in
   * order to function properly ! */
  mainloop = g_main_loop_new (NULL, FALSE);

  /* Simple code to have the mainloop shutdown after 4s */
  g_timeout_add_seconds (4, (GSourceFunc) g_main_loop_quit, mainloop);
  g_main_loop_run (mainloop);

  return 0;
}