ges: Port to the new commit based API in GNL

The GNL API changed to go from a model where user could
enable/disable updates in the composition, which leaded to races
in many places, to a model where any positioning change in the
composition is not directly done but 'cached' and then the user
has to commit those changes so they become effective in the media
processing stack.

The new API in GES is pretty similare and is basically copy
pasting this new design.

We still need to see if in some context it would make sense to add
a mode where we would commit any changes ourself at the end of our
operation for basic use cases.

Removed APIs:
  ges_timeline_enable_update
  ges_timeline_is_updating
  ges_track_enable_update
  ges_track_is_updating

New APIs:
  ges_track_commit
  ges_timeline_commit
This commit is contained in:
Thibault Saunier 2013-06-09 12:29:05 -04:00
parent 30f0924055
commit f6038e3ad2
18 changed files with 86 additions and 246 deletions

View file

@ -382,7 +382,6 @@ _loading_done (GESFormatter * self)
priv->parsecontext = NULL; priv->parsecontext = NULL;
g_hash_table_foreach (priv->layers, (GHFunc) _set_auto_transition, NULL); g_hash_table_foreach (priv->layers, (GHFunc) _set_auto_transition, NULL);
ges_timeline_enable_update (self->timeline, TRUE);
ges_project_set_loaded (self->project, self); ges_project_set_loaded (self->project, self);
} }

View file

