rtprtxsend: don't require clock-rate in caps

For multiplexing, the rtpstreams you are multiplexing might not use
the same clock-rate.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1881>
This commit is contained in:
Havard Graff 2017-08-11 16:33:23 +02:00 committed by GStreamer Marge Bot
parent 4d31641302
commit e5bd9839c4
2 changed files with 51 additions and 43 deletions

View file

@ -747,18 +747,24 @@ gst_rtp_rtx_send_get_ts_diff (SSRCRtxData * data)
if (!high_buf || !low_buf || high_buf == low_buf)
return 0;
high_ts = high_buf->timestamp;
low_ts = low_buf->timestamp;
if (data->clock_rate) {
high_ts = high_buf->timestamp;
low_ts = low_buf->timestamp;
/* it needs to work if ts wraps */
if (high_ts >= low_ts) {
result = (guint32) (high_ts - low_ts);
/* it needs to work if ts wraps */
if (high_ts >= low_ts) {
result = (guint32) (high_ts - low_ts);
} else {
result = (guint32) (high_ts + G_MAXUINT32 + 1 - low_ts);
}
result = gst_util_uint64_scale_int (result, 1000, data->clock_rate);
} else {
result = (guint32) (high_ts + G_MAXUINT32 + 1 - low_ts);
high_ts = GST_BUFFER_PTS (high_buf->buffer);
low_ts = GST_BUFFER_PTS (low_buf->buffer);
result = gst_util_uint64_scale_int_round (high_ts - low_ts, 1, GST_MSECOND);
}
/* return value in ms instead of clock ticks */
return (guint32) gst_util_uint64_scale_int (result, 1000, data->clock_rate);
return result;
}
/* Must be called with lock */

View file

