Use Timestamp to represent packet receive timestamps

Before this CL, timestamps of received packets were rounded
to the nearest millisecond and stored as int64_t. Due to the
rounding it sometimes happened that timestamps later in the
pipeline that are not rounded seem to occur even before the
video frame was received.

Change-Id: I92d8f3540b23baae2d4a1dc6a7cb3f58bcdaad18
Bug: webrtc:12722
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/216398
Reviewed-by: Chen Xing <chxg@google.com>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33916}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index c8e2952..212e9cd 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -90,6 +90,7 @@
     ":scoped_refptr",
     "../rtc_base:rtc_base_approved",
     "../rtc_base/system:rtc_export",
+    "units:timestamp",
   ]
   absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
 }
diff --git a/api/rtp_packet_info.cc b/api/rtp_packet_info.cc
index a9ebd9d..68e78d7 100644
--- a/api/rtp_packet_info.cc
+++ b/api/rtp_packet_info.cc
@@ -16,7 +16,7 @@
 namespace webrtc {
 
 RtpPacketInfo::RtpPacketInfo()
-    : ssrc_(0), rtp_timestamp_(0), receive_time_ms_(-1) {}
+    : ssrc_(0), rtp_timestamp_(0), receive_time_(Timestamp::MinusInfinity()) {}
 
 RtpPacketInfo::RtpPacketInfo(
     uint32_t ssrc,
@@ -24,19 +24,19 @@
     uint32_t rtp_timestamp,
     absl::optional<uint8_t> audio_level,
     absl::optional<AbsoluteCaptureTime> absolute_capture_time,
-    int64_t receive_time_ms)
+    Timestamp receive_time)
     : ssrc_(ssrc),
       csrcs_(std::move(csrcs)),
       rtp_timestamp_(rtp_timestamp),
       audio_level_(audio_level),
       absolute_capture_time_(absolute_capture_time),
-      receive_time_ms_(receive_time_ms) {}
+      receive_time_(receive_time) {}
 
 RtpPacketInfo::RtpPacketInfo(const RTPHeader& rtp_header,
-                             int64_t receive_time_ms)
+                             Timestamp receive_time)
     : ssrc_(rtp_header.ssrc),
       rtp_timestamp_(rtp_header.timestamp),
-      receive_time_ms_(receive_time_ms) {
+      receive_time_(receive_time) {
   const auto& extension = rtp_header.extension;
   const auto csrcs_count = std::min<size_t>(rtp_header.numCSRCs, kRtpCsrcSize);
 
@@ -49,12 +49,29 @@
   absolute_capture_time_ = extension.absolute_capture_time;
 }
 
+RtpPacketInfo::RtpPacketInfo(
+    uint32_t ssrc,
+    std::vector<uint32_t> csrcs,
+    uint32_t rtp_timestamp,
+    absl::optional<uint8_t> audio_level,
+    absl::optional<AbsoluteCaptureTime> absolute_capture_time,
+    int64_t receive_time_ms)
+    : RtpPacketInfo(ssrc,
+                    csrcs,
+                    rtp_timestamp,
+                    audio_level,
+                    absolute_capture_time,
+                    Timestamp::Millis(receive_time_ms)) {}
+RtpPacketInfo::RtpPacketInfo(const RTPHeader& rtp_header,
+                             int64_t receive_time_ms)
+    : RtpPacketInfo(rtp_header, Timestamp::Millis(receive_time_ms)) {}
+
 bool operator==(const RtpPacketInfo& lhs, const RtpPacketInfo& rhs) {
   return (lhs.ssrc() == rhs.ssrc()) && (lhs.csrcs() == rhs.csrcs()) &&
          (lhs.rtp_timestamp() == rhs.rtp_timestamp()) &&
          (lhs.audio_level() == rhs.audio_level()) &&
          (lhs.absolute_capture_time() == rhs.absolute_capture_time()) &&
-         (lhs.receive_time_ms() == rhs.receive_time_ms());
+         (lhs.receive_time() == rhs.receive_time());
 }
 
 }  // namespace webrtc
diff --git a/api/rtp_packet_info.h b/api/rtp_packet_info.h
index 639ba32..ed48470 100644
--- a/api/rtp_packet_info.h
+++ b/api/rtp_packet_info.h
@@ -17,6 +17,7 @@
 
 #include "absl/types/optional.h"
 #include "api/rtp_headers.h"