@ -98,9 +98,9 @@ static GParamSpec *_properties[LAST_SIGNAL] = { 0 };
static gboolean static gboolean
_emit_loaded_in_idle (EmitLoadedInIdle * data) _emit_loaded_in_idle (EmitLoadedInIdle * data)
{ {
ges_timeline_commit (data->timeline);
g_signal_emit (data->project, _signals[LOADED_SIGNAL], 0, data->timeline); g_signal_emit (data->project, _signals[LOADED_SIGNAL], 0, data->timeline);
ges_timeline_enable_update (data->timeline, TRUE);
gst_object_unref (data->project); gst_object_unref (data->project);
gst_object_unref (data->timeline); gst_object_unref (data->timeline);
g_slice_free (EmitLoadedInIdle, data); g_slice_free (EmitLoadedInIdle, data);
@ -201,7 +201,6 @@ _load_project (GESProject * project, GESTimeline * timeline, GError ** error)
} }
ges_project_add_formatter (GES_PROJECT (project), formatter); ges_project_add_formatter (GES_PROJECT (project), formatter);
ges_timeline_enable_update (timeline, FALSE);
ges_formatter_load_from_uri (formatter, timeline, priv->uri, &lerr); ges_formatter_load_from_uri (formatter, timeline, priv->uri, &lerr);
if (lerr) { if (lerr) {
GST_WARNING_OBJECT (project, "Could not load the timeline," GST_WARNING_OBJECT (project, "Could not load the timeline,"
@ -513,10 +512,10 @@ gboolean
ges_project_set_loaded (GESProject * project, GESFormatter * formatter) ges_project_set_loaded (GESProject * project, GESFormatter * formatter)
{ {
GST_INFO_OBJECT (project, "Emit project loaded"); GST_INFO_OBJECT (project, "Emit project loaded");
ges_timeline_commit (formatter->timeline);
g_signal_emit (project, _signals[LOADED_SIGNAL], 0, formatter->timeline); g_signal_emit (project, _signals[LOADED_SIGNAL], 0, formatter->timeline);
/* We are now done with that formatter */ /* We are now done with that formatter */
ges_timeline_enable_update (formatter->timeline, TRUE);
ges_project_remove_formatter (project, formatter); ges_project_remove_formatter (project, formatter);
return TRUE; return TRUE;
} }

View file

@ -35,6 +35,9 @@
* *
* To save/load a timeline, you can use the ges_timeline_load_from_uri() and * To save/load a timeline, you can use the ges_timeline_load_from_uri() and
* ges_timeline_save_to_uri() methods to use the default format. If you wish * ges_timeline_save_to_uri() methods to use the default format. If you wish
*
* Note that any change you make in the timeline will not actually be taken
* into account until you call the #ges_timeline_commit method.
*/ */
#include "ges-internal.h" #include "ges-internal.h"
@ -178,8 +181,6 @@ struct _GESTimelinePrivate
* and %FALSE otherwize */ * and %FALSE otherwize */
gboolean needs_transitions_update; gboolean needs_transitions_update;
gboolean updates_enabled;
/* While we are creating and adding the TrackElements for a clip, we need to /* While we are creating and adding the TrackElements for a clip, we need to
* ignore the child-added signal */ * ignore the child-added signal */
GESClip *ignore_track_element_added; GESClip *ignore_track_element_added;
@ -284,9 +285,6 @@ ges_timeline_get_property (GObject * object, guint property_id,
case PROP_SNAPPING_DISTANCE: case PROP_SNAPPING_DISTANCE:
g_value_set_uint64 (value, timeline->priv->snapping_distance); g_value_set_uint64 (value, timeline->priv->snapping_distance);
break; break;
case PROP_UPDATE:
g_value_set_boolean (value, ges_timeline_is_updating (timeline));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
@ -305,9 +303,6 @@ ges_timeline_set_property (GObject * object, guint property_id,
case PROP_SNAPPING_DISTANCE: case PROP_SNAPPING_DISTANCE:
timeline->priv->snapping_distance = g_value_get_uint64 (value); timeline->priv->snapping_distance = g_value_get_uint64 (value);
break; break;
case PROP_UPDATE:
ges_timeline_enable_update (timeline, g_value_get_boolean (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
} }
@ -419,27 +414,6 @@ ges_timeline_class_init (GESTimelineClass * klass)
g_object_class_install_property (object_class, PROP_SNAPPING_DISTANCE, g_object_class_install_property (object_class, PROP_SNAPPING_DISTANCE,
properties[PROP_SNAPPING_DISTANCE]); properties[PROP_SNAPPING_DISTANCE]);
/**
* GESTimeline:update:
*
* If %TRUE, then all modifications to objects within the timeline will
* cause a internal pipeline update (if required).
* If %FALSE, then only the timeline start/duration/stop properties
* will be updated, and the internal pipeline will only be updated when the
* property is set back to %TRUE.
*
* It is recommended to temporarily set this property to %FALSE before doing
* more than one modification in the timeline (like adding or moving
* several objects at once) in order to speed up the process, and then setting
* back the property to %TRUE when done.
*/
properties[PROP_UPDATE] = g_param_spec_boolean ("update", "Update",
"Update the internal pipeline on every modification", TRUE,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_UPDATE,
properties[PROP_UPDATE]);
/** /**
* GESTimeline::track-added: * GESTimeline::track-added:
* @timeline: the #GESTimeline * @timeline: the #GESTimeline
@ -572,8 +546,6 @@ ges_timeline_init (GESTimeline * self)
g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gst_object_unref); g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gst_object_unref);
priv->needs_transitions_update = TRUE; priv->needs_transitions_update = TRUE;
priv->updates_enabled = TRUE;
g_signal_connect_after (self, "select-tracks-for-object", g_signal_connect_after (self, "select-tracks-for-object",
G_CALLBACK (select_tracks_for_object_default), NULL); G_CALLBACK (select_tracks_for_object_default), NULL);
} }
@ -891,7 +863,7 @@ create_transitions (GESTimeline * timeline, GESTrackElement * track_element)
GESTimelinePrivate *priv = timeline->priv; GESTimelinePrivate *priv = timeline->priv;
if (!priv->needs_transitions_update || !priv->updates_enabled) if (!priv->needs_transitions_update)
return; return;
GST_DEBUG_OBJECT (timeline, "Creating transitions around %p", track_element); GST_DEBUG_OBJECT (timeline, "Creating transitions around %p", track_element);
@ -2513,8 +2485,6 @@ ges_timeline_add_track (GESTimeline * timeline, GESTrack * track)
/* Inform the track that it's currently being used by ourself */ /* Inform the track that it's currently being used by ourself */
ges_track_set_timeline (track, timeline); ges_track_set_timeline (track, timeline);
ges_track_enable_update (track, timeline->priv->updates_enabled);
GST_DEBUG ("Done adding track, emitting 'track-added' signal"); GST_DEBUG ("Done adding track, emitting 'track-added' signal");
/* emit 'track-added' */ /* emit 'track-added' */
@ -2700,65 +2670,41 @@ ges_timeline_get_layers (GESTimeline * timeline)
} }
/** /**
* ges_timeline_is_updating: * ges_timeline_commit:
* @timeline: a #GESTimeline * @timeline: a #GESTimeline
* *
* Get whether the timeline is updated for every change happening within or not. * Commits all the pending changes of the clips contained in the
* @timeline.
* *
* Returns: %TRUE if @timeline is updating on every changes, else %FALSE. * When timing changes happen in a timeline, the changes are not
* directly done inside GNL. This method needs to be called so any changes
* on a clip contained in the timeline actually happen at the media
* processing level.
*
* Returns: %TRUE if something as been commited %FALSE if nothing needed
* to be commited
*/ */
gboolean gboolean
ges_timeline_is_updating (GESTimeline * timeline) ges_timeline_commit (GESTimeline * timeline)
{
GList *tmp;
g_return_val_if_fail (GES_IS_TIMELINE (timeline), FALSE);
for (tmp = timeline->tracks; tmp; tmp = tmp->next) {
if (!ges_track_is_updating (GES_TRACK (tmp->data)))
return FALSE;
}
return TRUE;
}
/**
* ges_timeline_enable_update:
* @timeline: a #GESTimeline
* @enabled: Whether the timeline should update on every change or not.
*
* Control whether the timeline is updated for every change happening within.
*
* Users will want to use this method with %FALSE before doing lots of changes,
* and then call again with %TRUE for the changes to take effect in one go.
*
* Returns: %TRUE if the update status could be changed, else %FALSE.
*/
gboolean
ges_timeline_enable_update (GESTimeline * timeline, gboolean enabled)
{ {
GList *tmp; GList *tmp;
gboolean res = TRUE; gboolean res = TRUE;
GST_DEBUG_OBJECT (timeline, "%s updates", enabled ? "Enabling" : "Disabling"); GST_DEBUG_OBJECT (timeline, "commiting changes");
for (tmp = timeline->tracks; tmp; tmp = tmp->next) { for (tmp = timeline->tracks; tmp; tmp = tmp->next) {
if (!ges_track_enable_update (GES_TRACK (tmp->data), enabled)) if (!ges_track_commit (GES_TRACK (tmp->data)))
res = FALSE; res = FALSE;
} }
/* Make sure we reset the context */ /* Make sure we reset the context */
timeline->priv->movecontext.needs_move_ctx = TRUE; timeline->priv->movecontext.needs_move_ctx = TRUE;
timeline->priv->updates_enabled = enabled;
for (tmp = timeline->layers; tmp; tmp = tmp->next) { for (tmp = timeline->layers; tmp; tmp = tmp->next) {
_create_transitions_on_layer (timeline, GES_LAYER (tmp->data), _create_transitions_on_layer (timeline, GES_LAYER (tmp->data),
NULL, NULL, _find_transition_from_auto_transitions); NULL, NULL, _find_transition_from_auto_transitions);
} }
if (res)
g_object_notify_by_pspec (G_OBJECT (timeline), properties[PROP_UPDATE]);
return res; return res;
} }

View file

@ -116,8 +116,7 @@ gboolean ges_timeline_remove_track (GESTimeline *timeline, GESTrack *track);
GESTrack * ges_timeline_get_track_for_pad (GESTimeline *timeline, GstPad *pad); GESTrack * ges_timeline_get_track_for_pad (GESTimeline *timeline, GstPad *pad);
GList *ges_timeline_get_tracks (GESTimeline *timeline); GList *ges_timeline_get_tracks (GESTimeline *timeline);
gboolean ges_timeline_enable_update(GESTimeline * timeline, gboolean enabled); gboolean ges_timeline_commit (GESTimeline * timeline);
gboolean ges_timeline_is_updating (GESTimeline * timeline);
GstClockTime ges_timeline_get_duration (GESTimeline *timeline); GstClockTime ges_timeline_get_duration (GESTimeline *timeline);

View file

@ -102,21 +102,6 @@ static guint ges_track_element_signals[LAST_SIGNAL] = { 0 };
static GstElement *ges_track_element_create_gnl_object_func (GESTrackElement * static GstElement *ges_track_element_create_gnl_object_func (GESTrackElement *
object); object);
static void gnlobject_start_cb (GstElement * gnlobject, GParamSpec * arg
G_GNUC_UNUSED, GESTrackElement * track_element);
static void gnlobject_media_start_cb (GstElement * gnlobject, GParamSpec * arg
G_GNUC_UNUSED, GESTrackElement * track_element);
static void gnlobject_priority_cb (GstElement * gnlobject, GParamSpec * arg
G_GNUC_UNUSED, GESTrackElement * track_element);
static void gnlobject_duration_cb (GstElement * gnlobject, GParamSpec * arg
G_GNUC_UNUSED, GESTrackElement * track_element);
static void gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg
G_GNUC_UNUSED, GESTrackElement * track_element);
static void connect_properties_signals (GESTrackElement * object); static void connect_properties_signals (GESTrackElement * object);
static void connect_signal (gpointer key, gpointer value, gpointer user_data); static void connect_signal (gpointer key, gpointer value, gpointer user_data);
static void gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg static void gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
@ -322,7 +307,7 @@ _set_inpoint (GESTimelineElement * element, GstClockTime inpoint)
return FALSE; return FALSE;
g_object_set (object->priv->gnlobject, "media-start", inpoint, NULL); g_object_set (object->priv->gnlobject, "inpoint", inpoint, NULL);
} else } else
object->priv->pending_inpoint = inpoint; object->priv->pending_inpoint = inpoint;
@ -343,8 +328,7 @@ _set_duration (GESTimelineElement * element, GstClockTime duration)
if (G_UNLIKELY (duration == _DURATION (object))) if (G_UNLIKELY (duration == _DURATION (object)))
return FALSE; return FALSE;
g_object_set (priv->gnlobject, "duration", duration, g_object_set (priv->gnlobject, "duration", duration, NULL);
"media-duration", duration, NULL);
} else } else
priv->pending_duration = duration; priv->pending_duration = duration;
@ -384,15 +368,22 @@ ges_track_element_set_active (GESTrackElement * object, gboolean active)
{ {
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE); g_return_val_if_fail (GES_IS_TRACK_ELEMENT (object), FALSE);
GST_DEBUG ("object:%p, active:%d", object, active); GST_DEBUG_OBJECT (object, "object:%p, active:%d", object, active);
if (object->priv->gnlobject != NULL) { if (object->priv->gnlobject != NULL) {
if (G_UNLIKELY (active == object->active)) if (G_UNLIKELY (active == object->active))
return FALSE; return FALSE;
g_object_set (object->priv->gnlobject, "active", active, NULL); g_object_set (object->priv->gnlobject, "active", active, NULL);
if (active != object->active) {
object->active = active;
if (GES_TRACK_ELEMENT_GET_CLASS (object)->active_changed)
GES_TRACK_ELEMENT_GET_CLASS (object)->active_changed (object, active);
}
} else } else
object->priv->pending_active = active; object->priv->pending_active = active;
return TRUE; return TRUE;
} }
@ -415,25 +406,6 @@ ges_track_element_get_track_type (GESTrackElement * object)
return object->priv->track_type; return object->priv->track_type;
} }
/* Callbacks from the GNonLin object */
static void
gnlobject_start_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
GESTrackElement * track_element)
{
guint64 start;
g_object_get (gnlobject, "start", &start, NULL);
GST_DEBUG_OBJECT (gnlobject, "start : %" GST_TIME_FORMAT " current : %"
GST_TIME_FORMAT, GST_TIME_ARGS (start),
GST_TIME_ARGS (_START (track_element)));
if (start != _START (track_element)) {
ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (track_element),
start);
}
}
static void static void
gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg gst_element_prop_changed_cb (GstElement * element, GParamSpec * arg
G_GNUC_UNUSED, GESTrackElement * track_element) G_GNUC_UNUSED, GESTrackElement * track_element)
@ -467,82 +439,6 @@ connect_properties_signals (GESTrackElement * object)
} }
/* Callbacks from the GNonLin object */
static void
gnlobject_media_start_cb (GstElement * gnlobject,
GParamSpec * arg G_GNUC_UNUSED, GESTrackElement * track_element)
{
guint64 inpoint;
g_object_get (gnlobject, "media-start", &inpoint, NULL);
GST_DEBUG_OBJECT (gnlobject, "in-point : %" GST_TIME_FORMAT " current : %"
GST_TIME_FORMAT, GST_TIME_ARGS (inpoint),
GST_TIME_ARGS (_INPOINT (track_element)));
if (inpoint != _INPOINT (track_element)) {
ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (track_element),
inpoint);
}
}
static void
gnlobject_priority_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
GESTrackElement * track_element)
{
guint32 priority;
g_object_get (gnlobject, "priority", &priority, NULL);
GST_DEBUG ("gnlobject priority : %d current : %d", priority,
_PRIORITY (track_element));
if (priority != _PRIORITY (track_element)) {
ges_timeline_element_set_priority (GES_TIMELINE_ELEMENT (track_element),
priority);
}
}
static void
gnlobject_duration_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
GESTrackElement * track_element)
{
guint64 duration;
g_object_get (gnlobject, "duration", &duration, NULL);
GST_DEBUG_OBJECT (gnlobject, "duration : %" GST_TIME_FORMAT " current : %"
GST_TIME_FORMAT, GST_TIME_ARGS (duration),
GST_TIME_ARGS (_DURATION (track_element)));
if (duration != _DURATION (track_element)) {
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (track_element),
duration);
}
}
static void
gnlobject_active_cb (GstElement * gnlobject, GParamSpec * arg G_GNUC_UNUSED,
GESTrackElement * track_element)
{
gboolean active;
GESTrackElementClass *klass;
klass = GES_TRACK_ELEMENT_GET_CLASS (track_element);
g_object_get (gnlobject, "active", &active, NULL);
GST_DEBUG ("gnlobject active : %d current : %d", active,
track_element->active);
if (active != track_element->active) {
track_element->active = active;
if (klass->active_changed)
klass->active_changed (track_element, active);
}
}
/* default 'create_gnl_object' virtual method implementation */ /* default 'create_gnl_object' virtual method implementation */
static GstElement * static GstElement *
ges_track_element_create_gnl_object_func (GESTrackElement * self) ges_track_element_create_gnl_object_func (GESTrackElement * self)
@ -669,28 +565,22 @@ ensure_gnl_object (GESTrackElement * object)
res = TRUE; res = TRUE;
if (res) { if (res) {
/* Connect to property notifications */
/* FIXME : remember the signalids so we can remove them later on !!! */
g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::start",
G_CALLBACK (gnlobject_start_cb), object);
g_signal_connect (G_OBJECT (object->priv->gnlobject),
"notify::media-start", G_CALLBACK (gnlobject_media_start_cb), object);
g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::duration",
G_CALLBACK (gnlobject_duration_cb), object);
g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::priority",
G_CALLBACK (gnlobject_priority_cb), object);
g_signal_connect (G_OBJECT (object->priv->gnlobject), "notify::active",
G_CALLBACK (gnlobject_active_cb), object);
/* Set some properties on the GnlObject */ /* Set some properties on the GnlObject */
g_object_set (object->priv->gnlobject, g_object_set (object->priv->gnlobject,
"duration", object->priv->pending_duration, "duration", object->priv->pending_duration,
"media-duration", object->priv->pending_duration,
"start", object->priv->pending_start, "start", object->priv->pending_start,
"media-start", object->priv->pending_inpoint, "inpoint", object->priv->pending_inpoint,
"priority", object->priv->pending_priority, "priority", object->priv->pending_priority,
"active", object->priv->pending_active, NULL); "active", object->priv->pending_active, NULL);
/* Pendings values are not pending anymore */
GES_TIMELINE_ELEMENT_START (object) = object->priv->pending_start;
GES_TIMELINE_ELEMENT_INPOINT (object) = object->priv->pending_inpoint;
GES_TIMELINE_ELEMENT_DURATION (object) = object->priv->pending_duration;
GES_TIMELINE_ELEMENT_PRIORITY (object) = object->priv->pending_priority;
object->active = object->priv->pending_active;
if (object->priv->track != NULL) if (object->priv->track != NULL)
g_object_set (object->priv->gnlobject, g_object_set (object->priv->gnlobject,
"caps", ges_track_get_caps (object->priv->track), NULL); "caps", ges_track_get_caps (object->priv->track), NULL);

