Change StreamDataCounters to use Timestamp instead of int64_t

Bug: webrtc:13757
Change-Id: I11151682a07a2d95389f81cbd7f47f26ad8e67ce
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/306700
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40155}
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.cc b/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
index e4aec93..0d91ab9 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
@@ -45,7 +45,7 @@
           absl::c_all_of(name, isalnum));
 }
 
-StreamDataCounters::StreamDataCounters() : first_packet_time_ms(-1) {}
+StreamDataCounters::StreamDataCounters() = default;
 
 RtpPacketCounter::RtpPacketCounter(const RtpPacket& packet)
     : header_bytes(packet.headers_size()),
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
index 3b16521..ce39006 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
@@ -286,19 +286,6 @@
     total_packet_delay += other.total_packet_delay;
   }
 
-  void Subtract(const RtpPacketCounter& other) {
-    RTC_DCHECK_GE(header_bytes, other.header_bytes);
-    header_bytes -= other.header_bytes;
-    RTC_DCHECK_GE(payload_bytes, other.payload_bytes);
-    payload_bytes -= other.payload_bytes;
-    RTC_DCHECK_GE(padding_bytes, other.padding_bytes);
-    padding_bytes -= other.padding_bytes;
-    RTC_DCHECK_GE(packets, other.packets);
-    packets -= other.packets;
-    RTC_DCHECK_GE(total_packet_delay, other.total_packet_delay);
-    total_packet_delay -= other.total_packet_delay;
-  }
-
   bool operator==(const RtpPacketCounter& other) const {
     return header_bytes == other.header_bytes &&
            payload_bytes == other.payload_bytes &&
@@ -331,28 +318,24 @@
     transmitted.Add(other.transmitted);
     retransmitted.Add(other.retransmitted);
     fec.Add(other.fec);
-    if (other.first_packet_time_ms != -1 &&
-        (other.first_packet_time_ms < first_packet_time_ms ||
-         first_packet_time_ms == -1)) {
-      // Use oldest time.
-      first_packet_time_ms = other.first_packet_time_ms;
+    if (other.first_packet_time < first_packet_time) {
+      // Use oldest time (excluding unsed value represented as plus infinity.
+      first_packet_time = other.first_packet_time;
     }
   }
 
-  void Subtract(const StreamDataCounters& other) {
-    transmitted.Subtract(other.transmitted);
-    retransmitted.Subtract(other.retransmitted);
-    fec.Subtract(other.fec);
-    if (other.first_packet_time_ms != -1 &&
-        (other.first_packet_time_ms > first_packet_time_ms ||
-         first_packet_time_ms == -1)) {
-      // Use youngest time.
-      first_packet_time_ms = other.first_packet_time_ms;
+  void MaybeSetFirstPacketTime(Timestamp now) {
+    if (first_packet_time == Timestamp::PlusInfinity()) {
+      first_packet_time = now;
     }
   }
 
-  int64_t TimeSinceFirstPacketInMs(int64_t now_ms) const {
-    return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms);
+  // Return time since first packet is send/received, or zero if such event
+  // haven't happen.
+  TimeDelta TimeSinceFirstPacket(Timestamp now) const {
+    return first_packet_time == Timestamp::PlusInfinity()
+               ? TimeDelta::Zero()
+               : now - first_packet_time;
   }
 
   // Returns the number of bytes corresponding to the actual media payload (i.e.
@@ -363,7 +346,9 @@
            fec.payload_bytes;
   }
 
-  int64_t first_packet_time_ms;    // Time when first packet is sent/received.
+  // Time when first packet is sent/received.
+  Timestamp first_packet_time = Timestamp::PlusInfinity();
+
   RtpPacketCounter transmitted;    // Number of transmitted packets/bytes.
   RtpPacketCounter retransmitted;  // Number of retransmitted packets/bytes.
   RtpPacketCounter fec;            // Number of redundancy packets/bytes.
diff --git a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc
index be19c18..880b77d 100644
--- a/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc
+++ b/modules/rtp_rtcp/source/deprecated/deprecated_rtp_sender_egress.cc
@@ -434,14 +434,12 @@
 }
 
 void DEPRECATED_RtpSenderEgress::UpdateRtpStats(const RtpPacketToSend& packet) {
-  int64_t now_ms = clock_->TimeInMilliseconds();
+  Timestamp now = clock_->CurrentTime();
 
   StreamDataCounters* counters =
       packet.Ssrc() == rtx_ssrc_ ? &rtx_rtp_stats_ : &rtp_stats_;
 
-  if (counters->first_packet_time_ms == -1) {
-    counters->first_packet_time_ms = now_ms;
-  }
+  counters->MaybeSetFirstPacketTime(now);
 
   if (packet.packet_type() == RtpPacketMediaType::kForwardErrorCorrection) {
     counters->fec.AddPacket(packet);
@@ -454,7 +452,7 @@
 
   RTC_DCHECK(packet.packet_type().has_value());
   send_rates_[static_cast<size_t>(*packet.packet_type())].Update(packet.size(),
-                                                                 now_ms);
+                                                                 now.ms());
 
   if (rtp_stats_callback_) {
     rtp_stats_callback_->DataCountersUpdated(*counters, packet.Ssrc());
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc
index e5a5746..48a1fe8 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -110,7 +110,8 @@
 
 void StreamStatisticianImpl::UpdateCounters(const RtpPacketReceived& packet) {
   RTC_DCHECK_EQ(ssrc_, packet.Ssrc());
-  int64_t now_ms = clock_->TimeInMilliseconds();
+  Timestamp now = clock_->CurrentTime();
+  int64_t now_ms = now.ms();
 
   incoming_bitrate_.Update(packet.size(), now_ms);
   receive_counters_.transmitted.AddPacket(packet);
@@ -124,7 +125,7 @@
     received_seq_first_ = sequence_number;
     last_report_seq_max_ = sequence_number - 1;
     received_seq_max_ = sequence_number - 1;
-    receive_counters_.first_packet_time_ms = now_ms;
+    receive_counters_.first_packet_time = now;
   } else if (UpdateOutOfOrder(packet, sequence_number, now_ms)) {
     return;
   }
diff --git a/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
index 69164c2..66e3061 100644
--- a/modules/rtp_rtcp/source/receive_statistics_unittest.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
@@ -259,12 +259,12 @@
   ASSERT_TRUE(statistician != NULL);
 
   StreamDataCounters counters = statistician->GetReceiveStreamDataCounters();
-  EXPECT_GT(counters.first_packet_time_ms, -1);
+  EXPECT_TRUE(counters.first_packet_time.IsFinite());
   EXPECT_EQ(1u, counters.transmitted.packets);
 
   receive_statistics_->OnRtpPacket(packet1_);
   counters = statistician->GetReceiveStreamDataCounters();
-  EXPECT_GT(counters.first_packet_time_ms, -1);
+  EXPECT_TRUE(counters.first_packet_time.IsFinite());
   EXPECT_EQ(2u, counters.transmitted.packets);
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
index d183c5b..5e3406c 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2_unittest.cc
@@ -494,8 +494,8 @@
 
 TEST_F(RtpRtcpImpl2Test, AddStreamDataCounters) {
   StreamDataCounters rtp;
-  const int64_t kStartTimeMs = 1;
-  rtp.first_packet_time_ms = kStartTimeMs;
+  const Timestamp kStartTime = Timestamp::Seconds(1);
+  rtp.first_packet_time = kStartTime;
   rtp.transmitted.packets = 1;
   rtp.transmitted.payload_bytes = 1;
   rtp.transmitted.header_bytes = 2;
@@ -505,7 +505,6 @@
                                               rtp.transmitted.padding_bytes);
 
   StreamDataCounters rtp2;
-  rtp2.first_packet_time_ms = -1;
   rtp2.transmitted.packets = 10;
   rtp2.transmitted.payload_bytes = 10;
   rtp2.retransmitted.header_bytes = 4;
@@ -516,7 +515,7 @@
 
   StreamDataCounters sum = rtp;
   sum.Add(rtp2);
-  EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);
+  EXPECT_EQ(sum.first_packet_time, kStartTime);
   EXPECT_EQ(11U, sum.transmitted.packets);
   EXPECT_EQ(11U, sum.transmitted.payload_bytes);
   EXPECT_EQ(2U, sum.transmitted.header_bytes);
@@ -530,9 +529,9 @@
             rtp.transmitted.TotalBytes() + rtp2.transmitted.TotalBytes());
 
   StreamDataCounters rtp3;
-  rtp3.first_packet_time_ms = kStartTimeMs + 10;
+  rtp3.first_packet_time = kStartTime + TimeDelta::Millis(10);
   sum.Add(rtp3);
-  EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);  // Holds oldest time.
+  EXPECT_EQ(sum.first_packet_time, kStartTime);  // Holds oldest time.
 }
 
 TEST_F(RtpRtcpImpl2Test, SendsInitialNackList) {
diff --git a/modules/rtp_rtcp/source/rtp_sender_egress.cc b/modules/rtp_rtcp/source/rtp_sender_egress.cc
index a4aa748..212bc52 100644
--- a/modules/rtp_rtcp/source/rtp_sender_egress.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_egress.cc
@@ -581,9 +581,7 @@
     StreamDataCounters* counters =
         packet_ssrc == rtx_ssrc_ ? &rtx_rtp_stats_ : &rtp_stats_;
 
-    if (counters->first_packet_time_ms == -1) {
-      counters->first_packet_time_ms = now.ms();
-    }
+    counters->MaybeSetFirstPacketTime(now);
 
     if (packet_type == RtpPacketMediaType::kForwardErrorCorrection) {
       counters->fec.Add(counter);
diff --git a/video/receive_statistics_proxy.cc b/video/receive_statistics_proxy.cc
index 0d3cf79..faa0ea9 100644
--- a/video/receive_statistics_proxy.cc
+++ b/video/receive_statistics_proxy.cc
@@ -391,10 +391,9 @@
   if (rtx_stats)
     rtp_rtx_stats.Add(*rtx_stats);
 
-  int64_t elapsed_sec =
-      rtp_rtx_stats.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) /
-      1000;
-  if (elapsed_sec >= metrics::kMinRunTimeInSeconds) {
+  TimeDelta elapsed = rtp_rtx_stats.TimeSinceFirstPacket(clock_->CurrentTime());
+  if (elapsed >= TimeDelta::Seconds(metrics::kMinRunTimeInSeconds)) {
+    int64_t elapsed_sec = elapsed.seconds();
     RTC_HISTOGRAM_COUNTS_10000(
         "WebRTC.Video.BitrateReceivedInKbps",
         static_cast<int>(rtp_rtx_stats.transmitted.TotalBytes() * 8 /
diff --git a/video/receive_statistics_proxy_unittest.cc b/video/receive_statistics_proxy_unittest.cc
index 766ca39..7854c79 100644
--- a/video/receive_statistics_proxy_unittest.cc
+++ b/video/receive_statistics_proxy_unittest.cc
@@ -1143,8 +1143,7 @@
 TEST_F(ReceiveStatisticsProxyTest,
        RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
   StreamDataCounters data_counters;
-  data_counters.first_packet_time_ms =
-      time_controller_.GetClock()->TimeInMilliseconds();
+  data_counters.first_packet_time = time_controller_.GetClock()->CurrentTime();
 
   time_controller_.AdvanceTime(
       TimeDelta::Seconds(metrics::kMinRunTimeInSeconds) - TimeDelta::Millis(1));
@@ -1163,8 +1162,7 @@
 
 TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) {
   StreamDataCounters data_counters;
-  data_counters.first_packet_time_ms =
-      time_controller_.GetClock()->TimeInMilliseconds();
+  data_counters.first_packet_time = time_controller_.GetClock()->CurrentTime();
   time_controller_.AdvanceTime(
       TimeDelta::Seconds(metrics::kMinRunTimeInSeconds));
 
diff --git a/video/send_statistics_proxy_unittest.cc b/video/send_statistics_proxy_unittest.cc
index c374acc..9db7741 100644
--- a/video/send_statistics_proxy_unittest.cc
+++ b/video/send_statistics_proxy_unittest.cc
@@ -2618,7 +2618,7 @@
       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
   StreamDataCounters counters;
   StreamDataCounters rtx_counters;
-  counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
+  counters.first_packet_time = fake_clock_.CurrentTime();
 
   const int kMinRequiredPeriodSamples = 8;
   const int kPeriodIntervalMs = 2000;