rtpsession: Only suggest our internal ssrc if it's not a random one and was selected...
authorSebastian Dröge <sebastian@centricular.com>
Fri, 5 Jun 2015 14:43:08 +0000 (16:43 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 5 Jun 2015 14:45:54 +0000 (16:45 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=749581

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

index 1e623cca4ae8a6ffcfa957f7b3ee01ee86c90c73..022f3c3610f0f206e233bd61f06ce080e4bfacbe 100644 (file)
@@ -344,7 +344,7 @@ on_ssrc_collision (RTPSession * session, RTPSource * src, GstRtpSession * sess)
 
     /* if there is no source using the suggested ssrc, most probably because
      * this ssrc has just collided, suggest upstream to use it */
-    suggested_ssrc = rtp_session_suggest_ssrc (session);
+    suggested_ssrc = rtp_session_suggest_ssrc (session, NULL);
     internal_src = rtp_session_get_source_by_ssrc (session, suggested_ssrc);
     if (!internal_src)
       gst_structure_set (structure, "suggested-ssrc", G_TYPE_UINT,
@@ -2007,18 +2007,26 @@ gst_rtp_session_getcaps_send_rtp (GstPad * pad, GstRtpSession * rtpsession,
   GstCaps *result;
   GstStructure *s1, *s2;
   guint ssrc;
+  gboolean is_random;
 
   priv = rtpsession->priv;
 
-  ssrc = rtp_session_suggest_ssrc (priv->session);
+  ssrc = rtp_session_suggest_ssrc (priv->session, &is_random);
 
   /* we can basically accept anything but we prefer to receive packets with our
    * internal SSRC so that we don't have to patch it. Create a structure with
-   * the SSRC and another one without. */
-  s1 = gst_structure_new ("application/x-rtp", "ssrc", G_TYPE_UINT, ssrc, NULL);
-  s2 = gst_structure_new_empty ("application/x-rtp");
-
-  result = gst_caps_new_full (s1, s2, NULL);
+   * the SSRC and another one without.
+   * Only do this if the session actually decided on an ssrc already,
+   * otherwise we give upstream the opportunity to select an ssrc itself */
+  if (!is_random) {
+    s1 = gst_structure_new ("application/x-rtp", "ssrc", G_TYPE_UINT, ssrc,
+        NULL);
+    s2 = gst_structure_new_empty ("application/x-rtp");
+
+    result = gst_caps_new_full (s1, s2, NULL);
+  } else {
+    result = gst_caps_new_empty_simple ("application/x-rtp");
+  }
 
   if (filter) {
     GstCaps *caps = result;
index 497592bfa512c06d70bd9c1a02215d127bb89d80..e53fd2a32a452fd9c01b5a5b7640284bdc138185 100644 (file)
@@ -569,6 +569,7 @@ rtp_session_init (RTPSession * sess)
 
   /* this is the SSRC we suggest */
   sess->suggested_ssrc = rtp_session_create_new_ssrc (sess);
+  sess->internal_ssrc_set = FALSE;
 
   sess->first_rtcp = TRUE;
   sess->next_rtcp_check_time = GST_CLOCK_TIME_NONE;
@@ -666,6 +667,7 @@ rtp_session_set_property (GObject * object, guint prop_id,
     case PROP_INTERNAL_SSRC:
       RTP_SESSION_LOCK (sess);
       sess->suggested_ssrc = g_value_get_uint (value);
+      sess->internal_ssrc_set = TRUE;
       RTP_SESSION_UNLOCK (sess);
       if (sess->callbacks.reconfigure)
         sess->callbacks.reconfigure (sess, sess->reconfigure_user_data);
@@ -744,7 +746,7 @@ rtp_session_get_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_INTERNAL_SSRC:
-      g_value_set_uint (value, rtp_session_suggest_ssrc (sess));
+      g_value_set_uint (value, rtp_session_suggest_ssrc (sess, NULL));
       break;
     case PROP_INTERNAL_SOURCE:
       /* FIXME, return a random source */
@@ -1413,8 +1415,10 @@ check_collision (RTPSession * sess, RTPSource * source,
       /* mark the source BYE */
       rtp_source_mark_bye (source, "SSRC Collision");
       /* if we were suggesting this SSRC, change to something else */
-      if (sess->suggested_ssrc == ssrc)
+      if (sess->suggested_ssrc == ssrc) {
         sess->suggested_ssrc = rtp_session_create_new_ssrc (sess);
+        sess->internal_ssrc_set = TRUE;
+      }
 
       on_ssrc_collision (sess, source);
 
@@ -1522,8 +1526,6 @@ add_source (RTPSession * sess, RTPSource * src)
     sess->stats.active_sources++;
   if (src->internal) {
     sess->stats.internal_sources++;
-    if (sess->suggested_ssrc != src->ssrc)
-      sess->suggested_ssrc = src->ssrc;
   }
 
   /* update point-to-point status */
@@ -1633,13 +1635,14 @@ obtain_internal_source (RTPSession * sess, guint32 ssrc, gboolean * created,
 /**
  * rtp_session_suggest_ssrc:
  * @sess: a #RTPSession
+ * @is_random: if the suggested ssrc is random
  *
  * Suggest an unused SSRC in @sess.
  *
  * Returns: a free unused SSRC
  */
 guint32
-rtp_session_suggest_ssrc (RTPSession * sess)
+rtp_session_suggest_ssrc (RTPSession * sess, gboolean * is_random)
 {
   guint32 result;
 
@@ -1647,6 +1650,8 @@ rtp_session_suggest_ssrc (RTPSession * sess)
 
   RTP_SESSION_LOCK (sess);
   result = sess->suggested_ssrc;
+  if (is_random)
+    *is_random = !sess->internal_ssrc_set;
   RTP_SESSION_UNLOCK (sess);
 
   return result;
@@ -2738,6 +2743,8 @@ rtp_session_update_send_caps (RTPSession * sess, GstCaps * caps)
 
     RTP_SESSION_LOCK (sess);
     source = obtain_internal_source (sess, ssrc, &created, GST_CLOCK_TIME_NONE);
+    sess->suggested_ssrc = ssrc;
+    sess->internal_ssrc_set = TRUE;
     if (source) {
       rtp_source_update_caps (source, caps);
       g_object_unref (source);
@@ -3800,6 +3807,7 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
 
     source = obtain_internal_source (sess, sess->suggested_ssrc, &created,
         current_time);
+    sess->internal_ssrc_set = TRUE;
     g_object_unref (source);
   }
 
index 7f7fe6992b0f1f45b0add67a4fe8df1e2628c9ea..b23a1c6080b00447c697c4d650c1eec4be749ef4 100644 (file)
@@ -230,6 +230,7 @@ struct _RTPSession {
   guint        rtcp_rs_bandwidth;
 
   guint32       suggested_ssrc;
+  gboolean      internal_ssrc_set;
 
   /* for sender/receiver counting */
   guint32       key;
@@ -347,7 +348,7 @@ GstStructure *  rtp_session_get_sdes_struct        (RTPSession *sess);
 void            rtp_session_set_sdes_struct        (RTPSession *sess, const GstStructure *sdes);
 
 /* handling sources */
-guint32         rtp_session_suggest_ssrc           (RTPSession *sess);
+guint32         rtp_session_suggest_ssrc           (RTPSession *sess, gboolean *is_random);
 
 gboolean        rtp_session_add_source             (RTPSession *sess, RTPSource *src);
 guint           rtp_session_get_num_sources        (RTPSession *sess);