View file

@ -860,49 +860,30 @@ ges_track_get_timeline (GESTrack * track)
} }
/** /**
* ges_track_enable_update: * ges_track_commit:
* @track: a #GESTrack * @track: a #GESTrack
* @enabled: Whether the track should update on every change or not.
* *
* Control whether the track is updated for every change happening within. * Commits all the pending changes of the TrackElement contained in the
* track.
* *
* Users will want to use this method with %FALSE before doing lots of changes, * When timing changes happen in a timeline, the changes are not
* and then call again with %TRUE for the changes to take effect in one go. * directly done inside GNL. This method needs to be called so any changes
* on a clip contained in the timeline actually happen at the media
* processing level.
* *
* Returns: %TRUE if the update status could be changed, else %FALSE. * Returns: %TRUE if something as been commited %FALSE if nothing needed
* to be commited
*/ */
gboolean gboolean
ges_track_enable_update (GESTrack * track, gboolean enabled) ges_track_commit (GESTrack * track)
{ {
gboolean update; gboolean ret;
g_return_val_if_fail (GES_IS_TRACK (track), FALSE); g_return_val_if_fail (GES_IS_TRACK (track), FALSE);
g_object_set (track->priv->composition, "update", enabled, NULL); g_signal_emit_by_name (track->priv->composition, "commit", TRUE, &ret);
g_object_get (track->priv->composition, "update", &update, NULL);
track->priv->updating = update; return ret;
if (update == TRUE)
resort_and_fill_gaps (track);
return update == enabled;
}
/**
* ges_track_is_updating:
* @track: a #GESTrack
*
* Get whether the track is updated for every change happening within or not.
*
* Returns: %TRUE if @track is updating on every changes, else %FALSE.
*/
gboolean
ges_track_is_updating (GESTrack * track)
{
g_return_val_if_fail (GES_IS_TRACK (track), FALSE);
return track->priv->updating;
} }

