ges-launcher: add option to forward tags
authorMathieu Duponchelle <mathieu@centricular.com>
Tue, 10 Aug 2021 21:54:47 +0000 (23:54 +0200)
committerMathieu Duponchelle <mathieu@centricular.com>
Thu, 19 Aug 2021 22:11:45 +0000 (00:11 +0200)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-editing-services/-/merge_requests/265>

docs/gst_plugins_cache.json
plugins/nle/nlecomposition.c
tools/ges-launcher.c
tools/utils.h

index dc9b8d3..b318645 100644 (file)
                     }
                 },
                 "properties": {
+                    "drop-tags": {
+                        "blurb": "Whether the composition should drop tags from its children",
+                        "conditionally-available": false,
+                        "construct": false,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "true",
+                        "mutable": "playing",
+                        "readable": true,
+                        "type": "gboolean",
+                        "writable": true
+                    },
                     "id": {
                         "blurb": "The stream-id of the composition",
                         "conditionally-available": false,
index 2609540..97fa1b9 100644 (file)
@@ -50,9 +50,12 @@ enum
 {
   PROP_0,
   PROP_ID,
+  PROP_DROP_TAGS,
   PROP_LAST,
 };
 
+#define DEFAULT_DROP_TAGS TRUE
+
 /* Properties from NleObject */
 enum
 {
@@ -204,7 +207,9 @@ struct _NleCompositionPrivate
 
   guint seek_seqnum;
 
+  /* Both protected with object lock */
   gchar *id;
+  gboolean drop_tags;
 };
 
 #define ACTION_CALLBACK(__action) (((GCClosure*) (__action))->callback)
@@ -1041,6 +1046,11 @@ nle_composition_get_property (GObject * object, guint property_id,
       g_value_set_string (value, comp->priv->id);
       GST_OBJECT_UNLOCK (comp);
       break;
+    case PROP_DROP_TAGS:
+      GST_OBJECT_LOCK (comp);
+      g_value_set_boolean (value, comp->priv->drop_tags);
+      GST_OBJECT_UNLOCK (comp);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (comp, property_id, pspec);
   }
@@ -1059,6 +1069,11 @@ nle_composition_set_property (GObject * object, guint property_id,
       comp->priv->id = g_value_dup_string (value);
       GST_OBJECT_UNLOCK (comp);
       break;
+    case PROP_DROP_TAGS:
+      GST_OBJECT_LOCK (comp);
+      comp->priv->drop_tags = g_value_get_boolean (value);
+      GST_OBJECT_UNLOCK (comp);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (comp, property_id, pspec);
   }
@@ -1114,6 +1129,20 @@ nle_composition_class_init (NleCompositionClass * klass)
       g_param_spec_string ("id", "Id", "The stream-id of the composition",
       NULL,
       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_DOC_SHOW_DEFAULT);
+
+  /**
+   * NleComposition:drop-tags:
+   *
+   * Whether the composition should drop tags from its children
+   *
+   * Since: 1.20
+   */
+  properties[PROP_DROP_TAGS] =
+      g_param_spec_boolean ("drop-tags", "Drop tags",
+      "Whether the composition should drop tags from its children",
+      DEFAULT_DROP_TAGS,
+      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_DOC_SHOW_DEFAULT |
+      GST_PARAM_MUTABLE_PLAYING);
   g_object_class_install_properties (gobject_class, PROP_LAST, properties);
 
   _signals[COMMITED_SIGNAL] =
@@ -1168,6 +1197,7 @@ nle_composition_init (NleComposition * comp)
 
   priv->id = gst_pad_create_stream_id (NLE_OBJECT_SRC (comp),
       GST_ELEMENT (comp), NULL);
+  priv->drop_tags = DEFAULT_DROP_TAGS;
   priv->nle_event_pad_func = GST_PAD_EVENTFUNC (NLE_OBJECT_SRC (comp));
   gst_pad_set_event_function (NLE_OBJECT_SRC (comp),
       GST_DEBUG_FUNCPTR (nle_composition_event_handler));
@@ -1490,7 +1520,10 @@ ghost_event_probe_handler (GstPad * ghostpad G_GNUC_UNUSED,
       break;
     case GST_EVENT_TAG:
       GST_DEBUG_OBJECT (comp, "Dropping tag: %" GST_PTR_FORMAT, info->data);
-      retval = GST_PAD_PROBE_DROP;
+      GST_OBJECT_LOCK (comp);
+      if (comp->priv->drop_tags)
+        retval = GST_PAD_PROBE_DROP;
+      GST_OBJECT_UNLOCK (comp);
       break;
     case GST_EVENT_EOS:
     {
index f6fde10..aa0b711 100644 (file)
@@ -357,6 +357,39 @@ _set_restriction_caps (GESTimeline * timeline, GESLauncherParsedOptions * opts)
 }
 
 static void
+_set_track_forward_tags (const GValue * item, gpointer unused)
+{
+  GstElement *comp = g_value_get_object (item);
+
+  g_object_set (comp, "drop-tags", FALSE, NULL);
+}
+
+static void
+_set_tracks_forward_tags (GESTimeline * timeline,
+    GESLauncherParsedOptions * opts)
+{
+  GList *tmp, *tracks;
+
+  if (!opts->forward_tags)
+    return;
+
+  tracks = ges_timeline_get_tracks (timeline);
+
+  for (tmp = tracks; tmp; tmp = tmp->next) {
+    GstIterator *it =
+        gst_bin_iterate_all_by_element_factory_name (GST_BIN (tmp->data),
+        "nlecomposition");
+
+    gst_iterator_foreach (it,
+        (GstIteratorForeachFunction) _set_track_forward_tags, NULL);
+    gst_iterator_free (it);
+  }
+
+  g_list_free_full (tracks, gst_object_unref);
+
+}
+
+static void
 _check_has_audio_video (GESLauncher * self, gint * n_audio, gint * n_video)
 {
   GList *tmp, *tracks = ges_timeline_get_tracks (self->priv->timeline);
@@ -547,8 +580,8 @@ _set_rendering_details (GESLauncher * self)
   }
 
   proj =
-      GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE (self->
-              priv->timeline)));
+      GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE (self->priv->
+              timeline)));
 
   /* Setup profile/encoding if needed */
   if (opts->outputuri) {
@@ -748,6 +781,8 @@ retry:
     _set_restriction_caps (timeline, opts);
   }
 
