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.

<https://www.onvif.org/specs/stream/ONVIF-Streaming-Spec.pdf>
This commit is contained in:
Mathieu Duponchelle 2018-11-20 02:45:04 +01:00
parent 603c7a52fd
commit 280d86a841
3 changed files with 70 additions and 2 deletions

View file

@ -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);

View file

@ -293,6 +293,8 @@ struct _RTPSession {
gboolean is_doing_ptp;
GList *conflicting_addresses;
gboolean timestamp_sender_reports;
};
/**

View file

@ -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;
}