View file

@ -80,10 +80,9 @@ struct _GESTrackClass
}; };
const GstCaps* ges_track_get_caps (GESTrack *track); const GstCaps* ges_track_get_caps (GESTrack *track);
gboolean ges_track_is_updating (GESTrack *track);
GList* ges_track_get_elements (GESTrack *track); GList* ges_track_get_elements (GESTrack *track);
const GESTimeline* ges_track_get_timeline (GESTrack *track); const GESTimeline* ges_track_get_timeline (GESTrack *track);
gboolean ges_track_enable_update (GESTrack *track, gboolean enabled); gboolean ges_track_commit (GESTrack *track);
void ges_track_set_caps (GESTrack *track, const GstCaps *caps); void ges_track_set_caps (GESTrack *track, const GstCaps *caps);
void ges_track_set_timeline (GESTrack *track, GESTimeline *timeline); void ges_track_set_timeline (GESTrack *track, GESTimeline *timeline);
gboolean ges_track_add_element (GESTrack *track, GESTrackElement *object); gboolean ges_track_add_element (GESTrack *track, GESTrackElement *object);

View file

@ -82,6 +82,7 @@ GST_START_TEST (test_test_source_properties)
assert_equals_uint64 (_DURATION (trackelement), 51); assert_equals_uint64 (_DURATION (trackelement), 51);
assert_equals_uint64 (_INPOINT (trackelement), 12); assert_equals_uint64 (_INPOINT (trackelement), 12);
fail_unless (ges_timeline_commit (timeline));
/* And let's also check that it propagated correctly to GNonLin */ /* And let's also check that it propagated correctly to GNonLin */
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12,
51, 0, TRUE); 51, 0, TRUE);
@ -96,15 +97,18 @@ GST_START_TEST (test_test_source_properties)
assert_equals_uint64 (_DURATION (trackelement), 510); assert_equals_uint64 (_DURATION (trackelement), 510);
assert_equals_uint64 (_INPOINT (trackelement), 120); assert_equals_uint64 (_INPOINT (trackelement), 120);
fail_unless (ges_timeline_commit (timeline));
/* And let's also check that it propagated correctly to GNonLin */ /* And let's also check that it propagated correctly to GNonLin */
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510,
120, 510, 0, TRUE); 120, 510, 0, TRUE);
/* Test mute support */ /* Test mute support */
g_object_set (clip, "mute", TRUE, NULL); g_object_set (clip, "mute", TRUE, NULL);
fail_unless (ges_timeline_commit (timeline));
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510,
120, 510, 0, FALSE); 120, 510, 0, FALSE);
g_object_set (clip, "mute", FALSE, NULL); g_object_set (clip, "mute", FALSE, NULL);
fail_unless (ges_timeline_commit (timeline));
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510,
120, 510, 0, TRUE); 120, 510, 0, TRUE);
@ -322,6 +326,7 @@ GST_START_TEST (test_gap_filling_basic)
} }
} }
fail_unless (gap != NULL); fail_unless (gap != NULL);
fail_unless (ges_timeline_commit (timeline));
gap_object_check (gap, 5, 10, 0); gap_object_check (gap, 5, 10, 0);
clip2 = GES_CLIP (ges_test_clip_new ()); clip2 = GES_CLIP (ges_test_clip_new ());
@ -376,6 +381,7 @@ GST_START_TEST (test_gap_filling_empty_track)
gap = GST_BIN_CHILDREN (composition)->data; gap = GST_BIN_CHILDREN (composition)->data;
fail_unless (gap != NULL); fail_unless (gap != NULL);
fail_unless (ges_timeline_commit (timeline));
gap_object_check (gap, 0, 10, 0); gap_object_check (gap, 0, 10, 0);
gst_object_unref (timeline); gst_object_unref (timeline);