+#include "api/units/timestamp.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -35,8 +36,18 @@
                 uint32_t rtp_timestamp,
                 absl::optional<uint8_t> audio_level,
                 absl::optional<AbsoluteCaptureTime> absolute_capture_time,
-                int64_t receive_time_ms);
+                Timestamp receive_time);
 
+  RtpPacketInfo(const RTPHeader& rtp_header, Timestamp receive_time);
+
+  // TODO(bugs.webrtc.org/12722): Deprecated, remove once downstream projects
+  // are updated.
+  RtpPacketInfo(uint32_t ssrc,
+                std::vector<uint32_t> csrcs,
+                uint32_t rtp_timestamp,
+                absl::optional<uint8_t> audio_level,
+                absl::optional<AbsoluteCaptureTime> absolute_capture_time,
+                int64_t receive_time_ms);
   RtpPacketInfo(const RTPHeader& rtp_header, int64_t receive_time_ms);
 
   RtpPacketInfo(const RtpPacketInfo& other) = default;
@@ -64,8 +75,11 @@
     absolute_capture_time_ = value;
   }
 
-  int64_t receive_time_ms() const { return receive_time_ms_; }
-  void set_receive_time_ms(int64_t value) { receive_time_ms_ = value; }
+  Timestamp receive_time() const { return receive_time_; }
+  void set_receive_time(Timestamp value) { receive_time_ = value; }
+  // TODO(bugs.webrtc.org/12722): Deprecated, remove once downstream projects
+  // are updated.
+  int64_t receive_time_ms() const { return receive_time_.ms(); }
 
  private:
   // Fields from the RTP header:
@@ -83,7 +97,7 @@
   absl::optional<AbsoluteCaptureTime> absolute_capture_time_;
 
   // Local |webrtc::Clock|-based timestamp of when the packet was received.
-  int64_t receive_time_ms_;
+  Timestamp receive_time_;
 };
 
 bool operator==(const RtpPacketInfo& lhs, const RtpPacketInfo& rhs);
diff --git a/api/rtp_packet_info_unittest.cc b/api/rtp_packet_info_unittest.cc
index fe79f6d..7af7323 100644
--- a/api/rtp_packet_info_unittest.cc
+++ b/api/rtp_packet_info_unittest.cc
@@ -37,7 +37,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.ssrc(), value);
 
-  rhs = RtpPacketInfo(value, {}, {}, {}, {}, {});
+  rhs = RtpPacketInfo(value, {}, {}, {}, {}, Timestamp::Millis(0));
   EXPECT_EQ(rhs.ssrc(), value);
 }
 
@@ -64,7 +64,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.csrcs(), value);
 
-  rhs = RtpPacketInfo({}, value, {}, {}, {}, {});
+  rhs = RtpPacketInfo({}, value, {}, {}, {}, Timestamp::Millis(0));
   EXPECT_EQ(rhs.csrcs(), value);
 }
 
@@ -91,7 +91,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.rtp_timestamp(), value);
 
-  rhs = RtpPacketInfo({}, {}, value, {}, {}, {});
+  rhs = RtpPacketInfo({}, {}, value, {}, {}, Timestamp::Millis(0));
   EXPECT_EQ(rhs.rtp_timestamp(), value);
 }
 
@@ -118,7 +118,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.audio_level(), value);
 
-  rhs = RtpPacketInfo({}, {}, {}, value, {}, {});
+  rhs = RtpPacketInfo({}, {}, {}, value, {}, Timestamp::Millis(0));
   EXPECT_EQ(rhs.audio_level(), value);
 }
 
@@ -145,12 +145,12 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.absolute_capture_time(), value);
 
