mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
Use the correct SSRC(s) when routing a RTCB FB FIR
Previously we tried to route an incoming RTCP FB FIR to the correct ssrc using the "media source" component of the RTCP FB message. However, according to RFC5104 (section 4.3.1.2) the "media source" SHALL be set to 0. Instead the ssrc(s) in use are propagated via the FCI data. Now a specific GstForceKeyUnit event is sent for every ssrc. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3292>
This commit is contained in:
parent
cb225b3682
commit
9794c9bfd0
2 changed files with 33 additions and 19 deletions
|
@ -2742,9 +2742,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,
|
||||||
guint32 media_ssrc, gboolean fir, GstClockTime current_time)
|
const guint32 * ssrcs, guint num_ssrcs, gboolean fir,
|
||||||
|
GstClockTime current_time)
|
||||||
{
|
{
|
||||||
guint32 round_trip = 0;
|
guint32 round_trip = 0;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (ssrcs != NULL && num_ssrcs > 0, FALSE);
|
||||||
|
|
||||||
rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
&round_trip);
|
&round_trip);
|
||||||
|
@ -2770,14 +2774,17 @@ rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src,
|
||||||
|
|
||||||
src->last_keyframe_request = current_time;
|
src->last_keyframe_request = current_time;
|
||||||
|
|
||||||
GST_LOG ("received %s request from %X about %X %p(%p)", fir ? "FIR" : "PLI",
|
for (i = 0; i < num_ssrcs; ++i) {
|
||||||
rtp_source_get_ssrc (src), media_ssrc, sess->callbacks.process_rtp,
|
GST_LOG ("received %s request from %X about %X %p(%p)",
|
||||||
|
fir ? "FIR" : "PLI",
|
||||||
|
rtp_source_get_ssrc (src), ssrcs[i], 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, media_ssrc, fir,
|
sess->callbacks.request_key_unit (sess, ssrcs[i], fir,
|
||||||
sess->request_key_unit_user_data);
|
sess->request_key_unit_user_data);
|
||||||
RTP_SESSION_LOCK (sess);
|
RTP_SESSION_LOCK (sess);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2799,19 +2806,19 @@ rtp_session_process_pli (RTPSession * sess, guint32 sender_ssrc,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtp_session_request_local_key_unit (sess, src, media_ssrc, FALSE,
|
rtp_session_request_local_key_unit (sess, src, &media_ssrc, 1, FALSE,
|
||||||
current_time);
|
current_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
|
rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
|
||||||
guint32 media_ssrc, guint8 * fci_data, guint fci_length,
|
guint8 * fci_data, guint fci_length, GstClockTime current_time)
|
||||||
GstClockTime current_time)
|
|
||||||
{
|
{
|
||||||
RTPSource *src;
|
RTPSource *src;
|
||||||
guint32 ssrc;
|
guint32 ssrc;
|
||||||
guint position = 0;
|
guint position = 0;
|
||||||
gboolean our_request = FALSE;
|
guint32 ssrcs[32];
|
||||||
|
guint num_ssrcs = 0;
|
||||||
|
|
||||||
if (!sess->callbacks.request_key_unit)
|
if (!sess->callbacks.request_key_unit)
|
||||||
return;
|
return;
|
||||||
|
@ -2849,15 +2856,14 @@ rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
|
||||||
if (own == NULL)
|
if (own == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (own->internal) {
|
if (own->internal && num_ssrcs < 32) {
|
||||||
our_request = TRUE;
|
ssrcs[num_ssrcs++] = ssrc;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!our_request)
|
if (num_ssrcs == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rtp_session_request_local_key_unit (sess, src, media_ssrc, TRUE,
|
rtp_session_request_local_key_unit (sess, src, ssrcs, num_ssrcs, TRUE,
|
||||||
current_time);
|
current_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3022,8 +3028,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, media_ssrc, fci_data,
|
rtp_session_process_fir (sess, sender_ssrc, fci_data, fci_length,
|
||||||
fci_length, current_time);
|
current_time);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -988,6 +988,7 @@ GST_START_TEST (test_receive_regular_pli)
|
||||||
{
|
{
|
||||||
SessionHarness *h = session_harness_new ();
|
SessionHarness *h = session_harness_new ();
|
||||||
GstEvent *ev;
|
GstEvent *ev;
|
||||||
|
const GstStructure *s;
|
||||||
|
|
||||||
/* PLI packet */
|
/* PLI packet */
|
||||||
guint8 rtcp_pkt[] = {
|
guint8 rtcp_pkt[] = {
|
||||||
|
@ -1017,6 +1018,9 @@ GST_START_TEST (test_receive_regular_pli)
|
||||||
fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
|
fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
|
||||||
fail_unless_equals_int (GST_EVENT_CUSTOM_UPSTREAM, GST_EVENT_TYPE (ev));
|
fail_unless_equals_int (GST_EVENT_CUSTOM_UPSTREAM, GST_EVENT_TYPE (ev));
|
||||||
fail_unless (gst_video_event_is_force_key_unit (ev));
|
fail_unless (gst_video_event_is_force_key_unit (ev));
|
||||||
|
s = gst_event_get_structure (ev);
|
||||||
|
fail_unless (s);
|
||||||
|
fail_unless (G_VALUE_HOLDS_UINT (gst_structure_get_value (s, "ssrc")));
|
||||||
gst_event_unref (ev);
|
gst_event_unref (ev);
|
||||||
|
|
||||||
session_harness_free (h);
|
session_harness_free (h);
|
||||||
|
@ -1028,6 +1032,7 @@ GST_START_TEST (test_receive_pli_no_sender_ssrc)
|
||||||
{
|
{
|
||||||
SessionHarness *h = session_harness_new ();
|
SessionHarness *h = session_harness_new ();
|
||||||
GstEvent *ev;
|
GstEvent *ev;
|
||||||
|
const GstStructure *s;
|
||||||
|
|
||||||
/* PLI packet */
|
/* PLI packet */
|
||||||
guint8 rtcp_pkt[] = {
|
guint8 rtcp_pkt[] = {
|
||||||
|
@ -1057,6 +1062,9 @@ GST_START_TEST (test_receive_pli_no_sender_ssrc)
|
||||||
fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
|
fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
|
||||||
fail_unless_equals_int (GST_EVENT_CUSTOM_UPSTREAM, GST_EVENT_TYPE (ev));
|
fail_unless_equals_int (GST_EVENT_CUSTOM_UPSTREAM, GST_EVENT_TYPE (ev));
|
||||||
fail_unless (gst_video_event_is_force_key_unit (ev));
|
fail_unless (gst_video_event_is_force_key_unit (ev));
|
||||||
|
s = gst_event_get_structure (ev);
|
||||||
|
fail_unless (s);
|
||||||
|
fail_unless (G_VALUE_HOLDS_UINT (gst_structure_get_value (s, "ssrc")));
|
||||||
gst_event_unref (ev);
|
gst_event_unref (ev);
|
||||||
|
|
||||||
session_harness_free (h);
|
session_harness_free (h);
|
||||||
|
|
Loading…
Reference in a new issue