mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +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++)
|
for (i = 0; i < 32; i++)
|
||||||
g_hash_table_destroy (sess->ssrcs[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_free (sess->bye_reason);
|
||||||
|
|
||||||
g_hash_table_destroy (sess->cnames);
|
g_hash_table_destroy (sess->cnames);
|
||||||
|
@ -972,44 +969,6 @@ static RTPSourceCallbacks callbacks = {
|
||||||
(RTPSourceClockRate) source_clock_rate,
|
(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
|
static gboolean
|
||||||
check_collision (RTPSession * sess, RTPSource * source,
|
check_collision (RTPSession * sess, RTPSource * source,
|
||||||
RTPArrivalStats * arrival, gboolean rtp)
|
RTPArrivalStats * arrival, gboolean rtp)
|
||||||
|
@ -1054,7 +1013,8 @@ check_collision (RTPSession * sess, RTPSource * source,
|
||||||
} else {
|
} else {
|
||||||
/* This is sending with our ssrc, is it an address we already know */
|
/* 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
|
/* Its a known conflict, its probably a loop, not a collision
|
||||||
* lets just drop the incoming packet
|
* lets just drop the incoming packet
|
||||||
*/
|
*/
|
||||||
|
@ -2466,7 +2426,6 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
|
||||||
guint64 ntpnstime, GstClockTime running_time)
|
guint64 ntpnstime, GstClockTime running_time)
|
||||||
{
|
{
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
GList *item;
|
|
||||||
ReportData data;
|
ReportData data;
|
||||||
RTPSource *own;
|
RTPSource *own;
|
||||||
gboolean notify = FALSE;
|
gboolean notify = FALSE;
|
||||||
|
@ -2526,21 +2485,9 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for outdated collisions */
|
/* check for outdated collisions */
|
||||||
GST_DEBUG ("checking collision list");
|
GST_DEBUG ("Timing out collisions");
|
||||||
item = g_list_first (sess->conflicting_addresses);
|
rtp_source_timeout (sess->source, current_time,
|
||||||
while (item) {
|
data.interval * RTCP_INTERVAL_COLLISION_TIMEOUT);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sess->change_ssrc) {
|
if (sess->change_ssrc) {
|
||||||
GST_DEBUG ("need to change our SSRC (%08x)", own->ssrc);
|
GST_DEBUG ("need to change our SSRC (%08x)", own->ssrc);
|
||||||
|
|
|
@ -141,19 +141,6 @@ typedef struct {
|
||||||
RTPSessionReconsider reconsider;
|
RTPSessionReconsider reconsider;
|
||||||
} RTPSessionCallbacks;
|
} 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:
|
* RTPSession:
|
||||||
* @lock: lock to protect the session
|
* @lock: lock to protect the session
|
||||||
|
@ -165,7 +152,6 @@ typedef struct {
|
||||||
* @callbacks: callbacks
|
* @callbacks: callbacks
|
||||||
* @user_data: user data passed in callbacks
|
* @user_data: user data passed in callbacks
|
||||||
* @stats: session statistics
|
* @stats: session statistics
|
||||||
* @conflicting_addresses: GList of conflicting addresses
|
|
||||||
*
|
*
|
||||||
* The RTP session manager object
|
* The RTP session manager object
|
||||||
*/
|
*/
|
||||||
|
@ -204,7 +190,6 @@ struct _RTPSession {
|
||||||
|
|
||||||
RTPSessionStats stats;
|
RTPSessionStats stats;
|
||||||
|
|
||||||
GList *conflicting_addresses;
|
|
||||||
gboolean change_ssrc;
|
gboolean change_ssrc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,9 @@ rtp_source_finalize (GObject * object)
|
||||||
|
|
||||||
gst_caps_replace (&src->caps, NULL);
|
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);
|
G_OBJECT_CLASS (rtp_source_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1582,3 +1585,76 @@ rtp_source_get_last_rb (RTPSource * src, guint8 * fractionlost,
|
||||||
|
|
||||||
return TRUE;
|
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;
|
RTPSourceClockRate clock_rate;
|
||||||
} RTPSourceCallbacks;
|
} 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:
|
* RTPSource:
|
||||||
*
|
*
|
||||||
* A source in the #RTPSession
|
* A source in the #RTPSession
|
||||||
|
*
|
||||||
|
* @conflicting_addresses: GList of conflicting addresses
|
||||||
*/
|
*/
|
||||||
struct _RTPSource {
|
struct _RTPSource {
|
||||||
GObject object;
|
GObject object;
|
||||||
|
@ -151,6 +166,8 @@ struct _RTPSource {
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
|
|
||||||
RTPSourceStats stats;
|
RTPSourceStats stats;
|
||||||
|
|
||||||
|
GList *conflicting_addresses;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _RTPSourceClass {
|
struct _RTPSourceClass {
|
||||||
|
@ -219,4 +236,13 @@ gboolean rtp_source_get_last_rb (RTPSource *src, guint8 *fraction
|
||||||
|
|
||||||
void rtp_source_reset (RTPSource * src);
|
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__ */
|
#endif /* __RTP_SOURCE_H__ */
|
||||||
|
|
Loading…
Reference in a new issue