示例#1
0
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;
}
示例#2
0
GESTimeline *
effectTL (void)
{
  GESTimeline *timeline;
  GESLayer *layer;
  GESClip *clip1, *clip2;
  GESEffect *effect1, *effect2;

  timeline = ges_timeline_new_audio_video ();
  layer = ges_layer_new ();

  ges_timeline_add_layer (timeline, layer);

  clip1 =
      ges_clip_unknown_from_rel_path ("sd/trailer_400p.ogg", layer, 0, 0, 5);
  clip2 =
      ges_clip_unknown_from_rel_path ("sd/sintel_trailer-480p.ogv", layer, 5,
      5, 5);

  effect1 = ges_effect_new ("agingtv");
  ges_container_add (GES_CONTAINER (clip1), GES_TIMELINE_ELEMENT (effect1));

  effect2 = ges_effect_new ("rippletv");
//  some cool Frei0r plugins
//  "frei0r-filter-pixeliz0r", "frei0r-filter-flippo", "frei0r-filter-twolay0r"

  ges_container_add (GES_CONTAINER (clip2), GES_TIMELINE_ELEMENT (effect2));

  ges_timeline_commit (timeline);

  return timeline;
}
static void
_add_track_element (GESFormatter * self, GESClip * clip,
    GESTrackElement * trackelement, const gchar * track_id,
    GstStructure * children_properties, GstStructure * properties)
{
  GESBaseXmlFormatterPrivate *priv = _GET_PRIV (self);
  GESTrack *track = g_hash_table_lookup (priv->tracks, track_id);

  if (track == NULL) {
    GST_WARNING_OBJECT (self, "No track with id %s, can not add trackelement",
        track_id);
    gst_object_unref (trackelement);
    return;
  }

  GST_DEBUG_OBJECT (self, "Adding track_element: %" GST_PTR_FORMAT
      " To : %" GST_PTR_FORMAT, trackelement, clip);

  ges_container_add (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (trackelement));
  gst_structure_foreach (children_properties,
      (GstStructureForeachFunc) _set_child_property, trackelement);

  if (properties)
    gst_structure_foreach (properties,
        (GstStructureForeachFunc) set_property_foreach, trackelement);
}
static void
_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GESTimelineElement *self = GES_TIMELINE_ELEMENT (object);

  switch (property_id) {
    case PROP_PARENT:
      ges_timeline_element_set_parent (self, g_value_get_object (value));
      break;
    case PROP_TIMELINE:
      ges_timeline_element_set_timeline (self, g_value_get_object (value));
      break;
    case PROP_START:
      ges_timeline_element_set_start (self, g_value_get_uint64 (value));
      break;
    case PROP_INPOINT:
      ges_timeline_element_set_inpoint (self, g_value_get_uint64 (value));
      break;
    case PROP_DURATION:
      ges_timeline_element_set_duration (self, g_value_get_uint64 (value));
      break;
    case PROP_PRIORITY:
      ges_timeline_element_set_priority (self, g_value_get_uint (value));
      break;
    case PROP_MAX_DURATION:
      ges_timeline_element_set_max_duration (self, g_value_get_uint64 (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
  }
}
static void
_ges_container_remove_child_properties (GESContainer * container,
                                        GESTimelineElement * child)
{
    guint n_props, i;

    GParamSpec **child_props =
        ges_timeline_element_list_children_properties (child,
                &n_props);

    for (i = 0; i < n_props; i++) {
        GObject *prop_child;

        if (ges_timeline_element_lookup_child (child, child_props[i]->name,
                                               &prop_child, NULL)) {
            ges_timeline_element_remove_child_property (GES_TIMELINE_ELEMENT
                    (container), child_props[i]);

        }

        g_param_spec_unref (child_props[i]);
    }

    g_free (child_props);
}
static void
_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GESTimelineElement *self = GES_TIMELINE_ELEMENT (object);

  switch (property_id) {
    case PROP_PARENT:
      g_value_take_object (value, self->parent);
      break;
    case PROP_TIMELINE:
      g_value_take_object (value, self->timeline);
      break;
    case PROP_START:
      g_value_set_uint64 (value, self->start);
      break;
    case PROP_INPOINT:
      g_value_set_uint64 (value, self->inpoint);
      break;
    case PROP_DURATION:
      g_value_set_uint64 (value, self->duration);
      break;
    case PROP_MAX_DURATION:
      g_value_set_uint64 (value, self->maxduration);
      break;
    case PROP_PRIORITY:
      g_value_set_uint (value, self->priority);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
  }
}
static gboolean
_lookup_child (GESTrackElement * object,
    const gchar * prop_name, GstElement ** element, GParamSpec ** pspec)
{
  return
      GES_TIMELINE_ELEMENT_GET_CLASS (object)->lookup_child
      (GES_TIMELINE_ELEMENT (object), prop_name, (GObject **) element, pspec);
}
static void
ges_uri_clip_init (GESUriClip * self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
      GES_TYPE_URI_CLIP, GESUriClipPrivate);

  /* Setting the duration to -1 by default. */
  GES_TIMELINE_ELEMENT (self)->duration = GST_CLOCK_TIME_NONE;
}
static void
ges_timeline_element_finalize (GObject * self)
{
  GESTimelineElement *tle = GES_TIMELINE_ELEMENT (self);

  g_free (tle->name);

  G_OBJECT_CLASS (ges_timeline_element_parent_class)->finalize (self);
}
static void
ges_title_clip_init (GESTitleClip * self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
      GES_TYPE_TITLE_CLIP, GESTitleClipPrivate);

  GES_TIMELINE_ELEMENT (self)->duration = 0;
  /* Not 100% required since a new gobject's content will always be memzero'd */
}
示例#11
0
static void
ges_test_clip_init (GESTestClip * self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
      GES_TYPE_TEST_CLIP, GESTestClipPrivate);

  self->priv->freq = 0;
  self->priv->volume = 0;
  GES_TIMELINE_ELEMENT (self)->duration = 0;
}
static GList *
ges_uri_clip_create_track_elements (GESClip * clip, GESTrackType type)
{
  GList *res = NULL;
  const GList *tmp, *stream_assets;

  g_return_val_if_fail (GES_TIMELINE_ELEMENT (clip)->asset, NULL);

  stream_assets =
      ges_uri_clip_asset_get_stream_assets (GES_URI_CLIP_ASSET
      (GES_TIMELINE_ELEMENT (clip)->asset));
  for (tmp = stream_assets; tmp; tmp = tmp->next) {
    GESTrackElementAsset *asset = GES_TRACK_ELEMENT_ASSET (tmp->data);

    if (ges_track_element_asset_get_track_type (asset) == type)
      res = g_list_prepend (res, ges_asset_extract (GES_ASSET (asset), NULL));
  }

  return res;
}
示例#13
0
static void
deep_check (GESTimelineElement * element, GstClockTime start,
    GstClockTime inpoint, GstClockTime duration)
{
  GList *track_elements, *tmp;
  GstClockTime rstart, rinpoint, rduration;

  rstart = ges_timeline_element_get_start (GES_TIMELINE_ELEMENT (element));
  rinpoint = ges_timeline_element_get_inpoint (GES_TIMELINE_ELEMENT (element));
  rduration =
      ges_timeline_element_get_duration (GES_TIMELINE_ELEMENT (element));

  assert_equals_uint64 (rstart, start);
  assert_equals_uint64 (rinpoint, inpoint);
  assert_equals_uint64 (rduration, duration);

  track_elements = GES_CONTAINER_CHILDREN (element);
  for (tmp = track_elements; tmp; tmp = tmp->next) {
    rstart = ges_timeline_element_get_start (GES_TIMELINE_ELEMENT (tmp->data));
    rinpoint =
        ges_timeline_element_get_inpoint (GES_TIMELINE_ELEMENT (tmp->data));
    rduration =
        ges_timeline_element_get_duration (GES_TIMELINE_ELEMENT (tmp->data));
    assert_equals_uint64 (rstart, start);
    assert_equals_uint64 (rinpoint, inpoint);
    assert_equals_uint64 (rduration, duration);
  }
}
/**
 * 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;
}
static GESTimelineElement *
_paste (GESTimelineElement * element, GESTimelineElement * ref,
        GstClockTime paste_position)
{
    GList *tmp;
    ChildMapping *map;
    GESContainer *ncontainer =
        GES_CONTAINER (ges_timeline_element_copy (element, FALSE));
    GESContainer *self = GES_CONTAINER (element);

    for (tmp = self->priv->copied_children; tmp; tmp = tmp->next) {
        GESTimelineElement *nchild;

        map = tmp->data;
        nchild =
            ges_timeline_element_paste (map->child,
                                        paste_position - map->start_offset);
        ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (ncontainer),
                                           GES_TIMELINE_ELEMENT_TIMELINE (ref));
        ges_container_add (ncontainer, nchild);
    }

    return GES_TIMELINE_ELEMENT (ncontainer);
}
static void
ges_text_overlay_clip_init (GESTextOverlayClip * self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
      GES_TYPE_OVERLAY_TEXT_CLIP, GESTextOverlayClipPrivate);

  GES_TIMELINE_ELEMENT (self)->duration = 0;
  /* Not 100% needed since gobject contents are memzero'd when created */
  self->priv->text = NULL;
  self->priv->font_desc = NULL;
  self->priv->halign = DEFAULT_PROP_HALIGNMENT;
  self->priv->valign = DEFAULT_PROP_VALIGNMENT;
  self->priv->color = G_MAXUINT32;
  self->priv->xpos = 0.5;
  self->priv->ypos = 0.5;
}
static void
ges_title_clip_init (GESTitleClip * self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
      GES_TYPE_TITLE_CLIP, GESTitleClipPrivate);

  GES_TIMELINE_ELEMENT (self)->duration = 0;
  /* Not 100% required since a new gobject's content will always be memzero'd */
  self->priv->text = NULL;
  self->priv->font_desc = NULL;
  self->priv->halign = DEFAULT_HALIGNMENT;
  self->priv->valign = DEFAULT_VALIGNMENT;
  self->priv->color = G_MAXUINT32;
  self->priv->background = G_MAXUINT32;
  self->priv->xpos = 0.5;
  self->priv->ypos = 0.5;
}
/**
 * ges_layer_resync_priorities:
 * @layer: a #GESLayer
 *
 * Resyncs the priorities of the objects controlled by @layer.
 * This method
 */
