gesdemux: Add a testsrc to timelines if parent nleobject duration is too long
authorThibault Saunier <tsaunier@igalia.com>
Wed, 10 Jul 2019 23:36:21 +0000 (19:36 -0400)
committerThibault Saunier <tsaunier@igalia.com>
Fri, 26 Jul 2019 17:48:51 +0000 (13:48 -0400)
plugins/ges/gesdemux.c

index 1fa21282199c8b59845e39a05d8239ea2bc2a343..00d94a4d31b8a25b0a343d60ba0c05c5d030362b 100644 (file)
@@ -253,6 +253,75 @@ ges_demux_set_srcpad_probe (GstElement * element, GstPad * pad,
   return TRUE;
 }
 
+static void
+ges_demux_adapt_timeline_duration (GESDemux * self, GESTimeline * timeline)
+{
+  GType nleobject_type = g_type_from_name ("NleObject");
+  GstObject *parent, *tmpparent;
+
+  parent = gst_object_get_parent (GST_OBJECT (self));
+  while (parent) {
+    if (g_type_is_a (G_OBJECT_TYPE (parent), nleobject_type)) {
+      GstClockTime duration, inpoint, timeline_duration;
+
+      g_object_get (parent, "duration", &duration, "inpoint", &inpoint, NULL);
+      g_object_get (timeline, "duration", &timeline_duration, NULL);
+
+      if (inpoint + duration > timeline_duration) {
+        GESLayer *layer = ges_timeline_get_layer (timeline, 0);
+
+        if (layer) {
+          GESClip *clip = GES_CLIP (ges_test_clip_new ());
+          GList *tmp, *tracks = ges_timeline_get_tracks (timeline);
+
+          g_object_set (clip, "start", timeline_duration, "duration",
+              inpoint + duration, "vpattern", GES_VIDEO_TEST_PATTERN_SMPTE75,
+              NULL);
+          ges_layer_add_clip (layer, clip);
+          for (tmp = tracks; tmp; tmp = tmp->next) {
+            if (GES_IS_VIDEO_TRACK (tmp->data)) {
+              GESEffect *text;
+              GstCaps *caps;
+              gchar *effect_str_full = NULL;
+              const gchar *effect_str =
+                  "textoverlay text=\"Nested timeline too short, please FIX!\" halignment=center valignment=center";
+
+              g_object_get (tmp->data, "restriction-caps", &caps, NULL);
+              if (caps) {
+                gchar *caps_str = gst_caps_to_string (caps);
+                effect_str = effect_str_full =
+                    g_strdup_printf ("capsfilter caps=\"%s\" ! %s", caps_str,
+                    effect_str);
+                g_free (caps_str);
+                gst_caps_unref (caps);
+              }
+              text = ges_effect_new (effect_str);
+              g_free (effect_str_full);
+
+              ges_container_add (GES_CONTAINER (clip),
+                  GES_TIMELINE_ELEMENT (text));
+            }
+
+          }
+          g_list_free_full (tracks, gst_object_unref);
+          GST_INFO_OBJECT (timeline,
+              "Added test clip with duration: %" GST_TIME_FORMAT " - %"
+              GST_TIME_FORMAT " to match parent nleobject duration",
+              GST_TIME_ARGS (timeline_duration),
+              GST_TIME_ARGS (inpoint + duration - timeline_duration));
+        }
+      }
+      gst_object_unref (parent);
+
+      return;
+    }
+
+    tmpparent = parent;
+    parent = gst_object_get_parent (GST_OBJECT (parent));
+    gst_object_unref (tmpparent);
+  }
+}
+
 static gboolean
 ges_demux_create_timeline (GESDemux * self, gchar * uri, GError ** error)
 {
@@ -281,6 +350,7 @@ ges_demux_create_timeline (GESDemux * self, gchar * uri, GError ** error)
 
   g_main_loop_run (data.ml);
   g_main_loop_unref (data.ml);
+  ges_demux_adapt_timeline_duration (self, data.timeline);
 
   query = gst_query_new_uri ();
   if (gst_pad_peer_query (self->sinkpad, query)) {