mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
auto-transition: select track directly
By-pass the select-tracks-for-object signal for auto-transitions since their track element must land in the same track as the elements it is the auto-transition for.
This commit is contained in:
parent
269c2d1dc0
commit
067304a05f
2 changed files with 97 additions and 15 deletions
|
@ -150,6 +150,8 @@ struct _GESTimelinePrivate
|
||||||
* and %FALSE otherwize */
|
* and %FALSE otherwize */
|
||||||
gboolean needs_transitions_update;
|
gboolean needs_transitions_update;
|
||||||
|
|
||||||
|
GESTrack *auto_transition_track;
|
||||||
|
|
||||||
/* 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 */
|
||||||
gboolean track_elements_moving;
|
gboolean track_elements_moving;
|
||||||
|
@ -344,6 +346,8 @@ ges_timeline_dispose (GObject * object)
|
||||||
g_hash_table_unref (priv->all_elements);
|
g_hash_table_unref (priv->all_elements);
|
||||||
gst_object_unref (priv->stream_collection);
|
gst_object_unref (priv->stream_collection);
|
||||||
|
|
||||||
|
gst_clear_object (&priv->auto_transition_track);
|
||||||
|
|
||||||
G_OBJECT_CLASS (ges_timeline_parent_class)->dispose (object);
|
G_OBJECT_CLASS (ges_timeline_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,25 +901,46 @@ ges_timeline_create_transition (GESTimeline * timeline,
|
||||||
GESTrackElement * previous, GESTrackElement * next, GESClip * transition,
|
GESTrackElement * previous, GESTrackElement * next, GESClip * transition,
|
||||||
GESLayer * layer, guint64 start, guint64 duration)
|
GESLayer * layer, guint64 start, guint64 duration)
|
||||||
{
|
{
|
||||||
GESAsset *asset;
|
|
||||||
GESAutoTransition *auto_transition;
|
GESAutoTransition *auto_transition;
|
||||||
|
GESTrackElement *child;
|
||||||
|
/* track should not be NULL */
|
||||||
|
GESTrack *track = ges_track_element_get_track (next);
|
||||||
|
|
||||||
if (transition == NULL) {
|
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);
|
asset = ges_asset_request (GES_TYPE_TRANSITION_CLIP, "crossfade", NULL);
|
||||||
transition =
|
transition = ges_layer_add_asset (layer, asset, start, 0, duration,
|
||||||
ges_layer_add_asset (layer, asset, start, 0, duration,
|
|
||||||
ges_track_element_get_track_type (next));
|
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 {
|
} else {
|
||||||
GST_DEBUG_OBJECT (timeline,
|
GST_DEBUG_OBJECT (timeline,
|
||||||
"Reusing already existing transition: %" GST_PTR_FORMAT, transition);
|
"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 */
|
/* We know there is only 1 TrackElement */
|
||||||
auto_transition =
|
auto_transition = ges_auto_transition_new (child, previous, next);
|
||||||
ges_auto_transition_new (GES_CONTAINER_CHILDREN (transition)->data,
|
|
||||||
previous, next);
|
|
||||||
|
|
||||||
g_signal_connect (auto_transition, "destroy-me",
|
g_signal_connect (auto_transition, "destroy-me",
|
||||||
G_CALLBACK (_destroy_auto_transition_cb), timeline);
|
G_CALLBACK (_destroy_auto_transition_cb), timeline);
|
||||||
|
@ -1515,6 +1540,7 @@ static void
|
||||||
clip_track_element_added_cb (GESClip * clip,
|
clip_track_element_added_cb (GESClip * clip,
|
||||||
GESTrackElement * track_element, GESTimeline * timeline)
|
GESTrackElement * track_element, GESTimeline * timeline)
|
||||||
{
|
{
|
||||||
|
GESTrack *auto_trans_track;
|
||||||
gboolean error = FALSE;
|
gboolean error = FALSE;
|
||||||
|
|
||||||
if (timeline->priv->track_elements_moving) {
|
if (timeline->priv->track_elements_moving) {
|
||||||
|
@ -1531,8 +1557,23 @@ clip_track_element_added_cb (GESClip * clip,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
if (!_add_track_element_to_tracks (timeline, clip, track_element))
|
||||||
error = TRUE;
|
error = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
_set_track_selection_error (timeline, TRUE);
|
_set_track_selection_error (timeline, TRUE);
|
||||||
|
|
|
@ -536,7 +536,7 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
||||||
GESTimeline *timeline;
|
GESTimeline *timeline;
|
||||||
GESLayer *layer;
|
GESLayer *layer;
|
||||||
GESTrack *track1, *track2;
|
GESTrack *track1, *track2;
|
||||||
GESClip *s1, *s2, *s3, *s4;
|
GESClip *s1, *s2, *s3, *s4, *transition;
|
||||||
GESTrackElement *e1, *e2, *e3, *el, *el2, *e_copy;
|
GESTrackElement *e1, *e2, *e3, *el, *el2, *e_copy;
|
||||||
gboolean found_e1 = FALSE, found_e2 = FALSE, found_e3 = FALSE;
|
gboolean found_e1 = FALSE, found_e2 = FALSE, found_e3 = FALSE;
|
||||||
GList *trackelements, *tmp, *layers;
|
GList *trackelements, *tmp, *layers;
|
||||||
|
@ -549,6 +549,7 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
||||||
GST_DEBUG ("Create a timeline");
|
GST_DEBUG ("Create a timeline");
|
||||||
timeline = ges_timeline_new ();
|
timeline = ges_timeline_new ();
|
||||||
fail_unless (timeline != NULL);
|
fail_unless (timeline != NULL);
|
||||||
|
ges_timeline_set_auto_transition (timeline, TRUE);
|
||||||
|
|
||||||
GST_DEBUG ("Create a layer");
|
GST_DEBUG ("Create a layer");
|
||||||
layer = ges_layer_new ();
|
layer = ges_layer_new ();
|
||||||
|
@ -578,7 +579,7 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
||||||
/* s1 and s3 can overlap since they are destined for different tracks */
|
/* s1 and s3 can overlap since they are destined for different tracks */
|
||||||
/* s2 will overlap both */
|
/* s2 will overlap both */
|
||||||
/* s4 destined for no track */
|
/* 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, s2, 5, 10);
|
||||||
_CREATE_SOURCE (layer, s3, 0, 10);
|
_CREATE_SOURCE (layer, s3, 0, 10);
|
||||||
_CREATE_SOURCE (layer, s4, 0, 20);
|
_CREATE_SOURCE (layer, s4, 0, 20);
|
||||||
|
@ -648,6 +649,8 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
||||||
fail_unless (g_list_find (layers, layer) != NULL);
|
fail_unless (g_list_find (layers, layer) != NULL);
|
||||||
g_list_free_full (layers, gst_object_unref);
|
g_list_free_full (layers, gst_object_unref);
|
||||||
|
|
||||||
|
fail_unless (ges_layer_get_auto_transition (layer));
|
||||||
|
|
||||||
assert_equals_int (st_data.num_unrecognised, 0);
|
assert_equals_int (st_data.num_unrecognised, 0);
|
||||||
|
|
||||||
/* Make sure the associated TrackElements are in the Track */
|
/* Make sure the associated TrackElements are in the Track */
|
||||||
|
@ -756,11 +759,49 @@ GST_START_TEST (test_ges_timeline_multiple_tracks)
|
||||||
/* called once for source (where no track was selected) */
|
/* called once for source (where no track was selected) */
|
||||||
assert_equals_int (st_data.num_calls[0], 1);
|
assert_equals_int (st_data.num_calls[0], 1);
|
||||||
|
|
||||||
/* 2 sources + 2 effects */
|
/* 2 sources + 1 transition + 2 effects */
|
||||||
assert_num_in_track (track1, 4);
|
assert_num_in_track (track1, 5);
|
||||||
assert_num_in_track (track2, 4);
|
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);
|
gst_object_unref (timeline);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue