mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 14:06:23 +00:00
clip: make sure core child is active for non-core in same track
Each active non-core child must have a corresponding active core child in the same track. Therefore, if we de-activate a core child, we also need to de-activate all the non-core children in the same track. Similarly, if we activate a non-core child, we need to activate the corresponding core child as well. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
This commit is contained in:
parent
5159d367e2
commit
fd353705b9
2 changed files with 369 additions and 36 deletions
206
ges/ges-clip.c
206
ges/ges-clip.c
|
@ -51,6 +51,11 @@
|
|||
* #GESTimeline::select-tracks-for-object signal to coordinate which
|
||||
* tracks each element should land in.
|
||||
*
|
||||
* Note, no two core children within a clip can share the same #GESTrack.
|
||||
* Therefore, if you use #GESTimeline::select-tracks-for-object, you
|
||||
* should ensure that each core #GESTrackElement is destined for
|
||||
* different #GESTrack-s per clip (or no track).
|
||||
*
|
||||
* The #GESTimelineElement:in-point of the clip will control the
|
||||
* #GESTimelineElement:in-point of these core elements to be the same
|
||||
* value if their #GESTrackElement:has-internal-source is set to %TRUE.
|
||||
|
@ -76,6 +81,24 @@
|
|||
* effect will be applied to any source data **before** the other existing
|
||||
* effects. You can change the ordering of effects using
|
||||
* ges_clip_set_top_effect_index().
|
||||
*
|
||||
* Note, since an effect must be applied on top of a core child, if you
|
||||
* use #GESTimeline::select-tracks-for-object, you should ensure that the
|
||||
* added effects are destined for a #GESTrack that already contains a core
|
||||
* child (note that #GESTimeline::select-tracks-for-object will be called
|
||||
* for the core children before the added effects, so their tracks will be
|
||||
* selected before the effects).
|
||||
*
|
||||
* In addition, if the core child in the track is not
|
||||
* #GESTrackElement:active, then neither can any of its effects be
|
||||
* #GESTrackElement:active. Therefore, if a core child is made in-active,
|
||||
* all of the additional effects in the same track will also become
|
||||
* in-active. Similarly, if an effect is set to be active, then the core
|
||||
* child will also become active, but other effects will be left alone.
|
||||
* Finally, if an active effect is added to the track of an in-active core
|
||||
* child, it will become in-active as well. Note, in contrast, setting a
|
||||
* core child to be active, or an effect to be in-active will *not* change
|
||||
* the other children in the same track.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
|
@ -431,42 +454,67 @@ _child_has_internal_source_changed (GESClip * self, GESTimelineElement * child)
|
|||
#define _IS_PROP(prop) (g_strcmp0 (name, prop) == 0)
|
||||
|
||||
static void
|
||||
_child_property_changed_cb (GESTimelineElement * child, GParamSpec * pspec,
|
||||
GESClip * self)
|
||||
_child_active_changed (GESClip * self, GESTrackElement * child)
|
||||
{
|
||||
gboolean update = FALSE;
|
||||
const gchar *name = pspec->name;
|
||||
GList *tmp;
|
||||
GESTrack *track = ges_track_element_get_track (child);
|
||||
gboolean active = ges_track_element_is_active (child);
|
||||
gboolean is_core = _IS_CORE_CHILD (child);
|
||||
gboolean prev_prevent = self->priv->prevent_duration_limit_update;
|
||||
|
||||
if (_IS_PROP ("track") || _IS_PROP ("active")) {
|
||||
update = TRUE;
|
||||
} else if (_IS_PROP ("priority")) {
|
||||
update = TRUE;
|
||||
_child_priority_changed (GES_CONTAINER (self), child);
|
||||
} else if (_IS_PROP ("in-point")) {
|
||||
update = _child_inpoint_changed (self, child);
|
||||
} else if (_IS_PROP ("max-duration")) {
|
||||
update = TRUE;
|
||||
_child_max_duration_changed (GES_CONTAINER (self), child);
|
||||
} else if (_IS_PROP ("has-internal-source")) {
|
||||
_child_has_internal_source_changed (self, child);
|
||||
/* We want to ensure that each active non-core element has a
|
||||
* corresponding active core element in the same track */
|
||||
if (self->priv->setting_active || !track || is_core == active)
|
||||
return;
|
||||
|
||||
self->priv->prevent_duration_limit_update = TRUE;
|
||||
|
||||
/* If we are core, make all the non-core elements in-active
|
||||
* If we are non-core, make the core element active (should only be one) */
|
||||
for (tmp = GES_CONTAINER_CHILDREN (self); tmp; tmp = tmp->next) {
|
||||
GESTrackElement *sibling = tmp->data;
|
||||
|
||||
if (ges_track_element_get_track (sibling) == track
|
||||
&& _IS_CORE_CHILD (sibling) != is_core
|
||||
&& ges_track_element_is_active (sibling) != active) {
|
||||
|
||||
GST_INFO_OBJECT (self, "Setting active to %i for child %" GES_FORMAT
|
||||
" since the sibling %" GES_FORMAT " in the same track %"
|
||||
GST_PTR_FORMAT " has been set to %i", active, GES_ARGS (sibling),
|
||||
GES_ARGS (child), track, active);
|
||||
|
||||
if (!ges_track_element_set_active (sibling, active))
|
||||
GST_ERROR_OBJECT (self, "Failed to set active for child %"
|
||||
GES_FORMAT, GES_ARGS (sibling));
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
_update_duration_limit (self);
|
||||
self->priv->prevent_duration_limit_update = prev_prevent;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Restrict our children *
|
||||
****************************************************/
|
||||
|
||||
static gboolean
|
||||
_track_contains_core (GESClip * clip, GESTrack * track, gboolean core)
|
||||
static GESTrackElement *
|
||||
_find_core_in_track (GESClip * clip, GESTrack * track)
|
||||
{
|
||||
GList *tmp;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
|
||||
GESTrackElement *child = tmp->data;
|
||||
if (_IS_CORE_CHILD (child) == core
|
||||
&& ges_track_element_get_track (child) == track)
|
||||
if (_IS_CORE_CHILD (child) && ges_track_element_get_track (child) == track)
|
||||
return child;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_track_contains_non_core (GESClip * clip, GESTrack * track)
|
||||
{
|
||||
GList *tmp;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
|
||||
GESTrackElement *child = tmp->data;
|
||||
if (!_IS_CORE_CHILD (child) && ges_track_element_get_track (child) == track)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -477,6 +525,7 @@ ges_clip_can_set_track_of_child (GESClip * clip, GESTrackElement * child,
|
|||
GESTrack * track)
|
||||
{
|
||||
GESTrack *current_track = ges_track_element_get_track (child);
|
||||
GESTrackElement *core = NULL;
|
||||
|
||||
if (clip->priv->allow_any_track)
|
||||
return TRUE;
|
||||
|
@ -488,7 +537,7 @@ ges_clip_can_set_track_of_child (GESClip * clip, GESTrackElement * child,
|
|||
/* can not remove a core element from a track if a non-core one sits
|
||||
* above it */
|
||||
if (_IS_CORE_CHILD (child)
|
||||
&& _track_contains_core (clip, current_track, FALSE)) {
|
||||
&& _track_contains_non_core (clip, current_track)) {
|
||||
GST_INFO_OBJECT (clip, "Cannot move the core child %" GES_FORMAT
|
||||
" to the track %" GST_PTR_FORMAT " because it has non-core "
|
||||
"siblings above it in its current track %" GST_PTR_FORMAT,
|
||||
|
@ -514,17 +563,20 @@ ges_clip_can_set_track_of_child (GESClip * clip, GESTrackElement * child,
|
|||
clip_timeline);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
core = _find_core_in_track (clip, track);
|
||||
/* one core child per track, and other children (effects) can only be
|
||||
* placed in a track that already has a core child */
|
||||
if (_IS_CORE_CHILD (child)) {
|
||||
if (_track_contains_core (clip, track, TRUE)) {
|
||||
if (core) {
|
||||
GST_INFO_OBJECT (clip, "Cannot move the core child %" GES_FORMAT
|
||||
" to the track %" GST_PTR_FORMAT " because it contains a "
|
||||
"core sibling", GES_ARGS (child), track);
|
||||
"core sibling %" GES_FORMAT, GES_ARGS (child), track,
|
||||
GES_ARGS (core));
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (!_track_contains_core (clip, track, TRUE)) {
|
||||
if (!core) {
|
||||
GST_INFO_OBJECT (clip, "Cannot move the non-core child %"
|
||||
GES_FORMAT " to the track %" GST_PTR_FORMAT " because it "
|
||||
" does not contain a core sibling", GES_ARGS (child), track);
|
||||
|
@ -535,6 +587,77 @@ ges_clip_can_set_track_of_child (GESClip * clip, GESTrackElement * child,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_update_active_for_track (GESClip * self, GESTrackElement * child)
|
||||
{
|
||||
GESTrack *track = ges_track_element_get_track (child);
|
||||
GESTrackElement *core;
|
||||
gboolean active;
|
||||
gboolean prev_prevent = self->priv->prevent_duration_limit_update;
|
||||
|
||||
if (self->priv->allow_any_track || _IS_CORE_CHILD (child) || !track)
|
||||
return;
|
||||
|
||||
/* if we add a non-core to a track, but the core child is inactive, we
|
||||
* also need the non-core to be inactive */
|
||||
core = _find_core_in_track (self, track);
|
||||
|
||||
if (!core) {
|
||||
GST_ERROR_OBJECT (self, "The non-core child %" GES_FORMAT " is in "
|
||||
"the track %" GST_PTR_FORMAT " with no core sibling",
|
||||
GES_ARGS (child), track);
|
||||
active = FALSE;
|
||||
} else {
|
||||
active = ges_track_element_is_active (core);
|
||||
}
|
||||
|
||||
if (!active && ges_track_element_is_active (child)) {
|
||||
|
||||
GST_INFO_OBJECT (self, "De-activating non-core child %" GES_FORMAT
|
||||
" since the core child in the same track %" GST_PTR_FORMAT " is "
|
||||
"not active", GES_ARGS (child), track);
|
||||
|
||||
self->priv->prevent_duration_limit_update = TRUE;
|
||||
|
||||
if (!ges_track_element_set_active (child, FALSE))
|
||||
GST_ERROR_OBJECT (self, "Failed to de-activate child %" GES_FORMAT,
|
||||
GES_ARGS (child));
|
||||
|
||||
self->priv->prevent_duration_limit_update = prev_prevent;
|
||||
}
|
||||
}
|
||||
|
||||
#define _IS_PROP(prop) (g_strcmp0 (name, prop) == 0)
|
||||
|
||||
static void
|
||||
_child_property_changed_cb (GESTimelineElement * child, GParamSpec * pspec,
|
||||
GESClip * self)
|
||||
{
|
||||
gboolean update = FALSE;
|
||||
const gchar *name = pspec->name;
|
||||
|
||||
if (_IS_PROP ("track")) {
|
||||
update = TRUE;
|
||||
_update_active_for_track (self, GES_TRACK_ELEMENT (child));
|
||||
} else if (_IS_PROP ("active")) {
|
||||
update = TRUE;
|
||||
_child_active_changed (self, GES_TRACK_ELEMENT (child));
|
||||
} else if (_IS_PROP ("priority")) {
|
||||
update = TRUE;
|
||||
_child_priority_changed (GES_CONTAINER (self), child);
|
||||
} else if (_IS_PROP ("in-point")) {
|
||||
update = _child_inpoint_changed (self, child);
|
||||
} else if (_IS_PROP ("max-duration")) {
|
||||
update = TRUE;
|
||||
_child_max_duration_changed (GES_CONTAINER (self), child);
|
||||
} else if (_IS_PROP ("has-internal-source")) {
|
||||
_child_has_internal_source_changed (self, child);
|
||||
}
|
||||
|
||||
if (update)
|
||||
_update_duration_limit (self);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* *
|
||||
* GESTimelineElement virtual methods implementation *
|
||||
|
@ -835,7 +958,8 @@ static gboolean
|
|||
_add_child (GESContainer * container, GESTimelineElement * element)
|
||||
{
|
||||
GESClip *self = GES_CLIP (container);
|
||||
GESClipClass *klass = GES_CLIP_GET_CLASS (GES_CLIP (container));
|
||||
GESTrackElement *track_el = GES_TRACK_ELEMENT (element);
|
||||
GESClipClass *klass = GES_CLIP_GET_CLASS (self);
|
||||
guint32 min_prio, max_prio, new_prio;
|
||||
GESTrack *track;
|
||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (container);
|
||||
|
@ -855,8 +979,7 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
}
|
||||
|
||||
asset = ges_extractable_get_asset (GES_EXTRACTABLE (self));
|
||||
creator_asset =
|
||||
ges_track_element_get_creator_asset (GES_TRACK_ELEMENT (element));
|
||||
creator_asset = ges_track_element_get_creator_asset (track_el);
|
||||
if (creator_asset && asset != creator_asset) {
|
||||
GST_WARNING_OBJECT (self,
|
||||
"Cannot add the track element %" GES_FORMAT " as a child "
|
||||
|
@ -865,7 +988,7 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
track = ges_track_element_get_track (GES_TRACK_ELEMENT (element));
|
||||
track = ges_track_element_get_track (track_el);
|
||||
|
||||
if (track && ges_track_get_timeline (track) != timeline) {
|
||||
/* really, an element in a track should have the same timeline as
|
||||
|
@ -887,18 +1010,20 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
/* NOTE: Core track elements that are base effects are added like any
|
||||
* other core elements. In particular, they are *not* added to the
|
||||
* list of added effects, so we do not increase nb_effects. */
|
||||
GESTrackElement *core = (track && !priv->allow_any_track) ?
|
||||
_find_core_in_track (self, track) : NULL;
|
||||
|
||||
if (track && !priv->allow_any_track
|
||||
&& _track_contains_core (self, track, TRUE)) {
|
||||
if (core) {
|
||||
GST_WARNING_OBJECT (self, "Cannot add the core child %" GES_FORMAT
|
||||
" because it is in the same track %" GST_PTR_FORMAT " as an "
|
||||
"existing core child", GES_ARGS (element), track);
|
||||
"existing core child %" GES_FORMAT, GES_ARGS (element), track,
|
||||
GES_ARGS (core));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Set the core element to have the same in-point, which we don't
|
||||
* apply to effects */
|
||||
if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (element))) {
|
||||
if (ges_track_element_has_internal_source (track_el)) {
|
||||
/* adding can fail if the max-duration of the element is smaller
|
||||
* than the current in-point of the clip */
|
||||
if (!_set_inpoint0 (element, _INPOINT (self))) {
|
||||
|
@ -925,13 +1050,13 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
* the core elements). Need to shift the core elements up by 1
|
||||
* to make room. */
|
||||
|
||||
if (track && !priv->allow_any_track
|
||||
&& !_track_contains_core (GES_CLIP (self), track, TRUE)) {
|
||||
if (track && !priv->allow_any_track && !_find_core_in_track (self, track)) {
|
||||
GST_WARNING_OBJECT (self, "Cannot add the effect %" GES_FORMAT
|
||||
" because its track %" GST_PTR_FORMAT " does not contain one "
|
||||
"of the clip's core children", GES_ARGS (element), track);
|
||||
return FALSE;
|
||||
}
|
||||
_update_active_for_track (self, track_el);
|
||||
|
||||
/* new priority is the lowest priority effect */
|
||||
new_prio = min_prio;
|
||||
|
@ -2632,5 +2757,14 @@ ges_clip_add_child_to_track (GESClip * clip, GESTrackElement * child,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* call _child_track_changed now so that the "active" status of the
|
||||
* child can change. Note that this is needed because this method may
|
||||
* be called during ges_container_add, in which case "notify" for el
|
||||
* will be frozen. Thus, _update_active_for_track may not have been
|
||||
* called yet. It is important for us to call this now because when
|
||||
* the elements are un-frozen, we need to ensure the "active" status
|
||||
* is already set before the duration-limit is calculated */
|
||||
_update_active_for_track (clip, el);
|
||||
|
||||
return el;
|
||||
}
|
||||
|
|
|
@ -2049,6 +2049,204 @@ GST_START_TEST (test_can_add_effect)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
#define _assert_active(el, active) \
|
||||
fail_unless (ges_track_element_is_active (el) == active)
|
||||
|
||||
#define _assert_set_active(el, active) \
|
||||
fail_unless (ges_track_element_set_active (el, active))
|
||||
|
||||
GST_START_TEST (test_children_active)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
GESLayer *layer;
|
||||
GESClip *clip;
|
||||
GESTrack *track0, *track1, *select_track;
|
||||
GESTrackElement *effect0, *effect1, *effect2, *effect3;
|
||||
GESTrackElement *source0, *source1;
|
||||
|
||||
ges_init ();
|
||||
|
||||
timeline = ges_timeline_new ();
|
||||
|
||||
track0 = GES_TRACK (ges_video_track_new ());
|
||||
track1 = GES_TRACK (ges_video_track_new ());
|
||||
|
||||
fail_unless (ges_timeline_add_track (timeline, track0));
|
||||
fail_unless (ges_timeline_add_track (timeline, track1));
|
||||
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
|
||||
clip = GES_CLIP (ges_test_clip_new ());
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, clip));
|
||||
|
||||
assert_num_children (clip, 2);
|
||||
|
||||
source0 =
|
||||
ges_clip_find_track_element (clip, track0, GES_TYPE_VIDEO_TEST_SOURCE);
|
||||
source1 =
|
||||
ges_clip_find_track_element (clip, track1, GES_TYPE_VIDEO_TEST_SOURCE);
|
||||
|
||||
fail_unless (source0);
|
||||
fail_unless (source1);
|
||||
|
||||
gst_object_unref (source0);
|
||||
gst_object_unref (source1);
|
||||
|
||||
_assert_active (source0, TRUE);
|
||||
_assert_active (source1, TRUE);
|
||||
|
||||
_assert_set_active (source0, FALSE);
|
||||
|
||||
_assert_active (source0, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
|
||||
select_track = track0;
|
||||
g_signal_connect (timeline, "select-tracks-for-object",
|
||||
G_CALLBACK (_select_track), &select_track);
|
||||
|
||||
/* add an active effect should become inactive to match the core */
|
||||
effect0 = GES_TRACK_ELEMENT (ges_effect_new ("videobalance"));
|
||||
_assert_active (effect0, TRUE);
|
||||
|
||||
_assert_add (clip, effect0);
|
||||
fail_if (select_track);
|
||||
|
||||
_assert_active (source0, FALSE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
|
||||
/* adding inactive to track with inactive core does nothing */
|
||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("vertigotv"));
|
||||
_assert_active (effect1, TRUE);
|
||||
_assert_set_active (effect1, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
|
||||
select_track = track0;
|
||||
_assert_add (clip, effect1);
|
||||
fail_if (select_track);
|
||||
|
||||
_assert_active (source0, FALSE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
|
||||
/* adding active to track with active core does nothing */
|
||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
_assert_active (effect2, TRUE);
|
||||
|
||||
select_track = track1;
|
||||
_assert_add (clip, effect2);
|
||||
fail_if (select_track);
|
||||
|
||||
_assert_active (source0, FALSE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, TRUE);
|
||||
|
||||
/* adding inactive to track with active core does nothing */
|
||||
effect3 = GES_TRACK_ELEMENT (ges_effect_new ("alpha"));
|
||||
_assert_active (effect3, TRUE);
|
||||
_assert_set_active (effect3, FALSE);
|
||||
_assert_active (effect3, FALSE);
|
||||
|
||||
select_track = track1;
|
||||
_assert_add (clip, effect3);
|
||||
fail_if (select_track);
|
||||
|
||||
_assert_active (source0, FALSE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, TRUE);
|
||||
_assert_active (effect3, FALSE);
|
||||
|
||||
/* activate a core does not change non-core */
|
||||
_assert_set_active (source0, TRUE);
|
||||
|
||||
_assert_active (source0, TRUE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, TRUE);
|
||||
_assert_active (effect3, FALSE);
|
||||
|
||||
/* but de-activating a core will de-activate the non-core */
|
||||
_assert_set_active (source1, FALSE);
|
||||
|
||||
_assert_active (source0, TRUE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, FALSE);
|
||||
_assert_active (effect2, FALSE);
|
||||
_assert_active (effect3, FALSE);
|
||||
|
||||
/* activate a non-core will activate the core */
|
||||
_assert_set_active (effect3, TRUE);
|
||||
|
||||
_assert_active (source0, TRUE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, FALSE);
|
||||
_assert_active (effect3, TRUE);
|
||||
|
||||
/* if core is already active, nothing else happens */
|
||||
_assert_set_active (effect0, TRUE);
|
||||
|
||||
_assert_active (source0, TRUE);
|
||||
_assert_active (effect0, TRUE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, FALSE);
|
||||
_assert_active (effect3, TRUE);
|
||||
|
||||
_assert_set_active (effect1, TRUE);
|
||||
|
||||
_assert_active (source0, TRUE);
|
||||
_assert_active (effect0, TRUE);
|
||||
_assert_active (effect1, TRUE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, FALSE);
|
||||
_assert_active (effect3, TRUE);
|
||||
|
||||
_assert_set_active (effect2, TRUE);
|
||||
|
||||
_assert_active (source0, TRUE);
|
||||
_assert_active (effect0, TRUE);
|
||||
_assert_active (effect1, TRUE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, TRUE);
|
||||
_assert_active (effect3, TRUE);
|
||||
|
||||
/* de-activate a core will de-active all the non-core */
|
||||
_assert_set_active (source0, FALSE);
|
||||
|
||||
_assert_active (source0, FALSE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, TRUE);
|
||||
_assert_active (effect3, TRUE);
|
||||
|
||||
/* de-activate a non-core does nothing else */
|
||||
_assert_set_active (effect3, FALSE);
|
||||
|
||||
_assert_active (source0, FALSE);
|
||||
_assert_active (effect0, FALSE);
|
||||
_assert_active (effect1, FALSE);
|
||||
_assert_active (source1, TRUE);
|
||||
_assert_active (effect2, TRUE);
|
||||
_assert_active (effect3, FALSE);
|
||||
|
||||
gst_object_unref (timeline);
|
||||
|
||||
ges_deinit ();
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_children_inpoint)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
|
@ -3468,6 +3666,7 @@ ges_suite (void)
|
|||
tcase_add_test (tc_chain, test_effects_priorities);
|
||||
tcase_add_test (tc_chain, test_children_time_setters);
|
||||
tcase_add_test (tc_chain, test_can_add_effect);
|
||||
tcase_add_test (tc_chain, test_children_active);
|
||||
tcase_add_test (tc_chain, test_children_inpoint);
|
||||
tcase_add_test (tc_chain, test_children_max_duration);
|
||||
tcase_add_test (tc_chain, test_duration_limit);
|
||||
|
|
Loading…
Reference in a new issue