static gboolean
ges_layer_resync_priorities (GESLayer * layer)
{
  GList *tmp;
  GESTimelineElement *element;

  GST_DEBUG ("Resync priorities of %p", layer);

  /* TODO : Inhibit composition updates while doing this.
   * Ideally we want to do it from an even higher level, but here will
   * do in the meantime. */

  for (tmp = layer->priv->clips_start; tmp; tmp = tmp->next) {
    element = GES_TIMELINE_ELEMENT (tmp->data);
    _set_priority0 (element, _PRIORITY (element));
  }

  return TRUE;
}
示例#19
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);
}
static void
_add_all_groups (GESFormatter * self)
{
  GList *tmp;
  GESTimelineElement *child;
  GESBaseXmlFormatterPrivate *priv = GES_BASE_XML_FORMATTER (self)->priv;

  for (tmp = priv->groups; tmp; tmp = tmp->next) {
    GList *lchild;
    PendingGroup *pgroup = tmp->data;

    for (lchild = ((PendingGroup *) tmp->data)->pending_children; lchild;
        lchild = lchild->next) {
      child = g_hash_table_lookup (priv->containers, lchild->data);

      GST_DEBUG_OBJECT (tmp->data, "Adding %s child %" GST_PTR_FORMAT " %s",
          (const gchar *) lchild->data, child,
          GES_TIMELINE_ELEMENT_NAME (child));
      ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (pgroup->group), self->timeline);
      ges_container_add (GES_CONTAINER (pgroup->group), child);
    }
  }
}
/**
 * ges_layer_remove_clip:
 * @layer: a #GESLayer
 * @clip: the #GESClip to remove
 *
 * Removes the given @clip from the @layer and unparents it.
 * Unparenting it means the reference owned by @layer on the @clip will be
 * removed. If you wish to use the @clip after this function, make sure you
 * call gst_object_ref() before removing it from the @layer.
 *
 * Returns: TRUE if the clip could be removed, FALSE if the layer does
 * not want to remove the clip.
 */
