mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
clip: add the duration-limit property
The duration-limit is the maximum duration that can be set for the clip given its current children and their properties. If a change in the children properties causes this to drop below the current duration, it is automatically capped by this limit. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/169>
This commit is contained in:
parent
154816365f
commit
4b62749336
4 changed files with 799 additions and 161 deletions
452
ges/ges-clip.c
452
ges/ges-clip.c
|
@ -118,6 +118,9 @@ struct _GESClipPrivate
|
|||
|
||||
/* The formats supported by this Clip */
|
||||
GESTrackType supportedformats;
|
||||
|
||||
GstClockTime duration_limit;
|
||||
gboolean prevent_duration_limit_update;
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -125,6 +128,7 @@ enum
|
|||
PROP_0,
|
||||
PROP_LAYER,
|
||||
PROP_SUPPORTED_FORMATS,
|
||||
PROP_DURATION_LIMIT,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
|
@ -148,11 +152,176 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GESClip, ges_clip,
|
|||
#define _IS_CORE_CHILD(child) GES_TRACK_ELEMENT_IS_CORE(child)
|
||||
|
||||
#define _IS_TOP_EFFECT(child) \
|
||||
(!_IS_CORE_CHILD (child) && GES_IS_BASE_EFFECT (child))
|
||||
(!_IS_CORE_CHILD (child) && GES_IS_BASE_EFFECT (child))
|
||||
|
||||
#define _IS_CORE_INTERNAL_SOURCE_CHILD(child) \
|
||||
(_IS_CORE_CHILD (child) \
|
||||
&& ges_track_element_has_internal_source (GES_TRACK_ELEMENT (child)))
|
||||
&& ges_track_element_has_internal_source (GES_TRACK_ELEMENT (child)))
|
||||
|
||||
#define _MIN_CLOCK_TIME(a, b) \
|
||||
(GST_CLOCK_TIME_IS_VALID (a) ? \
|
||||
(GST_CLOCK_TIME_IS_VALID (b) ? MIN (a, b) : a) : b) \
|
||||
|
||||
#define _CLOCK_TIME_IS_LESS(first, second) \
|
||||
(GST_CLOCK_TIME_IS_VALID (first) && (!GST_CLOCK_TIME_IS_VALID (second) \
|
||||
|| first < second))
|
||||
|
||||
|
||||
typedef struct _DurationLimitData
|
||||
{
|
||||
GESTrackElement *child;
|
||||
GESTrack *track;
|
||||
guint32 priority;
|
||||
GstClockTime max_duration;
|
||||
GstClockTime inpoint;
|
||||
gboolean active;
|
||||
} DurationLimitData;
|
||||
|
||||
static DurationLimitData *
|
||||
_duration_limit_data_new (GESTrackElement * child)
|
||||
{
|
||||
GESTrack *track = ges_track_element_get_track (child);
|
||||
DurationLimitData *data = g_new0 (DurationLimitData, 1);
|
||||
|
||||
data->child = gst_object_ref (child);
|
||||
data->track = track ? gst_object_ref (track) : NULL;
|
||||
data->inpoint = _INPOINT (child);
|
||||
data->max_duration = _MAXDURATION (child);
|
||||
data->priority = _PRIORITY (child);
|
||||
data->active = ges_track_element_is_active (child);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
_duration_limit_data_free (gpointer data_p)
|
||||
{
|
||||
DurationLimitData *data = data_p;
|
||||
gst_clear_object (&data->track);
|
||||
gst_clear_object (&data->child);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static GList *
|
||||
_duration_limit_data_list (GESClip * clip)
|
||||
{
|
||||
GList *tmp, *list = NULL;
|
||||
|
||||
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next)
|
||||
list = g_list_prepend (list, _duration_limit_data_new (tmp->data));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static gint
|
||||
_cmp_by_track_then_priority (gconstpointer a_p, gconstpointer b_p)
|
||||
{
|
||||
const DurationLimitData *a = a_p, *b = b_p;
|
||||
if (a->track < b->track)
|
||||
return -1;
|
||||
else if (a->track > b->track)
|
||||
return 1;
|
||||
/* if higher priority (numerically lower) place later */
|
||||
if (a->priority < b->priority)
|
||||
return -1;
|
||||
else if (a->priority > b->priority)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define _INTERNAL_LIMIT(data) \
|
||||
((data->active && GST_CLOCK_TIME_IS_VALID (data->max_duration)) ? \
|
||||
data->max_duration - data->inpoint : GST_CLOCK_TIME_NONE)
|
||||
|
||||
static GstClockTime
|
||||
_calculate_duration_limit (GESClip * self, GList * child_data)
|
||||
{
|
||||
GstClockTime limit = GST_CLOCK_TIME_NONE;
|
||||
GList *tmp;
|
||||
|
||||
child_data = g_list_sort (child_data, _cmp_by_track_then_priority);
|
||||
|
||||
tmp = child_data;
|
||||
|
||||
while (tmp) {
|
||||
/* we have the first element in the track, of the lowest priority, and
|
||||
* work our way up from here */
|
||||
DurationLimitData *data = tmp->data;
|
||||
GESTrack *track = data->track;
|
||||
if (track) {
|
||||
GstClockTime track_limit = _INTERNAL_LIMIT (data);
|
||||
|
||||
for (tmp = tmp->next; tmp; tmp = tmp->next) {
|
||||
data = tmp->data;
|
||||
if (data->track != track)
|
||||
break;
|
||||
track_limit = _MIN_CLOCK_TIME (track_limit, _INTERNAL_LIMIT (data));
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (self, "duration-limit for track %" GST_PTR_FORMAT
|
||||
" is %" GST_TIME_FORMAT, track, GST_TIME_ARGS (track_limit));
|
||||
limit = _MIN_CLOCK_TIME (limit, track_limit);
|
||||
} else {
|
||||
/* children not in a track do not affect the duration-limit */
|
||||
for (tmp = tmp->next; tmp; tmp = tmp->next) {
|
||||
data = tmp->data;
|
||||
if (data->track)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
GST_LOG_OBJECT (self, "calculated duration-limit for the clip is %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (limit));
|
||||
|
||||
g_list_free_full (child_data, _duration_limit_data_free);
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
static void
|
||||
_update_duration_limit (GESClip * self)
|
||||
{
|
||||
GstClockTime duration_limit;
|
||||
|
||||
if (self->priv->prevent_duration_limit_update)
|
||||
return;
|
||||
|
||||
duration_limit = _calculate_duration_limit (self,
|
||||
_duration_limit_data_list (self));
|
||||
|
||||
if (duration_limit != self->priv->duration_limit) {
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (self);
|
||||
|
||||
self->priv->duration_limit = duration_limit;
|
||||
GST_INFO_OBJECT (self, "duration-limit for the clip is %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (duration_limit));
|
||||
|
||||
if (_CLOCK_TIME_IS_LESS (duration_limit, element->duration)) {
|
||||
gboolean res;
|
||||
|
||||
GST_INFO_OBJECT (self, "Automatically reducing duration to %"
|
||||
GST_TIME_FORMAT " to match the new duration-limit because "
|
||||
"the current duration %" GST_TIME_FORMAT " exceeds it",
|
||||
GST_TIME_ARGS (duration_limit), GST_TIME_ARGS (element->duration));
|
||||
|
||||
/* trim end with no snapping */
|
||||
if (element->timeline)
|
||||
res = timeline_tree_trim (timeline_get_tree (element->timeline),
|
||||
element, 0, GST_CLOCK_DIFF (duration_limit, element->duration),
|
||||
GES_EDGE_END, 0);
|
||||
else
|
||||
res = ges_timeline_element_set_duration (element, duration_limit);
|
||||
|
||||
if (!res)
|
||||
GST_ERROR_OBJECT (self, "Could not reduce the duration of the "
|
||||
"clip to below its duration-limit of %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (duration_limit));
|
||||
}
|
||||
/* notify after the auto-change in duration to allow the user to set
|
||||
* the duration in response to the change in their callbacks */
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DURATION_LIMIT]);
|
||||
}
|
||||
}
|
||||
|
||||
/* @min_priority: The absolute minimum priority a child of @container should have
|
||||
* @max_priority: The absolute maximum priority a child of @container should have
|
||||
|
@ -181,8 +350,7 @@ _get_priority_range (GESContainer * container, guint32 * min_priority,
|
|||
}
|
||||
|
||||
static void
|
||||
_child_priority_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
|
||||
_child_priority_changed (GESContainer * container, GESTimelineElement * child)
|
||||
{
|
||||
/* we do not change the rest of the clip in response to a change in
|
||||
* the child priority */
|
||||
|
@ -206,24 +374,29 @@ _child_priority_changed_cb (GESTimelineElement * child,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_child_inpoint_changed_cb (GESTimelineElement * child, GParamSpec * pspec,
|
||||
GESContainer * container)
|
||||
/* returns TRUE if duration-limit needs to be updated */
|
||||
static gboolean
|
||||
_child_inpoint_changed (GESClip * self, GESTimelineElement * child)
|
||||
{
|
||||
if (GES_CLIP (container)->priv->setting_inpoint)
|
||||
return;
|
||||
if (self->priv->setting_inpoint)
|
||||
return FALSE;
|
||||
|
||||
/* ignore non-core */
|
||||
/* if the track element has no internal content, then this means its
|
||||
* in-point has been set (back) to 0, we can ignore this update */
|
||||
/* if we have a non-core child, then we do not need the in-point of the
|
||||
* clip to change. Similarly, if the track element is core but has no
|
||||
* internal content, then this means its in-point has been set (back) to
|
||||
* 0, which means we do not need to update the in-point of the clip. */
|
||||
if (!_IS_CORE_INTERNAL_SOURCE_CHILD (child))
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
/* if setting the in-point of the clip, this will handle the change in
|
||||
* the duration-limit */
|
||||
|
||||
/* If the child->inpoint is the same as our own, set_inpoint will do
|
||||
* nothing. For example, when we set them in add_child (the notifies for
|
||||
* this are released after child_added is called because
|
||||
* ges_container_add freezes them) */
|
||||
_set_inpoint0 (GES_TIMELINE_ELEMENT (container), child->inpoint);
|
||||
_set_inpoint0 (GES_TIMELINE_ELEMENT (self), child->inpoint);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* called when a child is added, removed or their max-duration changes */
|
||||
|
@ -239,10 +412,8 @@ _update_max_duration (GESContainer * container)
|
|||
|
||||
for (tmp = container->children; tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
if (_IS_CORE_CHILD (child)
|
||||
&& GST_CLOCK_TIME_IS_VALID (child->maxduration))
|
||||
min = GST_CLOCK_TIME_IS_VALID (min) ? MIN (min, child->maxduration) :
|
||||
child->maxduration;
|
||||
if (_IS_CORE_CHILD (child))
|
||||
min = _MIN_CLOCK_TIME (min, child->maxduration);
|
||||
}
|
||||
priv->updating_max_duration = TRUE;
|
||||
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (container), min);
|
||||
|
@ -250,8 +421,8 @@ _update_max_duration (GESContainer * container)
|
|||
}
|
||||
|
||||
static void
|
||||
_child_max_duration_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * pspec, GESContainer * container)
|
||||
_child_max_duration_changed (GESContainer * container,
|
||||
GESTimelineElement * child)
|
||||
{
|
||||
/* ignore non-core */
|
||||
if (!_IS_CORE_CHILD (child))
|
||||
|
@ -261,8 +432,7 @@ _child_max_duration_changed_cb (GESTimelineElement * child,
|
|||
}
|
||||
|
||||
static void
|
||||
_child_has_internal_source_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * pspec, GESContainer * container)
|
||||
_child_has_internal_source_changed (GESClip * self, GESTimelineElement * child)
|
||||
{
|
||||
/* ignore non-core */
|
||||
/* if the track element is now registered to have no internal content,
|
||||
|
@ -271,7 +441,34 @@ _child_has_internal_source_changed_cb (GESTimelineElement * child,
|
|||
return;
|
||||
|
||||
/* otherwise, we need to make its in-point match ours */
|
||||
_set_inpoint0 (child, _INPOINT (container));
|
||||
_set_inpoint0 (child, _INPOINT (self));
|
||||
}
|
||||
|
||||
#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") || _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);
|
||||
}
|
||||
|
||||
if (update)
|
||||
_update_duration_limit (self);
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
|
@ -416,10 +613,13 @@ static gboolean
|
|||
_set_childrens_inpoint (GESTimelineElement * element, GstClockTime inpoint,
|
||||
gboolean break_on_failure)
|
||||
{
|
||||
GESClip *self = GES_CLIP (element);
|
||||
GList *tmp;
|
||||
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
||||
GESClipPrivate *priv = self->priv;
|
||||
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||
|
||||
priv->setting_inpoint = TRUE;
|
||||
priv->prevent_duration_limit_update = TRUE;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
|
||||
|
@ -428,12 +628,18 @@ _set_childrens_inpoint (GESTimelineElement * element, GstClockTime inpoint,
|
|||
GST_ERROR_OBJECT ("Could not set the in-point of child %"
|
||||
GES_FORMAT " to %" GST_TIME_FORMAT, GES_ARGS (child),
|
||||
GST_TIME_ARGS (inpoint));
|
||||
if (break_on_failure)
|
||||
if (break_on_failure) {
|
||||
priv->setting_inpoint = FALSE;
|
||||
priv->prevent_duration_limit_update = prev_prevent;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
priv->setting_inpoint = FALSE;
|
||||
priv->prevent_duration_limit_update = prev_prevent;
|
||||
|
||||
_update_duration_limit (self);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -452,7 +658,6 @@ static gboolean
|
|||
_set_duration (GESTimelineElement * element, GstClockTime duration)
|
||||
{
|
||||
GList *tmp, *children;
|
||||
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
|
||||
/* get copy of children, since GESContainer may resort the clip */
|
||||
|
@ -477,9 +682,12 @@ static gboolean
|
|||
_set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
||||
{
|
||||
GList *tmp;
|
||||
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
||||
GESClip *self = GES_CLIP (element);
|
||||
GESClipPrivate *priv = self->priv;
|
||||
GstClockTime new_min = GST_CLOCK_TIME_NONE;
|
||||
gboolean has_core = FALSE;
|
||||
gboolean res = FALSE;
|
||||
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||
|
||||
/* if we are setting based on a change in the minimum */
|
||||
if (priv->updating_max_duration)
|
||||
|
@ -487,6 +695,7 @@ _set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
|||
|
||||
/* else, we set every core child to have the same max duration */
|
||||
|
||||
priv->prevent_duration_limit_update = TRUE;
|
||||
priv->prevent_max_duration_update = TRUE;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
|
@ -498,14 +707,12 @@ _set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
|||
GST_ERROR_OBJECT ("Could not set the max-duration of child %"
|
||||
GES_FORMAT " to %" GST_TIME_FORMAT, GES_ARGS (child),
|
||||
GST_TIME_ARGS (maxduration));
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (child->maxduration))
|
||||
new_min = GST_CLOCK_TIME_IS_VALID (new_min) ?
|
||||
MIN (new_min, child->maxduration) : child->maxduration;
|
||||
new_min = _MIN_CLOCK_TIME (new_min, child->maxduration);
|
||||
}
|
||||
}
|
||||
}
|
||||
priv->prevent_max_duration_update = FALSE;
|
||||
priv->prevent_duration_limit_update = prev_prevent;
|
||||
|
||||
if (!has_core) {
|
||||
/* allow max-duration to be set arbitrarily when we have no
|
||||
|
@ -515,7 +722,8 @@ _set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
|||
GST_INFO_OBJECT (element,
|
||||
"Allowing max-duration of the clip to be set to %" GST_TIME_FORMAT
|
||||
" because it has no core children", GST_TIME_ARGS (maxduration));
|
||||
return TRUE;
|
||||
res = TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (new_min != maxduration) {
|
||||
|
@ -532,10 +740,15 @@ _set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
|||
priv->updating_max_duration = TRUE;
|
||||
ges_timeline_element_set_max_duration (element, new_min);
|
||||
priv->updating_max_duration = FALSE;
|
||||
return FALSE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
res = TRUE;
|
||||
|
||||
done:
|
||||
_update_duration_limit (self);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -544,7 +757,7 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
|||
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
||||
GList *tmp;
|
||||
guint32 min_prio, max_prio;
|
||||
|
||||
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
|
||||
/* send the new 'priority' to determine what the new 'min_prio' should
|
||||
|
@ -554,6 +767,7 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
|||
/* offsets will remain constant for the children */
|
||||
priv->prevent_resort = TRUE;
|
||||
priv->prevent_priority_offset_update = TRUE;
|
||||
priv->prevent_duration_limit_update = TRUE;
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
guint32 track_element_prio;
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
|
@ -582,9 +796,11 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
|||
_set_priority0 (child, track_element_prio);
|
||||
}
|
||||
/* no need to re-sort the container since we maintained the relative
|
||||
* offsets. As such, the height remains the same as well. */
|
||||
* offsets. As such, the height and duration-limit remains the same as
|
||||
* well. */
|
||||
priv->prevent_resort = FALSE;
|
||||
priv->prevent_priority_offset_update = FALSE;
|
||||
priv->prevent_duration_limit_update = prev_prevent;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -650,28 +866,30 @@ _compute_height (GESContainer * container)
|
|||
static gboolean
|
||||
_add_child (GESContainer * container, GESTimelineElement * element)
|
||||
{
|
||||
GESClip *self = GES_CLIP (container);
|
||||
GESClipClass *klass = GES_CLIP_GET_CLASS (GES_CLIP (container));
|
||||
guint max_prio, min_prio;
|
||||
GESTrack *track;
|
||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (container);
|
||||
GESClipPrivate *priv = GES_CLIP (container)->priv;
|
||||
GESClipPrivate *priv = self->priv;
|
||||
GESAsset *asset, *creator_asset;
|
||||
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||
|
||||
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (element), FALSE);
|
||||
|
||||
if (element->timeline && element->timeline != timeline) {
|
||||
GST_WARNING_OBJECT (container, "Cannot add %" GES_FORMAT " as a child "
|
||||
GST_WARNING_OBJECT (self, "Cannot add %" GES_FORMAT " as a child "
|
||||
"because its timeline is %" GST_PTR_FORMAT " rather than the "
|
||||
"clip's timeline %" GST_PTR_FORMAT, GES_ARGS (element),
|
||||
element->timeline, timeline);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
asset = ges_extractable_get_asset (GES_EXTRACTABLE (container));
|
||||
asset = ges_extractable_get_asset (GES_EXTRACTABLE (self));
|
||||
creator_asset =
|
||||
ges_track_element_get_creator_asset (GES_TRACK_ELEMENT (element));
|
||||
if (creator_asset && asset != creator_asset) {
|
||||
GST_WARNING_OBJECT (container,
|
||||
GST_WARNING_OBJECT (self,
|
||||
"Cannot add the track element %" GES_FORMAT " as a child "
|
||||
"because it is a core element created by another clip with a "
|
||||
"different asset to the current clip's asset", GES_ARGS (element));
|
||||
|
@ -685,7 +903,7 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
* the track, so we would have checked this with the
|
||||
* element->timeline check. But technically a user could get around
|
||||
* this, so we double check here. */
|
||||
GST_WARNING_OBJECT (container, "Cannot add %" GES_FORMAT " as a child "
|
||||
GST_WARNING_OBJECT (self, "Cannot add %" GES_FORMAT " as a child "
|
||||
"because its track %" GST_PTR_FORMAT " is part of the timeline %"
|
||||
GST_PTR_FORMAT " rather than the clip's timeline %" GST_PTR_FORMAT,
|
||||
GES_ARGS (element), track, ges_track_get_timeline (track), timeline);
|
||||
|
@ -700,8 +918,8 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
* list of added effects, so we do not increase nb_effects. */
|
||||
|
||||
if (track && !priv->allow_any_track
|
||||
&& _track_contains_core (GES_CLIP (container), track, TRUE)) {
|
||||
GST_WARNING_OBJECT (container, "Cannot add the core child %" GES_FORMAT
|
||||
&& _track_contains_core (self, track, TRUE)) {
|
||||
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);
|
||||
return FALSE;
|
||||
|
@ -712,11 +930,10 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (element))) {
|
||||
/* 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 (container))) {
|
||||
if (!_set_inpoint0 (element, _INPOINT (self))) {
|
||||
GST_ERROR_OBJECT (element, "Could not set the in-point of the "
|
||||
"element %" GES_FORMAT " to %" GST_TIME_FORMAT ". Not adding "
|
||||
"as a child", GES_ARGS (element),
|
||||
GST_TIME_ARGS (_INPOINT (container)));
|
||||
"as a child", GES_ARGS (element), GST_TIME_ARGS (_INPOINT (self)));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -730,20 +947,21 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
* to make room. */
|
||||
|
||||
if (track && !priv->allow_any_track
|
||||
&& !_track_contains_core (GES_CLIP (container), track, TRUE)) {
|
||||
GST_WARNING_OBJECT (container, "Cannot add the effect %" GES_FORMAT
|
||||
&& !_track_contains_core (GES_CLIP (self), track, TRUE)) {
|
||||
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;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (container, "Adding %ith effect: %" GES_FORMAT
|
||||
GST_DEBUG_OBJECT (self, "Adding %ith effect: %" GES_FORMAT
|
||||
" Priority %i", priv->nb_effects + 1, GES_ARGS (element),
|
||||
min_prio + priv->nb_effects);
|
||||
|
||||
/* changing priorities, and updating their offset */
|
||||
priv->prevent_resort = TRUE;
|
||||
tmp = g_list_nth (GES_CONTAINER_CHILDREN (container), priv->nb_effects);
|
||||
priv->prevent_duration_limit_update = TRUE;
|
||||
tmp = g_list_nth (container->children, priv->nb_effects);
|
||||
for (; tmp; tmp = tmp->next)
|
||||
ges_timeline_element_set_priority (GES_TIMELINE_ELEMENT (tmp->data),
|
||||
GES_TIMELINE_ELEMENT_PRIORITY (tmp->data) + 1);
|
||||
|
@ -751,30 +969,32 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
_set_priority0 (element, min_prio + priv->nb_effects);
|
||||
priv->nb_effects++;
|
||||
priv->prevent_resort = FALSE;
|
||||
priv->prevent_duration_limit_update = prev_prevent;
|
||||
/* no need to call _ges_container_sort_children (container) since
|
||||
* there is no change to the ordering yet (this happens after the
|
||||
* child is actually added) */
|
||||
/* The height has already changed (increased by 1) */
|
||||
_compute_height (container);
|
||||
/* update duration limit in _child_added */
|
||||
} else {
|
||||
if (_IS_TOP_EFFECT (element))
|
||||
GST_WARNING_OBJECT (container, "Cannot add the effect %" GES_FORMAT
|
||||
GST_WARNING_OBJECT (self, "Cannot add the effect %" GES_FORMAT
|
||||
" because it is not a core element created by the clip itself "
|
||||
"and the %s class does not allow for adding extra effects",
|
||||
GES_ARGS (element), G_OBJECT_CLASS_NAME (klass));
|
||||
else if (GES_CLIP_CLASS_CAN_ADD_EFFECTS (klass))
|
||||
GST_WARNING_OBJECT (container, "Cannot add the track element %"
|
||||
GST_WARNING_OBJECT (self, "Cannot add the track element %"
|
||||
GES_FORMAT " because it is neither a core element created by "
|
||||
"the clip itself, nor a GESBaseEffect", GES_ARGS (element));
|
||||
else
|
||||
GST_WARNING_OBJECT (container, "Cannot add the track element %"
|
||||
GST_WARNING_OBJECT (self, "Cannot add the track element %"
|
||||
GES_FORMAT " because it is not a core element created by the "
|
||||
"clip itself", GES_ARGS (element));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_set_start0 (element, GES_TIMELINE_ELEMENT_START (container));
|
||||
_set_duration0 (element, GES_TIMELINE_ELEMENT_DURATION (container));
|
||||
_set_start0 (element, GES_TIMELINE_ELEMENT_START (self));
|
||||
_set_duration0 (element, GES_TIMELINE_ELEMENT_DURATION (self));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -787,10 +1007,12 @@ _remove_child (GESContainer * container, GESTimelineElement * element)
|
|||
/* NOTE: notifies are currently frozen by ges_container_add */
|
||||
if (_IS_TOP_EFFECT (element)) {
|
||||
GList *tmp;
|
||||
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||
GST_DEBUG_OBJECT (container, "Resyncing effects priority.");
|
||||
|
||||
/* changing priorities, so preventing a re-sort */
|
||||
priv->prevent_resort = TRUE;
|
||||
priv->prevent_duration_limit_update = TRUE;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (container); tmp; tmp = tmp->next) {
|
||||
guint32 sibling_prio = GES_TIMELINE_ELEMENT_PRIORITY (tmp->data);
|
||||
if (sibling_prio > element->priority)
|
||||
|
@ -799,46 +1021,44 @@ _remove_child (GESContainer * container, GESTimelineElement * element)
|
|||
}
|
||||
priv->nb_effects--;
|
||||
priv->prevent_resort = FALSE;
|
||||
priv->prevent_duration_limit_update = prev_prevent;
|
||||
/* no need to re-sort the children since the rest keep the same
|
||||
* relative priorities */
|
||||
/* height may have changed */
|
||||
_compute_height (container);
|
||||
}
|
||||
/* duration-limit updated in _child_removed */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_added (GESContainer * container, GESTimelineElement * element)
|
||||
{
|
||||
g_signal_connect (element, "notify::priority",
|
||||
G_CALLBACK (_child_priority_changed_cb), container);
|
||||
g_signal_connect (element, "notify::in-point",
|
||||
G_CALLBACK (_child_inpoint_changed_cb), container);
|
||||
g_signal_connect (element, "notify::max-duration",
|
||||
G_CALLBACK (_child_max_duration_changed_cb), container);
|
||||
g_signal_connect (element, "notify::has-internal-source",
|
||||
G_CALLBACK (_child_has_internal_source_changed_cb), container);
|
||||
GESClip *self = GES_CLIP (container);
|
||||
|
||||
_child_priority_changed_cb (element, NULL, container);
|
||||
g_signal_connect (element, "notify", G_CALLBACK (_child_property_changed_cb),
|
||||
self);
|
||||
|
||||
_child_priority_changed (container, element);
|
||||
|
||||
if (_IS_CORE_CHILD (element))
|
||||
_update_max_duration (container);
|
||||
|
||||
_update_duration_limit (self);
|
||||
}
|
||||
|
||||
static void
|
||||
_child_removed (GESContainer * container, GESTimelineElement * element)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (element, _child_priority_changed_cb,
|
||||
container);
|
||||
g_signal_handlers_disconnect_by_func (element, _child_inpoint_changed_cb,
|
||||
container);
|
||||
g_signal_handlers_disconnect_by_func (element,
|
||||
_child_max_duration_changed_cb, container);
|
||||
g_signal_handlers_disconnect_by_func (element,
|
||||
_child_has_internal_source_changed_cb, container);
|
||||
GESClip *self = GES_CLIP (container);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (element, _child_property_changed_cb,
|
||||
self);
|
||||
|
||||
if (_IS_CORE_CHILD (element))
|
||||
_update_max_duration (container);
|
||||
|
||||
_update_duration_limit (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -855,12 +1075,17 @@ add_clip_to_list (gpointer key, gpointer clip, GList ** list)
|
|||
* NOTE: Since this does not change the creator asset of the child, this
|
||||
* should only be called for transferring children between clips with the
|
||||
* same asset.
|
||||
* NOTE: This also prevents the update of the duration-limit, so you
|
||||
* should ensure that you call _update_duration_limit on both clips when
|
||||
* transferring has completed.
|
||||
*/
|
||||
static void
|
||||
_transfer_child (GESClip * from_clip, GESClip * to_clip,
|
||||
GESTrackElement * child)
|
||||
{
|
||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (to_clip);
|
||||
gboolean prev_prevent_from = from_clip->priv->prevent_duration_limit_update;
|
||||
gboolean prev_prevent_to = to_clip->priv->prevent_duration_limit_update;
|
||||
|
||||
/* We need to bump the refcount to avoid the object to be destroyed */
|
||||
gst_object_ref (child);
|
||||
|
@ -868,6 +1093,9 @@ _transfer_child (GESClip * from_clip, GESClip * to_clip,
|
|||
/* don't want to change tracks */
|
||||
ges_timeline_set_moving_track_elements (timeline, TRUE);
|
||||
|
||||
from_clip->priv->prevent_duration_limit_update = TRUE;
|
||||
to_clip->priv->prevent_duration_limit_update = TRUE;
|
||||
|
||||
ges_container_remove (GES_CONTAINER (from_clip),
|
||||
GES_TIMELINE_ELEMENT (child));
|
||||
|
||||
|
@ -879,6 +1107,9 @@ _transfer_child (GESClip * from_clip, GESClip * to_clip,
|
|||
to_clip->priv->allow_any_track = FALSE;
|
||||
ges_timeline_set_moving_track_elements (timeline, FALSE);
|
||||
|
||||
from_clip->priv->prevent_duration_limit_update = prev_prevent_from;
|
||||
to_clip->priv->prevent_duration_limit_update = prev_prevent_to;
|
||||
|
||||
gst_object_unref (child);
|
||||
}
|
||||
|
||||
|
@ -942,6 +1173,14 @@ _ungroup (GESContainer * container, gboolean recursive)
|
|||
g_hash_table_foreach (_tracktype_clip, (GHFunc) add_clip_to_list, &ret);
|
||||
g_hash_table_unref (_tracktype_clip);
|
||||
|
||||
/* Need to update the duration limit.
|
||||
* Since we have divided the clip by its tracks, the duration-limit,
|
||||
* which is a minimum value calculated per track, can only increase in
|
||||
* value, which means the duration of the clip should not change, which
|
||||
* means updating should always be possible */
|
||||
for (tmp = ret; tmp; tmp = tmp->next)
|
||||
_update_duration_limit (tmp->data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1062,10 +1301,31 @@ _group (GList * containers)
|
|||
supported_formats |= ges_track_element_get_track_type (celement);
|
||||
}
|
||||
g_list_free_full (children, gst_object_unref);
|
||||
/* duration-limit should be GST_CLOCK_TIME_NONE now that we have no
|
||||
* children */
|
||||
_update_duration_limit (cclip);
|
||||
|
||||
ges_layer_remove_clip (layer, cclip);
|
||||
}
|
||||
|
||||
/* Need to update the duration limit.
|
||||
* Each received clip C_i that has been grouped may have had a different
|
||||
* duration-limit L_i. In each case the duration must be less than
|
||||
* this limit, and since each clip shares the same duration, we have
|
||||
* for each clip C_i:
|
||||
* duration <= L_i
|
||||
* Thus:
|
||||
* duration <= min_i (L_i)
|
||||
*
|
||||
* Now, upon grouping each clip C_i into C, we have not changed the
|
||||
* children properties that affect the duration-limit. And since the
|
||||
* duration-limit is calculated as the minimum amongst the tracks of C,
|
||||
* this means that the duration-limit for C should be
|
||||
* L = min_i (L_i) >= duration
|
||||
* Therefore, we can safely set the duration-limit of C to L without
|
||||
* changing the duration of C. */
|
||||
_update_duration_limit (GES_CLIP (ret));
|
||||
|
||||
ges_clip_set_supported_formats (GES_CLIP (ret), supported_formats);
|
||||
|
||||
return ret;
|
||||
|
@ -1075,10 +1335,13 @@ void
|
|||
ges_clip_empty_from_track (GESClip * clip, GESTrack * track)
|
||||
{
|
||||
GList *tmp;
|
||||
gboolean prev_prevent = clip->priv->prevent_duration_limit_update;
|
||||
|
||||
if (track == NULL)
|
||||
return;
|
||||
/* allow us to remove in any order */
|
||||
clip->priv->allow_any_track = TRUE;
|
||||
clip->priv->prevent_duration_limit_update = TRUE;
|
||||
|
||||
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
|
||||
GESTrackElement *child = tmp->data;
|
||||
|
@ -1089,6 +1352,8 @@ ges_clip_empty_from_track (GESClip * clip, GESTrack * track)
|
|||
}
|
||||
}
|
||||
clip->priv->allow_any_track = FALSE;
|
||||
clip->priv->prevent_duration_limit_update = prev_prevent;
|
||||
_update_duration_limit (clip);
|
||||
}
|
||||
|
||||
static GESTrackElement *
|
||||
|
@ -1261,6 +1526,8 @@ ges_clip_get_property (GObject * object, guint property_id,
|
|||
case PROP_SUPPORTED_FORMATS:
|
||||
g_value_set_flags (value, clip->priv->supportedformats);
|
||||
break;
|
||||
case PROP_DURATION_LIMIT:
|
||||
g_value_set_uint64 (value, clip->priv->duration_limit);
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
|
@ -1338,6 +1605,30 @@ ges_clip_class_init (GESClipClass * klass)
|
|||
g_object_class_install_property (object_class, PROP_LAYER,
|
||||
properties[PROP_LAYER]);
|
||||
|
||||
/**
|
||||
* GESClip:duration-limit:
|
||||
*
|
||||
* The maximum #GESTimelineElement:duration that can be *currently* set
|
||||
* for the clip, taking into account the #GESTimelineElement:in-point,
|
||||
* #GESTimelineElement:max-duration, GESTrackElement:active, and
|
||||
* #GESTrackElement:track properties of its children. If there is no
|
||||
* limit, this will be set to #GST_CLOCK_TIME_NONE.
|
||||
*
|
||||
* Note that whilst a clip has no children in any tracks, the limit will
|
||||
* be unknown, and similarly set to #GST_CLOCK_TIME_NONE.
|
||||
*
|
||||
* If the duration-limit would ever go below the current
|
||||
* #GESTimelineElement:duration of the clip due to a change in the above
|
||||
* variables, its #GESTimelineElement:duration will be set to the new
|
||||
* limit.
|
||||
*/
|
||||
properties[PROP_DURATION_LIMIT] =
|
||||
g_param_spec_uint64 ("duration-limit", "Duration Limit",
|
||||
"A limit on the duration of the clip", 0, G_MAXUINT64,
|
||||
GST_CLOCK_TIME_NONE, G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
g_object_class_install_property (object_class, PROP_DURATION_LIMIT,
|
||||
properties[PROP_DURATION_LIMIT]);
|
||||
|
||||
element_class->ripple = _ripple;
|
||||
element_class->ripple_end = _ripple_end;
|
||||
element_class->roll_start = _roll_start;
|
||||
|
@ -1367,6 +1658,7 @@ static void
|
|||
ges_clip_init (GESClip * self)
|
||||
{
|
||||
self->priv = ges_clip_get_instance_private (self);
|
||||
self->priv->duration_limit = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1697,6 +1989,22 @@ ges_clip_get_layer (GESClip * clip)
|
|||
return clip->priv->layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* ges_clip_get_duration_limit:
|
||||
* @clip: A #GESClip
|
||||
*
|
||||
* Gets the #GESClip:duration-limit of the clip.
|
||||
*
|
||||
* Returns: The duration-limit of @clip.
|
||||
*/
|
||||
GstClockTime
|
||||
ges_clip_get_duration_limit (GESClip * clip)
|
||||
{
|
||||
g_return_val_if_fail (GES_IS_CLIP (clip), GST_CLOCK_TIME_NONE);
|
||||
|
||||
return clip->priv->duration_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ges_clip_get_top_effects:
|
||||
* @clip: A #GESClip
|
||||
|
|
|
@ -193,4 +193,7 @@ GstClockTime ges_clip_get_timeline_time_from_source_frame (GESClip * clip,
|
|||
GESFrameNumber frame_number,
|
||||
GError ** err);
|
||||
|
||||
GES_API
|
||||
GstClockTime ges_clip_get_duration_limit (GESClip * clip);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -22,6 +22,14 @@
|
|||
#include <ges/ges.h>
|
||||
#include <gst/check/gstcheck.h>
|
||||
|
||||
#define _assert_add(clip, child) \
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip), \
|
||||
GES_TIMELINE_ELEMENT (child)))
|
||||
|
||||
#define _assert_remove(clip, child) \
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), \
|
||||
GES_TIMELINE_ELEMENT (child)))
|
||||
|
||||
GST_START_TEST (test_object_properties)
|
||||
{
|
||||
GESClip *clip;
|
||||
|
@ -95,8 +103,7 @@ GST_START_TEST (test_object_properties)
|
|||
nle_object_check (ges_track_element_get_nleobject (trackelement), 400, 510,
|
||||
120, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, TRUE);
|
||||
|
||||
ges_container_remove (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (trackelement));
|
||||
_assert_remove (clip, trackelement);
|
||||
|
||||
gst_object_unref (timeline);
|
||||
|
||||
|
@ -365,10 +372,10 @@ GST_START_TEST (test_split_object)
|
|||
GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
ges_container_add (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (effect1));
|
||||
_assert_add (clip, effect1);
|
||||
|
||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("vertigotv"));
|
||||
ges_container_add (GES_CONTAINER (clip), GES_TIMELINE_ELEMENT (effect2));
|
||||
_assert_add (clip, effect2);
|
||||
|
||||
/* Check that trackelement has the same properties */
|
||||
CHECK_OBJECT_PROPS (trackelement1, 42, 12, 50);
|
||||
|
@ -578,18 +585,15 @@ GST_START_TEST (test_clip_group_ungroup)
|
|||
|
||||
el = GES_TRACK_ELEMENT (ges_effect_new ("audioecho"));
|
||||
ges_track_element_set_track_type (el, GES_TRACK_TYPE_AUDIO);
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (el)));
|
||||
_assert_add (clip, el);
|
||||
|
||||
el = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
ges_track_element_set_track_type (el, GES_TRACK_TYPE_VIDEO);
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (el)));
|
||||
_assert_add (clip, el);
|
||||
|
||||
el = GES_TRACK_ELEMENT (ges_effect_new ("videobalance"));
|
||||
ges_track_element_set_track_type (el, GES_TRACK_TYPE_VIDEO);
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (el)));
|
||||
_assert_add (clip, el);
|
||||
|
||||
assert_num_children (clip, 5);
|
||||
CHECK_OBJECT_PROPS (clip, 0, 0, 10);
|
||||
|
@ -696,27 +700,27 @@ GST_START_TEST (test_clip_group_ungroup)
|
|||
assert_num_in_track (audio_track, 2);
|
||||
assert_num_in_track (video_track, 3);
|
||||
|
||||
ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (video_clip), 10);
|
||||
assert_set_start (video_clip, 10);
|
||||
CHECK_OBJECT_PROPS (video_clip, 10, 0, 10);
|
||||
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
||||
|
||||
_assert_regroup_fails (containers);
|
||||
|
||||
ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (video_clip), 0);
|
||||
ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (video_clip), 10);
|
||||
assert_set_start (video_clip, 0);
|
||||
assert_set_inpoint (video_clip, 10);
|
||||
CHECK_OBJECT_PROPS (video_clip, 0, 10, 10);
|
||||
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
||||
|
||||
_assert_regroup_fails (containers);
|
||||
|
||||
ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (video_clip), 0);
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (video_clip), 15);
|
||||
assert_set_inpoint (video_clip, 0);
|
||||
assert_set_duration (video_clip, 15);
|
||||
CHECK_OBJECT_PROPS (video_clip, 0, 0, 15);
|
||||
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
||||
|
||||
_assert_regroup_fails (containers);
|
||||
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (video_clip), 10);
|
||||
assert_set_duration (video_clip, 10);
|
||||
CHECK_OBJECT_PROPS (video_clip, 0, 0, 10);
|
||||
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
||||
|
||||
|
@ -897,8 +901,7 @@ GST_START_TEST (test_clip_can_group)
|
|||
/* can group if same asset but different tracks */
|
||||
clip1 = ges_layer_add_asset (layer1, asset2, 0, 0, 10, GES_TRACK_TYPE_VIDEO);
|
||||
fail_unless (clip1);
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip1),
|
||||
GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"))));
|
||||
_assert_add (clip1, ges_effect_new ("agingtv"));
|
||||
assert_num_children (clip1, 2);
|
||||
|
||||
clip2 = ges_layer_add_asset (layer1, asset2, 0, 0, 10, GES_TRACK_TYPE_AUDIO);
|
||||
|
@ -997,11 +1000,9 @@ GST_START_TEST (test_adding_children_to_track)
|
|||
fail_unless (ges_track_element_get_track (source) == track1);
|
||||
|
||||
effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect)));
|
||||
_assert_add (clip, effect);
|
||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("vertigotv"));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect2)));
|
||||
_assert_add (clip, effect2);
|
||||
assert_num_children (clip, 3);
|
||||
assert_num_in_track (track1, 3);
|
||||
assert_num_in_track (track2, 0);
|
||||
|
@ -1154,8 +1155,7 @@ GST_START_TEST (test_adding_children_to_track)
|
|||
/* removing core from the container, empties the non-core from their
|
||||
* tracks */
|
||||
gst_object_ref (added);
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (added)));
|
||||
_assert_remove (clip, added);
|
||||
assert_num_children (clip, 5);
|
||||
fail_unless (ges_track_element_get_track (source) == track1);
|
||||
fail_if (ges_track_element_get_track (added));
|
||||
|
@ -1167,10 +1167,8 @@ GST_START_TEST (test_adding_children_to_track)
|
|||
assert_num_in_track (track2, 0);
|
||||
gst_object_unref (added);
|
||||
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (added2)));
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (added3)));
|
||||
_assert_remove (clip, added2);
|
||||
_assert_remove (clip, added3);
|
||||
assert_num_children (clip, 3);
|
||||
assert_num_in_track (track1, 3);
|
||||
assert_num_in_track (track2, 0);
|
||||
|
@ -1234,14 +1232,13 @@ GST_START_TEST (test_adding_children_to_track)
|
|||
|
||||
/* can not add source at time 23 because it would result in three
|
||||
* overlapping sources in the track */
|
||||
fail_unless (ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (clip),
|
||||
23));
|
||||
assert_set_start (clip, 23);
|
||||
fail_if (ges_clip_add_child_to_track (clip, source, track1, NULL));
|
||||
assert_num_children (clip, 3);
|
||||
assert_num_in_track (track1, 4);
|
||||
|
||||
/* can add at 5, with overlap */
|
||||
fail_unless (ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (clip), 5));
|
||||
assert_set_start (clip, 5);
|
||||
added = ges_clip_add_child_to_track (clip, source, track1, NULL);
|
||||
/* added is the source since it was not already in a track */
|
||||
fail_unless (added == source);
|
||||
|
@ -1314,8 +1311,7 @@ GST_START_TEST (test_clip_refcount_remove_child)
|
|||
assert_num_in_track (track, 2);
|
||||
ASSERT_OBJECT_REFCOUNT (effect, "1 for the track + 1 timeline", 2);
|
||||
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect)));
|
||||
_assert_add (clip, effect);
|
||||
assert_num_children (clip, 2);
|
||||
ASSERT_OBJECT_REFCOUNT (effect, "1 for the container + 1 for the track"
|
||||
" + 1 timeline", 3);
|
||||
|
@ -1326,8 +1322,7 @@ GST_START_TEST (test_clip_refcount_remove_child)
|
|||
g_signal_connect (clip, "child-removed", G_CALLBACK (child_removed_cb),
|
||||
&called);
|
||||
gst_object_ref (effect);
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect)));
|
||||
_assert_remove (clip, effect);
|
||||
fail_unless (called == TRUE);
|
||||
ASSERT_OBJECT_REFCOUNT (effect, "1 test ref", 1);
|
||||
gst_object_unref (effect);
|
||||
|
@ -1377,18 +1372,15 @@ GST_START_TEST (test_clip_find_track_element)
|
|||
|
||||
effect = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
||||
fail_unless (ges_track_add_element (track, effect));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect)));
|
||||
_assert_add (clip, effect);
|
||||
|
||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
||||
fail_unless (ges_track_add_element (track1, effect1));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect1)));
|
||||
_assert_add (clip, effect1);
|
||||
|
||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
||||
fail_unless (ges_track_add_element (track2, effect2));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect2)));
|
||||
_assert_add (clip, effect2);
|
||||
|
||||
fail_if (selection_called);
|
||||
assert_num_children (clip, 6);
|
||||
|
@ -1529,16 +1521,13 @@ GST_START_TEST (test_effects_priorities)
|
|||
ges_layer_add_clip (layer, clip);
|
||||
|
||||
effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect)));
|
||||
_assert_add (clip, effect);
|
||||
|
||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect1)));
|
||||
_assert_add (clip, effect1);
|
||||
|
||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (effect2)));
|
||||
_assert_add (clip, effect2);
|
||||
|
||||
fail_unless_equals_int (MIN_NLE_PRIO + TRANSITIONS_HEIGHT + 0,
|
||||
_PRIORITY (effect));
|
||||
|
@ -1712,10 +1701,10 @@ GST_START_TEST (test_children_time_setters)
|
|||
ges_track_element_set_has_internal_source (child, TRUE);
|
||||
_test_children_time_setting_on_clip (clip, child);
|
||||
/* clip in a group */
|
||||
fail_unless (ges_container_add (group, GES_TIMELINE_ELEMENT (clip)));
|
||||
_assert_add (group, clip);
|
||||
_test_children_time_setting_on_clip (clip, child);
|
||||
/* group is removed from the timeline and destroyed when empty */
|
||||
ges_container_remove (group, GES_TIMELINE_ELEMENT (clip));
|
||||
_assert_remove (group, clip);
|
||||
/* child not in timeline */
|
||||
gst_object_ref (clip);
|
||||
fail_unless (ges_layer_remove_clip (layer, clip));
|
||||
|
@ -1803,9 +1792,9 @@ GST_START_TEST (test_children_inpoint)
|
|||
|
||||
clip = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
||||
|
||||
fail_unless (ges_timeline_element_set_start (clip, 5));
|
||||
fail_unless (ges_timeline_element_set_duration (clip, 20));
|
||||
fail_unless (ges_timeline_element_set_inpoint (clip, 30));
|
||||
assert_set_start (clip, 5);
|
||||
assert_set_duration (clip, 20);
|
||||
assert_set_inpoint (clip, 30);
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
||||
|
||||
|
@ -1833,13 +1822,13 @@ GST_START_TEST (test_children_inpoint)
|
|||
fail_if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (effect)));
|
||||
/* allow us to choose our own in-point */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect), TRUE);
|
||||
fail_unless (ges_timeline_element_set_start (effect, 104));
|
||||
fail_unless (ges_timeline_element_set_duration (effect, 53));
|
||||
fail_unless (ges_timeline_element_set_inpoint (effect, 67));
|
||||
assert_set_start (effect, 104);
|
||||
assert_set_duration (effect, 53);
|
||||
assert_set_inpoint (effect, 67);
|
||||
|
||||
/* adding the effect will change its start and duration, but not its
|
||||
* in-point */
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip), effect));
|
||||
_assert_add (clip, effect);
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 30, 20);
|
||||
|
@ -1865,7 +1854,7 @@ GST_START_TEST (test_children_inpoint)
|
|||
|
||||
/* when we set the in-point on a core-child with an internal source we
|
||||
* also set the clip and siblings with the same features */
|
||||
fail_unless (ges_timeline_element_set_inpoint (child1, 50));
|
||||
assert_set_inpoint (child1, 50);
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 50, 20);
|
||||
/* child with no internal source not changed */
|
||||
|
@ -1883,7 +1872,7 @@ GST_START_TEST (test_children_inpoint)
|
|||
CHECK_OBJECT_PROPS (child1, 5, 50, 20);
|
||||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
fail_unless (ges_timeline_element_set_inpoint (child0, 40));
|
||||
assert_set_inpoint (child0, 40);
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 40, 20);
|
||||
|
@ -1891,7 +1880,7 @@ GST_START_TEST (test_children_inpoint)
|
|||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
/* setting in-point on effect shouldn't change any other siblings */
|
||||
fail_unless (ges_timeline_element_set_inpoint (effect, 77));
|
||||
assert_set_inpoint (effect, 77);
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 40, 20);
|
||||
|
@ -1943,13 +1932,13 @@ GST_START_TEST (test_children_max_duration)
|
|||
|
||||
max_duration = clips[i].max_duration;
|
||||
fail_unless_equals_uint64 (_MAX_DURATION (clip), max_duration);
|
||||
fail_unless (ges_timeline_element_set_start (clip, 5));
|
||||
fail_unless (ges_timeline_element_set_duration (clip, 20));
|
||||
fail_unless (ges_timeline_element_set_inpoint (clip, 30));
|
||||
assert_set_start (clip, 5);
|
||||
assert_set_duration (clip, 20);
|
||||
assert_set_inpoint (clip, 30);
|
||||
|
||||
/* can set the max duration the clip to anything whilst it has
|
||||
* no core child */
|
||||
fail_unless (ges_timeline_element_set_max_duration (clip, 150));
|
||||
assert_set_max_duration (clip, 150);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 150);
|
||||
|
||||
|
@ -1960,31 +1949,31 @@ GST_START_TEST (test_children_max_duration)
|
|||
/* allow us to choose our own max-duration */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect),
|
||||
TRUE);
|
||||
fail_unless (ges_timeline_element_set_start (effect, 104));
|
||||
fail_unless (ges_timeline_element_set_duration (effect, 53));
|
||||
fail_unless (ges_timeline_element_set_max_duration (effect, 400));
|
||||
assert_set_start (effect, 104);
|
||||
assert_set_duration (effect, 53);
|
||||
assert_set_max_duration (effect, 400);
|
||||
|
||||
/* adding the effect will change its start and duration, but not its
|
||||
* max-duration (or in-point) */
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip), effect));
|
||||
_assert_add (clip, effect);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 150);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
/* only non-core, so can still set the max-duration */
|
||||
fail_unless (ges_timeline_element_set_max_duration (clip, 200));
|
||||
assert_set_max_duration (clip, 200);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 200);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
/* removing should not change the max-duration we set on the clip */
|
||||
gst_object_ref (effect);
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), effect));
|
||||
_assert_remove (clip, effect);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 200);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip), effect));
|
||||
_assert_add (clip, effect);
|
||||
gst_object_unref (effect);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 200);
|
||||
|
@ -2022,21 +2011,21 @@ GST_START_TEST (test_children_max_duration)
|
|||
|
||||
/* when setting max_duration of core children, clip will take the
|
||||
* minimum value */
|
||||
fail_unless (ges_timeline_element_set_max_duration (child0, new_max - 1));
|
||||
assert_set_max_duration (child0, new_max - 1);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max - 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, max_duration);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (child1, new_max - 2));
|
||||
assert_set_max_duration (child1, new_max - 2);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max - 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (child0, new_max + 1));
|
||||
assert_set_max_duration (child0, new_max + 1);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
|
@ -2092,21 +2081,21 @@ GST_START_TEST (test_children_max_duration)
|
|||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
/* setting below new_max is ok */
|
||||
fail_unless (ges_timeline_element_set_inpoint (child0, 15));
|
||||
assert_set_inpoint (child0, 15);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 15, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 15, 20, new_max + 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 15, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
fail_unless (ges_timeline_element_set_inpoint (child1, 25));
|
||||
assert_set_inpoint (child1, 25);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 25, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 25, 20, new_max + 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 25, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
fail_unless (ges_timeline_element_set_inpoint (clip, 30));
|
||||
assert_set_inpoint (clip, 30);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
|
@ -2114,7 +2103,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
/* non-core has no effect */
|
||||
fail_unless (ges_timeline_element_set_max_duration (effect, new_max + 500));
|
||||
assert_set_max_duration (effect, new_max + 500);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
|
@ -2123,7 +2112,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
|
||||
/* can set the in-point of non-core to be higher than the max_duration
|
||||
* of the clip */
|
||||
fail_unless (ges_timeline_element_set_inpoint (effect, new_max + 2));
|
||||
assert_set_inpoint (effect, new_max + 2);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
|
@ -2145,14 +2134,14 @@ GST_START_TEST (test_children_max_duration)
|
|||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, new_max + 2, 20, new_max + 500);
|
||||
|
||||
fail_unless (ges_timeline_element_set_inpoint (effect, 0));
|
||||
assert_set_inpoint (effect, 0);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, new_max + 500);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (effect, 400));
|
||||
assert_set_max_duration (effect, 400);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
|
@ -2161,7 +2150,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
|
||||
/* setting on the clip will set all the core children to the same
|
||||
* value */
|
||||
fail_unless (ges_timeline_element_set_max_duration (clip, 180));
|
||||
assert_set_max_duration (clip, 180);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 180);
|
||||
|
@ -2217,7 +2206,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
/* can now set the max-duration, which will effect the clip */
|
||||
fail_unless (ges_timeline_element_set_max_duration (child0, 140));
|
||||
assert_set_max_duration (child0, 140);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
|
@ -2232,7 +2221,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (child1, 130));
|
||||
assert_set_max_duration (child1, 130);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
|
@ -2245,7 +2234,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
gst_object_ref (effect);
|
||||
|
||||
/* removing non-core does nothing */
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), effect));
|
||||
_assert_remove (clip, effect);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
|
@ -2253,7 +2242,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||
|
||||
/* new minimum max-duration for the clip when we remove child1 */
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), child1));
|
||||
_assert_remove (clip, child1);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
|
@ -2262,7 +2251,7 @@ GST_START_TEST (test_children_max_duration)
|
|||
|
||||
/* with no core-children, the max-duration of the clip is set to
|
||||
* GST_CLOCK_TIME_NONE */
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), child0));
|
||||
_assert_remove (clip, child0);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
|
@ -2283,6 +2272,323 @@ GST_START_TEST (test_children_max_duration)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
#define _assert_duration_limit(clip, expect) \
|
||||
assert_equals_uint64 (ges_clip_get_duration_limit (GES_CLIP (clip)), expect)
|
||||
|
||||
GST_START_TEST (test_duration_limit)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
GESLayer *layer;
|
||||
GESClip *clip;
|
||||
GESTrackElement *video_source, *audio_source;
|
||||
GESTrackElement *effect1, *effect2, *effect3;
|
||||
GESTrack *track1, *track2;
|
||||
gint limit_notify_count = 0;
|
||||
gint duration_notify_count = 0;
|
||||
|
||||
ges_init ();
|
||||
|
||||
timeline = ges_timeline_new ();
|
||||
track1 = GES_TRACK (ges_video_track_new ());
|
||||
track2 = GES_TRACK (ges_audio_track_new ());
|
||||
|
||||
fail_unless (ges_timeline_add_track (timeline, track1));
|
||||
fail_unless (ges_timeline_add_track (timeline, track2));
|
||||
/* add track3 later */
|
||||
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
|
||||
clip = GES_CLIP (ges_test_clip_new ());
|
||||
g_signal_connect (clip, "notify::duration-limit", G_CALLBACK (_count_cb),
|
||||
&limit_notify_count);
|
||||
g_signal_connect (clip, "notify::duration", G_CALLBACK (_count_cb),
|
||||
&duration_notify_count);
|
||||
|
||||
/* no limit to begin with */
|
||||
_assert_duration_limit (clip, GST_CLOCK_TIME_NONE);
|
||||
|
||||
/* add effects */
|
||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("textoverlay"));
|
||||
ges_track_element_set_has_internal_source (effect1, TRUE);
|
||||
|
||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||
ges_track_element_set_has_internal_source (effect2, TRUE);
|
||||
|
||||
effect3 = GES_TRACK_ELEMENT (ges_effect_new ("audioecho"));
|
||||
ges_track_element_set_has_internal_source (effect3, TRUE);
|
||||
|
||||
_assert_add (clip, effect1);
|
||||
_assert_add (clip, effect2);
|
||||
_assert_add (clip, effect3);
|
||||
assert_num_children (clip, 3);
|
||||
_assert_duration_limit (clip, GST_CLOCK_TIME_NONE);
|
||||
assert_equals_int (limit_notify_count, 0);
|
||||
assert_equals_int (duration_notify_count, 0);
|
||||
|
||||
/* no change in duration limit whilst children are not in any track */
|
||||
assert_set_max_duration (effect1, 20);
|
||||
_assert_duration_limit (clip, GST_CLOCK_TIME_NONE);
|
||||
assert_equals_int (limit_notify_count, 0);
|
||||
assert_equals_int (duration_notify_count, 0);
|
||||
|
||||
assert_set_inpoint (effect1, 5);
|
||||
_assert_duration_limit (clip, GST_CLOCK_TIME_NONE);
|
||||
assert_equals_int (limit_notify_count, 0);
|
||||
assert_equals_int (duration_notify_count, 0);
|
||||
|
||||
/* set a duration that will be above the duration-limit */
|
||||
assert_set_duration (clip, 20);
|
||||
assert_equals_int (duration_notify_count, 1);
|
||||
|
||||
/* add to layer to create sources */
|
||||
fail_unless (ges_layer_add_clip (layer, clip));
|
||||
|
||||
/* duration-limit changes once because of effect1 */
|
||||
_assert_duration_limit (clip, 15);
|
||||
assert_equals_int (limit_notify_count, 1);
|
||||
assert_equals_int (duration_notify_count, 2);
|
||||
/* duration has automatically been set to the duration-limit */
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
|
||||
assert_num_children (clip, 5);
|
||||
assert_num_in_track (track1, 3);
|
||||
assert_num_in_track (track2, 2);
|
||||
|
||||
video_source = ges_clip_find_track_element (clip, track1, GES_TYPE_SOURCE);
|
||||
fail_unless (video_source);
|
||||
gst_object_unref (video_source);
|
||||
|
||||
audio_source = ges_clip_find_track_element (clip, track2, GES_TYPE_SOURCE);
|
||||
fail_unless (audio_source);
|
||||
gst_object_unref (audio_source);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
fail_unless (ges_track_element_get_track (video_source) == track1);
|
||||
fail_unless (ges_track_element_get_track_type (video_source) ==
|
||||
GES_TRACK_TYPE_VIDEO);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
fail_unless (ges_track_element_get_track (audio_source) == track2);
|
||||
fail_unless (ges_track_element_get_track_type (audio_source) ==
|
||||
GES_TRACK_TYPE_AUDIO);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
fail_unless (ges_track_element_get_track (effect1) == track1);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
fail_unless (ges_track_element_get_track (effect2) == track1);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
fail_unless (ges_track_element_get_track (effect3) == track2);
|
||||
|
||||
/* Make effect1 inactive, which will remove the duration-limit */
|
||||
fail_unless (ges_track_element_set_active (effect1, FALSE));
|
||||
_assert_duration_limit (clip, GST_CLOCK_TIME_NONE);
|
||||
assert_equals_int (limit_notify_count, 2);
|
||||
/* duration is unchanged */
|
||||
assert_equals_int (duration_notify_count, 2);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
|
||||
/* changing the in-point does not change the duration limit whilst
|
||||
* there is no max-duration */
|
||||
assert_set_inpoint (clip, 10);
|
||||
_assert_duration_limit (clip, GST_CLOCK_TIME_NONE);
|
||||
assert_equals_int (limit_notify_count, 2);
|
||||
assert_equals_int (duration_notify_count, 2);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 10, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 10, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 10, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
|
||||
assert_set_max_duration (video_source, 40);
|
||||
_assert_duration_limit (clip, 30);
|
||||
assert_equals_int (limit_notify_count, 3);
|
||||
assert_equals_int (duration_notify_count, 2);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 10, 15, 40);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 10, 15, 40);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 10, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
|
||||
/* set in-point using child */
|
||||
assert_set_inpoint (audio_source, 15);
|
||||
_assert_duration_limit (clip, 25);
|
||||
assert_equals_int (limit_notify_count, 4);
|
||||
assert_equals_int (duration_notify_count, 2);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 40);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 40);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
|
||||
/* set max-duration of core children */
|
||||
assert_set_max_duration (clip, 60);
|
||||
_assert_duration_limit (clip, 45);
|
||||
assert_equals_int (limit_notify_count, 5);
|
||||
assert_equals_int (duration_notify_count, 2);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, GST_CLOCK_TIME_NONE);
|
||||
|
||||
/* can set duration up to the limit */
|
||||
assert_set_duration (clip, 45);
|
||||
_assert_duration_limit (clip, 45);
|
||||
assert_equals_int (limit_notify_count, 5);
|
||||
assert_equals_int (duration_notify_count, 3);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 45, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 45, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 45, 60);
|
||||
/* effect1 has a duration that exceeds max-duration - in-point
|
||||
* ok since it is currently inactive */
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 45, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 45, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 45, GST_CLOCK_TIME_NONE);
|
||||
|
||||
/* limit the effects */
|
||||
assert_set_max_duration (effect2, 70);
|
||||
_assert_duration_limit (clip, 45);
|
||||
assert_equals_int (limit_notify_count, 5);
|
||||
assert_equals_int (duration_notify_count, 3);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 45, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 45, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 45, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 45, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 0, 45, 70);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 45, GST_CLOCK_TIME_NONE);
|
||||
|
||||
assert_set_inpoint (effect2, 40);
|
||||
_assert_duration_limit (clip, 30);
|
||||
assert_equals_int (limit_notify_count, 6);
|
||||
assert_equals_int (duration_notify_count, 4);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 30, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 30, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 30, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 30, 70);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 30, GST_CLOCK_TIME_NONE);
|
||||
|
||||
/* no change */
|
||||
assert_set_max_duration (effect3, 35);
|
||||
_assert_duration_limit (clip, 30);
|
||||
assert_equals_int (limit_notify_count, 6);
|
||||
assert_equals_int (duration_notify_count, 4);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 30, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 30, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 30, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 30, 70);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 30, 35);
|
||||
|
||||
/* make effect1 active again */
|
||||
fail_unless (ges_track_element_set_active (effect1, TRUE));
|
||||
_assert_duration_limit (clip, 15);
|
||||
assert_equals_int (limit_notify_count, 7);
|
||||
assert_equals_int (duration_notify_count, 5);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 15, 70);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, 35);
|
||||
|
||||
/* removing effect2 from track does not change limit */
|
||||
fail_unless (ges_track_remove_element (track1, effect2));
|
||||
_assert_duration_limit (clip, 15);
|
||||
assert_equals_int (limit_notify_count, 7);
|
||||
assert_equals_int (duration_notify_count, 5);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, 35);
|
||||
/* no track */
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 15, 70);
|
||||
|
||||
/* removing effect1 does */
|
||||
fail_unless (ges_track_remove_element (track1, effect1));
|
||||
_assert_duration_limit (clip, 35);
|
||||
assert_equals_int (limit_notify_count, 8);
|
||||
assert_equals_int (duration_notify_count, 5);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, 35);
|
||||
/* no track */
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 15, 70);
|
||||
|
||||
/* add back */
|
||||
fail_unless (ges_track_add_element (track1, effect2));
|
||||
_assert_duration_limit (clip, 30);
|
||||
assert_equals_int (limit_notify_count, 9);
|
||||
assert_equals_int (duration_notify_count, 5);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, 35);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 15, 70);
|
||||
/* no track */
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
|
||||
assert_set_duration (clip, 20);
|
||||
_assert_duration_limit (clip, 30);
|
||||
assert_equals_int (limit_notify_count, 9);
|
||||
assert_equals_int (duration_notify_count, 6);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 20, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 20, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 20, 35);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 20, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 20, 70);
|
||||
/* no track */
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 20, 20);
|
||||
|
||||
fail_unless (ges_track_add_element (track1, effect1));
|
||||
_assert_duration_limit (clip, 15);
|
||||
assert_equals_int (limit_notify_count, 10);
|
||||
assert_equals_int (duration_notify_count, 7);
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, 35);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 15, 70);
|
||||
|
||||
gst_object_ref (clip);
|
||||
fail_unless (ges_layer_remove_clip (layer, clip));
|
||||
|
||||
assert_num_in_track (track1, 0);
|
||||
assert_num_in_track (track2, 0);
|
||||
assert_num_children (clip, 5);
|
||||
|
||||
_assert_duration_limit (clip, GST_CLOCK_TIME_NONE);
|
||||
/* may have several changes in duration limit as the children are
|
||||
* emptied from their tracks */
|
||||
fail_unless (limit_notify_count > 10);
|
||||
assert_equals_int (duration_notify_count, 7);
|
||||
/* none in any track */
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (audio_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect3, 0, 0, 15, 35);
|
||||
CHECK_OBJECT_PROPS_MAX (video_source, 0, 15, 15, 60);
|
||||
CHECK_OBJECT_PROPS_MAX (effect1, 0, 5, 15, 20);
|
||||
CHECK_OBJECT_PROPS_MAX (effect2, 0, 40, 15, 70);
|
||||
|
||||
gst_object_unref (timeline);
|
||||
gst_object_unref (clip);
|
||||
|
||||
ges_deinit ();
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_children_properties_contain)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
|
@ -2297,7 +2603,7 @@ GST_START_TEST (test_children_properties_contain)
|
|||
timeline = ges_timeline_new_audio_video ();
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
clip = GES_CLIP (ges_test_clip_new ());
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (clip), 50);
|
||||
assert_set_duration (clip, 50);
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, clip));
|
||||
|
||||
|
@ -2404,7 +2710,7 @@ GST_START_TEST (test_children_properties_change)
|
|||
timeline = ges_timeline_new_audio_video ();
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
clip = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (clip), 50);
|
||||
assert_set_duration (clip, 50);
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip)));
|
||||
fail_unless (GES_CONTAINER_CHILDREN (clip));
|
||||
|
@ -2678,7 +2984,7 @@ GST_START_TEST (test_copy_paste_children_properties)
|
|||
timeline = ges_timeline_new_audio_video ();
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
clip = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (clip), 50);
|
||||
assert_set_duration (clip, 50);
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip)));
|
||||
|
||||
|
@ -2792,6 +3098,7 @@ ges_suite (void)
|
|||
tcase_add_test (tc_chain, test_can_add_effect);
|
||||
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);
|
||||
tcase_add_test (tc_chain, test_children_properties_contain);
|
||||
tcase_add_test (tc_chain, test_children_properties_change);
|
||||
tcase_add_test (tc_chain, test_copy_paste_children_properties);
|
||||
|
|
|
@ -106,6 +106,26 @@ G_STMT_START { \
|
|||
GST_TIME_ARGS (_MAX_DURATION(obj)), GST_TIME_ARGS (max_duration)); \
|
||||
}
|
||||
|
||||
#define assert_set_start(obj, start) \
|
||||
fail_unless (ges_timeline_element_set_start (\
|
||||
GES_TIMELINE_ELEMENT (obj), start), \
|
||||
"Could not set the start of " #obj " to " #start)
|
||||
|
||||
#define assert_set_duration(obj, duration) \
|
||||
fail_unless (ges_timeline_element_set_duration (\
|
||||
GES_TIMELINE_ELEMENT (obj), duration), \
|
||||
"Could not set the duration of " #obj " to " #duration)
|
||||
|
||||
#define assert_set_inpoint(obj, inpoint) \
|
||||
fail_unless (ges_timeline_element_set_inpoint (\
|
||||
GES_TIMELINE_ELEMENT (obj), inpoint), \
|
||||
"Could not set the in-point of " #obj " to " #inpoint)
|
||||
|
||||
#define assert_set_max_duration(obj, max_duration) \
|
||||
fail_unless (ges_timeline_element_set_max_duration (\
|
||||
GES_TIMELINE_ELEMENT (obj), max_duration), \
|
||||
"Could not set the max-duration of " #obj " to " #max_duration)
|
||||
|
||||
#define assert_num_in_track(track, val) \
|
||||
{ \
|
||||
GList *tmp = ges_track_get_elements (track); \
|
||||
|
|
Loading…
Reference in a new issue