* and %FALSE otherwize */
gboolean needs_transitions_update;
+ GESTrack *auto_transition_track;
+
/* While we are creating and adding the TrackElements for a clip, we need to
* ignore the child-added signal */
gboolean track_elements_moving;
g_hash_table_unref (priv->all_elements);
gst_object_unref (priv->stream_collection);
+ gst_clear_object (&priv->auto_transition_track);
+
G_OBJECT_CLASS (ges_timeline_parent_class)->dispose (object);
}
GESTrackElement * previous, GESTrackElement * next, GESClip * transition,
GESLayer * layer, guint64 start, guint64 duration)
{
- GESAsset *asset;
GESAutoTransition *auto_transition;
+ GESTrackElement *child;
+ /* track should not be NULL */
+ GESTrack *track = ges_track_element_get_track (next);
if (transition == NULL) {
- /* TODO make it possible to specify a Transition asset in the API */
+ GESAsset *asset;
+
+ LOCK_DYN (timeline);
+ timeline->priv->auto_transition_track = gst_object_ref (track);
+ UNLOCK_DYN (timeline);
+
asset = ges_asset_request (GES_TYPE_TRANSITION_CLIP, "crossfade", NULL);
- transition =
- ges_layer_add_asset (layer, asset, start, 0, duration,
+ transition = ges_layer_add_asset (layer, asset, start, 0, duration,
ges_track_element_get_track_type (next));
- g_object_unref (asset);
+ gst_object_unref (asset);
+
+ LOCK_DYN (timeline);
+ /* should have been set to NULL, but clear just in case */
+ gst_clear_object (&timeline->priv->auto_transition_track);
+ UNLOCK_DYN (timeline);
} else {
GST_DEBUG_OBJECT (timeline,
"Reusing already existing transition: %" GST_PTR_FORMAT, transition);
}
+ g_return_val_if_fail (transition, NULL);
+ g_return_val_if_fail (g_list_length (GES_CONTAINER_CHILDREN (transition)) ==
+ 1, NULL);
+ child = GES_CONTAINER_CHILDREN (transition)->data;
+ if (ges_track_element_get_track (child) != track) {
+ GST_ERROR_OBJECT (timeline, "The auto transition element %"
+ GES_FORMAT " for elements %" GES_FORMAT " and %" GES_FORMAT
+ " is not in the same track %" GST_PTR_FORMAT,
+ GES_ARGS (child), GES_ARGS (previous), GES_ARGS (next), track);
+ return NULL;
+ }
+
/* We know there is only 1 TrackElement */
- auto_transition =
- ges_auto_transition_new (GES_CONTAINER_CHILDREN (transition)->data,
- previous, next);
+ auto_transition = ges_auto_transition_new (child, previous, next);
g_signal_connect (auto_transition, "destroy-me",
G_CALLBACK (_destroy_auto_transition_cb), timeline);
clip_track_element_added_cb (GESClip * clip,
GESTrackElement * track_element, GESTimeline * timeline)
{
+ GESTrack *auto_trans_track;
gboolean error = FALSE;
if (timeline->priv->track_elements_moving) {
return;
}
- if (!_add_track_element_to_tracks (timeline, clip, track_element))
- error = TRUE;
+ LOCK_DYN (timeline);
+ /* take ownership of auto_transition_track. For auto-transitions, this
+ * should be used exactly once! */
+ auto_trans_track = timeline->priv->auto_transition_track;
+ timeline->priv->auto_transition_track = NULL;
+ UNLOCK_DYN (timeline);
+
+ if (auto_trans_track) {
+ /* don't use track-selection */
+ if (!ges_clip_add_child_to_track (clip, track_element, auto_trans_track,
+ NULL))
+ error = TRUE;
+ gst_object_unref (auto_trans_track);
+ } else {
+ if (!_add_track_element_to_tracks (timeline, clip, track_element))
+ error = TRUE;
+ }
if (error)
_set_track_selection_error (timeline, TRUE);
GESTimeline *timeline;
GESLayer *layer;
GESTrack *track1, *track2;
- GESClip *s1, *s2, *s3, *s4;
+ GESClip *s1, *s2, *s3, *s4, *transition;
GESTrackElement *e1, *e2, *e3, *el, *el2, *e_copy;
gboolean found_e1 = FALSE, found_e2 = FALSE, found_e3 = FALSE;
GList *trackelements, *tmp, *layers;
GST_DEBUG ("Create a timeline");
timeline = ges_timeline_new ();
fail_unless (timeline != NULL);
+ ges_timeline_set_auto_transition (timeline, TRUE);
GST_DEBUG ("Create a layer");
layer = ges_layer_new ();
/* s1 and s3 can overlap since they are destined for different tracks */
/* s2 will overlap both */
/* s4 destined for no track */
- _CREATE_SOURCE (layer, s1, 0, 10);
+ _CREATE_SOURCE (layer, s1, 0, 12);
_CREATE_SOURCE (layer, s2, 5, 10);
_CREATE_SOURCE (layer, s3, 0, 10);
_CREATE_SOURCE (layer, s4, 0, 20);
fail_unless (g_list_find (layers, layer) != NULL);
g_list_free_full (layers, gst_object_unref);
+ fail_unless (ges_layer_get_auto_transition (layer));
+
assert_equals_int (st_data.num_unrecognised, 0);
/* Make sure the associated TrackElements are in the Track */
/* called once for source (where no track was selected) */
assert_equals_int (st_data.num_calls[0], 1);
- /* 2 sources + 2 effects */
- assert_num_in_track (track1, 4);
- assert_num_in_track (track2, 4);
+ /* 2 sources + 1 transition + 2 effects */
+ assert_num_in_track (track1, 5);
+ assert_num_in_track (track2, 5);
+
+ el = NULL;
+ trackelements = ges_track_get_elements (track1);
+ for (tmp = trackelements; tmp; tmp = tmp->next) {
+ if (GES_IS_VIDEO_TRANSITION (tmp->data)) {
+ fail_if (el);
+ el = tmp->data;
+ }
+ }
+ g_list_free_full (trackelements, gst_object_unref);
+ fail_unless (GES_IS_CLIP (GES_TIMELINE_ELEMENT_PARENT (el)));
+ transition = GES_CLIP (GES_TIMELINE_ELEMENT_PARENT (el));
+ assert_layer (transition, layer);
+
+ CHECK_OBJECT_PROPS (transition, 5, 0, 7);
+ CHECK_OBJECT_PROPS (el, 5, 0, 7);
+ fail_unless (ges_track_element_get_track (el) == track1);
+ /* make sure we can change the transition type */
+ fail_unless (ges_video_transition_set_transition_type (GES_VIDEO_TRANSITION
+ (el), GES_VIDEO_STANDARD_TRANSITION_TYPE_BARNDOOR_H));
+ el = NULL;
+ trackelements = ges_track_get_elements (track2);
+ for (tmp = trackelements; tmp; tmp = tmp->next) {
+ if (GES_IS_VIDEO_TRANSITION (tmp->data)) {
+ fail_if (el);
+ el = tmp->data;
+ }
+ }
+ g_list_free_full (trackelements, gst_object_unref);
+ fail_unless (GES_IS_CLIP (GES_TIMELINE_ELEMENT_PARENT (el)));
+ transition = GES_CLIP (GES_TIMELINE_ELEMENT_PARENT (el));
+ assert_layer (transition, layer);
+ CHECK_OBJECT_PROPS (transition, 5, 0, 5);
+ CHECK_OBJECT_PROPS (el, 5, 0, 5);
+ fail_unless (ges_track_element_get_track (el) == track2);
+ /* make sure we can change the transition type */
+ fail_unless (ges_video_transition_set_transition_type (GES_VIDEO_TRANSITION
+ (el), GES_VIDEO_STANDARD_TRANSITION_TYPE_BARNDOOR_H));
gst_object_unref (timeline);