+  _set_tracks_forward_tags (timeline, opts);
+
   return TRUE;
 }
 
@@ -987,8 +1022,8 @@ _save_timeline (GESLauncher * self)
   if (opts->embed_nesteds) {
     GList *tmp, *assets;
     GESProject *proj =
-        GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE (self->priv->
-                timeline)));
+        GES_PROJECT (ges_extractable_get_asset (GES_EXTRACTABLE (self->
+                priv->timeline)));
 
     assets = ges_project_list_assets (proj, GES_TYPE_URI_CLIP);
     for (tmp = assets; tmp; tmp = tmp->next) {
@@ -1239,6 +1274,9 @@ ges_launcher_get_rendering_option_group (GESLauncherParsedOptions * opts)
           "of the rendered output. This will have no effect if no outputuri "
           "has been specified.",
         "<clip-name>"},
+    {"forward-tags", 0, 0, G_OPTION_ARG_NONE, &opts->forward_tags,
+          "Forward tags from input files to the output",
+        NULL},
     {"smart-rendering", 0, 0, G_OPTION_ARG_NONE, &opts->smartrender,
           "Avoid reencoding when rendering. This option implies --disable-mixing.",
         NULL},
index b11b53e..c067424 100644 (file)
@@ -51,6 +51,7 @@ typedef struct
 
   gboolean ignore_eos;
   gboolean interactive;
+  gboolean forward_tags;
 } GESLauncherParsedOptions;
 
 gchar * sanitize_timeline_description (gchar **args, GESLauncherParsedOptions *opts);