rtpsession: expose timeout-inactive-sources property

In some situations it is not desirable to time out when no data is
received any longer, users can opt in to this behavior via a new
property.

The property is also exposed on rtpbin and sdpdemux

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4880>
This commit is contained in:
Mathieu Duponchelle 2023-06-16 21:53:11 +02:00 committed by GStreamer Marge Bot
parent 170dcd58db
commit 7445b73e76
9 changed files with 188 additions and 21 deletions

View file

@ -229820,6 +229820,18 @@
"readable": true, "readable": true,
"type": "guint64", "type": "guint64",
"writable": true "writable": true
},
"timeout-inactive-rtp-sources": {
"blurb": "Whether RTP sources that don't receive RTP or RTCP packets for longer than 5x RTCP interval should be removed",
"conditionally-available": false,
"construct": true,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
} }
}, },
"rank": "none", "rank": "none",

View file

@ -79,6 +79,7 @@ enum
#define DEFAULT_REDIRECT TRUE #define DEFAULT_REDIRECT TRUE
#define DEFAULT_RTCP_MODE GST_SDP_DEMUX_RTCP_MODE_SENDRECV #define DEFAULT_RTCP_MODE GST_SDP_DEMUX_RTCP_MODE_SENDRECV
#define DEFAULT_MEDIA NULL #define DEFAULT_MEDIA NULL
#define DEFAULT_TIMEOUT_INACTIVE_RTP_SOURCES TRUE
enum enum
{ {
@ -89,6 +90,7 @@ enum
PROP_REDIRECT, PROP_REDIRECT,
PROP_RTCP_MODE, PROP_RTCP_MODE,
PROP_MEDIA, PROP_MEDIA,
PROP_TIMEOUT_INACTIVE_RTP_SOURCES,
}; };
static void gst_sdp_demux_finalize (GObject * object); static void gst_sdp_demux_finalize (GObject * object);
@ -202,6 +204,23 @@ gst_sdp_demux_class_init (GstSDPDemuxClass * klass)
"Media to use, e.g. audio or video (NULL = all)", DEFAULT_MEDIA, "Media to use, e.g. audio or video (NULL = all)", DEFAULT_MEDIA,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstSDPDemux:timeout-inactive-rtp-sources:
*
* Whether inactive RTP sources in the underlying RTP session
* should be timed out.
*
* Since: 1.24
*/
g_object_class_install_property (gobject_class,
PROP_TIMEOUT_INACTIVE_RTP_SOURCES,
g_param_spec_boolean ("timeout-inactive-rtp-sources",
"Time out inactive sources",
"Whether RTP sources that don't receive RTP or RTCP packets for longer "
"than 5x RTCP interval should be removed",
DEFAULT_TIMEOUT_INACTIVE_RTP_SOURCES,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate); gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
gst_element_class_add_static_pad_template (gstelement_class, &rtptemplate); gst_element_class_add_static_pad_template (gstelement_class, &rtptemplate);
@ -284,6 +303,9 @@ gst_sdp_demux_set_property (GObject * object, guint prop_id,
demux->media = g_intern_string (g_value_get_string (value)); demux->media = g_intern_string (g_value_get_string (value));
GST_OBJECT_UNLOCK (demux); GST_OBJECT_UNLOCK (demux);
break; break;
case PROP_TIMEOUT_INACTIVE_RTP_SOURCES:
demux->timeout_inactive_rtp_sources = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -319,6 +341,9 @@ gst_sdp_demux_get_property (GObject * object, guint prop_id, GValue * value,
g_value_set_string (value, demux->media); g_value_set_string (value, demux->media);
GST_OBJECT_UNLOCK (demux); GST_OBJECT_UNLOCK (demux);
break; break;
case PROP_TIMEOUT_INACTIVE_RTP_SOURCES:
g_value_set_boolean (value, demux->timeout_inactive_rtp_sources);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -1021,6 +1046,9 @@ gst_sdp_demux_configure_manager (GstSDPDemux * demux, char *rtsp_sdp)
demux); demux);
g_signal_connect (demux->session, "on-timeout", (GCallback) on_timeout, g_signal_connect (demux->session, "on-timeout", (GCallback) on_timeout,
demux); demux);
g_object_set (demux->session, "timeout-inactive-sources",
demux->timeout_inactive_rtp_sources, NULL);
} }
g_object_set (demux->session, "latency", demux->latency, NULL); g_object_set (demux->session, "latency", demux->latency, NULL);