-  rhs = RtpPacketInfo({}, {}, {}, {}, value, {});
+  rhs = RtpPacketInfo({}, {}, {}, {}, value, Timestamp::Millis(0));
   EXPECT_EQ(rhs.absolute_capture_time(), value);
 }
 
 TEST(RtpPacketInfoTest, ReceiveTimeMs) {
-  const int64_t value = 8868963877546349045LL;
+  const Timestamp timestamp = Timestamp::Micros(8868963877546349045LL);
 
   RtpPacketInfo lhs;
   RtpPacketInfo rhs;
@@ -158,8 +158,8 @@
   EXPECT_TRUE(lhs == rhs);
   EXPECT_FALSE(lhs != rhs);
 
-  rhs.set_receive_time_ms(value);
-  EXPECT_EQ(rhs.receive_time_ms(), value);
+  rhs.set_receive_time(timestamp);
+  EXPECT_EQ(rhs.receive_time(), timestamp);
 
   EXPECT_FALSE(lhs == rhs);
   EXPECT_TRUE(lhs != rhs);
@@ -170,10 +170,10 @@
   EXPECT_FALSE(lhs != rhs);
 
   rhs = RtpPacketInfo();
-  EXPECT_NE(rhs.receive_time_ms(), value);
+  EXPECT_NE(rhs.receive_time(), timestamp);
 
-  rhs = RtpPacketInfo({}, {}, {}, {}, {}, value);
-  EXPECT_EQ(rhs.receive_time_ms(), value);
+  rhs = RtpPacketInfo({}, {}, {}, {}, {}, timestamp);
+  EXPECT_EQ(rhs.receive_time(), timestamp);
 }
 
 }  // namespace webrtc
diff --git a/api/rtp_packet_infos_unittest.cc b/api/rtp_packet_infos_unittest.cc
index ce502ac..e83358f 100644
--- a/api/rtp_packet_infos_unittest.cc
+++ b/api/rtp_packet_infos_unittest.cc
@@ -27,9 +27,12 @@
 }  // namespace
 
 TEST(RtpPacketInfosTest, BasicFunctionality) {
-  RtpPacketInfo p0(123, {1, 2}, 89, 5, AbsoluteCaptureTime{45, 78}, 7);
-  RtpPacketInfo p1(456, {3, 4}, 89, 4, AbsoluteCaptureTime{13, 21}, 1);
-  RtpPacketInfo p2(789, {5, 6}, 88, 1, AbsoluteCaptureTime{99, 78}, 7);
+  RtpPacketInfo p0(123, {1, 2}, 89, 5, AbsoluteCaptureTime{45, 78},
+                   Timestamp::Millis(7));
+  RtpPacketInfo p1(456, {3, 4}, 89, 4, AbsoluteCaptureTime{13, 21},
+                   Timestamp::Millis(1));
+  RtpPacketInfo p2(789, {5, 6}, 88, 1, AbsoluteCaptureTime{99, 78},
+                   Timestamp::Millis(7));
 
   RtpPacketInfos x({p0, p1, p2});
 
@@ -52,9 +55,12 @@
 }
 
 TEST(RtpPacketInfosTest, CopyShareData) {
-  RtpPacketInfo p0(123, {1, 2}, 89, 5, AbsoluteCaptureTime{45, 78}, 7);
-  RtpPacketInfo p1(456, {3, 4}, 89, 4, AbsoluteCaptureTime{13, 21}, 1);
-  RtpPacketInfo p2(789, {5, 6}, 88, 1, AbsoluteCaptureTime{99, 78}, 7);
+  RtpPacketInfo p0(123, {1, 2}, 89, 5, AbsoluteCaptureTime{45, 78},
+                   Timestamp::Millis(7));
+  RtpPacketInfo p1(456, {3, 4}, 89, 4, AbsoluteCaptureTime{13, 21},
+                   Timestamp::Millis(1));
+  RtpPacketInfo p2(789, {5, 6}, 88, 1, AbsoluteCaptureTime{99, 78},
+                   Timestamp::Millis(7));
 
   RtpPacketInfos lhs({p0, p1, p2});
   RtpPacketInfos rhs = lhs;
diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc
index 7089d21..6a57b98 100644
--- a/audio/channel_receive.cc
+++ b/audio/channel_receive.cc
@@ -299,7 +299,7 @@
     // updating RtpSource information.
     if (source_tracker_) {
       RtpPacketInfos::vector_type packet_vector = {
-          RtpPacketInfo(rtpHeader, clock_->TimeInMilliseconds())};
+          RtpPacketInfo(rtpHeader, clock_->CurrentTime())};
       source_tracker_->OnFrameDelivered(RtpPacketInfos(packet_vector));
     }
 
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index d156352..6ac157f 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -565,19 +565,19 @@
     return kInvalidPointer;
   }
 