View file

@ -711,6 +711,7 @@ GST_START_TEST (test_ges_timeline_pipeline_change_state)
ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN); ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN);
gst_object_unref (asset); gst_object_unref (asset);
ges_timeline_commit (timeline);
ASSERT_SET_STATE (GST_ELEMENT (pipeline), GST_STATE_PLAYING, ASSERT_SET_STATE (GST_ELEMENT (pipeline), GST_STATE_PLAYING,
GST_STATE_CHANGE_ASYNC); GST_STATE_CHANGE_ASYNC);
fail_unless (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL, fail_unless (gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL,

View file

@ -70,6 +70,7 @@ GST_START_TEST (test_object_properties)
assert_equals_uint64 (_INPOINT (clip), 12); assert_equals_uint64 (_INPOINT (clip), 12);
ges_layer_add_clip (layer, GES_CLIP (clip)); ges_layer_add_clip (layer, GES_CLIP (clip));
ges_timeline_commit (timeline);
assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1); assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1);
trackelement = GES_CONTAINER_CHILDREN (clip)->data; trackelement = GES_CONTAINER_CHILDREN (clip)->data;
fail_unless (trackelement != NULL); fail_unless (trackelement != NULL);
@ -97,6 +98,7 @@ GST_START_TEST (test_object_properties)
assert_equals_uint64 (_INPOINT (trackelement), 120); assert_equals_uint64 (_INPOINT (trackelement), 120);
/* And let's also check that it propagated correctly to GNonLin */ /* And let's also check that it propagated correctly to GNonLin */
ges_timeline_commit (timeline);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510,
120, 510, 0, TRUE); 120, 510, 0, TRUE);
@ -104,6 +106,7 @@ GST_START_TEST (test_object_properties)
/* This time, we move the trackelement to see if the changes move /* This time, we move the trackelement to see if the changes move
* along to the parent and the gnonlin clip */ * along to the parent and the gnonlin clip */
g_object_set (trackelement, "start", (guint64) 400, NULL); g_object_set (trackelement, "start", (guint64) 400, NULL);
ges_timeline_commit (timeline);
assert_equals_uint64 (_START (clip), 400); assert_equals_uint64 (_START (clip), 400);
assert_equals_uint64 (_START (trackelement), 400); assert_equals_uint64 (_START (trackelement), 400);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 400, 510, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 400, 510,
@ -147,6 +150,7 @@ GST_START_TEST (test_split_object)
assert_equals_uint64 (_INPOINT (clip), 12); assert_equals_uint64 (_INPOINT (clip), 12);
ges_layer_add_clip (layer, GES_CLIP (clip)); ges_layer_add_clip (layer, GES_CLIP (clip));
ges_timeline_commit (timeline);
assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 2); assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 2);
trackelement = GES_CONTAINER_CHILDREN (clip)->data; trackelement = GES_CONTAINER_CHILDREN (clip)->data;
fail_unless (trackelement != NULL); fail_unless (trackelement != NULL);