gboolean
ges_layer_remove_clip (GESLayer * layer, GESClip * clip)
{
  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 ("layer:%p, clip:%p", layer, clip);

  current_layer = ges_clip_get_layer (clip);
  if (G_UNLIKELY (current_layer != layer)) {
    GST_WARNING ("Clip doesn't belong to this layer");

    if (current_layer != NULL)
      gst_object_unref (current_layer);

    return FALSE;
  }
  gst_object_unref (current_layer);

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

  /* inform the clip it's no longer in a layer */
  ges_clip_set_layer (clip, NULL);
  /* so neither in a timeline */
  ges_timeline_element_set_timeline (GES_TIMELINE_ELEMENT (clip), NULL);

  /* Remove it from our list of controlled objects */
  layer->priv->clips_start = g_list_remove (layer->priv->clips_start, clip);

  /* Remove our reference to the clip */
  gst_object_unref (clip);

  return TRUE;
}
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;
}
/**
 * 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;
}
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;
}
}

/**********************************************
 *                                            *
 *    Property notifications from Children    *
 *                                            *
 **********************************************/
static void
_child_start_changed_cb (GESTimelineElement * child,
                         GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
{
    ChildMapping *map;
    GstClockTime start;

    GESContainerPrivate *priv = container->priv;
    GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);

    map = g_hash_table_lookup (priv->mappings, child);
    g_assert (map);

    switch (container->children_control_mode) {
    case GES_CHILDREN_IGNORE_NOTIFIES:
        return;
    case GES_CHILDREN_UPDATE_ALL_VALUES:
        _ges_container_sort_children (container);
        start = container->children ?
                _START (container->children->data) : _START (container);

        if (start != _START (container)) {
            _DURATION (container) = _END (container) - start;
            _START (container) = start;
static void
extractable_set_asset (GESExtractable * extractable, GESAsset * asset)
{
  GES_TIMELINE_ELEMENT (extractable)->asset = asset;
}
示例#27
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);
}
示例#28
0
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);
  }
}