From 3aa69ca0bb771cfadfe6d1a29ae49da2dc39d8a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Par=C3=ADs=20D=C3=ADaz?= Date: Thu, 2 Feb 2017 12:55:25 +0100 Subject: [PATCH] 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 --- gst/rtpmanager/gstrtpsession.c | 6 +++--- gst/rtpmanager/rtpsession.c | 35 +++++++++++++++++----------------- gst/rtpmanager/rtpsession.h | 6 ++---- gst/rtpmanager/rtpsource.c | 2 ++ gst/rtpmanager/rtpsource.h | 1 + 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 149bed23a1..1434d9f8dd 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -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); diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index bcbc528391..3418ce55a8 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -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; diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index c25981adb8..5333b06f43 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -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; diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index 3554e0d235..172449de9c 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -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); } diff --git a/gst/rtpmanager/rtpsource.h b/gst/rtpmanager/rtpsource.h index 941c7d63e7..f5f093a71e 100644 --- a/gst/rtpmanager/rtpsource.h +++ b/gst/rtpmanager/rtpsource.h @@ -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;