View file

@ -92,6 +92,7 @@ GST_START_TEST (test_layer_properties)
assert_equals_uint64 (_DURATION (clip), 51); assert_equals_uint64 (_DURATION (clip), 51);
assert_equals_uint64 (_INPOINT (clip), 12); assert_equals_uint64 (_INPOINT (clip), 12);
assert_equals_uint64 (_PRIORITY (clip), 0); assert_equals_uint64 (_PRIORITY (clip), 0);
ges_timeline_commit (timeline);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12,
51, 0, TRUE); 51, 0, TRUE);
@ -99,6 +100,7 @@ GST_START_TEST (test_layer_properties)
g_object_set (layer, "priority", 1, NULL); g_object_set (layer, "priority", 1, NULL);
assert_equals_int (ges_layer_get_priority (layer), 1); assert_equals_int (ges_layer_get_priority (layer), 1);
assert_equals_uint64 (_PRIORITY (clip), 0); assert_equals_uint64 (_PRIORITY (clip), 0);
ges_timeline_commit (timeline);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12,
51, LAYER_HEIGHT, TRUE); 51, LAYER_HEIGHT, TRUE);
@ -106,6 +108,7 @@ GST_START_TEST (test_layer_properties)
g_object_set (layer, "priority", 31, NULL); g_object_set (layer, "priority", 31, NULL);
assert_equals_int (ges_layer_get_priority (layer), 31); assert_equals_int (ges_layer_get_priority (layer), 31);
assert_equals_uint64 (_PRIORITY (clip), 0); assert_equals_uint64 (_PRIORITY (clip), 0);
ges_timeline_commit (timeline);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12,
51, LAYER_HEIGHT * 31, TRUE); 51, LAYER_HEIGHT * 31, TRUE);
@ -113,6 +116,7 @@ GST_START_TEST (test_layer_properties)
g_object_set (layer, "priority", 0, NULL); g_object_set (layer, "priority", 0, NULL);
assert_equals_int (ges_layer_get_priority (layer), 0); assert_equals_int (ges_layer_get_priority (layer), 0);
assert_equals_uint64 (_PRIORITY (clip), 0); assert_equals_uint64 (_PRIORITY (clip), 0);
ges_timeline_commit (timeline);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 42, 51, 12,
51, 0, TRUE); 51, 0, TRUE);
@ -192,6 +196,7 @@ GST_START_TEST (test_layer_priorities)
trackelement3 = ges_clip_find_track_element (clip3, track, G_TYPE_NONE); trackelement3 = ges_clip_find_track_element (clip3, track, G_TYPE_NONE);
fail_unless (trackelement3 != NULL); fail_unless (trackelement3 != NULL);
ges_timeline_commit (timeline);
assert_equals_int (_PRIORITY (clip1), 0); assert_equals_int (_PRIORITY (clip1), 0);
gnlobj1 = ges_track_element_get_gnlobject (trackelement1); gnlobj1 = ges_track_element_get_gnlobject (trackelement1);
fail_unless (gnlobj1 != NULL); fail_unless (gnlobj1 != NULL);
@ -217,6 +222,7 @@ GST_START_TEST (test_layer_priorities)
g_object_set (layer1, "priority", 2, NULL); g_object_set (layer1, "priority", 2, NULL);
g_object_set (layer2, "priority", 0, NULL); g_object_set (layer2, "priority", 0, NULL);
g_object_set (layer3, "priority", 1, NULL); g_object_set (layer3, "priority", 1, NULL);
ges_timeline_commit (timeline);
/* And check the new priorities */ /* And check the new priorities */
assert_equals_int (ges_layer_get_priority (layer1), 2); assert_equals_int (ges_layer_get_priority (layer1), 2);
@ -235,6 +241,7 @@ GST_START_TEST (test_layer_priorities)
/* And move objects around */ /* And move objects around */
fail_unless (ges_clip_move_to_layer (clip2, layer1)); fail_unless (ges_clip_move_to_layer (clip2, layer1));
fail_unless (ges_clip_move_to_layer (clip3, layer1)); fail_unless (ges_clip_move_to_layer (clip3, layer1));
ges_timeline_commit (timeline);
objs = ges_layer_get_clips (layer1); objs = ges_layer_get_clips (layer1);
assert_equals_int (g_list_length (objs), 3); assert_equals_int (g_list_length (objs), 3);
@ -261,6 +268,7 @@ GST_START_TEST (test_layer_priorities)
* refected on it containing Clip */ * refected on it containing Clip */
ges_timeline_element_set_priority (GES_TIMELINE_ELEMENT (trackelement3), ges_timeline_element_set_priority (GES_TIMELINE_ELEMENT (trackelement3),
LAYER_HEIGHT * 2); LAYER_HEIGHT * 2);
ges_timeline_commit (timeline);
g_object_get (gnlobj3, "priority", &prio3, NULL); g_object_get (gnlobj3, "priority", &prio3, NULL);
assert_equals_int (prio3, 2 * LAYER_HEIGHT); assert_equals_int (prio3, 2 * LAYER_HEIGHT);
assert_equals_int (_PRIORITY (clip3), LAYER_HEIGHT - 1); assert_equals_int (_PRIORITY (clip3), LAYER_HEIGHT - 1);

