layer: Add ability to get clips in a given interval
authorsuhas2go <suhas2go@gmail.com>
Fri, 17 Mar 2017 19:02:56 +0000 (19:02 +0000)
committerThibault Saunier <thibault.saunier@osg.samsung.com>
Tue, 28 Mar 2017 14:29:37 +0000 (11:29 -0300)
Reviewed-by: Alex Băluț <<alexandru.balut@gmail.com>>
Reviewed-by: Thibault Saunier <thibault.saunier@collabora.com>
Differential Revision: https://phabricator.freedesktop.org/D1689

ges/ges-layer.c
ges/ges-layer.h
tests/check/ges/layer.c

index a66759f..ce94993 100644 (file)
@@ -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;
+}
index 4c4ef3b..fa33ca4 100644 (file)
@@ -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);
index dad061f..b293f82 100644 (file)
@@ -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;
 }