From b43ee8f5b14684a621fe5d27d25ec00808ed8278 Mon Sep 17 00:00:00 2001 From: Havard Graff Date: Tue, 10 Apr 2018 18:05:47 +0200 Subject: [PATCH] rtpsession: Try media_ssrc if no src can be found for PLI sender_ssrc Some RTP stacks out there does not set the sender_ssrc. In order to be more robust, try to lookup the media_ssrc before dropping the PLI. https://bugzilla.gnome.org/show_bug.cgi?id=795139 --- gst/rtpmanager/rtpsession.c | 8 +++- tests/check/Makefile.am | 2 +- tests/check/elements/rtpsession.c | 90 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index e79dfb6..7b5aca0 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -2612,8 +2612,12 @@ rtp_session_process_pli (RTPSession * sess, guint32 sender_ssrc, return; src = find_source (sess, sender_ssrc); - if (src == NULL) - return; + if (src == NULL) { + /* try to find a src with media_ssrc instead */ + src = find_source (sess, media_ssrc); + if (src == NULL) + return; + } rtp_session_request_local_key_unit (sess, src, media_ssrc, FALSE, current_time); diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 905cd60..8339457 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -603,7 +603,7 @@ elements_rtprtx_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) elements_rtprtx_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-$(GST_API_VERSION) $(LDADD) elements_rtpsession_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) -elements_rtpsession_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_NET_LIBS) -lgstrtp-$(GST_API_VERSION) $(GIO_LIBS) $(LDADD) +elements_rtpsession_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_NET_LIBS) -lgstrtp-$(GST_API_VERSION) -lgstvideo-$(GST_API_VERSION) $(GIO_LIBS) $(LDADD) elements_rtpcollision_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS) elements_rtpcollision_LDADD = $(GST_PLUGINS_BASE_LIBS) $(GST_NET_LIBS) -lgstrtp-$(GST_API_VERSION) $(GIO_LIBS) $(LDADD) diff --git a/tests/check/elements/rtpsession.c b/tests/check/elements/rtpsession.c index 82243bd..bc02fc2 100644 --- a/tests/check/elements/rtpsession.c +++ b/tests/check/elements/rtpsession.c @@ -30,6 +30,7 @@ #include #include #include +#include #define TEST_BUF_CLOCK_RATE 8000 #define TEST_BUF_PT 0 @@ -801,6 +802,93 @@ GST_START_TEST (test_ignore_suspicious_bye) GST_END_TEST; +static GstBuffer * +create_buffer (guint8 * data, gsize size) +{ + return gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY, + data, size, 0, size, NULL, NULL); +} + +GST_START_TEST (test_receive_regular_pli) +{ + SessionHarness *h = session_harness_new (); + GstEvent *ev; + + /* PLI packet */ + guint8 rtcp_pkt[] = { + 0x81, /* PLI */ + 0xce, /* Type 206 Application layer feedback */ + 0x00, 0x02, /* Length */ + 0x37, 0x56, 0x93, 0xed, /* Sender SSRC */ + 0x37, 0x56, 0x93, 0xed /* Media SSRC */ + }; + + fail_unless_equals_int (GST_FLOW_OK, + session_harness_send_rtp (h, generate_test_buffer (0, 928420845))); + + session_harness_recv_rtcp (h, create_buffer (rtcp_pkt, sizeof (rtcp_pkt))); + fail_unless_equals_int (3, + gst_harness_upstream_events_received (h->send_rtp_h)); + + /* Remove the first 2 reconfigure events */ + fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL); + fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev)); + gst_event_unref (ev); + fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL); + fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev)); + gst_event_unref (ev); + + /* Then pull and check the force key-unit event */ + 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 (gst_video_event_is_force_key_unit (ev)); + gst_event_unref (ev); + + session_harness_free (h); +} + +GST_END_TEST; + +GST_START_TEST (test_receive_pli_no_sender_ssrc) +{ + SessionHarness *h = session_harness_new (); + GstEvent *ev; + + /* PLI packet */ + guint8 rtcp_pkt[] = { + 0x81, /* PLI */ + 0xce, /* Type 206 Application layer feedback */ + 0x00, 0x02, /* Length */ + 0x00, 0x00, 0x00, 0x00, /* Sender SSRC */ + 0x37, 0x56, 0x93, 0xed /* Media SSRC */ + }; + + fail_unless_equals_int (GST_FLOW_OK, + session_harness_send_rtp (h, generate_test_buffer (0, 928420845))); + + session_harness_recv_rtcp (h, create_buffer (rtcp_pkt, sizeof (rtcp_pkt))); + fail_unless_equals_int (3, + gst_harness_upstream_events_received (h->send_rtp_h)); + + /* Remove the first 2 reconfigure events */ + fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL); + fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev)); + gst_event_unref (ev); + fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL); + fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev)); + gst_event_unref (ev); + + /* Then pull and check the force key-unit event */ + 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 (gst_video_event_is_force_key_unit (ev)); + gst_event_unref (ev); + + session_harness_free (h); +} + +GST_END_TEST; + GST_START_TEST (test_illegal_rtcp_fb_packet) { SessionHarness *h = session_harness_new (); @@ -921,6 +1009,8 @@ rtpsession_suite (void) tcase_add_test (tc_chain, test_ignore_suspicious_bye); tcase_add_test (tc_chain, test_illegal_rtcp_fb_packet); tcase_add_test (tc_chain, test_feedback_rtcp_race); + tcase_add_test (tc_chain, test_receive_regular_pli); + tcase_add_test (tc_chain, test_receive_pli_no_sender_ssrc); return s; } -- 2.7.4