mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
rtpsession: Process received Full Intra Requests
Process FIR requests according to RFC 5104 https://bugzilla.gnome.org/show_bug.cgi?id=658419
This commit is contained in:
parent
e7ae593993
commit
0ad78db0a3
2 changed files with 76 additions and 21 deletions
|
@ -2158,45 +2158,93 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet,
|
|||
GST_DEBUG ("received APP");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src,
|
||||
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) {
|
||||
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 < 2 * round_trip_in_ns) {
|
||||
GST_DEBUG ("Ignoring %s request 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),
|
||||
GST_TIME_ARGS (round_trip_in_ns));;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
sess->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,
|
||||
sess->callbacks.request_key_unit);
|
||||
|
||||
sess->callbacks.request_key_unit (sess, fir,
|
||||
sess->request_key_unit_user_data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
rtp_session_request_local_key_unit (sess, src, FALSE, current_time);
|
||||
}
|
||||
|
||||
static void
|
||||
rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
|
||||
guint8 * fci_data, guint fci_length, GstClockTime current_time)
|
||||
{
|
||||
RTPSource *src;
|
||||
guint32 ssrc;
|
||||
guint position = 0;
|
||||
gboolean our_request = FALSE;
|
||||
|
||||
if (!sess->callbacks.request_key_unit)
|
||||
return;
|
||||
|
||||
if (fci_length < 8)
|
||||
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);
|
||||
for (position = 0; position < fci_length; position += 8) {
|
||||
guint8 *data = fci_data + position;
|
||||
|
||||
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));;
|
||||
ssrc = GST_READ_UINT32_BE (data);
|
||||
|
||||
if (ssrc == rtp_source_get_ssrc (sess->source)) {
|
||||
our_request = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!our_request)
|
||||
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);
|
||||
rtp_session_request_local_key_unit (sess, src, TRUE, current_time);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2240,7 +2288,9 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet,
|
|||
rtp_source_retain_rtcp_packet (src, packet, arrival->running_time);
|
||||
}
|
||||
|
||||
if (rtp_source_get_ssrc (sess->source) == media_ssrc) {
|
||||
if (rtp_source_get_ssrc (sess->source) == media_ssrc ||
|
||||
/* PSFB FIR puts the media ssrc inside the FCI */
|
||||
(type == GST_RTCP_TYPE_PSFB && fbtype == GST_RTCP_PSFB_TYPE_FIR)) {
|
||||
switch (type) {
|
||||
case GST_RTCP_TYPE_PSFB:
|
||||
switch (fbtype) {
|
||||
|
@ -2248,6 +2298,10 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet,
|
|||
rtp_session_process_pli (sess, sender_ssrc, media_ssrc,
|
||||
current_time);
|
||||
break;
|
||||
case GST_RTCP_PSFB_TYPE_FIR:
|
||||
rtp_session_process_fir (sess, sender_ssrc, fci_data, fci_length,
|
||||
current_time);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -237,6 +237,7 @@ struct _RTPSession {
|
|||
|
||||
GArray *rtcp_pli_requests;
|
||||
GstClockTime last_keyframe_request;
|
||||
gboolean last_keyframe_all_headers;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue