From 280d86a841eb58324fcc5da3db19cdb04c4b41ef Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Tue, 20 Nov 2018 02:45:04 +0100 Subject: [PATCH] rtpsession: Add disable-sr-timestamp property The Onvif Streaming Spec, in section 6.11, mandates that when Rate-Control is disabled potential RTCP packets shall have their timestamps set to 0. --- gst/rtpmanager/rtpsession.c | 30 +++++++++++++++++++++-- gst/rtpmanager/rtpsession.h | 2 ++ tests/check/elements/rtpsession.c | 40 +++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index d43938b3fb..b7354c10b0 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -75,6 +75,7 @@ enum #define DEFAULT_MAX_MISORDER_TIME 2000 #define DEFAULT_RTP_PROFILE GST_RTP_PROFILE_AVP #define DEFAULT_RTCP_REDUCED_SIZE FALSE +#define DEFAULT_RTCP_DISABLE_SR_TIMESTAMP FALSE enum { @@ -99,7 +100,8 @@ enum PROP_MAX_MISORDER_TIME, PROP_STATS, PROP_RTP_PROFILE, - PROP_RTCP_REDUCED_SIZE + PROP_RTCP_REDUCED_SIZE, + PROP_RTCP_DISABLE_SR_TIMESTAMP }; /* update average packet size */ @@ -583,6 +585,21 @@ rtp_session_class_init (RTPSessionClass * klass) DEFAULT_RTCP_REDUCED_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /** + * RTPSession::disable-sr-timestamp: + * + * Whether sender reports should be timestamped. + * + * Since: 1.16 + */ + g_object_class_install_property (gobject_class, + PROP_RTCP_DISABLE_SR_TIMESTAMP, + g_param_spec_boolean ("disable-sr-timestamp", + "Disable Sender Report Timestamp", + "Whether sender reports should be timestamped", + DEFAULT_RTCP_DISABLE_SR_TIMESTAMP, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + klass->get_source_by_ssrc = GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc); klass->send_rtcp = GST_DEBUG_FUNCPTR (rtp_session_send_rtcp); @@ -663,6 +680,7 @@ rtp_session_init (RTPSession * sess) DEFAULT_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD; sess->rtp_profile = DEFAULT_RTP_PROFILE; sess->reduced_size_rtcp = DEFAULT_RTCP_REDUCED_SIZE; + sess->timestamp_sender_reports = !DEFAULT_RTCP_DISABLE_SR_TIMESTAMP; sess->is_doing_ptp = TRUE; } @@ -850,6 +868,9 @@ rtp_session_set_property (GObject * object, guint prop_id, case PROP_RTCP_REDUCED_SIZE: sess->reduced_size_rtcp = g_value_get_boolean (value); break; + case PROP_RTCP_DISABLE_SR_TIMESTAMP: + sess->timestamp_sender_reports = !g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -929,6 +950,9 @@ rtp_session_get_property (GObject * object, guint prop_id, case PROP_RTCP_REDUCED_SIZE: g_value_set_boolean (value, sess->reduced_size_rtcp); break; + case PROP_RTCP_DISABLE_SR_TIMESTAMP: + g_value_set_boolean (value, !sess->timestamp_sender_reports); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3403,7 +3427,9 @@ session_start_rtcp (RTPSession * sess, ReportData * data) /* fill in sender report info */ gst_rtcp_packet_sr_set_sender_info (packet, own->ssrc, - ntptime, rtptime, packet_count, octet_count); + sess->timestamp_sender_reports ? ntptime : 0, + sess->timestamp_sender_reports ? rtptime : 0, + packet_count, octet_count); } else { /* we are only receiver, create RR */ GST_DEBUG ("create RR for SSRC %08x", own->ssrc); diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 0c54895d7a..9158f48669 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -293,6 +293,8 @@ struct _RTPSession { gboolean is_doing_ptp; GList *conflicting_addresses; + + gboolean timestamp_sender_reports; }; /** diff --git a/tests/check/elements/rtpsession.c b/tests/check/elements/rtpsession.c index 9f00f7d85f..877eb4639b 100644 --- a/tests/check/elements/rtpsession.c +++ b/tests/check/elements/rtpsession.c @@ -1691,6 +1691,45 @@ GST_START_TEST (test_request_nack_packing) GST_END_TEST; +GST_START_TEST (test_disable_sr_timestamp) +{ + SessionHarness *h = session_harness_new (); + GstBuffer *buf; + GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT; + GstRTCPPacket rtcp_packet; + guint64 ntptime; + guint32 rtptime; + + g_object_set (h->internal_session, "disable-sr-timestamp", TRUE, NULL); + + /* Push RTP buffer to make sure RTCP-thread have started */ + fail_unless_equals_int (GST_FLOW_OK, + session_harness_send_rtp (h, generate_test_buffer (0, 0xDEADBEEF))); + + /* crank the RTCP-thread and pull out rtcp, generating a stats-callback */ + session_harness_crank_clock (h); + buf = session_harness_pull_rtcp (h); + + gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp); + + fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet)); + + fail_unless_equals_int (GST_RTCP_TYPE_SR, + gst_rtcp_packet_get_type (&rtcp_packet)); + + gst_rtcp_packet_sr_get_sender_info (&rtcp_packet, NULL, &ntptime, &rtptime, + NULL, NULL); + + fail_unless_equals_uint64 (ntptime, 0); + fail_unless (rtptime == 0); + + gst_rtcp_buffer_unmap (&rtcp); + gst_buffer_unref (buf); + + session_harness_free (h); +} + +GST_END_TEST; static Suite * rtpsession_suite (void) @@ -1719,6 +1758,7 @@ rtpsession_suite (void) tcase_add_test (tc_chain, test_dont_send_rtcp_while_idle); tcase_add_test (tc_chain, test_send_rtcp_when_signalled); tcase_add_test (tc_chain, test_change_sent_sdes); + tcase_add_test (tc_chain, test_disable_sr_timestamp); return s; }