rtpsession: relate received FIRs and PLIs to source

This is needed in order to:
 - Avoid ignoring requests for different media sources.
 - Add SSRC field in the GstForceKeyUnit event.

https://bugzilla.gnome.org/show_bug.cgi?id=778013
This commit is contained in:
Miguel París Díaz 2017-02-02 12:55:25 +01:00 committed by Olivier Crête
parent 19c9600ea6
commit 3aa69ca0bb
5 changed files with 26 additions and 24 deletions

View file

@ -299,7 +299,7 @@ static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess,
static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
gpointer user_data);
static void gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data);
static void gst_rtp_session_request_key_unit (RTPSession * sess,
static void gst_rtp_session_request_key_unit (RTPSession * sess, guint32 ssrc,
gboolean all_headers, gpointer user_data);
static GstClockTime gst_rtp_session_request_time (RTPSession * session,
gpointer user_data);
@ -2647,7 +2647,7 @@ wrong_pad:
static void
gst_rtp_session_request_key_unit (RTPSession * sess,
gboolean all_headers, gpointer user_data)
guint32 ssrc, gboolean all_headers, gpointer user_data)
{
GstRtpSession *rtpsession = GST_RTP_SESSION (user_data);
GstEvent *event;
@ -2660,7 +2660,7 @@ gst_rtp_session_request_key_unit (RTPSession * sess,
if (send_rtp_sink) {
event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
gst_structure_new ("GstForceKeyUnit",
gst_structure_new ("GstForceKeyUnit", "ssrc", G_TYPE_UINT, ssrc,
"all-headers", G_TYPE_BOOLEAN, all_headers, NULL));
gst_pad_push_event (send_rtp_sink, event);
gst_object_unref (send_rtp_sink);

View file

@ -662,8 +662,6 @@ rtp_session_init (RTPSession * sess)
sess->rtp_profile = DEFAULT_RTP_PROFILE;
sess->reduced_size_rtcp = DEFAULT_RTCP_REDUCED_SIZE;
sess->last_keyframe_request = GST_CLOCK_TIME_NONE;
sess->is_doing_ptp = TRUE;
}
@ -2565,13 +2563,13 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet,
static gboolean
rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src,
gboolean fir, GstClockTime current_time)
guint32 media_ssrc, gboolean fir, GstClockTime current_time)
{
guint32 round_trip = 0;
rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, &round_trip);
if (sess->last_keyframe_request != GST_CLOCK_TIME_NONE && round_trip) {
if (src->last_keyframe_request != GST_CLOCK_TIME_NONE && round_trip) {
GstClockTime round_trip_in_ns = gst_util_uint64_scale (round_trip,
GST_SECOND, 65536);
@ -2580,24 +2578,24 @@ rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src,
if (round_trip_in_ns > 5 * GST_SECOND)
round_trip_in_ns = GST_SECOND / 2;
if (current_time - sess->last_keyframe_request < 2 * round_trip_in_ns) {
GST_DEBUG ("Ignoring %s request because one was send without one "
if (current_time - src->last_keyframe_request < 2 * round_trip_in_ns) {
GST_DEBUG ("Ignoring %s request from %X because one was send without one "
"RTT (%" GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")",
fir ? "FIR" : "PLI",
GST_TIME_ARGS (current_time - sess->last_keyframe_request),
fir ? "FIR" : "PLI", rtp_source_get_ssrc (src),
GST_TIME_ARGS (current_time - src->last_keyframe_request),
GST_TIME_ARGS (round_trip_in_ns));
return FALSE;
}
}
sess->last_keyframe_request = current_time;
src->last_keyframe_request = current_time;
GST_LOG ("received %s request from %X %p(%p)", fir ? "FIR" : "PLI",
rtp_source_get_ssrc (src), sess->callbacks.process_rtp,
GST_LOG ("received %s request from %X about %X %p(%p)", fir ? "FIR" : "PLI",
rtp_source_get_ssrc (src), media_ssrc, sess->callbacks.process_rtp,
sess->callbacks.request_key_unit);
RTP_SESSION_UNLOCK (sess);
sess->callbacks.request_key_unit (sess, fir,
sess->callbacks.request_key_unit (sess, media_ssrc, fir,
sess->request_key_unit_user_data);
RTP_SESSION_LOCK (sess);
@ -2617,12 +2615,14 @@ rtp_session_process_pli (RTPSession * sess, guint32 sender_ssrc,
if (src == NULL)
return;
rtp_session_request_local_key_unit (sess, src, FALSE, current_time);
rtp_session_request_local_key_unit (sess, src, media_ssrc, FALSE,
current_time);
}
static void
rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
guint8 * fci_data, guint fci_length, GstClockTime current_time)
guint32 media_ssrc, guint8 * fci_data, guint fci_length,
GstClockTime current_time)
{
RTPSource *src;
guint32 ssrc;
@ -2673,7 +2673,8 @@ rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
if (!our_request)
return;
rtp_session_request_local_key_unit (sess, src, TRUE, current_time);
rtp_session_request_local_key_unit (sess, src, media_ssrc, TRUE,
current_time);
}
static void
@ -2764,8 +2765,8 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet,
case GST_RTCP_PSFB_TYPE_FIR:
if (src)
src->stats.recv_fir_count++;
rtp_session_process_fir (sess, sender_ssrc, fci_data, fci_length,
current_time);
rtp_session_process_fir (sess, sender_ssrc, media_ssrc, fci_data,
fci_length, current_time);
break;
default:
break;

View file

@ -120,6 +120,7 @@ typedef void (*RTPSessionReconsider) (RTPSession *sess, gpointer user_data);
/**
* RTPSessionRequestKeyUnit:
* @sess: an #RTPSession
* @ssrc: SSRC of the source related to the key unit request
* @all_headers: %TRUE if "all-headers" property should be set on the key unit
* request
* @user_data: user data specified when registering
@ -127,7 +128,7 @@ typedef void (*RTPSessionReconsider) (RTPSession *sess, gpointer user_data);
* Asks the encoder to produce a key unit as soon as possibly within the
* bandwidth constraints
*/
typedef void (*RTPSessionRequestKeyUnit) (RTPSession *sess,
typedef void (*RTPSessionRequestKeyUnit) (RTPSession *sess, guint32 ssrc,
gboolean all_headers, gpointer user_data);
/**
@ -275,9 +276,6 @@ struct _RTPSession {
GstClockTime rtcp_feedback_retention_window;
guint rtcp_immediate_feedback_threshold;
GstClockTime last_keyframe_request;
gboolean last_keyframe_all_headers;
gboolean is_doing_ptp;
GList *conflicting_addresses;

View file

@ -301,6 +301,8 @@ rtp_source_init (RTPSource * src)
src->reported_in_sr_of = g_hash_table_new (g_direct_hash, g_direct_equal);
src->last_keyframe_request = GST_CLOCK_TIME_NONE;
rtp_source_reset (src);
}

View file

@ -194,6 +194,7 @@ struct _RTPSource {
gboolean send_fir;
guint8 current_send_fir_seqnum;
gint last_fir_count;
GstClockTime last_keyframe_request;
gboolean send_nack;
GArray *nacks;