-  int64_t receive_time_ms = clock_->TimeInMilliseconds();
+  Timestamp receive_time = clock_->CurrentTime();
   stats_->ReceivedPacket();
 
   PacketList packet_list;
   // Insert packet in a packet list.
-  packet_list.push_back([&rtp_header, &payload, &receive_time_ms] {
+  packet_list.push_back([&rtp_header, &payload, &receive_time] {
     // Convert to Packet.
     Packet packet;
     packet.payload_type = rtp_header.payloadType;
     packet.sequence_number = rtp_header.sequenceNumber;
     packet.timestamp = rtp_header.timestamp;
     packet.payload.SetData(payload.data(), payload.size());
-    packet.packet_info = RtpPacketInfo(rtp_header, receive_time_ms);
+    packet.packet_info = RtpPacketInfo(rtp_header, receive_time);
     // Waiting time will be set upon inserting the packet in the buffer.
     RTC_DCHECK(!packet.waiting_time);
     return packet;
diff --git a/modules/audio_coding/neteq/neteq_impl_unittest.cc b/modules/audio_coding/neteq/neteq_impl_unittest.cc
index c2a2bee..b3c25ca 100644
--- a/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -497,7 +497,7 @@
 
   // Insert one packet.
   clock_.AdvanceTimeMilliseconds(123456);
-  int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
+  Timestamp expected_receive_time = clock_.CurrentTime();
   EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
 
   // Pull audio once.
@@ -518,7 +518,7 @@
     EXPECT_THAT(packet_info.csrcs(), ElementsAre(43, 65, 17));
     EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
     EXPECT_FALSE(packet_info.audio_level().has_value());
-    EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
+    EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
   }
 
   // Start with a simple check that the fake decoder is behaving as expected.
@@ -590,7 +590,7 @@
 
   // Insert one packet.
   clock_.AdvanceTimeMilliseconds(123456);
-  int64_t expected_receive_time_ms = clock_.TimeInMilliseconds();
+  Timestamp expected_receive_time = clock_.CurrentTime();
   EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
 
   // Pull audio once.
@@ -610,7 +610,7 @@
     EXPECT_THAT(packet_info.csrcs(), IsEmpty());
     EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
     EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
-    EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
+    EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
   }
 
   // Insert two more packets. The first one is out of order, and is already too
@@ -626,7 +626,7 @@
   rtp_header.extension.audioLevel = 2;
   payload[0] = 2;
   clock_.AdvanceTimeMilliseconds(2000);
-  expected_receive_time_ms = clock_.TimeInMilliseconds();
+  expected_receive_time = clock_.CurrentTime();
   EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
 
   // Expect only the second packet to be decoded (the one with "2" as the first
@@ -656,7 +656,7 @@
     EXPECT_THAT(packet_info.csrcs(), IsEmpty());
     EXPECT_EQ(packet_info.rtp_timestamp(), rtp_header.timestamp);
     EXPECT_EQ(packet_info.audio_level(), rtp_header.extension.audioLevel);
-    EXPECT_EQ(packet_info.receive_time_ms(), expected_receive_time_ms);
+    EXPECT_EQ(packet_info.receive_time(), expected_receive_time);
   }
 
   EXPECT_CALL(mock_decoder, Die());
diff --git a/modules/audio_coding/neteq/red_payload_splitter.cc b/modules/audio_coding/neteq/red_payload_splitter.cc
index 5681464..f5cd9c2 100644
--- a/modules/audio_coding/neteq/red_payload_splitter.cc
+++ b/modules/audio_coding/neteq/red_payload_splitter.cc
@@ -139,7 +139,7 @@
             /*rtp_timestamp=*/new_packet.timestamp,
             /*audio_level=*/absl::nullopt,
             /*absolute_capture_time=*/absl::nullopt,
-            /*receive_time_ms=*/red_packet.packet_info.receive_time_ms());
+            /*receive_time=*/red_packet.packet_info.receive_time());
         new_packets.push_front(std::move(new_packet));
         payload_ptr += payload_length;
       }
