mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-24 16:18:16 +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 */
|
/* The formats supported by this Clip */
|
||||||
GESTrackType supportedformats;
|
GESTrackType supportedformats;
|
||||||
|
|
||||||
|
GstClockTime duration_limit;
|
||||||
|
gboolean prevent_duration_limit_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -125,6 +128,7 @@ enum
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_LAYER,
|
PROP_LAYER,
|
||||||
PROP_SUPPORTED_FORMATS,
|
PROP_SUPPORTED_FORMATS,
|
||||||
|
PROP_DURATION_LIMIT,
|
||||||
PROP_LAST
|
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_CORE_CHILD(child) GES_TRACK_ELEMENT_IS_CORE(child)
|
||||||
|
|
||||||
#define _IS_TOP_EFFECT(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) \
|
#define _IS_CORE_INTERNAL_SOURCE_CHILD(child) \
|
||||||
(_IS_CORE_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
|
/* @min_priority: The absolute minimum priority a child of @container should have
|
||||||
* @max_priority: The absolute maximum 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
|
static void
|
||||||
_child_priority_changed_cb (GESTimelineElement * child,
|
_child_priority_changed (GESContainer * container, GESTimelineElement * child)
|
||||||
GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
|
|
||||||
{
|
{
|
||||||
/* we do not change the rest of the clip in response to a change in
|
/* we do not change the rest of the clip in response to a change in
|
||||||
* the child priority */
|
* the child priority */
|
||||||
|
@ -206,24 +374,29 @@ _child_priority_changed_cb (GESTimelineElement * child,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* returns TRUE if duration-limit needs to be updated */
|
||||||
_child_inpoint_changed_cb (GESTimelineElement * child, GParamSpec * pspec,
|
static gboolean
|
||||||
GESContainer * container)
|
_child_inpoint_changed (GESClip * self, GESTimelineElement * child)
|
||||||
{
|
{
|
||||||
if (GES_CLIP (container)->priv->setting_inpoint)
|
if (self->priv->setting_inpoint)
|
||||||
return;
|
return FALSE;
|
||||||
|
|
||||||
/* ignore non-core */
|
/* if we have a non-core child, then we do not need the in-point of the
|
||||||
/* if the track element has no internal content, then this means its
|
* clip to change. Similarly, if the track element is core but has no
|
||||||
* in-point has been set (back) to 0, we can ignore this update */
|
* 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))
|
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
|
/* 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
|
* nothing. For example, when we set them in add_child (the notifies for
|
||||||
* this are released after child_added is called because
|
* this are released after child_added is called because
|
||||||
* ges_container_add freezes them) */
|
* 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 */
|
/* 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) {
|
for (tmp = container->children; tmp; tmp = tmp->next) {
|
||||||
GESTimelineElement *child = tmp->data;
|
GESTimelineElement *child = tmp->data;
|
||||||
if (_IS_CORE_CHILD (child)
|
if (_IS_CORE_CHILD (child))
|
||||||
&& GST_CLOCK_TIME_IS_VALID (child->maxduration))
|
min = _MIN_CLOCK_TIME (min, child->maxduration);
|
||||||
min = GST_CLOCK_TIME_IS_VALID (min) ? MIN (min, child->maxduration) :
|
|
||||||
child->maxduration;
|
|
||||||
}
|
}
|
||||||
priv->updating_max_duration = TRUE;
|
priv->updating_max_duration = TRUE;
|
||||||
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (container), min);
|
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (container), min);
|
||||||
|
@ -250,8 +421,8 @@ _update_max_duration (GESContainer * container)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_child_max_duration_changed_cb (GESTimelineElement * child,
|
_child_max_duration_changed (GESContainer * container,
|
||||||
GParamSpec * pspec, GESContainer * container)
|
GESTimelineElement * child)
|
||||||
{
|
{
|
||||||
/* ignore non-core */
|
/* ignore non-core */
|
||||||
if (!_IS_CORE_CHILD (child))
|
if (!_IS_CORE_CHILD (child))
|
||||||
|
@ -261,8 +432,7 @@ _child_max_duration_changed_cb (GESTimelineElement * child,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_child_has_internal_source_changed_cb (GESTimelineElement * child,
|
_child_has_internal_source_changed (GESClip * self, GESTimelineElement * child)
|
||||||
GParamSpec * pspec, GESContainer * container)
|
|
||||||
{
|
{
|
||||||
/* ignore non-core */
|
/* ignore non-core */
|
||||||
/* if the track element is now registered to have no internal content,
|
/* 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;
|
return;
|
||||||
|
|
||||||
/* otherwise, we need to make its in-point match ours */
|
/* 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,
|
_set_childrens_inpoint (GESTimelineElement * element, GstClockTime inpoint,
|
||||||
gboolean break_on_failure)
|
gboolean break_on_failure)
|
||||||
{
|
{
|
||||||
|
GESClip *self = GES_CLIP (element);
|
||||||
GList *tmp;
|
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->setting_inpoint = TRUE;
|
||||||
|
priv->prevent_duration_limit_update = TRUE;
|
||||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||||
GESTimelineElement *child = tmp->data;
|
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 %"
|
GST_ERROR_OBJECT ("Could not set the in-point of child %"
|
||||||
GES_FORMAT " to %" GST_TIME_FORMAT, GES_ARGS (child),
|
GES_FORMAT " to %" GST_TIME_FORMAT, GES_ARGS (child),
|
||||||
GST_TIME_ARGS (inpoint));
|
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;
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
priv->setting_inpoint = FALSE;
|
priv->setting_inpoint = FALSE;
|
||||||
|
priv->prevent_duration_limit_update = prev_prevent;
|
||||||
|
|
||||||
|
_update_duration_limit (self);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -452,7 +658,6 @@ static gboolean
|
||||||
_set_duration (GESTimelineElement * element, GstClockTime duration)
|
_set_duration (GESTimelineElement * element, GstClockTime duration)
|
||||||
{
|
{
|
||||||
GList *tmp, *children;
|
GList *tmp, *children;
|
||||||
|
|
||||||
GESContainer *container = GES_CONTAINER (element);
|
GESContainer *container = GES_CONTAINER (element);
|
||||||
|
|
||||||
/* get copy of children, since GESContainer may resort the clip */
|
/* get copy of children, since GESContainer may resort the clip */
|
||||||
|
@ -477,9 +682,12 @@ static gboolean
|
||||||
_set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
_set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
||||||
{
|
{
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
GESClip *self = GES_CLIP (element);
|
||||||
|
GESClipPrivate *priv = self->priv;
|
||||||
GstClockTime new_min = GST_CLOCK_TIME_NONE;
|
GstClockTime new_min = GST_CLOCK_TIME_NONE;
|
||||||
gboolean has_core = FALSE;
|
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 we are setting based on a change in the minimum */
|
||||||
if (priv->updating_max_duration)
|
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 */
|
/* else, we set every core child to have the same max duration */
|
||||||
|
|
||||||
|
priv->prevent_duration_limit_update = TRUE;
|
||||||
priv->prevent_max_duration_update = TRUE;
|
priv->prevent_max_duration_update = TRUE;
|
||||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||||
GESTimelineElement *child = tmp->data;
|
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 %"
|
GST_ERROR_OBJECT ("Could not set the max-duration of child %"
|
||||||
GES_FORMAT " to %" GST_TIME_FORMAT, GES_ARGS (child),
|
GES_FORMAT " to %" GST_TIME_FORMAT, GES_ARGS (child),
|
||||||
GST_TIME_ARGS (maxduration));
|
GST_TIME_ARGS (maxduration));
|
||||||
|
new_min = _MIN_CLOCK_TIME (new_min, child->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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
priv->prevent_max_duration_update = FALSE;
|
priv->prevent_max_duration_update = FALSE;
|
||||||
|
priv->prevent_duration_limit_update = prev_prevent;
|
||||||
|
|
||||||
if (!has_core) {
|
if (!has_core) {
|
||||||
/* allow max-duration to be set arbitrarily when we have no
|
/* 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,
|
GST_INFO_OBJECT (element,
|
||||||
"Allowing max-duration of the clip to be set to %" GST_TIME_FORMAT
|
"Allowing max-duration of the clip to be set to %" GST_TIME_FORMAT
|
||||||
" because it has no core children", GST_TIME_ARGS (maxduration));
|
" because it has no core children", GST_TIME_ARGS (maxduration));
|
||||||
return TRUE;
|
res = TRUE;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_min != maxduration) {
|
if (new_min != maxduration) {
|
||||||
|
@ -532,10 +740,15 @@ _set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
||||||
priv->updating_max_duration = TRUE;
|
priv->updating_max_duration = TRUE;
|
||||||
ges_timeline_element_set_max_duration (element, new_min);
|
ges_timeline_element_set_max_duration (element, new_min);
|
||||||
priv->updating_max_duration = FALSE;
|
priv->updating_max_duration = FALSE;
|
||||||
return FALSE;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
res = TRUE;
|
||||||
|
|
||||||
|
done:
|
||||||
|
_update_duration_limit (self);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -544,7 +757,7 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
||||||
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
guint32 min_prio, max_prio;
|
guint32 min_prio, max_prio;
|
||||||
|
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||||
GESContainer *container = GES_CONTAINER (element);
|
GESContainer *container = GES_CONTAINER (element);
|
||||||
|
|
||||||
/* send the new 'priority' to determine what the new 'min_prio' should
|
/* 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 */
|
/* offsets will remain constant for the children */
|
||||||
priv->prevent_resort = TRUE;
|
priv->prevent_resort = TRUE;
|
||||||
priv->prevent_priority_offset_update = TRUE;
|
priv->prevent_priority_offset_update = TRUE;
|
||||||
|
priv->prevent_duration_limit_update = TRUE;
|
||||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||||
guint32 track_element_prio;
|
guint32 track_element_prio;
|
||||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||||
|
@ -582,9 +796,11 @@ _set_priority (GESTimelineElement * element, guint32 priority)
|
||||||
_set_priority0 (child, track_element_prio);
|
_set_priority0 (child, track_element_prio);
|
||||||
}
|
}
|
||||||
/* no need to re-sort the container since we maintained the relative
|
/* 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_resort = FALSE;
|
||||||
priv->prevent_priority_offset_update = FALSE;
|
priv->prevent_priority_offset_update = FALSE;
|
||||||
|
priv->prevent_duration_limit_update = prev_prevent;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -650,28 +866,30 @@ _compute_height (GESContainer * container)
|
||||||
static gboolean
|
static gboolean
|
||||||
_add_child (GESContainer * container, GESTimelineElement * element)
|
_add_child (GESContainer * container, GESTimelineElement * element)
|
||||||
{
|
{
|
||||||
|
GESClip *self = GES_CLIP (container);
|
||||||
GESClipClass *klass = GES_CLIP_GET_CLASS (GES_CLIP (container));
|
GESClipClass *klass = GES_CLIP_GET_CLASS (GES_CLIP (container));
|
||||||
guint max_prio, min_prio;
|
guint max_prio, min_prio;
|
||||||
GESTrack *track;
|
GESTrack *track;
|
||||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (container);
|
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (container);
|
||||||
GESClipPrivate *priv = GES_CLIP (container)->priv;
|
GESClipPrivate *priv = self->priv;
|
||||||
GESAsset *asset, *creator_asset;
|
GESAsset *asset, *creator_asset;
|
||||||
|
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||||
|
|
||||||
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (element), FALSE);
|
g_return_val_if_fail (GES_IS_TRACK_ELEMENT (element), FALSE);
|
||||||
|
|
||||||
if (element->timeline && element->timeline != timeline) {
|
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 "
|
"because its timeline is %" GST_PTR_FORMAT " rather than the "
|
||||||
"clip's timeline %" GST_PTR_FORMAT, GES_ARGS (element),
|
"clip's timeline %" GST_PTR_FORMAT, GES_ARGS (element),
|
||||||
element->timeline, timeline);
|
element->timeline, timeline);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
asset = ges_extractable_get_asset (GES_EXTRACTABLE (container));
|
asset = ges_extractable_get_asset (GES_EXTRACTABLE (self));
|
||||||
creator_asset =
|
creator_asset =
|
||||||
ges_track_element_get_creator_asset (GES_TRACK_ELEMENT (element));
|
ges_track_element_get_creator_asset (GES_TRACK_ELEMENT (element));
|
||||||
if (creator_asset && asset != creator_asset) {
|
if (creator_asset && asset != creator_asset) {
|
||||||
GST_WARNING_OBJECT (container,
|
GST_WARNING_OBJECT (self,
|
||||||
"Cannot add the track element %" GES_FORMAT " as a child "
|
"Cannot add the track element %" GES_FORMAT " as a child "
|
||||||
"because it is a core element created by another clip with a "
|
"because it is a core element created by another clip with a "
|
||||||
"different asset to the current clip's asset", GES_ARGS (element));
|
"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
|
* the track, so we would have checked this with the
|
||||||
* element->timeline check. But technically a user could get around
|
* element->timeline check. But technically a user could get around
|
||||||
* this, so we double check here. */
|
* 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 %"
|
"because its track %" GST_PTR_FORMAT " is part of the timeline %"
|
||||||
GST_PTR_FORMAT " rather than the clip's timeline %" GST_PTR_FORMAT,
|
GST_PTR_FORMAT " rather than the clip's timeline %" GST_PTR_FORMAT,
|
||||||
GES_ARGS (element), track, ges_track_get_timeline (track), timeline);
|
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. */
|
* list of added effects, so we do not increase nb_effects. */
|
||||||
|
|
||||||
if (track && !priv->allow_any_track
|
if (track && !priv->allow_any_track
|
||||||
&& _track_contains_core (GES_CLIP (container), track, TRUE)) {
|
&& _track_contains_core (self, track, TRUE)) {
|
||||||
GST_WARNING_OBJECT (container, "Cannot add the core child %" GES_FORMAT
|
GST_WARNING_OBJECT (self, "Cannot add the core child %" GES_FORMAT
|
||||||
" because it is in the same track %" GST_PTR_FORMAT " as an "
|
" because it is in the same track %" GST_PTR_FORMAT " as an "
|
||||||
"existing core child", GES_ARGS (element), track);
|
"existing core child", GES_ARGS (element), track);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -712,11 +930,10 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
||||||
if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (element))) {
|
if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (element))) {
|
||||||
/* adding can fail if the max-duration of the element is smaller
|
/* adding can fail if the max-duration of the element is smaller
|
||||||
* than the current in-point of the clip */
|
* 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 "
|
GST_ERROR_OBJECT (element, "Could not set the in-point of the "
|
||||||
"element %" GES_FORMAT " to %" GST_TIME_FORMAT ". Not adding "
|
"element %" GES_FORMAT " to %" GST_TIME_FORMAT ". Not adding "
|
||||||
"as a child", GES_ARGS (element),
|
"as a child", GES_ARGS (element), GST_TIME_ARGS (_INPOINT (self)));
|
||||||
GST_TIME_ARGS (_INPOINT (container)));
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -730,20 +947,21 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
||||||
* to make room. */
|
* to make room. */
|
||||||
|
|
||||||
if (track && !priv->allow_any_track
|
if (track && !priv->allow_any_track
|
||||||
&& !_track_contains_core (GES_CLIP (container), track, TRUE)) {
|
&& !_track_contains_core (GES_CLIP (self), track, TRUE)) {
|
||||||
GST_WARNING_OBJECT (container, "Cannot add the effect %" GES_FORMAT
|
GST_WARNING_OBJECT (self, "Cannot add the effect %" GES_FORMAT
|
||||||
" because its track %" GST_PTR_FORMAT " does not contain one "
|
" because its track %" GST_PTR_FORMAT " does not contain one "
|
||||||
"of the clip's core children", GES_ARGS (element), track);
|
"of the clip's core children", GES_ARGS (element), track);
|
||||||
return FALSE;
|
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),
|
" Priority %i", priv->nb_effects + 1, GES_ARGS (element),
|
||||||
min_prio + priv->nb_effects);
|
min_prio + priv->nb_effects);
|
||||||
|
|
||||||
/* changing priorities, and updating their offset */
|
/* changing priorities, and updating their offset */
|
||||||
priv->prevent_resort = TRUE;
|
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)
|
for (; tmp; tmp = tmp->next)
|
||||||
ges_timeline_element_set_priority (GES_TIMELINE_ELEMENT (tmp->data),
|
ges_timeline_element_set_priority (GES_TIMELINE_ELEMENT (tmp->data),
|
||||||
GES_TIMELINE_ELEMENT_PRIORITY (tmp->data) + 1);
|
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);
|
_set_priority0 (element, min_prio + priv->nb_effects);
|
||||||
priv->nb_effects++;
|
priv->nb_effects++;
|
||||||
priv->prevent_resort = FALSE;
|
priv->prevent_resort = FALSE;
|
||||||
|
priv->prevent_duration_limit_update = prev_prevent;
|
||||||
/* no need to call _ges_container_sort_children (container) since
|
/* no need to call _ges_container_sort_children (container) since
|
||||||
* there is no change to the ordering yet (this happens after the
|
* there is no change to the ordering yet (this happens after the
|
||||||
* child is actually added) */
|
* child is actually added) */
|
||||||
/* The height has already changed (increased by 1) */
|
/* The height has already changed (increased by 1) */
|
||||||
_compute_height (container);
|
_compute_height (container);
|
||||||
|
/* update duration limit in _child_added */
|
||||||
} else {
|
} else {
|
||||||
if (_IS_TOP_EFFECT (element))
|
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 "
|
" because it is not a core element created by the clip itself "
|
||||||
"and the %s class does not allow for adding extra effects",
|
"and the %s class does not allow for adding extra effects",
|
||||||
GES_ARGS (element), G_OBJECT_CLASS_NAME (klass));
|
GES_ARGS (element), G_OBJECT_CLASS_NAME (klass));
|
||||||
else if (GES_CLIP_CLASS_CAN_ADD_EFFECTS (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 "
|
GES_FORMAT " because it is neither a core element created by "
|
||||||
"the clip itself, nor a GESBaseEffect", GES_ARGS (element));
|
"the clip itself, nor a GESBaseEffect", GES_ARGS (element));
|
||||||
else
|
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 "
|
GES_FORMAT " because it is not a core element created by the "
|
||||||
"clip itself", GES_ARGS (element));
|
"clip itself", GES_ARGS (element));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_start0 (element, GES_TIMELINE_ELEMENT_START (container));
|
_set_start0 (element, GES_TIMELINE_ELEMENT_START (self));
|
||||||
_set_duration0 (element, GES_TIMELINE_ELEMENT_DURATION (container));
|
_set_duration0 (element, GES_TIMELINE_ELEMENT_DURATION (self));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -787,10 +1007,12 @@ _remove_child (GESContainer * container, GESTimelineElement * element)
|
||||||
/* NOTE: notifies are currently frozen by ges_container_add */
|
/* NOTE: notifies are currently frozen by ges_container_add */
|
||||||
if (_IS_TOP_EFFECT (element)) {
|
if (_IS_TOP_EFFECT (element)) {
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
gboolean prev_prevent = priv->prevent_duration_limit_update;
|
||||||
GST_DEBUG_OBJECT (container, "Resyncing effects priority.");
|
GST_DEBUG_OBJECT (container, "Resyncing effects priority.");
|
||||||
|
|
||||||
/* changing priorities, so preventing a re-sort */
|
/* changing priorities, so preventing a re-sort */
|
||||||
priv->prevent_resort = TRUE;
|
priv->prevent_resort = TRUE;
|
||||||
|
priv->prevent_duration_limit_update = TRUE;
|
||||||
for (tmp = GES_CONTAINER_CHILDREN (container); tmp; tmp = tmp->next) {
|
for (tmp = GES_CONTAINER_CHILDREN (container); tmp; tmp = tmp->next) {
|
||||||
guint32 sibling_prio = GES_TIMELINE_ELEMENT_PRIORITY (tmp->data);
|
guint32 sibling_prio = GES_TIMELINE_ELEMENT_PRIORITY (tmp->data);
|
||||||
if (sibling_prio > element->priority)
|
if (sibling_prio > element->priority)
|
||||||
|
@ -799,46 +1021,44 @@ _remove_child (GESContainer * container, GESTimelineElement * element)
|
||||||
}
|
}
|
||||||
priv->nb_effects--;
|
priv->nb_effects--;
|
||||||
priv->prevent_resort = FALSE;
|
priv->prevent_resort = FALSE;
|
||||||
|
priv->prevent_duration_limit_update = prev_prevent;
|
||||||
/* no need to re-sort the children since the rest keep the same
|
/* no need to re-sort the children since the rest keep the same
|
||||||
* relative priorities */
|
* relative priorities */
|
||||||
/* height may have changed */
|
/* height may have changed */
|
||||||
_compute_height (container);
|
_compute_height (container);
|
||||||
}
|
}
|
||||||
|
/* duration-limit updated in _child_removed */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_child_added (GESContainer * container, GESTimelineElement * element)
|
_child_added (GESContainer * container, GESTimelineElement * element)
|
||||||
{
|
{
|
||||||
g_signal_connect (element, "notify::priority",
|
GESClip *self = GES_CLIP (container);
|
||||||
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);
|
|
||||||
|
|
||||||
_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))
|
if (_IS_CORE_CHILD (element))
|
||||||
_update_max_duration (container);
|
_update_max_duration (container);
|
||||||
|
|
||||||
|
_update_duration_limit (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_child_removed (GESContainer * container, GESTimelineElement * element)
|
_child_removed (GESContainer * container, GESTimelineElement * element)
|
||||||
{
|
{
|
||||||
g_signal_handlers_disconnect_by_func (element, _child_priority_changed_cb,
|
GESClip *self = GES_CLIP (container);
|
||||||
container);
|
|
||||||
g_signal_handlers_disconnect_by_func (element, _child_inpoint_changed_cb,
|
g_signal_handlers_disconnect_by_func (element, _child_property_changed_cb,
|
||||||
container);
|
self);
|
||||||
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);
|
|
||||||
|
|
||||||
if (_IS_CORE_CHILD (element))
|
if (_IS_CORE_CHILD (element))
|
||||||
_update_max_duration (container);
|
_update_max_duration (container);
|
||||||
|
|
||||||
|
_update_duration_limit (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
* NOTE: Since this does not change the creator asset of the child, this
|
||||||
* should only be called for transferring children between clips with the
|
* should only be called for transferring children between clips with the
|
||||||
* same asset.
|
* 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
|
static void
|
||||||
_transfer_child (GESClip * from_clip, GESClip * to_clip,
|
_transfer_child (GESClip * from_clip, GESClip * to_clip,
|
||||||
GESTrackElement * child)
|
GESTrackElement * child)
|
||||||
{
|
{
|
||||||
GESTimeline *timeline = GES_TIMELINE_ELEMENT_TIMELINE (to_clip);
|
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 */
|
/* We need to bump the refcount to avoid the object to be destroyed */
|
||||||
gst_object_ref (child);
|
gst_object_ref (child);
|
||||||
|
@ -868,6 +1093,9 @@ _transfer_child (GESClip * from_clip, GESClip * to_clip,
|
||||||
/* don't want to change tracks */
|
/* don't want to change tracks */
|
||||||
ges_timeline_set_moving_track_elements (timeline, TRUE);
|
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_container_remove (GES_CONTAINER (from_clip),
|
||||||
GES_TIMELINE_ELEMENT (child));
|
GES_TIMELINE_ELEMENT (child));
|
||||||
|
|
||||||
|
@ -879,6 +1107,9 @@ _transfer_child (GESClip * from_clip, GESClip * to_clip,
|
||||||
to_clip->priv->allow_any_track = FALSE;
|
to_clip->priv->allow_any_track = FALSE;
|
||||||
ges_timeline_set_moving_track_elements (timeline, 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);
|
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_foreach (_tracktype_clip, (GHFunc) add_clip_to_list, &ret);
|
||||||
g_hash_table_unref (_tracktype_clip);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1062,10 +1301,31 @@ _group (GList * containers)
|
||||||
supported_formats |= ges_track_element_get_track_type (celement);
|
supported_formats |= ges_track_element_get_track_type (celement);
|
||||||
}
|
}
|
||||||
g_list_free_full (children, gst_object_unref);
|
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);
|
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);
|
ges_clip_set_supported_formats (GES_CLIP (ret), supported_formats);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1075,10 +1335,13 @@ void
|
||||||
ges_clip_empty_from_track (GESClip * clip, GESTrack * track)
|
ges_clip_empty_from_track (GESClip * clip, GESTrack * track)
|
||||||
{
|
{
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
gboolean prev_prevent = clip->priv->prevent_duration_limit_update;
|
||||||
|
|
||||||
if (track == NULL)
|
if (track == NULL)
|
||||||
return;
|
return;
|
||||||
/* allow us to remove in any order */
|
/* allow us to remove in any order */
|
||||||
clip->priv->allow_any_track = TRUE;
|
clip->priv->allow_any_track = TRUE;
|
||||||
|
clip->priv->prevent_duration_limit_update = TRUE;
|
||||||
|
|
||||||
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
|
for (tmp = GES_CONTAINER_CHILDREN (clip); tmp; tmp = tmp->next) {
|
||||||
GESTrackElement *child = tmp->data;
|
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->allow_any_track = FALSE;
|
||||||
|
clip->priv->prevent_duration_limit_update = prev_prevent;
|
||||||
|
_update_duration_limit (clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GESTrackElement *
|
static GESTrackElement *
|
||||||
|
@ -1261,6 +1526,8 @@ ges_clip_get_property (GObject * object, guint property_id,
|
||||||
case PROP_SUPPORTED_FORMATS:
|
case PROP_SUPPORTED_FORMATS:
|
||||||
g_value_set_flags (value, clip->priv->supportedformats);
|
g_value_set_flags (value, clip->priv->supportedformats);
|
||||||
break;
|
break;
|
||||||
|
case PROP_DURATION_LIMIT:
|
||||||
|
g_value_set_uint64 (value, clip->priv->duration_limit);
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
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,
|
g_object_class_install_property (object_class, PROP_LAYER,
|
||||||
properties[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 = _ripple;
|
||||||
element_class->ripple_end = _ripple_end;
|
element_class->ripple_end = _ripple_end;
|
||||||
element_class->roll_start = _roll_start;
|
element_class->roll_start = _roll_start;
|
||||||
|
@ -1367,6 +1658,7 @@ static void
|
||||||
ges_clip_init (GESClip * self)
|
ges_clip_init (GESClip * self)
|
||||||
{
|
{
|
||||||
self->priv = ges_clip_get_instance_private (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;
|
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:
|
* ges_clip_get_top_effects:
|
||||||
* @clip: A #GESClip
|
* @clip: A #GESClip
|
||||||
|
|
|
@ -193,4 +193,7 @@ GstClockTime ges_clip_get_timeline_time_from_source_frame (GESClip * clip,
|
||||||
GESFrameNumber frame_number,
|
GESFrameNumber frame_number,
|
||||||
GError ** err);
|
GError ** err);
|
||||||
|
|
||||||
|
GES_API
|
||||||
|
GstClockTime ges_clip_get_duration_limit (GESClip * clip);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -22,6 +22,14 @@
|
||||||
#include <ges/ges.h>
|
#include <ges/ges.h>
|
||||||
#include <gst/check/gstcheck.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)
|
GST_START_TEST (test_object_properties)
|
||||||
{
|
{
|
||||||
GESClip *clip;
|
GESClip *clip;
|
||||||
|
@ -95,8 +103,7 @@ GST_START_TEST (test_object_properties)
|
||||||
nle_object_check (ges_track_element_get_nleobject (trackelement), 400, 510,
|
nle_object_check (ges_track_element_get_nleobject (trackelement), 400, 510,
|
||||||
120, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, TRUE);
|
120, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, TRUE);
|
||||||
|
|
||||||
ges_container_remove (GES_CONTAINER (clip),
|
_assert_remove (clip, trackelement);
|
||||||
GES_TIMELINE_ELEMENT (trackelement));
|
|
||||||
|
|
||||||
gst_object_unref (timeline);
|
gst_object_unref (timeline);
|
||||||
|
|
||||||
|
@ -365,10 +372,10 @@ GST_START_TEST (test_split_object)
|
||||||
GES_TIMELINE_ELEMENT (clip));
|
GES_TIMELINE_ELEMENT (clip));
|
||||||
|
|
||||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
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"));
|
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 that trackelement has the same properties */
|
||||||
CHECK_OBJECT_PROPS (trackelement1, 42, 12, 50);
|
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"));
|
el = GES_TRACK_ELEMENT (ges_effect_new ("audioecho"));
|
||||||
ges_track_element_set_track_type (el, GES_TRACK_TYPE_AUDIO);
|
ges_track_element_set_track_type (el, GES_TRACK_TYPE_AUDIO);
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, el);
|
||||||
GES_TIMELINE_ELEMENT (el)));
|
|
||||||
|
|
||||||
el = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
el = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||||
ges_track_element_set_track_type (el, GES_TRACK_TYPE_VIDEO);
|
ges_track_element_set_track_type (el, GES_TRACK_TYPE_VIDEO);
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, el);
|
||||||
GES_TIMELINE_ELEMENT (el)));
|
|
||||||
|
|
||||||
el = GES_TRACK_ELEMENT (ges_effect_new ("videobalance"));
|
el = GES_TRACK_ELEMENT (ges_effect_new ("videobalance"));
|
||||||
ges_track_element_set_track_type (el, GES_TRACK_TYPE_VIDEO);
|
ges_track_element_set_track_type (el, GES_TRACK_TYPE_VIDEO);
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, el);
|
||||||
GES_TIMELINE_ELEMENT (el)));
|
|
||||||
|
|
||||||
assert_num_children (clip, 5);
|
assert_num_children (clip, 5);
|
||||||
CHECK_OBJECT_PROPS (clip, 0, 0, 10);
|
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 (audio_track, 2);
|
||||||
assert_num_in_track (video_track, 3);
|
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 (video_clip, 10, 0, 10);
|
||||||
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
||||||
|
|
||||||
_assert_regroup_fails (containers);
|
_assert_regroup_fails (containers);
|
||||||
|
|
||||||
ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (video_clip), 0);
|
assert_set_start (video_clip, 0);
|
||||||
ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (video_clip), 10);
|
assert_set_inpoint (video_clip, 10);
|
||||||
CHECK_OBJECT_PROPS (video_clip, 0, 10, 10);
|
CHECK_OBJECT_PROPS (video_clip, 0, 10, 10);
|
||||||
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
||||||
|
|
||||||
_assert_regroup_fails (containers);
|
_assert_regroup_fails (containers);
|
||||||
|
|
||||||
ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (video_clip), 0);
|
assert_set_inpoint (video_clip, 0);
|
||||||
ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (video_clip), 15);
|
assert_set_duration (video_clip, 15);
|
||||||
CHECK_OBJECT_PROPS (video_clip, 0, 0, 15);
|
CHECK_OBJECT_PROPS (video_clip, 0, 0, 15);
|
||||||
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
CHECK_OBJECT_PROPS (audio_clip, 0, 0, 10);
|
||||||
|
|
||||||
_assert_regroup_fails (containers);
|
_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 (video_clip, 0, 0, 10);
|
||||||
CHECK_OBJECT_PROPS (audio_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 */
|
/* can group if same asset but different tracks */
|
||||||
clip1 = ges_layer_add_asset (layer1, asset2, 0, 0, 10, GES_TRACK_TYPE_VIDEO);
|
clip1 = ges_layer_add_asset (layer1, asset2, 0, 0, 10, GES_TRACK_TYPE_VIDEO);
|
||||||
fail_unless (clip1);
|
fail_unless (clip1);
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip1),
|
_assert_add (clip1, ges_effect_new ("agingtv"));
|
||||||
GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"))));
|
|
||||||
assert_num_children (clip1, 2);
|
assert_num_children (clip1, 2);
|
||||||
|
|
||||||
clip2 = ges_layer_add_asset (layer1, asset2, 0, 0, 10, GES_TRACK_TYPE_AUDIO);
|
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);
|
fail_unless (ges_track_element_get_track (source) == track1);
|
||||||
|
|
||||||
effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect);
|
||||||
GES_TIMELINE_ELEMENT (effect)));
|
|
||||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("vertigotv"));
|
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("vertigotv"));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect2);
|
||||||
GES_TIMELINE_ELEMENT (effect2)));
|
|
||||||
assert_num_children (clip, 3);
|
assert_num_children (clip, 3);
|
||||||
assert_num_in_track (track1, 3);
|
assert_num_in_track (track1, 3);
|
||||||
assert_num_in_track (track2, 0);
|
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
|
/* removing core from the container, empties the non-core from their
|
||||||
* tracks */
|
* tracks */
|
||||||
gst_object_ref (added);
|
gst_object_ref (added);
|
||||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
_assert_remove (clip, added);
|
||||||
GES_TIMELINE_ELEMENT (added)));
|
|
||||||
assert_num_children (clip, 5);
|
assert_num_children (clip, 5);
|
||||||
fail_unless (ges_track_element_get_track (source) == track1);
|
fail_unless (ges_track_element_get_track (source) == track1);
|
||||||
fail_if (ges_track_element_get_track (added));
|
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);
|
assert_num_in_track (track2, 0);
|
||||||
gst_object_unref (added);
|
gst_object_unref (added);
|
||||||
|
|
||||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
_assert_remove (clip, added2);
|
||||||
GES_TIMELINE_ELEMENT (added2)));
|
_assert_remove (clip, added3);
|
||||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
|
||||||
GES_TIMELINE_ELEMENT (added3)));
|
|
||||||
assert_num_children (clip, 3);
|
assert_num_children (clip, 3);
|
||||||
assert_num_in_track (track1, 3);
|
assert_num_in_track (track1, 3);
|
||||||
assert_num_in_track (track2, 0);
|
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
|
/* can not add source at time 23 because it would result in three
|
||||||
* overlapping sources in the track */
|
* overlapping sources in the track */
|
||||||
fail_unless (ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (clip),
|
assert_set_start (clip, 23);
|
||||||
23));
|
|
||||||
fail_if (ges_clip_add_child_to_track (clip, source, track1, NULL));
|
fail_if (ges_clip_add_child_to_track (clip, source, track1, NULL));
|
||||||
assert_num_children (clip, 3);
|
assert_num_children (clip, 3);
|
||||||
assert_num_in_track (track1, 4);
|
assert_num_in_track (track1, 4);
|
||||||
|
|
||||||
/* can add at 5, with overlap */
|
/* 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 = ges_clip_add_child_to_track (clip, source, track1, NULL);
|
||||||
/* added is the source since it was not already in a track */
|
/* added is the source since it was not already in a track */
|
||||||
fail_unless (added == source);
|
fail_unless (added == source);
|
||||||
|
@ -1314,8 +1311,7 @@ GST_START_TEST (test_clip_refcount_remove_child)
|
||||||
assert_num_in_track (track, 2);
|
assert_num_in_track (track, 2);
|
||||||
ASSERT_OBJECT_REFCOUNT (effect, "1 for the track + 1 timeline", 2);
|
ASSERT_OBJECT_REFCOUNT (effect, "1 for the track + 1 timeline", 2);
|
||||||
|
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect);
|
||||||
GES_TIMELINE_ELEMENT (effect)));
|
|
||||||
assert_num_children (clip, 2);
|
assert_num_children (clip, 2);
|
||||||
ASSERT_OBJECT_REFCOUNT (effect, "1 for the container + 1 for the track"
|
ASSERT_OBJECT_REFCOUNT (effect, "1 for the container + 1 for the track"
|
||||||
" + 1 timeline", 3);
|
" + 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),
|
g_signal_connect (clip, "child-removed", G_CALLBACK (child_removed_cb),
|
||||||
&called);
|
&called);
|
||||||
gst_object_ref (effect);
|
gst_object_ref (effect);
|
||||||
fail_unless (ges_container_remove (GES_CONTAINER (clip),
|
_assert_remove (clip, effect);
|
||||||
GES_TIMELINE_ELEMENT (effect)));
|
|
||||||
fail_unless (called == TRUE);
|
fail_unless (called == TRUE);
|
||||||
ASSERT_OBJECT_REFCOUNT (effect, "1 test ref", 1);
|
ASSERT_OBJECT_REFCOUNT (effect, "1 test ref", 1);
|
||||||
gst_object_unref (effect);
|
gst_object_unref (effect);
|
||||||
|
@ -1377,18 +1372,15 @@ GST_START_TEST (test_clip_find_track_element)
|
||||||
|
|
||||||
effect = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
effect = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
||||||
fail_unless (ges_track_add_element (track, effect));
|
fail_unless (ges_track_add_element (track, effect));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect);
|
||||||
GES_TIMELINE_ELEMENT (effect)));
|
|
||||||
|
|
||||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
||||||
fail_unless (ges_track_add_element (track1, effect1));
|
fail_unless (ges_track_add_element (track1, effect1));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect1);
|
||||||
GES_TIMELINE_ELEMENT (effect1)));
|
|
||||||
|
|
||||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("identity"));
|
||||||
fail_unless (ges_track_add_element (track2, effect2));
|
fail_unless (ges_track_add_element (track2, effect2));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect2);
|
||||||
GES_TIMELINE_ELEMENT (effect2)));
|
|
||||||
|
|
||||||
fail_if (selection_called);
|
fail_if (selection_called);
|
||||||
assert_num_children (clip, 6);
|
assert_num_children (clip, 6);
|
||||||
|
@ -1529,16 +1521,13 @@ GST_START_TEST (test_effects_priorities)
|
||||||
ges_layer_add_clip (layer, clip);
|
ges_layer_add_clip (layer, clip);
|
||||||
|
|
||||||
effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
effect = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect);
|
||||||
GES_TIMELINE_ELEMENT (effect)));
|
|
||||||
|
|
||||||
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
effect1 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect1);
|
||||||
GES_TIMELINE_ELEMENT (effect1)));
|
|
||||||
|
|
||||||
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
effect2 = GES_TRACK_ELEMENT (ges_effect_new ("agingtv"));
|
||||||
fail_unless (ges_container_add (GES_CONTAINER (clip),
|
_assert_add (clip, effect2);
|
||||||
GES_TIMELINE_ELEMENT (effect2)));
|
|
||||||
|
|
||||||
fail_unless_equals_int (MIN_NLE_PRIO + TRANSITIONS_HEIGHT + 0,
|
fail_unless_equals_int (MIN_NLE_PRIO + TRANSITIONS_HEIGHT + 0,
|
||||||
_PRIORITY (effect));
|
_PRIORITY (effect));
|
||||||
|
@ -1712,10 +1701,10 @@ GST_START_TEST (test_children_time_setters)
|
||||||
ges_track_element_set_has_internal_source (child, TRUE);
|
ges_track_element_set_has_internal_source (child, TRUE);
|
||||||
_test_children_time_setting_on_clip (clip, child);
|
_test_children_time_setting_on_clip (clip, child);
|
||||||
/* clip in a group */
|
/* 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);
|
_test_children_time_setting_on_clip (clip, child);
|
||||||
/* group is removed from the timeline and destroyed when empty */
|
/* 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 */
|
/* child not in timeline */
|
||||||
gst_object_ref (clip);
|
gst_object_ref (clip);
|
||||||
fail_unless (ges_layer_remove_clip (layer, 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 ());
|
clip = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
||||||
|
|
||||||
fail_unless (ges_timeline_element_set_start (clip, 5));
|
assert_set_start (clip, 5);
|
||||||
fail_unless (ges_timeline_element_set_duration (clip, 20));
|
assert_set_duration (clip, 20);
|
||||||
fail_unless (ges_timeline_element_set_inpoint (clip, 30));
|
assert_set_inpoint (clip, 30);
|
||||||
|
|
||||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
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)));
|
fail_if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (effect)));
|
||||||
/* allow us to choose our own in-point */
|
/* allow us to choose our own in-point */
|
||||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect), TRUE);
|
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect), TRUE);
|
||||||
fail_unless (ges_timeline_element_set_start (effect, 104));
|
assert_set_start (effect, 104);
|
||||||
fail_unless (ges_timeline_element_set_duration (effect, 53));
|
assert_set_duration (effect, 53);
|
||||||
fail_unless (ges_timeline_element_set_inpoint (effect, 67));
|
assert_set_inpoint (effect, 67);
|
||||||
|
|
||||||
/* adding the effect will change its start and duration, but not its
|
/* adding the effect will change its start and duration, but not its
|
||||||
* in-point */
|
* 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 (clip, 5, 30, 20);
|
||||||
CHECK_OBJECT_PROPS (child0, 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
|
/* 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 */
|
* 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);
|
CHECK_OBJECT_PROPS (clip, 5, 50, 20);
|
||||||
/* child with no internal source not changed */
|
/* 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 (child1, 5, 50, 20);
|
||||||
CHECK_OBJECT_PROPS (effect, 5, 67, 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 (clip, 5, 40, 20);
|
||||||
CHECK_OBJECT_PROPS (child0, 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);
|
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||||
|
|
||||||
/* setting in-point on effect shouldn't change any other siblings */
|
/* 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 (clip, 5, 40, 20);
|
||||||
CHECK_OBJECT_PROPS (child0, 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;
|
max_duration = clips[i].max_duration;
|
||||||
fail_unless_equals_uint64 (_MAX_DURATION (clip), max_duration);
|
fail_unless_equals_uint64 (_MAX_DURATION (clip), max_duration);
|
||||||
fail_unless (ges_timeline_element_set_start (clip, 5));
|
assert_set_start (clip, 5);
|
||||||
fail_unless (ges_timeline_element_set_duration (clip, 20));
|
assert_set_duration (clip, 20);
|
||||||
fail_unless (ges_timeline_element_set_inpoint (clip, 30));
|
assert_set_inpoint (clip, 30);
|
||||||
|
|
||||||
/* can set the max duration the clip to anything whilst it has
|
/* can set the max duration the clip to anything whilst it has
|
||||||
* no core child */
|
* 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);
|
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 */
|
/* allow us to choose our own max-duration */
|
||||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect),
|
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect),
|
||||||
TRUE);
|
TRUE);
|
||||||
fail_unless (ges_timeline_element_set_start (effect, 104));
|
assert_set_start (effect, 104);
|
||||||
fail_unless (ges_timeline_element_set_duration (effect, 53));
|
assert_set_duration (effect, 53);
|
||||||
fail_unless (ges_timeline_element_set_max_duration (effect, 400));
|
assert_set_max_duration (effect, 400);
|
||||||
|
|
||||||
/* adding the effect will change its start and duration, but not its
|
/* adding the effect will change its start and duration, but not its
|
||||||
* max-duration (or in-point) */
|
* 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 (clip, 5, 30, 20, 150);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||||
|
|
||||||
/* only non-core, so can still set the max-duration */
|
/* 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 (clip, 5, 30, 20, 200);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||||
|
|
||||||
/* removing should not change the max-duration we set on the clip */
|
/* removing should not change the max-duration we set on the clip */
|
||||||
gst_object_ref (effect);
|
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 (clip, 5, 30, 20, 200);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
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);
|
gst_object_unref (effect);
|
||||||
|
|
||||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 200);
|
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
|
/* when setting max_duration of core children, clip will take the
|
||||||
* minimum value */
|
* 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 (clip, 5, 30, 20, new_max - 1);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 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 (child1, 5, 30, 20, max_duration);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
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 (clip, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 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, new_max - 2);
|
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
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 (clip, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
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);
|
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||||
|
|
||||||
/* setting below new_max is ok */
|
/* 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 (clip, 5, 15, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 15, 20, new_max + 1);
|
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 (child1, 5, 15, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
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 (clip, 5, 25, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 25, 20, new_max + 1);
|
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 (child1, 5, 25, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
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 (clip, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
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);
|
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||||
|
|
||||||
/* non-core has no effect */
|
/* 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 (clip, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
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
|
/* can set the in-point of non-core to be higher than the max_duration
|
||||||
* of the clip */
|
* 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 (clip, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
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 (child1, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, new_max + 2, 20, new_max + 500);
|
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 (clip, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 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, new_max - 2);
|
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, new_max + 500);
|
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 (clip, 5, 30, 20, new_max - 2);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
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
|
/* setting on the clip will set all the core children to the same
|
||||||
* value */
|
* 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 (clip, 5, 30, 20, 180);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 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);
|
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||||
|
|
||||||
/* can now set the max-duration, which will effect the clip */
|
/* 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 (clip, 5, 30, 20, 140);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 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 (child1, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
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 (clip, 5, 30, 20, 130);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||||
|
@ -2245,7 +2234,7 @@ GST_START_TEST (test_children_max_duration)
|
||||||
gst_object_ref (effect);
|
gst_object_ref (effect);
|
||||||
|
|
||||||
/* removing non-core does nothing */
|
/* 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 (clip, 5, 30, 20, 130);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
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);
|
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 400);
|
||||||
|
|
||||||
/* new minimum max-duration for the clip when we remove child1 */
|
/* 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 (clip, 5, 30, 20, 140);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 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
|
/* with no core-children, the max-duration of the clip is set to
|
||||||
* GST_CLOCK_TIME_NONE */
|
* 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 (clip, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||||
|
@ -2283,6 +2272,323 @@ GST_START_TEST (test_children_max_duration)
|
||||||
|
|
||||||
GST_END_TEST;
|
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)
|
GST_START_TEST (test_children_properties_contain)
|
||||||
{
|
{
|
||||||
GESTimeline *timeline;
|
GESTimeline *timeline;
|
||||||
|
@ -2297,7 +2603,7 @@ GST_START_TEST (test_children_properties_contain)
|
||||||
timeline = ges_timeline_new_audio_video ();
|
timeline = ges_timeline_new_audio_video ();
|
||||||
layer = ges_timeline_append_layer (timeline);
|
layer = ges_timeline_append_layer (timeline);
|
||||||
clip = GES_CLIP (ges_test_clip_new ());
|
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));
|
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 ();
|
timeline = ges_timeline_new_audio_video ();
|
||||||
layer = ges_timeline_append_layer (timeline);
|
layer = ges_timeline_append_layer (timeline);
|
||||||
clip = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
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_layer_add_clip (layer, GES_CLIP (clip)));
|
||||||
fail_unless (GES_CONTAINER_CHILDREN (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 ();
|
timeline = ges_timeline_new_audio_video ();
|
||||||
layer = ges_timeline_append_layer (timeline);
|
layer = ges_timeline_append_layer (timeline);
|
||||||
clip = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
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_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_can_add_effect);
|
||||||
tcase_add_test (tc_chain, test_children_inpoint);
|
tcase_add_test (tc_chain, test_children_inpoint);
|
||||||
tcase_add_test (tc_chain, test_children_max_duration);
|
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_contain);
|
||||||
tcase_add_test (tc_chain, test_children_properties_change);
|
tcase_add_test (tc_chain, test_children_properties_change);
|
||||||
tcase_add_test (tc_chain, test_copy_paste_children_properties);
|
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)); \
|
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) \
|
#define assert_num_in_track(track, val) \
|
||||||
{ \
|
{ \
|
||||||
GList *tmp = ges_track_get_elements (track); \
|
GList *tmp = ges_track_get_elements (track); \
|
||||||
|
|
Loading…
Reference in a new issue