rtpmanager: Add 'source-stats' to stats and notify
authorStian Selnes <stian@pexip.com>
Tue, 14 Jul 2015 13:19:44 +0000 (15:19 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Sun, 11 Oct 2015 09:57:09 +0000 (10:57 +0100)
Add statitics from each rtp source to the rtp session property.
'source-stats' is a GValueArray where each element is a GstStructure of
stats for one rtp source.

The availability of new stats is signaled via g_object_notify.

https://bugzilla.gnome.org/show_bug.cgi?id=752669

gst/rtpmanager/gstrtpsession.c
gst/rtpmanager/rtpsession.c

index 985b29b..51ac0da 100644 (file)
@@ -465,6 +465,12 @@ on_sender_ssrc_active (RTPSession * session, RTPSource * src,
       src->ssrc);
 }
 
+static void
+on_notify_stats (RTPSession * session, GParamSpec *spec, GstRtpSession *rtpsession)
+{
+  g_object_notify (G_OBJECT (rtpsession), "stats");
+}
+
 #define gst_rtp_session_parent_class parent_class
 G_DEFINE_TYPE (GstRtpSession, gst_rtp_session, GST_TYPE_ELEMENT);
 
@@ -728,6 +734,8 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
    *      dropped (due to bandwidth constraints)
    *  "sent-nack-count" G_TYPE_UINT   Number of NACKs sent
    *  "recv-nack-count" G_TYPE_UINT   Number of NACKs received
+   *  "source-stats"    G_TYPE_BOXED  GValueArray of #RTPSource::stats for all
+   *      RTP sources (Since 1.8)
    *
    * Since: 1.4
    */
@@ -825,6 +833,8 @@ gst_rtp_session_init (GstRtpSession * rtpsession)
       (GCallback) on_new_sender_ssrc, rtpsession);
   g_signal_connect (rtpsession->priv->session, "on-sender-ssrc-active",
       (GCallback) on_sender_ssrc_active, rtpsession);
+  g_signal_connect (rtpsession->priv->session, "notify::stats",
+      (GCallback) on_notify_stats, rtpsession);
   rtpsession->priv->ptmap = g_hash_table_new_full (NULL, NULL, NULL,
       (GDestroyNotify) gst_caps_unref);
 
index 6ab3777..89295c1 100644 (file)
@@ -542,6 +542,8 @@ rtp_session_class_init (RTPSessionClass * klass)
    *      dropped (due to bandwidth constraints)
    *  "sent-nack-count" G_TYPE_UINT   Number of NACKs sent
    *  "recv-nack-count" G_TYPE_UINT   Number of NACKs received
+   *  "source-stats"    G_TYPE_BOXED  GValueArray of #RTPSource::stats for all
+   *      RTP sources (Since 1.8)
    *
    * Since: 1.4
    */
@@ -701,15 +703,43 @@ rtp_session_create_sources (RTPSession * sess)
   return res;
 }
 
+static void
+create_source_stats (gpointer key, RTPSource * source, GValueArray *arr)
+{
+  GValue value = G_VALUE_INIT;
+  GstStructure *s;
+
+  g_object_get (source, "stats", &s, NULL);
+
+  g_value_init (&value, GST_TYPE_STRUCTURE);
+  gst_value_set_structure (&value, s);
+  g_value_array_append (arr, &value);
+  gst_structure_free (s);
+  g_value_unset (&value);
+}
+
 static GstStructure *
 rtp_session_create_stats (RTPSession * sess)
 {
   GstStructure *s;
+  GValueArray *source_stats;
+  GValue source_stats_v = G_VALUE_INIT;
+  guint size;
 
   s = gst_structure_new ("application/x-rtp-session-stats",
       "rtx-drop-count", G_TYPE_UINT, sess->stats.nacks_dropped,
       "sent-nack-count", G_TYPE_UINT, sess->stats.nacks_sent,
-      "recv-nack-count", G_TYPE_UINT, sess->stats.nacks_received, NULL);
+      "recv-nack-count", G_TYPE_UINT, sess->stats.nacks_received,
+      NULL);
+
+  size = g_hash_table_size (sess->ssrcs[sess->mask_idx]);
+  source_stats = g_value_array_new (size);
+  g_hash_table_foreach (sess->ssrcs[sess->mask_idx],
+      (GHFunc) create_source_stats, source_stats);
+
+  g_value_init (&source_stats_v, G_TYPE_VALUE_ARRAY);
+  g_value_take_boxed (&source_stats_v, source_stats);
+  gst_structure_take_value (s, "source-stats", &source_stats_v);
 
   return s;
 }
@@ -3953,6 +3983,9 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
   /* update point-to-point status */
   session_update_ptp (sess);
 
+  /* notify about updated statistics */
+  g_object_notify (G_OBJECT (sess), "stats");
+
   /* see if we need to generate SR or RR packets */
   if (!is_rtcp_time (sess, current_time, &data))
     goto done;