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, static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
gpointer user_data); gpointer user_data);
static void gst_rtp_session_reconsider (RTPSession * sess, 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); gboolean all_headers, gpointer user_data);
static GstClockTime gst_rtp_session_request_time (RTPSession * session, static GstClockTime gst_rtp_session_request_time (RTPSession * session,
gpointer user_data); gpointer user_data);
@ -2647,7 +2647,7 @@ wrong_pad:
static void static void
gst_rtp_session_request_key_unit (RTPSession * sess, 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); GstRtpSession *rtpsession = GST_RTP_SESSION (user_data);
GstEvent *event; GstEvent *event;
@ -2660,7 +2660,7 @@ gst_rtp_session_request_key_unit (RTPSession * sess,
if (send_rtp_sink) { if (send_rtp_sink) {
event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, 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)); "all-headers", G_TYPE_BOOLEAN, all_headers, NULL));
gst_pad_push_event (send_rtp_sink, event); gst_pad_push_event (send_rtp_sink, event);
gst_object_unref (send_rtp_sink); gst_object_unref (send_rtp_sink);

View file

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

View file

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

View file

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