@ -132,7 +132,7 @@ create_rtp_buffer (guint32 ssrc, guint8 payload_type, guint16 seqnum)
static GstBuffer *
create_rtp_buffer_with_timestamp (guint32 ssrc, guint8 payload_type,
guint16 seqnum, guint32 timestamp)
guint16 seqnum, guint32 timestamp, GstClockTime pts)
{
guint payload_size = 29;
GstRTPBuffer *rtpbuf = create_rtp_buffer_ex (ssrc, payload_type, seqnum,
@ -143,6 +143,9 @@ create_rtp_buffer_with_timestamp (guint32 ssrc, guint8 payload_type,
gst_rtp_buffer_unmap (rtpbuf);
g_free (rtpbuf);
GST_BUFFER_PTS (ret) = pts;
return ret;
}
@ -173,9 +176,7 @@ GST_START_TEST (test_rtxsend_basic)
g_object_set (h->element, "payload-type-map", pt_map, NULL);
gst_harness_set_src_caps_str (h, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
/* push a packet */
fail_unless_equals_int (GST_FLOW_OK,
@ -216,9 +217,7 @@ GST_START_TEST (test_rtxsend_disabled_enabled_disabled)
g_object_set (h->element, "ssrc-map", ssrc_map, NULL);
gst_harness_set_src_caps_str (h, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
/* push, pull, request-rtx, verify nothing arrives */
fail_unless_equals_int (GST_FLOW_OK,
@ -295,9 +294,7 @@ GST_START_TEST (test_rtxreceive_empty_rtx_packet)
"96", G_TYPE_UINT, rtx_pt, NULL);
g_object_set (h->element, "payload-type-map", pt_map, NULL);
gst_harness_set_src_caps_str (h, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
/* Assosiating master stream & rtx stream */
gst_harness_push_upstream_event (h,
@ -343,13 +340,9 @@ GST_START_TEST (test_rtxsend_rtxreceive)
g_object_set (hsend->element, "payload-type-map", pt_map, NULL);
gst_harness_set_src_caps_str (hsend, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
gst_harness_set_src_caps_str (hrecv, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
/* Push 'packets_num' packets through rtxsend to rtxreceive */
for (i = 0; i < packets_num; i++) {
@ -427,13 +420,9 @@ GST_START_TEST (test_rtxsend_rtxreceive_with_packet_loss)
g_object_set (hsend->element, "payload-type-map", pt_map, NULL);
gst_harness_set_src_caps_str (hsend, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
gst_harness_set_src_caps_str (hrecv, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
/* Getting rid of reconfigure event. Making sure there is no upstream
events in the queue. Preparation step before the test. */
@ -597,9 +586,7 @@ GST_START_TEST (test_multi_rtxsend_rtxreceive_with_packet_loss)
pt_map = create_rtxsenders (senders, 5);
g_object_set (hrecv->element, "payload-type-map", pt_map, NULL);
gst_harness_set_src_caps_str (hrecv, "application/x-rtp, "
"media = (string)video, payload = (int)80, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
"clock-rate = (int)90000");
/* Getting rid of reconfigure event. Making sure there is no upstream
events in the queue. Preparation step before the test. */
@ -694,7 +681,8 @@ GST_START_TEST (test_multi_rtxsend_rtxreceive_with_packet_loss)
GST_END_TEST;
static void
test_rtxsender_packet_retention (gboolean test_with_time)
test_rtxsender_packet_retention (gboolean test_with_time,
gboolean clock_rate_in_caps)
{
guint master_ssrc = 1234567;
guint master_pt = 96;
@ -710,6 +698,7 @@ test_rtxsender_packet_retention (gboolean test_with_time)
GstStructure *ssrc_map = gst_structure_new ("application/x-rtp-ssrc-map",
"1234567", G_TYPE_UINT, rtx_ssrc, NULL);
gint i, j;
GstClockTime pts = 0;
h = gst_harness_new ("rtprtxsend");
@ -723,15 +712,19 @@ test_rtxsender_packet_retention (gboolean test_with_time)
"max-size-time", test_with_time ? 499 : 0,
"payload-type-map", pt_map, "ssrc-map", ssrc_map, NULL);
gst_harness_set_src_caps_str (h, "application/x-rtp, "
"media = (string)video, payload = (int)96, "
"ssrc = (uint)1234567, clock-rate = (int)90000, "
"encoding-name = (string)RAW");
if (clock_rate_in_caps) {
gst_harness_set_src_caps_str (h, "application/x-rtp, "
"clock-rate = (int)90000");
} else {
gst_harness_set_src_caps_str (h, "application/x-rtp");
}
/* Now push all buffers and request retransmission every time for all of them */
for (i = 0; i < num_buffers; ++i, timestamp += timestamp_delta) {
for (i = 0; i < num_buffers; i++) {
pts += GST_SECOND / 30;
timestamp += timestamp_delta;
/* Request to retransmit all the previous ones */
for (j = 0; j < i; ++j) {
for (j = 0; j < i; j++) {
guint rtx_seqnum = 0x100 + j;
gst_harness_push_upstream_event (h,
create_rtx_event (master_ssrc, master_pt, rtx_seqnum));
@ -747,7 +740,7 @@ test_rtxsender_packet_retention (gboolean test_with_time)
to be sure, rtprtxsend can handle it properly */
push_pull_and_verify (h,
create_rtp_buffer_with_timestamp (master_ssrc, master_pt, 0x100 + i,
timestamp), FALSE, master_ssrc, master_pt, 0x100 + i);
timestamp, pts), FALSE, master_ssrc, master_pt, 0x100 + i);
}
gst_structure_free (pt_map);
@ -757,14 +750,21 @@ test_rtxsender_packet_retention (gboolean test_with_time)
GST_START_TEST (test_rtxsender_max_size_packets)
{
test_rtxsender_packet_retention (FALSE);
test_rtxsender_packet_retention (FALSE, TRUE);
}
GST_END_TEST;
GST_START_TEST (test_rtxsender_max_size_time)
{
test_rtxsender_packet_retention (TRUE);
test_rtxsender_packet_retention (TRUE, TRUE);
}
GST_END_TEST;
GST_START_TEST (test_rtxsender_max_size_time_no_clock_rate)
{
test_rtxsender_packet_retention (TRUE, FALSE);
}
GST_END_TEST;
@ -933,6 +933,8 @@ rtprtx_suite (void)
tcase_add_test (tc_chain, test_multi_rtxsend_rtxreceive_with_packet_loss);
tcase_add_test (tc_chain, test_rtxsender_max_size_packets);
tcase_add_test (tc_chain, test_rtxsender_max_size_time);
tcase_add_test (tc_chain, test_rtxsender_max_size_time_no_clock_rate);
tcase_add_test (tc_chain, test_rtxqueue_max_size_packets);
tcase_add_test (tc_chain, test_rtxqueue_max_size_time);
tcase_add_test (tc_chain, test_rtxsender_clock_rate_map);