mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
layer: Add ability to get clips in a given interval
Reviewed-by: Alex Băluț <<alexandru.balut@gmail.com>> Reviewed-by: Thibault Saunier <thibault.saunier@collabora.com> Differential Revision: https://phabricator.freedesktop.org/D1689
This commit is contained in:
parent
dd8dacdfde
commit
6dc0cd0dec
3 changed files with 147 additions and 0 deletions
|
@ -734,3 +734,40 @@ ges_layer_set_timeline (GESLayer * layer, GESTimeline * timeline)
|
|||
|
||||
layer->timeline = timeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* ges_layer_get_clips_in_interval:
|
||||
* @layer: a #GESLayer
|
||||
* @start: start of the interval
|
||||
* @end: end of the interval
|
||||
*
|
||||
* Gets the clips which appear between @start and @end on @layer.
|
||||
*
|
||||
* Returns: (transfer full) (element-type GESClip): a #GList of clips intersecting [@start, @end) interval on @layer.
|
||||
*/
|
||||
GList *
|
||||
ges_layer_get_clips_in_interval (GESLayer * layer, GstClockTime start,
|
||||
GstClockTime end)
|
||||
{
|
||||
GList *tmp;
|
||||
GList *intersecting_clips = NULL;
|
||||
GstClockTime clip_start, clip_end;
|
||||
gboolean clip_intersects;
|
||||
for (tmp = layer->priv->clips_start; tmp; tmp = tmp->next) {
|
||||
clip_intersects = FALSE;
|
||||
clip_start = ges_timeline_element_get_start (tmp->data);
|
||||
clip_end = clip_start + ges_timeline_element_get_duration (tmp->data);
|
||||
if (start <= clip_start && clip_start < end)
|
||||
clip_intersects = TRUE;
|
||||
else if (start < clip_end && clip_end <= end)
|
||||
clip_intersects = TRUE;
|
||||
else if (clip_start < start && clip_end > end)
|
||||
clip_intersects = TRUE;
|
||||
|
||||
if (clip_intersects)
|
||||
intersecting_clips =
|
||||
g_list_insert_sorted (intersecting_clips, tmp->data,
|
||||
(GCompareFunc) element_start_compare);
|
||||
}
|
||||
return intersecting_clips;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,8 @@ void ges_layer_set_priority (GESLayer * layer,
|
|||
|
||||
gboolean ges_layer_is_empty (GESLayer * layer);
|
||||
|
||||
GList* ges_layer_get_clips_in_interval (GESLayer * layer, GstClockTime start, GstClockTime end);
|
||||
|
||||
guint ges_layer_get_priority (GESLayer * layer);
|
||||
|
||||
gboolean ges_layer_get_auto_transition (GESLayer * layer);
|
||||
|
|
|
@ -1753,6 +1753,113 @@ GST_START_TEST (test_layer_meta_foreach)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_layer_get_clips_in_interval)
|
||||
{
|
||||
GESTimeline *timeline;
|
||||
GESLayer *layer;
|
||||
GESClip *clip, *clip2, *clip3;
|
||||
GList *objects, *current;
|
||||
|
||||
ges_init ();
|
||||
|
||||
timeline = ges_timeline_new_audio_video ();
|
||||
layer = ges_layer_new ();
|
||||
ges_timeline_add_layer (timeline, layer);
|
||||
|
||||
clip = (GESClip *) ges_test_clip_new ();
|
||||
fail_unless (clip != NULL);
|
||||
g_object_set (clip, "start", 10, "duration", 30, NULL);
|
||||
assert_equals_uint64 (_START (clip), 10);
|
||||
assert_equals_uint64 (_DURATION (clip), 30);
|
||||
|
||||
ges_layer_add_clip (layer, GES_CLIP (clip));
|
||||
|
||||
/* Clip's start lies between the interval */
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 0, 30);
|
||||
assert_equals_int (g_list_length (objects), 1);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 0, 11);
|
||||
assert_equals_int (g_list_length (objects), 1);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
/* Clip's end lies between the interval */
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 30, 50);
|
||||
assert_equals_int (g_list_length (objects), 1);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 39, 50);
|
||||
assert_equals_int (g_list_length (objects), 1);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
/* Clip exactly overlaps the interval */
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 10, 40);
|
||||
assert_equals_int (g_list_length (objects), 1);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
/* Clip completely inside the interval */
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 0, 50);
|
||||
assert_equals_int (g_list_length (objects), 1);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
/* Interval completely inside the clip duration */
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 20, 30);
|
||||
assert_equals_int (g_list_length (objects), 1);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
|
||||
/* No intersecting clip */
|
||||
objects = ges_layer_get_clips_in_interval (layer, 0, 10);
|
||||
assert_equals_int (g_list_length (objects), 0);
|
||||
|
||||
objects = ges_layer_get_clips_in_interval (layer, 40, 50);
|
||||
assert_equals_int (g_list_length (objects), 0);
|
||||
|
||||
/* Multiple intersecting clips */
|
||||
clip2 = (GESClip *) ges_test_clip_new ();
|
||||
fail_unless (clip2 != NULL);
|
||||
g_object_set (clip2, "start", 50, "duration", 10, NULL);
|
||||
assert_equals_uint64 (_START (clip2), 50);
|
||||
assert_equals_uint64 (_DURATION (clip2), 10);
|
||||
|
||||
ges_layer_add_clip (layer, GES_CLIP (clip2));
|
||||
|
||||
clip3 = (GESClip *) ges_test_clip_new ();
|
||||
fail_unless (clip3 != NULL);
|
||||
g_object_set (clip3, "start", 0, "duration", 5, NULL);
|
||||
assert_equals_uint64 (_START (clip3), 0);
|
||||
assert_equals_uint64 (_DURATION (clip3), 5);
|
||||
|
||||
ges_layer_add_clip (layer, GES_CLIP (clip3));
|
||||
|
||||
/**
|
||||
* Our timeline:
|
||||
* -------------
|
||||
*
|
||||
* |-------- 0--------------- 0--------- |
|
||||
* layer: | clip3 | | clip | | clip2 | |
|
||||
* |-------05 10-------------40 50--------60 |
|
||||
* |--------------------------------------------------|
|
||||
*
|
||||
*/
|
||||
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 4, 52);
|
||||
assert_equals_int (g_list_length (objects), 3);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip3));
|
||||
current = current->next;
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
current = current->next;
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip2));
|
||||
|
||||
current = objects = ges_layer_get_clips_in_interval (layer, 39, 65);
|
||||
assert_equals_int (g_list_length (objects), 2);
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip));
|
||||
current = current->next;
|
||||
fail_unless (current->data == GES_TIMELINE_ELEMENT (clip2));
|
||||
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
ges_suite (void)
|
||||
{
|
||||
|
@ -1784,6 +1891,7 @@ ges_suite (void)
|
|||
tcase_add_test (tc_chain, test_layer_meta_value);
|
||||
tcase_add_test (tc_chain, test_layer_meta_register);
|
||||
tcase_add_test (tc_chain, test_layer_meta_foreach);
|
||||
tcase_add_test (tc_chain, test_layer_get_clips_in_interval);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue