timeline: Create stable stream IDs
authorThibault Saunier <tsaunier@igalia.com>
Thu, 6 Jun 2019 21:21:01 +0000 (17:21 -0400)
committerThibault Saunier <tsaunier@igalia.com>
Fri, 5 Jul 2019 21:52:55 +0000 (17:52 -0400)
ges/ges-timeline.c
ges/ges-track.c
plugins/nle/nlecomposition.c

index 9d2f8a7..ef437bf 100644 (file)
@@ -317,8 +317,6 @@ ges_timeline_finalize (GObject * object)
   G_OBJECT_CLASS (ges_timeline_parent_class)->finalize (object);
 }
 
-
-
 static void
 ges_timeline_handle_message (GstBin * bin, GstMessage * message)
 {
@@ -1434,9 +1432,12 @@ track_element_removed_cb (GESTrack * track,
 
 static GstPadProbeReturn
 _pad_probe_cb (GstPad * mixer_pad, GstPadProbeInfo * info,
-    GESTimeline * timeline)
+    TrackPrivate * tr_priv)
 {
   GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+  GESTimeline *timeline = tr_priv->timeline;
+  gchar *stream_id;
+
   if (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START) {
     LOCK_DYN (timeline);
     if (timeline->priv->stream_start_group_id == -1) {
@@ -1445,7 +1446,9 @@ _pad_probe_cb (GstPad * mixer_pad, GstPadProbeInfo * info,
         timeline->priv->stream_start_group_id = gst_util_group_id_next ();
     }
 
-    info->data = gst_event_make_writable (event);
+    gst_event_unref (event);
+    g_object_get (tr_priv->track, "id", &stream_id, NULL);
+    info->data = gst_event_new_stream_start (stream_id);
     gst_event_set_group_id (GST_PAD_PROBE_INFO_EVENT (info),
         timeline->priv->stream_start_group_id);
     UNLOCK_DYN (timeline);
@@ -1500,7 +1503,7 @@ _ghost_track_srcpad (TrackPrivate * tr_priv)
 
   tr_priv->probe_id = gst_pad_add_probe (pad,
       GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-      (GstPadProbeCallback) _pad_probe_cb, tr_priv->timeline, NULL);
+      (GstPadProbeCallback) _pad_probe_cb, tr_priv, NULL);
 
   UNLOCK_DYN (tr_priv->timeline);
 }
index 3cb3859..789b420 100644 (file)
@@ -94,6 +94,7 @@ enum
   ARG_TYPE,
   ARG_DURATION,
   ARG_MIXING,
+  ARG_ID,
   ARG_LAST,
   TRACK_ELEMENT_ADDED,
   TRACK_ELEMENT_REMOVED,
@@ -424,6 +425,9 @@ ges_track_get_property (GObject * object, guint property_id,
     case ARG_MIXING:
       g_value_set_boolean (value, track->priv->mixing);
       break;
+    case ARG_ID:
+      g_object_get_property (G_OBJECT (track->priv->composition), "id", value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
   }
@@ -448,6 +452,9 @@ ges_track_set_property (GObject * object, guint property_id,
     case ARG_MIXING:
       ges_track_set_mixing (track, g_value_get_boolean (value));
       break;
+    case ARG_ID:
+      g_object_set_property (G_OBJECT (track->priv->composition), "id", value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
   }
@@ -638,6 +645,11 @@ ges_track_class_init (GESTrackClass * klass)
   g_object_class_install_property (object_class, ARG_MIXING,
       properties[ARG_MIXING]);
 
+  properties[ARG_ID] =
+      g_param_spec_string ("id", "Id", "The stream-id of the composition",
+      NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, ARG_ID, properties[ARG_ID]);
+
   gst_element_class_add_static_pad_template (gstelement_class,
       &ges_track_src_pad_template);
 
index 1d17c03..1e471b5 100644 (file)
@@ -49,7 +49,7 @@ GST_DEBUG_CATEGORY_STATIC (nlecomposition_debug);
 enum
 {
   PROP_0,
-  PROP_DEACTIVATED_ELEMENTS_STATE,
+  PROP_ID,
   PROP_LAST,
 };
 
@@ -201,6 +201,8 @@ struct _NleCompositionPrivate
   NleUpdateStackReason updating_reason;
 
   guint seek_seqnum;
+
+  gchar *id;
 };
 
 #define ACTION_CALLBACK(__action) (((GCClosure*) (__action))->callback)
@@ -208,6 +210,7 @@ struct _NleCompositionPrivate
 static guint _signals[LAST_SIGNAL] = { 0 };
 
 static GParamSpec *nleobject_properties[NLEOBJECT_PROP_LAST];
+static GParamSpec *properties[PROP_LAST];
 
 G_DEFINE_TYPE_WITH_CODE (NleComposition, nle_composition, NLE_TYPE_OBJECT,
     G_ADD_PRIVATE (NleComposition)
@@ -971,6 +974,41 @@ drop:
 }
 
 static void
+nle_composition_get_property (GObject * object, guint property_id,
+    GValue * value, GParamSpec * pspec)
+{
+  NleComposition *comp = (NleComposition *) object;
+
+  switch (property_id) {
+    case PROP_ID:
+      GST_OBJECT_LOCK (comp);
+      g_value_set_string (value, comp->priv->id);
+      GST_OBJECT_UNLOCK (comp);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (comp, property_id, pspec);
+  }
+}
+
+static void
+nle_composition_set_property (GObject * object, guint property_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  NleComposition *comp = (NleComposition *) object;
+
+  switch (property_id) {
+    case PROP_ID:
+      GST_OBJECT_LOCK (comp);
+      g_free (comp->priv->id);
+      comp->priv->id = g_value_dup_string (value);
+      GST_OBJECT_UNLOCK (comp);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (comp, property_id, pspec);
+  }
+}
+
+static void
 nle_composition_class_init (NleCompositionClass * klass)
 {
   GObjectClass *gobject_class;
@@ -991,6 +1029,10 @@ nle_composition_class_init (NleCompositionClass * klass)
 
   gobject_class->dispose = GST_DEBUG_FUNCPTR (nle_composition_dispose);
   gobject_class->finalize = GST_DEBUG_FUNCPTR (nle_composition_finalize);
+  gobject_class->get_property =
+      GST_DEBUG_FUNCPTR (nle_composition_get_property);
+  gobject_class->set_property =
+      GST_DEBUG_FUNCPTR (nle_composition_set_property);
 
   gstelement_class->change_state = nle_composition_change_state;
 
@@ -1012,6 +1054,11 @@ nle_composition_class_init (NleCompositionClass * klass)
   nleobject_properties[NLEOBJECT_PROP_DURATION] =
       g_object_class_find_property (gobject_class, "duration");
 
+  properties[PROP_ID] =
+      g_param_spec_string ("id", "Id", "The stream-id of the composition",
+      NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_properties (gobject_class, PROP_LAST, properties);
+
   _signals[COMMITED_SIGNAL] =
       g_signal_new ("commited", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
       0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
@@ -1063,6 +1110,8 @@ nle_composition_init (NleComposition * comp)
 
   nle_composition_reset (comp);
 
+  priv->id = gst_pad_create_stream_id (NLE_OBJECT_SRC (comp),
+      GST_ELEMENT (comp), NULL);
   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));
@@ -1141,6 +1190,7 @@ nle_composition_finalize (GObject * object)
 
   g_mutex_clear (&priv->actions_lock);
   g_cond_clear (&priv->actions_cond);
+  g_free (priv->id);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -1273,8 +1323,10 @@ ghost_event_probe_handler (GstPad * ghostpad G_GNUC_UNUSED,
     case GST_EVENT_STREAM_START:
       if (g_atomic_int_compare_and_exchange (&priv->send_stream_start, TRUE,
               FALSE)) {
-        /* FIXME: Do we want to create a new stream ID here? */
-        GST_DEBUG_OBJECT (comp, "forward stream-start %p", event);
+
+        gst_event_unref (event);
+        event = info->data = gst_event_new_stream_start (g_strdup (priv->id));
+        GST_INFO_OBJECT (comp, "forward stream-start %p (%s)", event, priv->id);
       } else {
         GST_DEBUG_OBJECT (comp, "dropping stream-start %p", event);
         retval = GST_PAD_PROBE_DROP;