We will also need to track SSRC conflicts in remote sources.
See #607615
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);
(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)
} 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
*/
guint64 ntpnstime, GstClockTime running_time)
{
GstFlowReturn result = GST_FLOW_OK;
- GList *item;
ReportData data;
RTPSource *own;
gboolean notify = FALSE;
}
/* 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);
} 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
* @callbacks: callbacks
* @user_data: user data passed in callbacks
* @stats: session statistics
- * @conflicting_addresses: GList of conflicting addresses
*
* The RTP session manager object
*/
RTPSessionStats stats;
- GList *conflicting_addresses;
gboolean change_ssrc;
};
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);
}
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;
+ }
+}
} 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;
gpointer user_data;
RTPSourceStats stats;
+
+ GList *conflicting_addresses;
};
struct _RTPSourceClass {
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__ */