mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
rtpsession: Move SSRC conflicts lists into RTPSource
We will also need to track SSRC conflicts in remote sources. See #607615
This commit is contained in:
parent
38f2b4735d
commit
f336ea283f
4 changed files with 107 additions and 73 deletions
|
@ -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);
|
||||
|
|
|
@ -141,19 +141,6 @@ typedef struct {
|
|||
RTPSessionReconsider reconsider;
|
||||
} 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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,10 +100,25 @@ typedef struct {
|
|||
RTPSourceClockRate clock_rate;
|
||||
} 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__ */
|
||||
|
|
Loading…
Reference in a new issue