View file

@ -66,6 +66,7 @@ GST_START_TEST (test_overlay_properties)
assert_equals_uint64 (_INPOINT (clip), 12); assert_equals_uint64 (_INPOINT (clip), 12);
ges_layer_add_clip (layer, GES_CLIP (clip)); ges_layer_add_clip (layer, GES_CLIP (clip));
ges_timeline_commit (timeline);
assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1); assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1);
trackelement = GES_CONTAINER_CHILDREN (clip)->data; trackelement = GES_CONTAINER_CHILDREN (clip)->data;
fail_unless (trackelement != NULL); fail_unless (trackelement != NULL);
@ -85,6 +86,7 @@ GST_START_TEST (test_overlay_properties)
/* Change more properties, see if they propagate */ /* Change more properties, see if they propagate */
g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510, g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510,
"in-point", (guint64) 120, NULL); "in-point", (guint64) 120, NULL);
ges_timeline_commit (timeline);
assert_equals_uint64 (_START (clip), 420); assert_equals_uint64 (_START (clip), 420);
assert_equals_uint64 (_DURATION (clip), 510); assert_equals_uint64 (_DURATION (clip), 510);
assert_equals_uint64 (_INPOINT (clip), 120); assert_equals_uint64 (_INPOINT (clip), 120);

View file

@ -32,15 +32,13 @@ gchar * ges_test_get_image_uri (void);
gchar * ges_test_file_uri (const gchar *filename); gchar * ges_test_file_uri (const gchar *filename);
#define gnl_object_check(gnlobj, start, duration, mstart, mduration, priority, active) { \ #define gnl_object_check(gnlobj, start, duration, mstart, mduration, priority, active) { \
guint64 pstart, pdur, pmstart, pmdur, pprio, pact; \ guint64 pstart, pdur, inpoint, pprio, pact; \
g_object_get (gnlobj, "start", &pstart, "duration", &pdur, \ g_object_get (gnlobj, "start", &pstart, "duration", &pdur, \
"media-start", &pmstart, "media-duration", &pmdur, \ "inpoint", &inpoint, "priority", &pprio, "active", &pact, \
"priority", &pprio, "active", &pact, \
NULL); \ NULL); \
assert_equals_uint64 (pstart, start); \ assert_equals_uint64 (pstart, start); \
assert_equals_uint64 (pdur, duration); \ assert_equals_uint64 (pdur, duration); \
assert_equals_uint64 (pmstart, mstart); \ assert_equals_uint64 (inpoint, mstart); \
assert_equals_uint64 (pmdur, mduration); \
assert_equals_int (pprio, priority); \ assert_equals_int (pprio, priority); \
assert_equals_int (pact, active); \ assert_equals_int (pact, active); \
} }

View file

@ -563,7 +563,6 @@ GST_START_TEST (test_simple_triming)
element = ges_layer_get_clips (layer)->data; element = ges_layer_get_clips (layer)->data;
deep_check (element, 0, 0, 10); deep_check (element, 0, 0, 10);
ges_timeline_enable_update (timeline, FALSE);
ges_clip_edit (GES_CLIP (element), NULL, -1, GES_EDIT_MODE_TRIM, ges_clip_edit (GES_CLIP (element), NULL, -1, GES_EDIT_MODE_TRIM,
GES_EDGE_START, 5); GES_EDGE_START, 5);
deep_check (element, 5, 5, 5); deep_check (element, 5, 5, 5);