diff --git a/modules/rtp_rtcp/source/source_tracker_unittest.cc b/modules/rtp_rtcp/source/source_tracker_unittest.cc
index 32f9f4b..c88e801 100644
--- a/modules/rtp_rtcp/source/source_tracker_unittest.cc
+++ b/modules/rtp_rtcp/source/source_tracker_unittest.cc
@@ -111,7 +111,7 @@
       packet_infos.emplace_back(GenerateSsrc(), GenerateCsrcs(),
                                 GenerateRtpTimestamp(), GenerateAudioLevel(),
                                 GenerateAbsoluteCaptureTime(),
-                                GenerateReceiveTimeMs());
+                                GenerateReceiveTime());
     }
 
     return RtpPacketInfos(std::move(packet_infos));
@@ -192,8 +192,9 @@
     return value;
   }
 
-  int64_t GenerateReceiveTimeMs() {
-    return std::uniform_int_distribution<int64_t>()(generator_);
+  Timestamp GenerateReceiveTime() {
+    return Timestamp::Micros(
+        std::uniform_int_distribution<int64_t>()(generator_));
   }
 
   const uint32_t ssrcs_count_;
@@ -248,14 +249,14 @@
   constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime =
       AbsoluteCaptureTime{/*absolute_capture_timestamp=*/12,
                           /*estimated_capture_clock_offset=*/absl::nullopt};
-  constexpr int64_t kReceiveTimeMs = 60;
+  constexpr Timestamp kReceiveTime = Timestamp::Millis(60);
 
   SimulatedClock clock(1000000000000ULL);
   SourceTracker tracker(&clock);
 
   tracker.OnFrameDelivered(RtpPacketInfos(
       {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp, kAudioLevel,
-                     kAbsoluteCaptureTime, kReceiveTimeMs)}));
+                     kAbsoluteCaptureTime, kReceiveTime)}));
 
   int64_t timestamp_ms = clock.TimeInMilliseconds();
   constexpr RtpSource::Extensions extensions = {kAudioLevel,
@@ -283,15 +284,15 @@
       AbsoluteCaptureTime{12, 34};
   constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 =
       AbsoluteCaptureTime{56, 78};
-  constexpr int64_t kReceiveTimeMs0 = 60;
-  constexpr int64_t kReceiveTimeMs1 = 61;
+  constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60);
+  constexpr Timestamp kReceiveTime1 = Timestamp::Millis(61);
 
   SimulatedClock clock(1000000000000ULL);
   SourceTracker tracker(&clock);
 
   tracker.OnFrameDelivered(RtpPacketInfos(
       {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kAudioLevel0,
-                     kAbsoluteCaptureTime0, kReceiveTimeMs0)}));
+                     kAbsoluteCaptureTime0, kReceiveTime0)}));
 
   int64_t timestamp_ms_0 = clock.TimeInMilliseconds();
 
@@ -299,7 +300,7 @@
 
   tracker.OnFrameDelivered(RtpPacketInfos(
       {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kAudioLevel1,
-                     kAbsoluteCaptureTime1, kReceiveTimeMs1)}));
+                     kAbsoluteCaptureTime1, kReceiveTime1)}));
 
   int64_t timestamp_ms_1 = clock.TimeInMilliseconds();
 
@@ -333,21 +334,21 @@
       AbsoluteCaptureTime{12, 34};
   constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 =
       AbsoluteCaptureTime{56, 78};
-  constexpr int64_t kReceiveTimeMs0 = 60;
-  constexpr int64_t kReceiveTimeMs1 = 61;
+  constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60);
+  constexpr Timestamp kReceiveTime1 = Timestamp::Millis(61);
 
   SimulatedClock clock(1000000000000ULL);
   SourceTracker tracker(&clock);
 
   tracker.OnFrameDelivered(RtpPacketInfos(
       {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kAudioLevel0,
-                     kAbsoluteCaptureTime0, kReceiveTimeMs0)}));
+                     kAbsoluteCaptureTime0, kReceiveTime0)}));
 
   clock.AdvanceTimeMilliseconds(17);
 
   tracker.OnFrameDelivered(RtpPacketInfos(
       {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kAudioLevel1,
-                     kAbsoluteCaptureTime1, kReceiveTimeMs1)}));
+                     kAbsoluteCaptureTime1, kReceiveTime1)}));
 
   int64_t timestamp_ms_1 = clock.TimeInMilliseconds();
 
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index 94312bf..b28517e 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -274,6 +274,7 @@
     "../../api:rtp_headers",
     "../../api:rtp_packet_info",
     "../../api:sequence_checker",
