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;
+}
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)
{
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;
}