rtpsession: Move SSRC conflicts lists into RTPSource
authorOlivier CrĂȘte <olivier.crete@collabora.co.uk>
Fri, 5 Mar 2010 14:46:48 +0000 (15:46 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 10 Mar 2010 10:21:18 +0000 (11:21 +0100)
We will also need to track SSRC conflicts in remote sources.

See #607615

gst/rtpmanager/rtpsession.c
gst/rtpmanager/rtpsession.h
gst/rtpmanager/rtpsource.c
gst/rtpmanager/rtpsource.h

index bf8cfd0..99ec2e5 100644 (file)
@@ -369,9 +369,6 @@ rtp_session_finalize (GObject * object)
   for (i = 0; i < 32; i++)
     g_hash_table_destroy (sess->ssrcs[i]);
 
-  g_list_foreach (sess->conflicting_addresses, (GFunc) g_free, NULL);
-  g_list_free (sess->conflicting_addresses);
-
   g_free (sess->bye_reason);
 
   g_hash_table_destroy (sess->cnames);
@@ -972,44 +969,6 @@ static RTPSourceCallbacks callbacks = {
   (RTPSourceClockRate) source_clock_rate,
 };
 
-/**
- * find_add_conflicting_addresses:
- * @sess: The session to check in
- * @arrival: The arrival stats for the buffer
- *
- * Checks if an address which has a conflict is already known,
- *  otherwise remembers it to prevent loops.
- *
- * Returns: TRUE if it was a known conflict, FALSE otherwise
- */
-
-static gboolean
-find_add_conflicting_addresses (RTPSession * sess, RTPArrivalStats * arrival)
-{
-  GList *item;
-  RTPConflictingAddress *new_conflict;
-
-  for (item = g_list_first (sess->conflicting_addresses);
-      item; item = g_list_next (item)) {
-    RTPConflictingAddress *known_conflict = item->data;
-
-    if (gst_netaddress_equal (&arrival->address, &known_conflict->address)) {
-      known_conflict->time = arrival->current_time;
-      return TRUE;
-    }
-  }
-
-  new_conflict = g_new0 (RTPConflictingAddress, 1);
-
-  memcpy (&new_conflict->address, &arrival->address, sizeof (GstNetAddress));
-  new_conflict->time = arrival->current_time;
-
-  sess->conflicting_addresses = g_list_prepend (sess->conflicting_addresses,
-      new_conflict);
-
-  return FALSE;
-}
-
 static gboolean
 check_collision (RTPSession * sess, RTPSource * source,
     RTPArrivalStats * arrival, gboolean rtp)
@@ -1054,7 +1013,8 @@ check_collision (RTPSession * sess, RTPSource * source,
   } else {
     /* This is sending with our ssrc, is it an address we already know */
 
-    if (find_add_conflicting_addresses (sess, arrival)) {
+    if (rtp_source_find_add_conflicting_address (source, &arrival->address,
+            arrival->current_time)) {
       /* Its a known conflict, its probably a loop, not a collision
        * lets just drop the incoming packet
        */
@@ -2466,7 +2426,6 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
     guint64 ntpnstime, GstClockTime running_time)
 {
   GstFlowReturn result = GST_FLOW_OK;
-  GList *item;
   ReportData data;
   RTPSource *own;
   gboolean notify = FALSE;
@@ -2526,21 +2485,9 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
   }
 
   /* check for outdated collisions */
-  GST_DEBUG ("checking collision list");
-  item = g_list_first (sess->conflicting_addresses);
-  while (item) {
-    RTPConflictingAddress *known_conflict = item->data;
-    GList *next_item = g_list_next (item);
-
-    if (known_conflict->time < current_time - (data.interval *
-            RTCP_INTERVAL_COLLISION_TIMEOUT)) {
-      sess->conflicting_addresses =
-          g_list_delete_link (sess->conflicting_addresses, item);
-      GST_DEBUG ("collision %p timed out", known_conflict);
-      g_free (known_conflict);
-    }
-    item = next_item;
-  }
+  GST_DEBUG ("Timing out collisions");
+  rtp_source_timeout (sess->source, current_time,
+      data.interval * RTCP_INTERVAL_COLLISION_TIMEOUT);
 
   if (sess->change_ssrc) {
     GST_DEBUG ("need to change our SSRC (%08x)", own->ssrc);
index ffced1a..1a5909a 100644 (file)
@@ -142,19 +142,6 @@ typedef struct {
 } RTPSessionCallbacks;
 
 /**
- * RTPConflictingAddress:
- * @address: #GstNetAddress which conflicted
- * @last_conflict_time: time when the last conflict was seen
- *
- * This structure is used to account for addresses that have conflicted to find
- * loops.
- */
-typedef struct {
-  GstNetAddress address;
-  GstClockTime time;
-} RTPConflictingAddress;
-
-/**
  * RTPSession:
  * @lock: lock to protect the session
  * @source: the source of this session
@@ -165,7 +152,6 @@ typedef struct {
  * @callbacks: callbacks
  * @user_data: user data passed in callbacks
  * @stats: session statistics
- * @conflicting_addresses: GList of conflicting addresses
  *
  * The RTP session manager object
  */
@@ -204,7 +190,6 @@ struct _RTPSession {
 
   RTPSessionStats stats;
 
-  GList         *conflicting_addresses;
   gboolean      change_ssrc;
 };
 
index 0b014b6..568811b 100644 (file)
@@ -188,6 +188,9 @@ rtp_source_finalize (GObject * object)
 
   gst_caps_replace (&src->caps, NULL);
 
+  g_list_foreach (src->conflicting_addresses, (GFunc) g_free, NULL);
+  g_list_free (src->conflicting_addresses);
+
   G_OBJECT_CLASS (rtp_source_parent_class)->finalize (object);
 }
 
@@ -1582,3 +1585,76 @@ rtp_source_get_last_rb (RTPSource * src, guint8 * fractionlost,
 
   return TRUE;
 }
+
+/**
+ * rtp_source_find_add_conflicting_address:
+ * @src: The source the packet came in
+ * @address: address to check for
+ * @time: The time when the packet that is in conflict arrived
+ *
+ * Checks if an address which has a conflict is already known,
+ *  otherwise remembers it to prevent loops.
+ *
+ * Returns: TRUE if it was a known conflict, FALSE otherwise
+ */
+
+gboolean
+rtp_source_find_add_conflicting_address (RTPSource * src,
+    GstNetAddress * address, GstClockTime time)
+{
+  GList *item;
+  RTPConflictingAddress *new_conflict;
+
+  for (item = g_list_first (src->conflicting_addresses);
+      item; item = g_list_next (item)) {
+    RTPConflictingAddress *known_conflict = item->data;
+
+    if (gst_netaddress_equal (address, &known_conflict->address)) {
+      known_conflict->time = time;
+      return TRUE;
+    }
+  }
+
+  new_conflict = g_new0 (RTPConflictingAddress, 1);
+
+  memcpy (&new_conflict->address, address, sizeof (GstNetAddress));
+  new_conflict->time = time;
+
+  src->conflicting_addresses = g_list_prepend (src->conflicting_addresses,
+      new_conflict);
+
+  return FALSE;
+}
+
+/**
+ * rtp_source_timeout:
+ * @src: The #RTPSource
+ * @current_time: The current time
+ * @collision_timeout: The amount of time after which a collision is timed out
+ *
+ * This is processed on each RTCP interval. It times out old collisions.
+ */
+
+void
+rtp_source_timeout (RTPSource * src, GstClockTime current_time,
+    GstClockTime collision_timeout)
+{
+  GList *item;
+
+  item = g_list_first (src->conflicting_addresses);
+  while (item) {
+    RTPConflictingAddress *known_conflict = item->data;
+    GList *next_item = g_list_next (item);
+
+    if (known_conflict->time < current_time - collision_timeout) {
+      gchar buf[40];
+
+      src->conflicting_addresses =
+          g_list_delete_link (src->conflicting_addresses, item);
+      gst_netaddress_to_string (&known_conflict->address, buf, 40);
+      GST_DEBUG ("collision %p timed out: %s", known_conflict, buf);
+      g_free (known_conflict);
+    }
+    item = next_item;
+  }
+}
index f15e862..7cba4e3 100644 (file)
@@ -101,9 +101,24 @@ typedef struct {
 } RTPSourceCallbacks;
 
 /**
+ * RTPConflictingAddress:
+ * @address: #GstNetAddress which conflicted
+ * @last_conflict_time: time when the last conflict was seen
+ *
+ * This structure is used to account for addresses that have conflicted to find
+ * loops.
+ */
+typedef struct {
+  GstNetAddress address;
+  GstClockTime time;
+} RTPConflictingAddress;
+
+/**
  * RTPSource:
  *
  * A source in the #RTPSession
+ *
+ * @conflicting_addresses: GList of conflicting addresses
  */
 struct _RTPSource {
   GObject       object;
@@ -151,6 +166,8 @@ struct _RTPSource {
   gpointer           user_data;
 
   RTPSourceStats stats;
+
+  GList         *conflicting_addresses;
 };
 
 struct _RTPSourceClass {
@@ -219,4 +236,13 @@ gboolean        rtp_source_get_last_rb         (RTPSource *src, guint8 *fraction
 
 void            rtp_source_reset               (RTPSource * src);
 
+gboolean        rtp_source_find_add_conflicting_address (RTPSource * src,
+                                                GstNetAddress *address,
+                                                GstClockTime time);
+
+void            rtp_source_timeout             (RTPSource * src,
+                                                GstClockTime current_time,
+                                                GstClockTime collision_timeout);
+
+
 #endif /* __RTP_SOURCE_H__ */