View file

@ -124,6 +124,7 @@ struct _GstSDPDemux {
gboolean redirect; gboolean redirect;
const gchar *media; /* if non-NULL only hook up these kinds of media (video/audio) */ /* interned string */ const gchar *media; /* if non-NULL only hook up these kinds of media (video/audio) */ /* interned string */
GstSDPDemuxRTCPMode rtcp_mode; GstSDPDemuxRTCPMode rtcp_mode;
gboolean timeout_inactive_rtp_sources;
/* session management */ /* session management */
GstElement *session; GstElement *session;

View file

@ -17679,6 +17679,18 @@
"type": "GstStructure", "type": "GstStructure",
"writable": true "writable": true
}, },
"timeout-inactive-sources": {
"blurb": "Whether sources that don't receive RTP or RTCP packets for longer than 5x RTCP interval should be removed",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"ts-offset-smoothing-factor": { "ts-offset-smoothing-factor": {
"blurb": "Sets a smoothing factor for the timestamp offset in number of values for a calculated running moving average. (0 = no smoothing factor)", "blurb": "Sets a smoothing factor for the timestamp offset in number of values for a calculated running moving average. (0 = no smoothing factor)",
"conditionally-available": false, "conditionally-available": false,
@ -19611,6 +19623,18 @@
"type": "GstStructure", "type": "GstStructure",
"writable": false "writable": false
}, },
"timeout-inactive-sources": {
"blurb": "Whether sources that don't receive RTP or RTCP packets for longer than 5x RTCP interval should be removed",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"twcc-stats": { "twcc-stats": {
"blurb": "Various statistics from TWCC", "blurb": "Various statistics from TWCC",
"conditionally-available": false, "conditionally-available": false,
@ -20454,6 +20478,18 @@
"type": "GstStructure", "type": "GstStructure",
"writable": false "writable": false
}, },
"timeout-inactive-sources": {
"blurb": "Whether sources that don't receive RTP or RTCP packets for longer than 5x RTCP interval should be removed",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"twcc-feedback-interval": { "twcc-feedback-interval": {
"blurb": "The interval to send TWCC reports on", "blurb": "The interval to send TWCC reports on",
"conditionally-available": false, "conditionally-available": false,

View file

@ -358,6 +358,7 @@ enum
#define DEFAULT_MIN_TS_OFFSET MIN_TS_OFFSET_ROUND_OFF_COMP #define DEFAULT_MIN_TS_OFFSET MIN_TS_OFFSET_ROUND_OFF_COMP
#define DEFAULT_TS_OFFSET_SMOOTHING_FACTOR 0 #define DEFAULT_TS_OFFSET_SMOOTHING_FACTOR 0
#define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE #define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE
#define DEFAULT_TIMEOUT_INACTIVE_SOURCES TRUE
enum enum
{ {
@ -391,6 +392,7 @@ enum
PROP_FEC_DECODERS, PROP_FEC_DECODERS,
PROP_FEC_ENCODERS, PROP_FEC_ENCODERS,
PROP_UPDATE_NTP64_HEADER_EXT, PROP_UPDATE_NTP64_HEADER_EXT,
PROP_TIMEOUT_INACTIVE_SOURCES,
}; };
#define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type()) #define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
@ -783,6 +785,9 @@ create_session (GstRtpBin * rtpbin, gint id)
g_object_set (session, "update-ntp64-header-ext", g_object_set (session, "update-ntp64-header-ext",
rtpbin->update_ntp64_header_ext, NULL); rtpbin->update_ntp64_header_ext, NULL);
g_object_set (session, "timeout-inactive-sources",
rtpbin->timeout_inactive_sources, NULL);
GST_OBJECT_UNLOCK (rtpbin); GST_OBJECT_UNLOCK (rtpbin);
/* provide clock_rate to the session manager when needed */ /* provide clock_rate to the session manager when needed */
@ -3002,6 +3007,22 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
DEFAULT_UPDATE_NTP64_HEADER_EXT, DEFAULT_UPDATE_NTP64_HEADER_EXT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstRtpBin:timeout-inactive-sources:
*
* Whether inactive sources should be timed out
*
* Since: 1.24
*/
g_object_class_install_property (gobject_class,
PROP_TIMEOUT_INACTIVE_SOURCES,
g_param_spec_boolean ("timeout-inactive-sources",
"Time out inactive sources",
"Whether sources that don't receive RTP or RTCP packets for longer "
"than 5x RTCP interval should be removed",
DEFAULT_TIMEOUT_INACTIVE_SOURCES,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
gstelement_class->request_new_pad = gstelement_class->request_new_pad =
GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad); GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
@ -3093,6 +3114,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin)
rtpbin->min_ts_offset_is_set = FALSE; rtpbin->min_ts_offset_is_set = FALSE;
rtpbin->ts_offset_smoothing_factor = DEFAULT_TS_OFFSET_SMOOTHING_FACTOR; rtpbin->ts_offset_smoothing_factor = DEFAULT_TS_OFFSET_SMOOTHING_FACTOR;
rtpbin->update_ntp64_header_ext = DEFAULT_UPDATE_NTP64_HEADER_EXT; rtpbin->update_ntp64_header_ext = DEFAULT_UPDATE_NTP64_HEADER_EXT;
rtpbin->timeout_inactive_sources = DEFAULT_TIMEOUT_INACTIVE_SOURCES;
/* some default SDES entries */ /* some default SDES entries */
cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ()); cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
@ -3439,6 +3461,13 @@ gst_rtp_bin_set_property (GObject * object, guint prop_id,
gst_rtp_bin_propagate_property_to_session (rtpbin, gst_rtp_bin_propagate_property_to_session (rtpbin,
"update-ntp64-header-ext", value); "update-ntp64-header-ext", value);
break; break;
case PROP_TIMEOUT_INACTIVE_SOURCES:
GST_RTP_BIN_LOCK (rtpbin);
rtpbin->timeout_inactive_sources = g_value_get_boolean (value);
GST_RTP_BIN_UNLOCK (rtpbin);
gst_rtp_bin_propagate_property_to_session (rtpbin,
"timeout-inactive-sources", value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -3551,6 +3580,9 @@ gst_rtp_bin_get_property (GObject * object, guint prop_id,
case PROP_UPDATE_NTP64_HEADER_EXT: case PROP_UPDATE_NTP64_HEADER_EXT:
g_value_set_boolean (value, rtpbin->update_ntp64_header_ext); g_value_set_boolean (value, rtpbin->update_ntp64_header_ext);
break; break;
case PROP_TIMEOUT_INACTIVE_SOURCES:
g_value_set_boolean (value, rtpbin->timeout_inactive_sources);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;

View file

@ -100,6 +100,8 @@ struct _GstRtpBin {
gboolean update_ntp64_header_ext; gboolean update_ntp64_header_ext;
gboolean timeout_inactive_sources;
/*< private >*/ /*< private >*/
GstRtpBinPrivate *priv; GstRtpBinPrivate *priv;
}; };

View file

@ -224,6 +224,7 @@ enum
#define DEFAULT_NTP_TIME_SOURCE GST_RTP_NTP_TIME_SOURCE_NTP #define DEFAULT_NTP_TIME_SOURCE GST_RTP_NTP_TIME_SOURCE_NTP
#define DEFAULT_RTCP_SYNC_SEND_TIME TRUE #define DEFAULT_RTCP_SYNC_SEND_TIME TRUE
#define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE #define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE
#define DEFAULT_TIMEOUT_INACTIVE_SOURCES TRUE
enum enum
{ {
@ -246,7 +247,8 @@ enum
PROP_RTP_PROFILE, PROP_RTP_PROFILE,
PROP_NTP_TIME_SOURCE, PROP_NTP_TIME_SOURCE,
PROP_RTCP_SYNC_SEND_TIME, PROP_RTCP_SYNC_SEND_TIME,
PROP_UPDATE_NTP64_HEADER_EXT PROP_UPDATE_NTP64_HEADER_EXT,
PROP_TIMEOUT_INACTIVE_SOURCES,
}; };
#define GST_RTP_SESSION_LOCK(sess) g_mutex_lock (&(sess)->priv->lock) #define GST_RTP_SESSION_LOCK(sess) g_mutex_lock (&(sess)->priv->lock)
@ -830,6 +832,22 @@ gst_rtp_session_class_init (GstRtpSessionClass * klass)
DEFAULT_UPDATE_NTP64_HEADER_EXT, DEFAULT_UPDATE_NTP64_HEADER_EXT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstRtpSession:timeout-inactive-sources:
*
* Whether inactive sources should be timed out
*
* Since: 1.24
*/
g_object_class_install_property (gobject_class,
PROP_TIMEOUT_INACTIVE_SOURCES,
g_param_spec_boolean ("timeout-inactive-sources",
"Time out inactive sources",
"Whether sources that don't receive RTP or RTCP packets for longer "
"than 5x RTCP interval should be removed",
DEFAULT_TIMEOUT_INACTIVE_SOURCES,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstelement_class->change_state = gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_rtp_session_change_state); GST_DEBUG_FUNCPTR (gst_rtp_session_change_state);
gstelement_class->request_new_pad = gstelement_class->request_new_pad =
@ -1008,6 +1026,10 @@ gst_rtp_session_set_property (GObject * object, guint prop_id,
g_object_set_property (G_OBJECT (priv->session), g_object_set_property (G_OBJECT (priv->session),
"update-ntp64-header-ext", value); "update-ntp64-header-ext", value);
break; break;
case PROP_TIMEOUT_INACTIVE_SOURCES:
g_object_set_property (G_OBJECT (priv->session),
"timeout-inactive-sources", value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -1091,6 +1113,10 @@ gst_rtp_session_get_property (GObject * object, guint prop_id,
g_object_get_property (G_OBJECT (priv->session), g_object_get_property (G_OBJECT (priv->session),
"update-ntp64-header-ext", value); "update-ntp64-header-ext", value);
break; break;
case PROP_TIMEOUT_INACTIVE_SOURCES:
g_object_get_property (G_OBJECT (priv->session),
"timeout-inactive-sources", value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;

View file

@ -82,6 +82,7 @@ enum
#define DEFAULT_FAVOR_NEW FALSE #define DEFAULT_FAVOR_NEW FALSE
#define DEFAULT_TWCC_FEEDBACK_INTERVAL GST_CLOCK_TIME_NONE #define DEFAULT_TWCC_FEEDBACK_INTERVAL GST_CLOCK_TIME_NONE
#define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE #define DEFAULT_UPDATE_NTP64_HEADER_EXT TRUE
#define DEFAULT_TIMEOUT_INACTIVE_SOURCES TRUE
enum enum
{ {
@ -110,6 +111,7 @@ enum
PROP_RTCP_DISABLE_SR_TIMESTAMP, PROP_RTCP_DISABLE_SR_TIMESTAMP,
PROP_TWCC_FEEDBACK_INTERVAL, PROP_TWCC_FEEDBACK_INTERVAL,
PROP_UPDATE_NTP64_HEADER_EXT, PROP_UPDATE_NTP64_HEADER_EXT,
PROP_TIMEOUT_INACTIVE_SOURCES,
PROP_LAST, PROP_LAST,
}; };
@ -660,6 +662,21 @@ rtp_session_class_init (RTPSessionClass * klass)
DEFAULT_UPDATE_NTP64_HEADER_EXT, DEFAULT_UPDATE_NTP64_HEADER_EXT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
/**
* RTPSession:timeout-inactive-sources:
*
* Whether inactive sources should be timed out
*
* Since: 1.24
*/
properties[PROP_TIMEOUT_INACTIVE_SOURCES] =
g_param_spec_boolean ("timeout-inactive-sources",
"Time out inactive sources",
"Whether sources that don't receive RTP or RTCP packets for longer "
"than 5x RTCP interval should be removed",
DEFAULT_TIMEOUT_INACTIVE_SOURCES,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, PROP_LAST, properties); g_object_class_install_properties (gobject_class, PROP_LAST, properties);
klass->get_source_by_ssrc = klass->get_source_by_ssrc =
@ -706,6 +723,7 @@ rtp_session_init (RTPSession * sess)
sess->mtu = DEFAULT_RTCP_MTU; sess->mtu = DEFAULT_RTCP_MTU;
sess->update_ntp64_header_ext = DEFAULT_UPDATE_NTP64_HEADER_EXT; sess->update_ntp64_header_ext = DEFAULT_UPDATE_NTP64_HEADER_EXT;
sess->timeout_inactive_sources = DEFAULT_TIMEOUT_INACTIVE_SOURCES;
sess->probation = DEFAULT_PROBATION; sess->probation = DEFAULT_PROBATION;
sess->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME; sess->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME;
@ -950,6 +968,9 @@ rtp_session_set_property (GObject * object, guint prop_id,
case PROP_UPDATE_NTP64_HEADER_EXT: case PROP_UPDATE_NTP64_HEADER_EXT:
sess->update_ntp64_header_ext = g_value_get_boolean (value); sess->update_ntp64_header_ext = g_value_get_boolean (value);
break; break;
case PROP_TIMEOUT_INACTIVE_SOURCES:
sess->timeout_inactive_sources = g_value_get_boolean (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -1039,6 +1060,9 @@ rtp_session_get_property (GObject * object, guint prop_id,
case PROP_UPDATE_NTP64_HEADER_EXT: case PROP_UPDATE_NTP64_HEADER_EXT:
g_value_set_boolean (value, sess->update_ntp64_header_ext); g_value_set_boolean (value, sess->update_ntp64_header_ext);
break; break;
case PROP_TIMEOUT_INACTIVE_SOURCES:
g_value_set_boolean (value, sess->timeout_inactive_sources);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -3793,6 +3817,7 @@ typedef struct
gboolean may_suppress; gboolean may_suppress;
GQueue output; GQueue output;
guint nacked_seqnums; guint nacked_seqnums;
gboolean timeout_inactive_sources;
} ReportData; } ReportData;
static void static void
@ -4186,27 +4211,29 @@ session_cleanup (const gchar * key, RTPSource * source, ReportData * data)
remove = TRUE; remove = TRUE;
} }
/* sources that were inactive for more than 5 times the deterministic reporting if (data->timeout_inactive_sources) {
* interval get timed out. the min timeout is 5 seconds. */ /* sources that were inactive for more than 5 times the deterministic reporting
/* mind old time that might pre-date last time going to PLAYING */ * interval get timed out. the min timeout is 5 seconds. */
btime = MAX (source->last_activity, sess->start_time); /* mind old time that might pre-date last time going to PLAYING */
if (data->current_time > btime) { btime = MAX (source->last_activity, sess->start_time);
interval = MAX (binterval * 5, 5 * GST_SECOND); if (data->current_time > btime) {
if (data->current_time - btime > interval) { interval = MAX (binterval * 5, 5 * GST_SECOND);
GST_DEBUG ("removing timeout source %08x, last %" GST_TIME_FORMAT, if (data->current_time - btime > interval) {
source->ssrc, GST_TIME_ARGS (btime)); GST_DEBUG ("removing timeout source %08x, last %" GST_TIME_FORMAT,
if (source->internal) { source->ssrc, GST_TIME_ARGS (btime));
/* this is an internal source that is not using our suggested ssrc. if (source->internal) {
* since there must be another source using this ssrc, we can remove /* this is an internal source that is not using our suggested ssrc.
* this one instead of making it a receiver forever */ * since there must be another source using this ssrc, we can remove
if (source->ssrc != sess->suggested_ssrc * this one instead of making it a receiver forever */
&& source->media_ssrc != sess->suggested_ssrc) { if (source->ssrc != sess->suggested_ssrc
rtp_source_mark_bye (source, "timed out"); && source->media_ssrc != sess->suggested_ssrc) {
/* do not schedule bye here, since we are inside the RTCP timeout rtp_source_mark_bye (source, "timed out");
* processing and scheduling bye will interfere with SR/RR sending */ /* do not schedule bye here, since we are inside the RTCP timeout
* processing and scheduling bye will interfere with SR/RR sending */
}
} else {
remove = TRUE;
} }
} else {
remove = TRUE;
} }
} }
} }
@ -4660,6 +4687,7 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
data.num_to_report = 0; data.num_to_report = 0;
data.may_suppress = FALSE; data.may_suppress = FALSE;
data.nacked_seqnums = 0; data.nacked_seqnums = 0;
data.timeout_inactive_sources = sess->timeout_inactive_sources;
g_queue_init (&data.output); g_queue_init (&data.output);
RTP_SESSION_LOCK (sess); RTP_SESSION_LOCK (sess);

View file

@ -315,6 +315,8 @@ struct _RTPSession {
gboolean update_ntp64_header_ext; gboolean update_ntp64_header_ext;
gboolean timeout_inactive_sources;
/* Transport-wide cc-extension */ /* Transport-wide cc-extension */
RTPTWCCManager *twcc; RTPTWCCManager *twcc;
RTPTWCCStats *twcc_stats; RTPTWCCStats *twcc_stats;