+    "../../api/units:timestamp",
     "../../api/video:encoded_image",
     "../../api/video:video_frame",
     "../../api/video:video_frame_type",
diff --git a/modules/video_coding/jitter_buffer_unittest.cc b/modules/video_coding/jitter_buffer_unittest.cc
index acfee8c..752ceb8 100644
--- a/modules/video_coding/jitter_buffer_unittest.cc
+++ b/modules/video_coding/jitter_buffer_unittest.cc
@@ -67,8 +67,7 @@
     video_header.is_first_packet_in_frame = true;
     video_header.frame_type = VideoFrameType::kVideoFrameDelta;
     packet_.reset(new VCMPacket(data_, size_, rtp_header, video_header,
-                                /*ntp_time_ms=*/0,
-                                clock_->TimeInMilliseconds()));
+                                /*ntp_time_ms=*/0, clock_->CurrentTime()));
   }
 
   VCMEncodedFrame* DecodeCompleteFrame() {
@@ -541,7 +540,7 @@
   video_header.codec = kVideoCodecGeneric;
   video_header.frame_type = VideoFrameType::kEmptyFrame;
   VCMPacket empty_packet(data_, 0, rtp_header, video_header,
-                         /*ntp_time_ms=*/0, clock_->TimeInMilliseconds());
+                         /*ntp_time_ms=*/0, clock_->CurrentTime());
   EXPECT_EQ(kOldPacket,
             jitter_buffer_->InsertPacket(empty_packet, &retransmitted));
   empty_packet.seqNum += 1;
diff --git a/modules/video_coding/packet.cc b/modules/video_coding/packet.cc
index 0c4a658..324248a 100644
--- a/modules/video_coding/packet.cc
+++ b/modules/video_coding/packet.cc
@@ -34,7 +34,7 @@
                      const RTPHeader& rtp_header,
                      const RTPVideoHeader& videoHeader,
                      int64_t ntp_time_ms,
-                     int64_t receive_time_ms)
+                     Timestamp receive_time)
     : payloadType(rtp_header.payloadType),
       timestamp(rtp_header.timestamp),
       ntp_time_ms_(ntp_time_ms),
@@ -47,7 +47,7 @@
       insertStartCode(videoHeader.codec == kVideoCodecH264 &&
                       videoHeader.is_first_packet_in_frame),
       video_header(videoHeader),
-      packet_info(rtp_header, receive_time_ms) {
+      packet_info(rtp_header, receive_time) {
   if (is_first_packet_in_frame() && markerBit) {
     completeNALU = kNaluComplete;
   } else if (is_first_packet_in_frame()) {
diff --git a/modules/video_coding/packet.h b/modules/video_coding/packet.h
index f157e10..9aa2d5c 100644
--- a/modules/video_coding/packet.h
+++ b/modules/video_coding/packet.h
@@ -17,6 +17,7 @@
 #include "absl/types/optional.h"
 #include "api/rtp_headers.h"
 #include "api/rtp_packet_info.h"
+#include "api/units/timestamp.h"
 #include "api/video/video_frame_type.h"
 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
@@ -41,7 +42,7 @@
             const RTPHeader& rtp_header,
             const RTPVideoHeader& video_header,
             int64_t ntp_time_ms,
-            int64_t receive_time_ms);
+            Timestamp receive_time);
 
   ~VCMPacket();
 
diff --git a/modules/video_coding/packet_buffer.cc b/modules/video_coding/packet_buffer.cc
index 1291f78..99f2891 100644
--- a/modules/video_coding/packet_buffer.cc
+++ b/modules/video_coding/packet_buffer.cc
@@ -36,7 +36,7 @@
 
 PacketBuffer::Packet::Packet(const RtpPacketReceived& rtp_packet,
                              const RTPVideoHeader& video_header,
-                             int64_t receive_time_ms)
+                             Timestamp receive_time)
     : marker_bit(rtp_packet.Marker()),
       payload_type(rtp_packet.PayloadType()),
       seq_num(rtp_packet.SequenceNumber()),
@@ -48,7 +48,7 @@
                   rtp_packet.Timestamp(),
                   /*audio_level=*/absl::nullopt,
                   rtp_packet.GetExtension<AbsoluteCaptureTimeExtension>(),
-                  receive_time_ms) {}
+                  receive_time) {}
 
 PacketBuffer::PacketBuffer(size_t start_buffer_size, size_t max_buffer_size)
     : max_size_(max_buffer_size),
