rtprtxsend: don't require clock-rate in caps
authorHavard Graff <havard.graff@gmail.com>
Fri, 11 Aug 2017 14:33:23 +0000 (16:33 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 15 Mar 2022 19:05:00 +0000 (19:05 +0000)
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>

subprojects/gst-plugins-good/gst/rtpmanager/gstrtprtxsend.c
subprojects/gst-plugins-good/tests/check/elements/rtprtx.c

index 4883ee7..1ebcb22 100644 (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 */
index 64f4383..87b1cc6 100644 (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);