View file

@ -66,6 +66,7 @@ GST_START_TEST (test_title_source_properties)
assert_equals_uint64 (_INPOINT (clip), 12); assert_equals_uint64 (_INPOINT (clip), 12);
ges_layer_add_clip (layer, GES_CLIP (clip)); ges_layer_add_clip (layer, GES_CLIP (clip));
ges_timeline_commit (timeline);
assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1); assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1);
trackelement = GES_CONTAINER_CHILDREN (clip)->data; trackelement = GES_CONTAINER_CHILDREN (clip)->data;
fail_unless (trackelement != NULL); fail_unless (trackelement != NULL);
@ -85,6 +86,7 @@ GST_START_TEST (test_title_source_properties)
/* Change more properties, see if they propagate */ /* Change more properties, see if they propagate */
g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510, g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510,
"in-point", (guint64) 120, NULL); "in-point", (guint64) 120, NULL);
ges_timeline_commit (timeline);
assert_equals_uint64 (_START (clip), 420); assert_equals_uint64 (_START (clip), 420);
assert_equals_uint64 (_DURATION (clip), 510); assert_equals_uint64 (_DURATION (clip), 510);
assert_equals_uint64 (_INPOINT (clip), 120); assert_equals_uint64 (_INPOINT (clip), 120);

View file

@ -98,6 +98,7 @@ GST_START_TEST (test_transition_properties)
assert_equals_uint64 (_INPOINT (clip), 12); assert_equals_uint64 (_INPOINT (clip), 12);
fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip))); fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip)));
ges_timeline_commit (timeline);
assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1); assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1);
trackelement = GES_CONTAINER_CHILDREN (clip)->data; trackelement = GES_CONTAINER_CHILDREN (clip)->data;
fail_unless (trackelement != NULL); fail_unless (trackelement != NULL);
@ -114,6 +115,7 @@ GST_START_TEST (test_transition_properties)
/* Change more properties, see if they propagate */ /* Change more properties, see if they propagate */
g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510, g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510,
"in-point", (guint64) 120, NULL); "in-point", (guint64) 120, NULL);
ges_timeline_commit (timeline);
assert_equals_uint64 (_START (clip), 420); assert_equals_uint64 (_START (clip), 420);
assert_equals_uint64 (_DURATION (clip), 510); assert_equals_uint64 (_DURATION (clip), 510);
assert_equals_uint64 (_INPOINT (clip), 120); assert_equals_uint64 (_INPOINT (clip), 120);

View file

@ -146,6 +146,7 @@ GST_START_TEST (test_filesource_properties)
fail_unless (GES_IS_ASSET (asset)); fail_unless (GES_IS_ASSET (asset));
clip = ges_layer_add_asset (layer, GES_ASSET (asset), clip = ges_layer_add_asset (layer, GES_ASSET (asset),
42, 12, 51, GES_TRACK_TYPE_AUDIO); 42, 12, 51, GES_TRACK_TYPE_AUDIO);
ges_timeline_commit (timeline);
assert_is_type (clip, GES_TYPE_URI_CLIP); assert_is_type (clip, GES_TYPE_URI_CLIP);
assert_equals_uint64 (_START (clip), 42); assert_equals_uint64 (_START (clip), 42);
assert_equals_uint64 (_DURATION (clip), 51); assert_equals_uint64 (_DURATION (clip), 51);
@ -170,6 +171,7 @@ GST_START_TEST (test_filesource_properties)
/* Change more properties, see if they propagate */ /* Change more properties, see if they propagate */
g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510, g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510,
"in-point", (guint64) 120, NULL); "in-point", (guint64) 120, NULL);
ges_timeline_commit (timeline);
assert_equals_uint64 (_START (clip), 420); assert_equals_uint64 (_START (clip), 420);
assert_equals_uint64 (_DURATION (clip), 510); assert_equals_uint64 (_DURATION (clip), 510);
assert_equals_uint64 (_INPOINT (clip), 120); assert_equals_uint64 (_INPOINT (clip), 120);
@ -183,9 +185,11 @@ GST_START_TEST (test_filesource_properties)
/* Test mute support */ /* Test mute support */
g_object_set (clip, "mute", TRUE, NULL); g_object_set (clip, "mute", TRUE, NULL);
ges_timeline_commit (timeline);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510,
120, 510, 0, FALSE); 120, 510, 0, FALSE);
g_object_set (clip, "mute", FALSE, NULL); g_object_set (clip, "mute", FALSE, NULL);
ges_timeline_commit (timeline);
gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510, gnl_object_check (ges_track_element_get_gnlobject (trackelement), 420, 510,
120, 510, 0, TRUE); 120, 510, 0, TRUE);

View file

@ -281,6 +281,7 @@ create_pipeline (gchar * load_path, gchar * save_path, int argc, char **argv,
if (!(timeline = create_timeline (argc, argv, audio, video))) if (!(timeline = create_timeline (argc, argv, audio, video)))
goto failure; goto failure;
} }
ges_timeline_commit (timeline);
/* save project if path is given. we do this now in case GES crashes or /* save project if path is given. we do this now in case GES crashes or
* hangs during playback. */ * hangs during playback. */