diff --git a/modules/video_coding/packet_buffer.h b/modules/video_coding/packet_buffer.h
index c0cc752..e8d2446 100644
--- a/modules/video_coding/packet_buffer.h
+++ b/modules/video_coding/packet_buffer.h
@@ -18,6 +18,7 @@
 
 #include "absl/base/attributes.h"
 #include "api/rtp_packet_info.h"
+#include "api/units/timestamp.h"
 #include "api/video/encoded_image.h"
 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
 #include "modules/rtp_rtcp/source/rtp_video_header.h"
@@ -34,7 +35,7 @@
     Packet() = default;
     Packet(const RtpPacketReceived& rtp_packet,
            const RTPVideoHeader& video_header,
-           int64_t receive_time_ms);
+           Timestamp receive_time);
     Packet(const Packet&) = delete;
     Packet(Packet&&) = delete;
     Packet& operator=(const Packet&) = delete;
diff --git a/modules/video_coding/video_receiver.cc b/modules/video_coding/video_receiver.cc
index 74b04ac..43dbc9f 100644
--- a/modules/video_coding/video_receiver.cc
+++ b/modules/video_coding/video_receiver.cc
@@ -279,7 +279,7 @@
   // Callers don't provide any ntp time.
   const VCMPacket packet(incomingPayload, payloadLength, rtp_header,
                          video_header, /*ntp_time_ms=*/0,
-                         clock_->TimeInMilliseconds());
+                         clock_->CurrentTime());
   int32_t ret = _receiver.InsertPacket(packet);
 
   // TODO(holmer): Investigate if this somehow should use the key frame
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
index 273c0e8..436b3ba 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
@@ -353,17 +353,16 @@
   stream_frame_counters_.at(key).received++;
   // Determine the time of the last received packet of this video frame.
   RTC_DCHECK(!input_image.PacketInfos().empty());
-  int64_t last_receive_time =
+  Timestamp last_receive_time =
       std::max_element(input_image.PacketInfos().cbegin(),
                        input_image.PacketInfos().cend(),
                        [](const RtpPacketInfo& a, const RtpPacketInfo& b) {
-                         return a.receive_time_ms() < b.receive_time_ms();
+                         return a.receive_time() < b.receive_time();
                        })
