diff options
author | Olivier CrĂȘte <olivier.crete@collabora.co.uk> | 2010-10-19 22:21:54 +0200 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2011-02-01 18:28:51 +0100 |
commit | a630c68fc312d4ec79ca514f8770802da3c8ce26 (patch) | |
tree | 8d591e94c3038a969694119d2e3f265ecca8cb4b | |
parent | a61bb9e94b23f6dbed0319d6f018a8d857b2edcb (diff) |
rtpsession: Don't relay more than one PLI request per RTT
Drop PLI requests if one was relay in the last RTT, the other side may
just not have received the keyframe yet.
-rw-r--r-- | gst/rtpmanager/rtpsession.c | 49 | ||||
-rw-r--r-- | gst/rtpmanager/rtpsession.h | 1 |
2 files changed, 45 insertions, 5 deletions
diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index d3a7a548f..cf73043f6 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -2007,10 +2007,50 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet, GST_DEBUG ("received APP"); } +static void +rtp_session_process_pli (RTPSession * sess, guint32 sender_ssrc, + guint32 media_ssrc, GstClockTime current_time) +{ + RTPSource *src; + guint32 round_trip = 0; + + if (!sess->callbacks.request_key_unit) + return; + + src = g_hash_table_lookup (sess->ssrcs[sess->mask_idx], + GINT_TO_POINTER (sender_ssrc)); + + if (!src) + return; + + if (sess->last_keyframe_request != GST_CLOCK_TIME_NONE && + rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, + &round_trip)) { + GstClockTime round_trip_in_ns = gst_util_uint64_scale (round_trip, + GST_SECOND, 65536); + + if (sess->last_keyframe_request != GST_CLOCK_TIME_NONE && + current_time - sess->last_keyframe_request < round_trip_in_ns) { + GST_DEBUG ("Ignoring PLI because one was send without one RTT (%" + GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", + GST_TIME_ARGS (current_time - sess->last_keyframe_request), + GST_TIME_ARGS (round_trip_in_ns));; + return; + } + } + + sess->last_keyframe_request = current_time; + + GST_LOG ("received PLI from %X %p(%p)", sender_ssrc, + sess->callbacks.process_rtp, sess->callbacks.request_key_unit); + + sess->callbacks.request_key_unit (sess, FALSE, + sess->request_key_unit_user_data); +} static void rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, - RTPArrivalStats * arrival) + RTPArrivalStats * arrival, GstClockTime current_time) { GstRTCPType type = gst_rtcp_packet_get_type (packet); GstRTCPFBType fbtype = gst_rtcp_packet_fb_get_type (packet); @@ -2052,9 +2092,8 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, case GST_RTCP_TYPE_PSFB: switch (fbtype) { case GST_RTCP_PSFB_TYPE_PLI: - if (sess->callbacks.request_key_unit) - sess->callbacks.request_key_unit (sess, FALSE, - sess->request_key_unit_user_data); + rtp_session_process_pli (sess, sender_ssrc, media_ssrc, + current_time); break; default: break; @@ -2136,7 +2175,7 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, break; case GST_RTCP_TYPE_RTPFB: case GST_RTCP_TYPE_PSFB: - rtp_session_process_feedback (sess, &packet, &arrival); + rtp_session_process_feedback (sess, &packet, &arrival, current_time); break; default: GST_WARNING ("got unknown RTCP packet"); diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 0cc1f6bfd..95109425d 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -221,6 +221,7 @@ struct _RTPSession { GstClockTime rtcp_feedback_retention_window; GArray *rtcp_pli_requests; + GstClockTime last_keyframe_request; }; /** |