mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
clip: re-handle child in-point and max-duration
The in-point of a clip is kept in sync with its core children, unless they have no has-internal-source. The max-duration is defined as the minimum max-duration amongst the clip's core children. If it is set to a new value, this sets the max-duration of its core children to the same value if they have has-internal-source set as TRUE. Non-core children (such as effects on a source clip) do not influence these values. As part of this, we no longer track in-point in GESContainer. Unlike start and duration, the in-point of a timeline element does not refer to its extent in the timeline. As such, it has little meaning for most collections of timeline-elements, in particular GESGroups. As such, there is no generic way to relate the in-point of a container to its children.
This commit is contained in:
parent
7725e48a80
commit
cd9cba55c0
9 changed files with 600 additions and 119 deletions
188
ges/ges-clip.c
188
ges/ges-clip.c
|
@ -53,7 +53,12 @@
|
|||
*
|
||||
* The #GESTimelineElement:in-point of the clip will control the
|
||||
* #GESTimelineElement:in-point of these core elements to be the same
|
||||
* value.
|
||||
* value if their #GESTrackElement:has-internal-source is set to %TRUE.
|
||||
* The #GESTimelineElement:max-duration of the clip is the minimum
|
||||
* #GESTimelineElement:max-duration of its children. If you set its value
|
||||
* to anything other than its current value, this will also set the
|
||||
* #GESTimelineElement:max-duration of all its core children to the same
|
||||
* value if their #GESTrackElement:has-internal-source is set to %TRUE.
|
||||
*
|
||||
* ## Effects
|
||||
*
|
||||
|
@ -100,6 +105,10 @@ struct _GESClipPrivate
|
|||
gboolean prevent_priority_offset_update;
|
||||
gboolean prevent_resort;
|
||||
|
||||
gboolean updating_max_duration;
|
||||
gboolean prevent_max_duration_update;
|
||||
gboolean setting_inpoint;
|
||||
|
||||
/* The formats supported by this Clip */
|
||||
GESTrackType supportedformats;
|
||||
};
|
||||
|
@ -178,6 +187,81 @@ _child_priority_changed_cb (GESTimelineElement * child,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_child_inpoint_changed_cb (GESTimelineElement * child, GParamSpec * pspec,
|
||||
GESContainer * container)
|
||||
{
|
||||
if (GES_CLIP (container)->priv->setting_inpoint)
|
||||
return;
|
||||
|
||||
/* ignore non-core */
|
||||
if (!ELEMENT_FLAG_IS_SET (child, GES_TRACK_ELEMENT_IS_CORE))
|
||||
return;
|
||||
|
||||
/* if the track element has no internal content, then this means its
|
||||
* in-point has been set (back) to 0, we can ignore this update */
|
||||
if (!ges_track_element_has_internal_source (GES_TRACK_ELEMENT (child)))
|
||||
return;
|
||||
|
||||
/* If the child->inpoint is the same as our own, set_inpoint will do
|
||||
* nothing. For example, when we set them in add_child (the notifies for
|
||||
* this are released after child_added is called because
|
||||
* ges_container_add freezes them) */
|
||||
_set_inpoint0 (GES_TIMELINE_ELEMENT (container), child->inpoint);
|
||||
}
|
||||
|
||||
/* called when a child is added, removed or their max-duration changes */
|
||||
static void
|
||||
_update_max_duration (GESContainer * container)
|
||||
{
|
||||
GList *tmp;
|
||||
GstClockTime min = GST_CLOCK_TIME_NONE;
|
||||
GESClipPrivate *priv = GES_CLIP (container)->priv;
|
||||
|
||||
if (priv->prevent_max_duration_update)
|
||||
return;
|
||||
|
||||
for (tmp = container->children; tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
if (ELEMENT_FLAG_IS_SET (child, GES_TRACK_ELEMENT_IS_CORE)
|
||||
&& GST_CLOCK_TIME_IS_VALID (child->maxduration))
|
||||
min = GST_CLOCK_TIME_IS_VALID (min) ? MIN (min, child->maxduration) :
|
||||
child->maxduration;
|
||||
}
|
||||
priv->updating_max_duration = TRUE;
|
||||
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (container), min);
|
||||
priv->updating_max_duration = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_max_duration_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * pspec, GESContainer * container)
|
||||
{
|
||||
/* ignore non-core */
|
||||
if (!ELEMENT_FLAG_IS_SET (child, GES_TRACK_ELEMENT_IS_CORE))
|
||||
return;
|
||||
|
||||
_update_max_duration (container);
|
||||
}
|
||||
|
||||
static void
|
||||
_child_has_internal_source_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * pspec, GESContainer * container)
|
||||
{
|
||||
/* ignore non-core */
|
||||
if (!ELEMENT_FLAG_IS_SET (child, GES_TRACK_ELEMENT_IS_CORE))
|
||||
return;
|
||||
|
||||
/* if the track element is now registered to have no internal content,
|
||||
* we don't have to do anything */
|
||||
if (!ges_track_element_has_internal_source (GES_TRACK_ELEMENT (child)))
|
||||
return;
|
||||
|
||||
/* otherwise, we need to make its in-point match ours */
|
||||
_set_inpoint0 (child, _INPOINT (container));
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* *
|
||||
* GESTimelineElement virtual methods implementation *
|
||||
|
@ -211,22 +295,18 @@ _set_start (GESTimelineElement * element, GstClockTime start)
|
|||
static gboolean
|
||||
_set_inpoint (GESTimelineElement * element, GstClockTime inpoint)
|
||||
{
|
||||
GList *tmp, *children;
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
GList *tmp;
|
||||
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
||||
|
||||
children = ges_container_get_children (container, FALSE);
|
||||
container->children_control_mode = GES_CHILDREN_IGNORE_NOTIFIES;
|
||||
for (tmp = children; tmp; tmp = g_list_next (tmp)) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
priv->setting_inpoint = TRUE;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
|
||||
/* FIXME: we should allow the inpoint to be different for children
|
||||
* that are *not* the core track elements of the clip. E.g. if we
|
||||
* add a GESEffect to a clip, we should not be editing its inpoint */
|
||||
if (child != container->initiated_move)
|
||||
if (ELEMENT_FLAG_IS_SET (child, GES_TRACK_ELEMENT_IS_CORE)
|
||||
&& ges_track_element_has_internal_source (GES_TRACK_ELEMENT (child)))
|
||||
_set_inpoint0 (child, inpoint);
|
||||
}
|
||||
container->children_control_mode = GES_CHILDREN_UPDATE;
|
||||
g_list_free_full (children, gst_object_unref);
|
||||
priv->setting_inpoint = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -260,10 +340,46 @@ static gboolean
|
|||
_set_max_duration (GESTimelineElement * element, GstClockTime maxduration)
|
||||
{
|
||||
GList *tmp;
|
||||
GESClipPrivate *priv = GES_CLIP (element)->priv;
|
||||
GstClockTime new_min = GST_CLOCK_TIME_NONE;
|
||||
|
||||
for (tmp = GES_CONTAINER (element)->children; tmp; tmp = g_list_next (tmp))
|
||||
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (tmp->data),
|
||||
maxduration);
|
||||
/* if we are setting based on a change in the minimum */
|
||||
if (priv->updating_max_duration)
|
||||
return TRUE;
|
||||
|
||||
/* else, we set every core child to have the same max duration */
|
||||
|
||||
priv->prevent_max_duration_update = TRUE;
|
||||
for (tmp = GES_CONTAINER_CHILDREN (element); tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *child = tmp->data;
|
||||
|
||||
if (ELEMENT_FLAG_IS_SET (child, GES_TRACK_ELEMENT_IS_CORE)
|
||||
&& ges_track_element_has_internal_source (GES_TRACK_ELEMENT (child))) {
|
||||
ges_timeline_element_set_max_duration (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;
|
||||
|
||||
if (new_min != maxduration) {
|
||||
if (GST_CLOCK_TIME_IS_VALID (new_min))
|
||||
GST_WARNING_OBJECT (element, "Failed to set the max-duration of the "
|
||||
"clip to %" GST_TIME_FORMAT " because it was not possible to "
|
||||
"match this with the actual minimum of %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (maxduration), GST_TIME_ARGS (new_min));
|
||||
else
|
||||
GST_WARNING_OBJECT (element, "Failed to set the max-duration of the "
|
||||
"clip to %" GST_TIME_FORMAT " because it has no core children "
|
||||
"whose max-duration could be set to anything other than "
|
||||
"GST_CLOCK_TIME_NONE", GST_TIME_ARGS (maxduration));
|
||||
priv->updating_max_duration = TRUE;
|
||||
ges_timeline_element_set_max_duration (element, new_min);
|
||||
priv->updating_max_duration = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -384,7 +500,8 @@ _add_child (GESContainer * container, GESTimelineElement * element)
|
|||
|
||||
/* Set the core element to have the same in-point, which we don't
|
||||
* apply to effects */
|
||||
_set_inpoint0 (element, GES_TIMELINE_ELEMENT_INPOINT (container));
|
||||
if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (element)))
|
||||
_set_inpoint0 (element, _INPOINT (container));
|
||||
} else if (GES_CLIP_CLASS_CAN_ADD_EFFECTS (klass)
|
||||
&& GES_IS_BASE_EFFECT (element)) {
|
||||
GList *tmp;
|
||||
|
@ -471,11 +588,17 @@ _remove_child (GESContainer * container, GESTimelineElement * element)
|
|||
static void
|
||||
_child_added (GESContainer * container, GESTimelineElement * element)
|
||||
{
|
||||
/* FIXME: adjust the max-duration according to the new child */
|
||||
g_signal_connect (G_OBJECT (element), "notify::priority",
|
||||
G_CALLBACK (_child_priority_changed_cb), container);
|
||||
g_signal_connect (G_OBJECT (element), "notify::in-point",
|
||||
G_CALLBACK (_child_inpoint_changed_cb), container);
|
||||
g_signal_connect (G_OBJECT (element), "notify::max-duration",
|
||||
G_CALLBACK (_child_max_duration_changed_cb), container);
|
||||
g_signal_connect (G_OBJECT (element), "notify::has-internal-source",
|
||||
G_CALLBACK (_child_has_internal_source_changed_cb), container);
|
||||
|
||||
_child_priority_changed_cb (element, NULL, container);
|
||||
_update_max_duration (container);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -483,6 +606,14 @@ _child_removed (GESContainer * container, GESTimelineElement * element)
|
|||
{
|
||||
g_signal_handlers_disconnect_by_func (element, _child_priority_changed_cb,
|
||||
container);
|
||||
g_signal_handlers_disconnect_by_func (element, _child_inpoint_changed_cb,
|
||||
container);
|
||||
g_signal_handlers_disconnect_by_func (element,
|
||||
_child_max_duration_changed_cb, container);
|
||||
g_signal_handlers_disconnect_by_func (element,
|
||||
_child_has_internal_source_changed_cb, container);
|
||||
|
||||
_update_max_duration (container);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -928,9 +1059,15 @@ ges_clip_class_init (GESClipClass * klass)
|
|||
static void
|
||||
ges_clip_init (GESClip * self)
|
||||
{
|
||||
self->priv = ges_clip_get_instance_private (self);
|
||||
self->priv->layer = NULL;
|
||||
self->priv->nb_effects = 0;
|
||||
GESClipPrivate *priv;
|
||||
priv = self->priv = ges_clip_get_instance_private (self);
|
||||
priv->layer = NULL;
|
||||
priv->nb_effects = 0;
|
||||
priv->prevent_priority_offset_update = FALSE;
|
||||
priv->prevent_resort = FALSE;
|
||||
priv->updating_max_duration = FALSE;
|
||||
priv->prevent_max_duration_update = FALSE;
|
||||
priv->setting_inpoint = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1061,12 +1198,6 @@ ges_clip_create_track_elements (GESClip * clip, GESTrackType type)
|
|||
for (tmp = track_elements; tmp; tmp = tmp->next) {
|
||||
GESTimelineElement *elem = tmp->data;
|
||||
ELEMENT_SET_FLAG (elem, GES_TRACK_ELEMENT_IS_CORE);
|
||||
|
||||
/* FIXME: we should set the max duration of the clip based on the
|
||||
* max duration of the child. Not the other way around. */
|
||||
if (GST_CLOCK_TIME_IS_VALID (GES_TIMELINE_ELEMENT_MAX_DURATION (clip)))
|
||||
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (elem),
|
||||
GES_TIMELINE_ELEMENT_MAX_DURATION (clip));
|
||||
}
|
||||
result = g_list_concat (track_elements, result);
|
||||
}
|
||||
|
@ -1583,6 +1714,9 @@ ges_clip_split (GESClip * clip, guint64 position)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* FIXME: in-point for non-core track elements should be shifted by
|
||||
* the split (adding them to the new clip will not set their in-point)
|
||||
* Handle this once generic time effects are supported in splitting */
|
||||
ges_container_add (GES_CONTAINER (new_object),
|
||||
GES_TIMELINE_ELEMENT (new_trackelement));
|
||||
ges_track_element_copy_properties (GES_TIMELINE_ELEMENT (trackelement),
|
||||
|
|
|
@ -58,12 +58,10 @@ typedef struct
|
|||
|
||||
GstClockTime start_offset;
|
||||
GstClockTime duration_offset;
|
||||
GstClockTime inpoint_offset;
|
||||
gint32 priority_offset;
|
||||
|
||||
gulong start_notifyid;
|
||||
gulong duration_notifyid;
|
||||
gulong inpoint_notifyid;
|
||||
gulong child_property_added_notifyid;
|
||||
gulong child_property_removed_notifyid;
|
||||
} ChildMapping;
|
||||
|
@ -120,8 +118,6 @@ _free_mapping (ChildMapping * mapping)
|
|||
g_signal_handler_disconnect (child, mapping->start_notifyid);
|
||||
if (mapping->duration_notifyid)
|
||||
g_signal_handler_disconnect (child, mapping->duration_notifyid);
|
||||
if (mapping->inpoint_notifyid)
|
||||
g_signal_handler_disconnect (child, mapping->inpoint_notifyid);
|
||||
if (mapping->child_property_added_notifyid)
|
||||
g_signal_handler_disconnect (child, mapping->child_property_added_notifyid);
|
||||
if (mapping->child_property_removed_notifyid)
|
||||
|
@ -186,22 +182,6 @@ _set_start (GESTimelineElement * element, GstClockTime start)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_inpoint (GESTimelineElement * element, GstClockTime inpoint)
|
||||
{
|
||||
GList *tmp;
|
||||
GESContainer *container = GES_CONTAINER (element);
|
||||
|
||||
for (tmp = container->children; tmp; tmp = g_list_next (tmp)) {
|
||||
GESTimelineElement *child = (GESTimelineElement *) tmp->data;
|
||||
ChildMapping *map = g_hash_table_lookup (container->priv->mappings, child);
|
||||
|
||||
map->inpoint_offset = inpoint - _INPOINT (child);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_duration (GESTimelineElement * element, GstClockTime duration)
|
||||
{
|
||||
|
@ -369,7 +349,6 @@ _deep_copy (GESTimelineElement * element, GESTimelineElement * copy)
|
|||
tmp->data));
|
||||
map->child = ges_timeline_element_copy (tmp->data, TRUE);
|
||||
map->start_notifyid = 0;
|
||||
map->inpoint_notifyid = 0;
|
||||
map->duration_notifyid = 0;
|
||||
|
||||
ccopy->priv->copied_children = g_list_prepend (ccopy->priv->copied_children,
|
||||
|
@ -532,7 +511,6 @@ ges_container_class_init (GESContainerClass * klass)
|
|||
|
||||
element_class->set_start = _set_start;
|
||||
element_class->set_duration = _set_duration;
|
||||
element_class->set_inpoint = _set_inpoint;
|
||||
element_class->lookup_child = _lookup_child;
|
||||
element_class->get_track_types = _get_track_types;
|
||||
element_class->paste = _paste;
|
||||
|
@ -625,34 +603,6 @@ _child_start_changed_cb (GESTimelineElement * child,
|
|||
container->children_control_mode = pmode;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_inpoint_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
|
||||
{
|
||||
ChildMapping *map;
|
||||
|
||||
GESContainerPrivate *priv = container->priv;
|
||||
GESTimelineElement *element = GES_TIMELINE_ELEMENT (container);
|
||||
|
||||
if (container->children_control_mode == GES_CHILDREN_IGNORE_NOTIFIES)
|
||||
return;
|
||||
|
||||
map = g_hash_table_lookup (priv->mappings, child);
|
||||
g_assert (map);
|
||||
|
||||
if (container->children_control_mode == GES_CHILDREN_UPDATE_OFFSETS
|
||||
|| ELEMENT_FLAG_IS_SET (child, GES_TIMELINE_ELEMENT_SET_SIMPLE)) {
|
||||
map->inpoint_offset = _INPOINT (container) - _INPOINT (child);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* We update all the children calling our set_inpoint method */
|
||||
container->initiated_move = child;
|
||||
_set_inpoint0 (element, _INPOINT (child) + map->inpoint_offset);
|
||||
container->initiated_move = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_child_duration_changed_cb (GESTimelineElement * child,
|
||||
GParamSpec * arg G_GNUC_UNUSED, GESContainer * container)
|
||||
|
@ -838,7 +788,6 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
|
|||
mapping->child = gst_object_ref (child);
|
||||
mapping->start_offset = _START (container) - _START (child);
|
||||
mapping->duration_offset = _DURATION (container) - _DURATION (child);
|
||||
mapping->inpoint_offset = _INPOINT (container) - _INPOINT (child);
|
||||
|
||||
g_hash_table_insert (priv->mappings, child, mapping);
|
||||
|
||||
|
@ -853,9 +802,6 @@ ges_container_add (GESContainer * container, GESTimelineElement * child)
|
|||
mapping->duration_notifyid =
|
||||
g_signal_connect (G_OBJECT (child), "notify::duration",
|
||||
G_CALLBACK (_child_duration_changed_cb), container);
|
||||
mapping->inpoint_notifyid =
|
||||
g_signal_connect (G_OBJECT (child), "notify::in-point",
|
||||
G_CALLBACK (_child_inpoint_changed_cb), container);
|
||||
|
||||
if (ges_timeline_element_set_parent (child, GES_TIMELINE_ELEMENT (container))
|
||||
== FALSE) {
|
||||
|
|
|
@ -303,6 +303,9 @@ _child_removed (GESContainer * container, GESTimelineElement * element)
|
|||
priv->video_transitions = g_slist_remove (priv->video_transitions, element);
|
||||
gst_object_unref (element);
|
||||
}
|
||||
/* call parent method */
|
||||
GES_CONTAINER_CLASS (ges_transition_clip_parent_class)->child_removed
|
||||
(container, element);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -322,6 +325,9 @@ _child_added (GESContainer * container, GESTimelineElement * element)
|
|||
ges_timeline_element_add_child_property (GES_TIMELINE_ELEMENT (container),
|
||||
g_object_class_find_property (eklass, "border"), G_OBJECT (element));
|
||||
}
|
||||
/* call parent method */
|
||||
GES_CONTAINER_CLASS (ges_transition_clip_parent_class)->child_added
|
||||
(container, element);
|
||||
}
|
||||
|
||||
static GESTrackElement *
|
||||
|
|
|
@ -302,8 +302,6 @@ extractable_set_asset (GESExtractable * self, GESAsset * asset)
|
|||
_set_duration0 (GES_TIMELINE_ELEMENT (uriclip),
|
||||
ges_uri_clip_asset_get_duration (uri_clip_asset));
|
||||
|
||||
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (uriclip),
|
||||
ges_uri_clip_asset_get_max_duration (uri_clip_asset));
|
||||
ges_uri_clip_set_is_image (uriclip,
|
||||
ges_uri_clip_asset_is_image (uri_clip_asset));
|
||||
|
||||
|
@ -421,6 +419,7 @@ uri_clip_set_max_duration (GESTimelineElement * element,
|
|||
{
|
||||
if (_DURATION (element) == GST_CLOCK_TIME_NONE || _DURATION (element) == 0)
|
||||
/* If we don't have a valid duration, use the max duration */
|
||||
/* FIXME: don't do this when we have time effects */
|
||||
_set_duration0 (element, maxduration - _INPOINT (element));
|
||||
|
||||
return
|
||||
|
@ -488,17 +487,28 @@ ges_uri_clip_create_track_elements (GESClip * clip, GESTrackType type)
|
|||
{
|
||||
GList *res = NULL;
|
||||
const GList *tmp, *stream_assets;
|
||||
GESAsset *asset = GES_TIMELINE_ELEMENT (clip)->asset;
|
||||
GESUriClipAsset *uri_asset;
|
||||
GstClockTime max_duration;
|
||||
|
||||
g_return_val_if_fail (GES_TIMELINE_ELEMENT (clip)->asset, NULL);
|
||||
g_return_val_if_fail (asset, NULL);
|
||||
|
||||
uri_asset = GES_URI_CLIP_ASSET (asset);
|
||||
|
||||
max_duration = ges_uri_clip_asset_get_max_duration (uri_asset);
|
||||
stream_assets = ges_uri_clip_asset_get_stream_assets (uri_asset);
|
||||
|
||||
stream_assets =
|
||||
ges_uri_clip_asset_get_stream_assets (GES_URI_CLIP_ASSET
|
||||
(GES_TIMELINE_ELEMENT (clip)->asset));
|
||||
for (tmp = stream_assets; tmp; tmp = tmp->next) {
|
||||
GESTrackElementAsset *asset = GES_TRACK_ELEMENT_ASSET (tmp->data);
|
||||
GESTrackElementAsset *element_asset = GES_TRACK_ELEMENT_ASSET (tmp->data);
|
||||
|
||||
if (ges_track_element_asset_get_track_type (asset) == type)
|
||||
res = g_list_prepend (res, ges_asset_extract (GES_ASSET (asset), NULL));
|
||||
if (ges_track_element_asset_get_track_type (element_asset) == type) {
|
||||
GESTrackElement *element =
|
||||
GES_TRACK_ELEMENT (ges_asset_extract (GES_ASSET (element_asset),
|
||||
NULL));
|
||||
ges_timeline_element_set_max_duration (GES_TIMELINE_ELEMENT (element),
|
||||
max_duration);
|
||||
res = g_list_prepend (res, element);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -792,19 +792,8 @@ _count_cb (GObject * obj, GParamSpec * pspec, gint * count)
|
|||
}
|
||||
|
||||
static void
|
||||
_test_children_time_setting_on_clip (GESClip * clip, GESTimelineElement * child)
|
||||
_test_children_time_setting_on_clip (GESClip * clip, GESTrackElement * child)
|
||||
{
|
||||
/* FIXME: Don't necessarily want to change the inpoint of all the
|
||||
* children if the clip inpoint changes. Really, we would only expect
|
||||
* the inpoint to change for the source elements within a clip.
|
||||
* Setting the inpoint of an operation may be irrelevant, and for
|
||||
* operations where it *is* relevant, we would ideally want it to be
|
||||
* independent from the source element's inpoint (unlike the start and
|
||||
* duration values).
|
||||
* However, this is the current behaviour, but if this is changed this
|
||||
* test should be changed to only check that source elements have
|
||||
* their inpoint changed, and operation elements have their inpoint
|
||||
* unchanged */
|
||||
_assert_children_time_setter (clip, child, "in-point",
|
||||
ges_timeline_element_set_inpoint, 11, 101);
|
||||
_assert_children_time_setter (clip, child, "in-point",
|
||||
|
@ -842,14 +831,16 @@ GST_START_TEST (test_children_time_setters)
|
|||
GESClip *clip = clips[i];
|
||||
GESContainer *group = GES_CONTAINER (ges_group_new ());
|
||||
GList *children;
|
||||
GESTimelineElement *child;
|
||||
GESTrackElement *child;
|
||||
/* no children */
|
||||
_test_children_time_setting_on_clip (clip, NULL);
|
||||
/* child in timeline */
|
||||
fail_unless (ges_layer_add_clip (layer, clip));
|
||||
children = GES_CONTAINER_CHILDREN (clip);
|
||||
fail_unless (children);
|
||||
child = GES_TIMELINE_ELEMENT (children->data);
|
||||
child = GES_TRACK_ELEMENT (children->data);
|
||||
/* make sure the child can have its in-point set */
|
||||
ges_track_element_set_has_internal_source (child, TRUE);
|
||||
_test_children_time_setting_on_clip (clip, child);
|
||||
/* clip in a group */
|
||||
ges_container_add (group, GES_TIMELINE_ELEMENT (clip));
|
||||
|
@ -861,7 +852,8 @@ GST_START_TEST (test_children_time_setters)
|
|||
fail_unless (ges_layer_remove_clip (layer, clip));
|
||||
children = GES_CONTAINER_CHILDREN (clip);
|
||||
fail_unless (children);
|
||||
child = GES_TIMELINE_ELEMENT (children->data);
|
||||
child = GES_TRACK_ELEMENT (children->data);
|
||||
ges_track_element_set_has_internal_source (child, TRUE);
|
||||
_test_children_time_setting_on_clip (clip, child);
|
||||
gst_object_unref (clip);
|
||||
}
|
||||
|
@ -926,6 +918,376 @@ GST_START_TEST (test_can_add_effect)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_children_inpoint)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
GESLayer *layer;
|
||||
GESTimelineElement *clip, *child0, *child1, *effect;
|
||||
GList *children;
|
||||
|
||||
ges_init ();
|
||||
|
||||
timeline = ges_timeline_new_audio_video ();
|
||||
fail_unless (timeline);
|
||||
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
|
||||
clip = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
||||
|
||||
fail_unless (ges_timeline_element_set_start (clip, 5));
|
||||
fail_unless (ges_timeline_element_set_duration (clip, 20));
|
||||
fail_unless (ges_timeline_element_set_inpoint (clip, 30));
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip)));
|
||||
|
||||
/* clip now has children */
|
||||
children = GES_CONTAINER_CHILDREN (clip);
|
||||
fail_unless (children);
|
||||
child0 = children->data;
|
||||
fail_unless (children->next);
|
||||
child1 = children->next->data;
|
||||
fail_unless (children->next->next == NULL);
|
||||
|
||||
fail_unless (ges_track_element_has_internal_source (GES_TRACK_ELEMENT
|
||||
(child0)));
|
||||
fail_unless (ges_track_element_has_internal_source (GES_TRACK_ELEMENT
|
||||
(child1)));
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 30, 20);
|
||||
|
||||
/* add a non-core element */
|
||||
effect = GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"));
|
||||
fail_if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT (effect)));
|
||||
/* allow us to choose our own in-point */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect), TRUE);
|
||||
fail_unless (ges_timeline_element_set_start (effect, 104));
|
||||
fail_unless (ges_timeline_element_set_duration (effect, 53));
|
||||
fail_unless (ges_timeline_element_set_inpoint (effect, 67));
|
||||
|
||||
/* adding the effect will change its start and duration, but not its
|
||||
* in-point */
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip), effect));
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
/* register child0 as having no internal source, which means its
|
||||
* in-point will be set to 0 */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (child0), FALSE);
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 0, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
/* should not be able to set the in-point to non-zero */
|
||||
fail_if (ges_timeline_element_set_inpoint (child0, 40));
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 0, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 30, 20);
|
||||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
/* when we set the in-point on a core-child with an internal source we
|
||||
* also set the clip and siblings with the same features */
|
||||
fail_unless (ges_timeline_element_set_inpoint (child1, 50));
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 50, 20);
|
||||
/* child with no internal source not changed */
|
||||
CHECK_OBJECT_PROPS (child0, 5, 0, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 50, 20);
|
||||
/* non-core no changed */
|
||||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
/* setting back to having internal source will put in sync with the
|
||||
* in-point of the clip */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (child0), TRUE);
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 50, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 50, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 50, 20);
|
||||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
fail_unless (ges_timeline_element_set_inpoint (child0, 40));
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (effect, 5, 67, 20);
|
||||
|
||||
/* setting in-point on effect shouldn't change any other siblings */
|
||||
fail_unless (ges_timeline_element_set_inpoint (effect, 77));
|
||||
|
||||
CHECK_OBJECT_PROPS (clip, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (child0, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (child1, 5, 40, 20);
|
||||
CHECK_OBJECT_PROPS (effect, 5, 77, 20);
|
||||
|
||||
gst_object_unref (timeline);
|
||||
|
||||
ges_deinit ();
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_children_max_duration)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
GESLayer *layer;
|
||||
gchar *uri;
|
||||
GESTimelineElement *clips[] = { NULL, NULL };
|
||||
GESTimelineElement *child0, *child1, *effect;
|
||||
guint i;
|
||||
GstClockTime max_duration, new_max;
|
||||
GList *children;
|
||||
|
||||
ges_init ();
|
||||
|
||||
timeline = ges_timeline_new_audio_video ();
|
||||
fail_unless (timeline);
|
||||
|
||||
layer = ges_timeline_append_layer (timeline);
|
||||
|
||||
uri = ges_test_get_audio_video_uri ();
|
||||
clips[0] = GES_TIMELINE_ELEMENT (ges_uri_clip_new (uri));
|
||||
fail_unless (clips[0]);
|
||||
g_free (uri);
|
||||
|
||||
clips[1] = GES_TIMELINE_ELEMENT (ges_test_clip_new ());
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (clips); i++) {
|
||||
GESTimelineElement *clip = clips[i];
|
||||
fail_unless (_MAX_DURATION (clip) == GST_CLOCK_TIME_NONE);
|
||||
|
||||
fail_unless (ges_timeline_element_set_start (clip, 5));
|
||||
fail_unless (ges_timeline_element_set_duration (clip, 20));
|
||||
fail_unless (ges_timeline_element_set_inpoint (clip, 30));
|
||||
/* can not set the max duration when we have no children */
|
||||
fail_if (ges_timeline_element_set_max_duration (clip, 150));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
|
||||
fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip)));
|
||||
|
||||
/* clip now has children */
|
||||
children = GES_CONTAINER_CHILDREN (clip);
|
||||
fail_unless (children);
|
||||
child0 = children->data;
|
||||
fail_unless (children->next);
|
||||
child1 = children->next->data;
|
||||
fail_unless (children->next->next == NULL);
|
||||
|
||||
fail_unless (ges_track_element_has_internal_source (GES_TRACK_ELEMENT
|
||||
(child0)));
|
||||
fail_unless (ges_track_element_has_internal_source (GES_TRACK_ELEMENT
|
||||
(child1)));
|
||||
|
||||
if (GES_IS_URI_CLIP (clip)) {
|
||||
/* uri clip children should be created with a max-duration set */
|
||||
/* each created child has the same max-duration */
|
||||
max_duration = _MAX_DURATION (child0);
|
||||
fail_unless (max_duration != GST_CLOCK_TIME_NONE);
|
||||
new_max = max_duration;
|
||||
} else {
|
||||
max_duration = GST_CLOCK_TIME_NONE;
|
||||
/* need a valid clock time that is not too large */
|
||||
new_max = 500;
|
||||
}
|
||||
|
||||
/* added children do not change the clip's max-duration, but will
|
||||
* instead set it to the minimum value of its children */
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, max_duration);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, max_duration);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, max_duration);
|
||||
|
||||
/* add a non-core element */
|
||||
effect = GES_TIMELINE_ELEMENT (ges_effect_new ("agingtv"));
|
||||
fail_if (ges_track_element_has_internal_source (GES_TRACK_ELEMENT
|
||||
(effect)));
|
||||
/* allow us to choose our own max-duration */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (effect),
|
||||
TRUE);
|
||||
fail_unless (ges_timeline_element_set_start (effect, 104));
|
||||
fail_unless (ges_timeline_element_set_duration (effect, 53));
|
||||
fail_unless (ges_timeline_element_set_max_duration (effect, 1));
|
||||
|
||||
/* adding the effect will change its start and duration, but not its
|
||||
* max-duration (or in-point) */
|
||||
fail_unless (ges_container_add (GES_CONTAINER (clip), effect));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, max_duration);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, max_duration);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, max_duration);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* when setting max_duration of core children, clip will take the
|
||||
* minimum value */
|
||||
fail_unless (ges_timeline_element_set_max_duration (child0, new_max - 1));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max - 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, max_duration);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (child1, new_max - 2));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max - 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (child0, new_max + 1));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* non-core has no effect */
|
||||
fail_unless (ges_timeline_element_set_max_duration (effect, new_max - 4));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, new_max - 4);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (effect, 1));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, new_max + 1);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, new_max - 2);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* setting on the clip will set all the core children to the same
|
||||
* value */
|
||||
fail_unless (ges_timeline_element_set_max_duration (clip, 180));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* register child0 as having no internal source, which means its
|
||||
* in-point will be set to 0 and max-duration set to
|
||||
* GST_CLOCK_TIME_NONE */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (child0),
|
||||
FALSE);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* should not be able to set the max-duration to a valid time */
|
||||
fail_if (ges_timeline_element_set_max_duration (child0, 40));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, 180);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* same with child1 */
|
||||
/* clock time of the clip should now be GST_CLOCK_TIME_NONE */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (child1),
|
||||
FALSE);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* should not be able to set the max of the clip to anything else
|
||||
* when it has no core children with an internal source */
|
||||
fail_if (ges_timeline_element_set_max_duration (clip, 150));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* setting back to having an internal source will not immediately
|
||||
* change the max-duration (unlike in-point) */
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (child0),
|
||||
TRUE);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* can now set the max-duration, which will effect the clip */
|
||||
fail_unless (ges_timeline_element_set_max_duration (child0, 140));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 0, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
ges_track_element_set_has_internal_source (GES_TRACK_ELEMENT (child1),
|
||||
TRUE);
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, GST_CLOCK_TIME_NONE);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
fail_unless (ges_timeline_element_set_max_duration (child1, 130));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* removing a child may change the max_duration of the clip */
|
||||
gst_object_ref (child0);
|
||||
gst_object_ref (child1);
|
||||
gst_object_ref (effect);
|
||||
|
||||
/* removing non-core does nothing */
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), effect));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* new minimum max-duration for the clip when we remove child1 */
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), child1));
|
||||
|
||||
CHECK_OBJECT_PROPS_MAX (clip, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child0, 5, 30, 20, 140);
|
||||
CHECK_OBJECT_PROPS_MAX (child1, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
/* with no core-children, the max-duration of the clip is set to
|
||||
* GST_CLOCK_TIME_NONE */
|
||||
fail_unless (ges_container_remove (GES_CONTAINER (clip), child0));
|
||||
|
||||
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 (child1, 5, 30, 20, 130);
|
||||
CHECK_OBJECT_PROPS_MAX (effect, 5, 0, 20, 1);
|
||||
|
||||
fail_unless (ges_layer_remove_clip (layer, GES_CLIP (clip)));
|
||||
|
||||
gst_object_unref (child0);
|
||||
gst_object_unref (child1);
|
||||
gst_object_unref (effect);
|
||||
}
|
||||
|
||||
gst_object_unref (timeline);
|
||||
|
||||
ges_deinit ();
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_children_properties_contain)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
|
@ -1444,6 +1806,8 @@ ges_suite (void)
|
|||
tcase_add_test (tc_chain, test_effects_priorities);
|
||||
tcase_add_test (tc_chain, test_children_time_setters);
|
||||
tcase_add_test (tc_chain, test_can_add_effect);
|
||||
tcase_add_test (tc_chain, test_children_inpoint);
|
||||
tcase_add_test (tc_chain, test_children_max_duration);
|
||||
tcase_add_test (tc_chain, test_children_properties_contain);
|
||||
tcase_add_test (tc_chain, test_children_properties_change);
|
||||
tcase_add_test (tc_chain, test_copy_paste_children_properties);
|
||||
|
|
|
@ -79,10 +79,11 @@ GST_START_TEST (test_overlay_properties)
|
|||
/* Check that trackelement has the same properties */
|
||||
assert_equals_uint64 (_START (trackelement), 42);
|
||||
assert_equals_uint64 (_DURATION (trackelement), 51);
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 12);
|
||||
/* in-point is 0 since it does not have has-internal-source */
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 0);
|
||||
|
||||
/* And let's also check that it propagated correctly to GNonLin */
|
||||
nle_object_check (ges_track_element_get_nleobject (trackelement), 42, 51, 12,
|
||||
nle_object_check (ges_track_element_get_nleobject (trackelement), 42, 51, 0,
|
||||
51, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, TRUE);
|
||||
|
||||
/* Change more properties, see if they propagate */
|
||||
|
@ -94,11 +95,11 @@ GST_START_TEST (test_overlay_properties)
|
|||
assert_equals_uint64 (_INPOINT (clip), 120);
|
||||
assert_equals_uint64 (_START (trackelement), 420);
|
||||
assert_equals_uint64 (_DURATION (trackelement), 510);
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 120);
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 0);
|
||||
|
||||
/* And let's also check that it propagated correctly to GNonLin */
|
||||
nle_object_check (ges_track_element_get_nleobject (trackelement), 420, 510,
|
||||
120, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT + 0, TRUE);
|
||||
0, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT + 0, TRUE);
|
||||
|
||||
ges_container_remove (GES_CONTAINER (clip),
|
||||
GES_TIMELINE_ELEMENT (trackelement));
|
||||
|
|
|
@ -88,6 +88,7 @@ G_STMT_START { \
|
|||
#define _START(obj) GES_TIMELINE_ELEMENT_START (obj)
|
||||
#define _DURATION(obj) GES_TIMELINE_ELEMENT_DURATION (obj)
|
||||
#define _INPOINT(obj) GES_TIMELINE_ELEMENT_INPOINT (obj)
|
||||
#define _MAX_DURATION(obj) GES_TIMELINE_ELEMENT_MAX_DURATION (obj)
|
||||
#define _PRIORITY(obj) GES_TIMELINE_ELEMENT_PRIORITY (obj)
|
||||
#ifndef _END
|
||||
#define _END(obj) (_START(obj) + _DURATION(obj))
|
||||
|
@ -99,6 +100,14 @@ G_STMT_START { \
|
|||
fail_unless (_DURATION (obj) == duration, "%s duration is %" GST_TIME_FORMAT " != %" GST_TIME_FORMAT, GES_TIMELINE_ELEMENT_NAME(obj), GST_TIME_ARGS (_DURATION(obj)), GST_TIME_ARGS (duration));\
|
||||
}
|
||||
|
||||
#define CHECK_OBJECT_PROPS_MAX(obj, start, inpoint, duration, max_duration) {\
|
||||
CHECK_OBJECT_PROPS (obj, start, inpoint, duration); \
|
||||
fail_unless (_MAX_DURATION(obj) == max_duration, "%s max-duration is " \
|
||||
"%" GST_TIME_FORMAT " != %" GST_TIME_FORMAT, \
|
||||
GES_TIMELINE_ELEMENT_NAME(obj), \
|
||||
GST_TIME_ARGS (_MAX_DURATION(obj)), GST_TIME_ARGS (max_duration)); \
|
||||
}
|
||||
|
||||
/* assert that the time property (start, duration or in-point) is the
|
||||
* same as @cmp for the clip and all its children */
|
||||
#define assert_clip_children_time_val(clip, property, cmp) \
|
||||
|
@ -106,6 +115,7 @@ G_STMT_START { \
|
|||
GList *tmp; \
|
||||
GstClockTime read_val; \
|
||||
gchar *name = GES_TIMELINE_ELEMENT (clip)->name; \
|
||||
gboolean is_inpoint = (g_strcmp0 (property, "in-point") == 0); \
|
||||
g_object_get (clip, property, &read_val, NULL); \
|
||||
fail_unless (read_val == cmp, "The %s property for clip %s is %" \
|
||||
GST_TIME_FORMAT ", rather than the expected value of %" \
|
||||
|
@ -115,10 +125,16 @@ G_STMT_START { \
|
|||
tmp = tmp->next) { \
|
||||
GESTimelineElement *child = tmp->data; \
|
||||
g_object_get (child, property, &read_val, NULL); \
|
||||
fail_unless (read_val == cmp, "The %s property for the child %s " \
|
||||
"of clip %s is %" GST_TIME_FORMAT ", rather than the expected " \
|
||||
"value of %" GST_TIME_FORMAT, property, child->name, name, \
|
||||
GST_TIME_ARGS (read_val), GST_TIME_ARGS (cmp)); \
|
||||
if (!is_inpoint || ges_track_element_has_internal_source ( \
|
||||
GES_TRACK_ELEMENT (child))) \
|
||||
fail_unless (read_val == cmp, "The %s property for the child %s " \
|
||||
"of clip %s is %" GST_TIME_FORMAT ", rather than the expected" \
|
||||
" value of %" GST_TIME_FORMAT, property, child->name, name, \
|
||||
GST_TIME_ARGS (read_val), GST_TIME_ARGS (cmp)); \
|
||||
else \
|
||||
fail_unless (read_val == 0, "The %s property for the child %s " \
|
||||
"of clip %s is %" GST_TIME_FORMAT ", rather than 0", \
|
||||
property, child->name, name, GST_TIME_ARGS (read_val)); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,10 @@ GST_START_TEST (test_title_source_properties)
|
|||
"in-point", (guint64) 12, NULL);
|
||||
assert_equals_uint64 (_START (clip), 42);
|
||||
assert_equals_uint64 (_DURATION (clip), 51);
|
||||
assert_equals_uint64 (_INPOINT (clip), 0);
|
||||
/* the clip can have a non-zero in-point, but this won't affect any
|
||||
* of the core children because they have their has-internal-source set
|
||||
* to FALSE */
|
||||
assert_equals_uint64 (_INPOINT (clip), 12);
|
||||
|
||||
ges_layer_add_clip (layer, GES_CLIP (clip));
|
||||
ges_timeline_commit (timeline);
|
||||
|
@ -91,7 +94,7 @@ GST_START_TEST (test_title_source_properties)
|
|||
ges_timeline_commit (timeline);
|
||||
assert_equals_uint64 (_START (clip), 420);
|
||||
assert_equals_uint64 (_DURATION (clip), 510);
|
||||
assert_equals_uint64 (_INPOINT (clip), 0);
|
||||
assert_equals_uint64 (_INPOINT (clip), 120);
|
||||
assert_equals_uint64 (_START (trackelement), 420);
|
||||
assert_equals_uint64 (_DURATION (trackelement), 510);
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 0);
|
||||
|
|
|
@ -109,10 +109,11 @@ GST_START_TEST (test_transition_properties)
|
|||
/* Check that trackelement has the same properties */
|
||||
assert_equals_uint64 (_START (trackelement), 42);
|
||||
assert_equals_uint64 (_DURATION (trackelement), 51);
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 12);
|
||||
/* in-point is 0 since it does not have has-internal-source */
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 0);
|
||||
|
||||
/* And let's also check that it propagated correctly to GNonLin */
|
||||
nle_object_check (ges_track_element_get_nleobject (trackelement), 42, 51, 12,
|
||||
nle_object_check (ges_track_element_get_nleobject (trackelement), 42, 51, 0,
|
||||
51, MIN_NLE_PRIO, TRUE);
|
||||
|
||||
/* Change more properties, see if they propagate */
|
||||
|
@ -124,11 +125,11 @@ GST_START_TEST (test_transition_properties)
|
|||
assert_equals_uint64 (_INPOINT (clip), 120);
|
||||
assert_equals_uint64 (_START (trackelement), 420);
|
||||
assert_equals_uint64 (_DURATION (trackelement), 510);
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 120);
|
||||
assert_equals_uint64 (_INPOINT (trackelement), 0);
|
||||
|
||||
/* And let's also check that it propagated correctly to GNonLin */
|
||||
nle_object_check (ges_track_element_get_nleobject (trackelement), 420, 510,
|
||||
120, 510, MIN_NLE_PRIO + 0, TRUE);
|
||||
0, 510, MIN_NLE_PRIO + 0, TRUE);
|
||||
|
||||
/* test changing vtype */
|
||||
GST_DEBUG ("Setting to crossfade");
|
||||
|
|
Loading…
Reference in a new issue