-          ->receive_time_ms();
-  it->second.OnFramePreDecode(
-      peer_index,
-      /*received_time=*/Timestamp::Millis(last_receive_time),
-      /*decode_start_time=*/Now());
+          ->receive_time();
+  it->second.OnFramePreDecode(peer_index,
+                              /*received_time=*/last_receive_time,
+                              /*decode_start_time=*/Now());
 }
 
 void DefaultVideoQualityAnalyzer::OnFrameDecoded(
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
index 4cdc681..8d8a1af 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
@@ -63,13 +63,13 @@
 EncodedImage FakeEncode(const VideoFrame& frame) {
   EncodedImage image;
   std::vector<RtpPacketInfo> packet_infos;
-  packet_infos.push_back(
-      RtpPacketInfo(/*ssrc=*/1,
-                    /*csrcs=*/{},
-                    /*rtp_timestamp=*/frame.timestamp(),
-                    /*audio_level=*/absl::nullopt,
-                    /*absolute_capture_time=*/absl::nullopt,
-                    /*receive_time_ms=*/frame.timestamp_us() + 10));
+  packet_infos.push_back(RtpPacketInfo(
+      /*ssrc=*/1,
+      /*csrcs=*/{},
+      /*rtp_timestamp=*/frame.timestamp(),
+      /*audio_level=*/absl::nullopt,
+      /*absolute_capture_time=*/absl::nullopt,
+      /*receive_time=*/Timestamp::Micros(frame.timestamp_us() + 10000)));
   image.SetPacketInfos(RtpPacketInfos(packet_infos));
   return image;
 }
diff --git a/video/rtp_video_stream_receiver.cc b/video/rtp_video_stream_receiver.cc
index 7e8fe99..9111b6a 100644
--- a/video/rtp_video_stream_receiver.cc
+++ b/video/rtp_video_stream_receiver.cc
@@ -507,7 +507,7 @@
     const RTPVideoHeader& video) {
   RTC_DCHECK_RUN_ON(&worker_task_checker_);
   auto packet = std::make_unique<video_coding::PacketBuffer::Packet>(
-      rtp_packet, video, clock_->TimeInMilliseconds());
+      rtp_packet, video, clock_->CurrentTime());
 
   // Try to extrapolate absolute capture time if it is missing.
   packet->packet_info.set_absolute_capture_time(
@@ -752,16 +752,16 @@
     if (packet->is_first_packet_in_frame()) {
       first_packet = packet.get();
       max_nack_count = packet->times_nacked;
-      min_recv_time = packet->packet_info.receive_time_ms();
-      max_recv_time = packet->packet_info.receive_time_ms();
+      min_recv_time = packet->packet_info.receive_time().ms();
+      max_recv_time = packet->packet_info.receive_time().ms();
       payloads.clear();
       packet_infos.clear();
     } else {
       max_nack_count = std::max(max_nack_count, packet->times_nacked);
       min_recv_time =
-          std::min(min_recv_time, packet->packet_info.receive_time_ms());
+          std::min(min_recv_time, packet->packet_info.receive_time().ms());
       max_recv_time =
-          std::max(max_recv_time, packet->packet_info.receive_time_ms());
+          std::max(max_recv_time, packet->packet_info.receive_time().ms());
     }
     payloads.emplace_back(packet->video_payload);
     packet_infos.push_back(packet->packet_info);
diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc
index fdbd5b6..5b282b4 100644
--- a/video/rtp_video_stream_receiver2.cc
+++ b/video/rtp_video_stream_receiver2.cc
@@ -474,7 +474,7 @@
     const RTPVideoHeader& video) {
   RTC_DCHECK_RUN_ON(&worker_task_checker_);
   auto packet = std::make_unique<video_coding::PacketBuffer::Packet>(
-      rtp_packet, video, clock_->TimeInMilliseconds());
+      rtp_packet, video, clock_->CurrentTime());
 
   // Try to extrapolate absolute capture time if it is missing.
   packet->packet_info.set_absolute_capture_time(
@@ -718,16 +718,16 @@
     if (packet->is_first_packet_in_frame()) {
       first_packet = packet.get();
       max_nack_count = packet->times_nacked;
-      min_recv_time = packet->packet_info.receive_time_ms();
-      max_recv_time = packet->packet_info.receive_time_ms();
+      min_recv_time = packet->packet_info.receive_time().ms();
+      max_recv_time = packet->packet_info.receive_time().ms();
       payloads.clear();
       packet_infos.clear();
     } else {
       max_nack_count = std::max(max_nack_count, packet->times_nacked);
       min_recv_time =
-          std::min(min_recv_time, packet->packet_info.receive_time_ms());
+          std::min(min_recv_time, packet->packet_info.receive_time().ms());
       max_recv_time =
-          std::max(max_recv_time, packet->packet_info.receive_time_ms());
+          std::max(max_recv_time, packet->packet_info.receive_time().ms());
     }
     payloads.emplace_back(packet->video_payload);
     packet_infos.push_back(packet->packet_info);
diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc
index 7a23112..3bbc070 100644
--- a/video/video_receive_stream2_unittest.cc
+++ b/video/video_receive_stream2_unittest.cc
@@ -388,16 +388,16 @@
     info.set_csrcs({kCsrc});
     info.set_rtp_timestamp(kRtpTimestamp);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 5000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
     infos.push_back(info);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 3000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
     infos.push_back(info);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 2000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
     infos.push_back(info);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 4000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(1000));
     infos.push_back(info);
 
     packet_infos = RtpPacketInfos(std::move(infos));
diff --git a/video/video_receive_stream_unittest.cc b/video/video_receive_stream_unittest.cc
index e69820e..c320bfa 100644
--- a/video/video_receive_stream_unittest.cc
+++ b/video/video_receive_stream_unittest.cc
@@ -336,16 +336,16 @@
     info.set_csrcs({kCsrc});
     info.set_rtp_timestamp(kRtpTimestamp);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 5000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
     infos.push_back(info);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 3000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
     infos.push_back(info);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 2000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
     infos.push_back(info);
 
-    info.set_receive_time_ms(clock_->TimeInMilliseconds() - 4000);
+    info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(4000));
     infos.push_back(info);
 
     packet_infos = RtpPacketInfos(std::move(infos));