stats: use Timestamp instead of uint64_t

making it clear what unit is being used.

BUG=webrtc:13756

Change-Id: I6354d35a8e02bb93a905ccf32cb0b294b4813e41
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/289460
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39008}
diff --git a/api/stats/rtc_stats.h b/api/stats/rtc_stats.h
index d4ba51d..abe2a5b 100644
--- a/api/stats/rtc_stats.h
+++ b/api/stats/rtc_stats.h
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/units/timestamp.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/system/rtc_export.h"
 #include "rtc_base/system/rtc_export_template.h"
@@ -42,7 +43,7 @@
 // Derived classes list their dictionary members, RTCStatsMember<T>, as public
 // fields, allowing the following:
 //
-// RTCFooStats foo("fooId", GetCurrentTime());
+// RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime()));
 // foo.bar = 42;
 // foo.baz = std::vector<std::string>();
 // foo.baz->push_back("hello world");
@@ -55,15 +56,20 @@
 // }
 class RTC_EXPORT RTCStats {
  public:
+  RTCStats(const std::string& id, Timestamp timestamp)
+      : id_(id), timestamp_(timestamp) {}
   RTCStats(std::string id, int64_t timestamp_us)
-      : id_(std::move(id)), timestamp_us_(timestamp_us) {}
+      : RTCStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
+
   virtual ~RTCStats() {}
 
   virtual std::unique_ptr<RTCStats> copy() const = 0;
 
   const std::string& id() const { return id_; }
   // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
-  int64_t timestamp_us() const { return timestamp_us_; }
+  int64_t timestamp_us() const { return timestamp_.us(); }
+  Timestamp timestamp() const { return timestamp_; }
+
   // Returns the static member variable `kType` of the implementing class.
   virtual const char* type() const = 0;
   // Returns a vector of pointers to all the `RTCStatsMemberInterface` members
@@ -97,7 +103,7 @@
   MembersOfThisObjectAndAncestors(size_t additional_capacity) const;
 
   std::string const id_;
-  int64_t timestamp_us_;
+  Timestamp timestamp_;
 };
 
 // All `RTCStats` classes should use these macros.
diff --git a/api/stats/rtcstats_objects.h b/api/stats/rtcstats_objects.h
index 9d3e697..1647989 100644
--- a/api/stats/rtcstats_objects.h
+++ b/api/stats/rtcstats_objects.h
@@ -120,6 +120,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCCertificateStats(std::string id, Timestamp timestamp);
   RTCCertificateStats(std::string id, int64_t timestamp_us);
   RTCCertificateStats(const RTCCertificateStats& other);
   ~RTCCertificateStats() override;
@@ -149,6 +150,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCCodecStats(std::string id, Timestamp timestamp);
   RTCCodecStats(std::string id, int64_t timestamp_us);
   RTCCodecStats(const RTCCodecStats& other);
   ~RTCCodecStats() override;
@@ -166,6 +168,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCDataChannelStats(std::string id, Timestamp timestamp);
   RTCDataChannelStats(std::string id, int64_t timestamp_us);
   RTCDataChannelStats(const RTCDataChannelStats& other);
   ~RTCDataChannelStats() override;
@@ -186,6 +189,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCIceCandidatePairStats(std::string id, Timestamp timestamp);
   RTCIceCandidatePairStats(std::string id, int64_t timestamp_us);
   RTCIceCandidatePairStats(const RTCIceCandidatePairStats& other);
   ~RTCIceCandidatePairStats() override;
@@ -254,6 +258,7 @@
   RTCNonStandardStatsMember<std::string> network_adapter_type;
 
  protected:
+  RTCIceCandidateStats(std::string id, Timestamp timestamp, bool is_remote);
   RTCIceCandidateStats(std::string id, int64_t timestamp_us, bool is_remote);
 };
 
@@ -265,6 +270,7 @@
 class RTC_EXPORT RTCLocalIceCandidateStats final : public RTCIceCandidateStats {
  public:
   static const char kType[];
+  RTCLocalIceCandidateStats(std::string id, Timestamp timestamp);
   RTCLocalIceCandidateStats(std::string id, int64_t timestamp_us);
   std::unique_ptr<RTCStats> copy() const override;
   const char* type() const override;
@@ -274,6 +280,7 @@
     : public RTCIceCandidateStats {
  public:
   static const char kType[];
+  RTCRemoteIceCandidateStats(std::string id, Timestamp timestamp);
   RTCRemoteIceCandidateStats(std::string id, int64_t timestamp_us);
   std::unique_ptr<RTCStats> copy() const override;
   const char* type() const override;
@@ -284,6 +291,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  DEPRECATED_RTCMediaStreamStats(std::string id, Timestamp timestamp);
   DEPRECATED_RTCMediaStreamStats(std::string id, int64_t timestamp_us);
   DEPRECATED_RTCMediaStreamStats(const DEPRECATED_RTCMediaStreamStats& other);
   ~DEPRECATED_RTCMediaStreamStats() override;
@@ -300,6 +308,9 @@
   WEBRTC_RTCSTATS_DECL();
 
   DEPRECATED_RTCMediaStreamTrackStats(std::string id,
+                                      Timestamp timestamp,
+                                      const char* kind);
+  DEPRECATED_RTCMediaStreamTrackStats(std::string id,
                                       int64_t timestamp_us,
                                       const char* kind);
   DEPRECATED_RTCMediaStreamTrackStats(
@@ -345,6 +356,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCPeerConnectionStats(std::string id, Timestamp timestamp);
   RTCPeerConnectionStats(std::string id, int64_t timestamp_us);
   RTCPeerConnectionStats(const RTCPeerConnectionStats& other);
   ~RTCPeerConnectionStats() override;
@@ -372,6 +384,7 @@
   RTCStatsMember<std::string> media_type;  // renamed to kind.
 
  protected:
+  RTCRTPStreamStats(std::string id, Timestamp timestamp);
   RTCRTPStreamStats(std::string id, int64_t timestamp_us);
 };
 
@@ -387,6 +400,7 @@
   RTCStatsMember<int32_t> packets_lost;  // Signed per RFC 3550
 
  protected:
+  RTCReceivedRtpStreamStats(std::string id, Timestamp timestamp);
   RTCReceivedRtpStreamStats(std::string id, int64_t timestamp_us);
 };
 
@@ -402,6 +416,7 @@
   RTCStatsMember<uint64_t> bytes_sent;
 
  protected:
+  RTCSentRtpStreamStats(std::string id, Timestamp timestamp);
   RTCSentRtpStreamStats(std::string id, int64_t timestamp_us);
 };
 
@@ -411,6 +426,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCInboundRTPStreamStats(std::string id, Timestamp timestamp);
   RTCInboundRTPStreamStats(std::string id, int64_t timestamp_us);
   RTCInboundRTPStreamStats(const RTCInboundRTPStreamStats& other);
   ~RTCInboundRTPStreamStats() override;
@@ -498,6 +514,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCOutboundRTPStreamStats(std::string id, Timestamp timestamp);
   RTCOutboundRTPStreamStats(std::string id, int64_t timestamp_us);
   RTCOutboundRTPStreamStats(const RTCOutboundRTPStreamStats& other);
   ~RTCOutboundRTPStreamStats() override;
@@ -551,6 +568,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCRemoteInboundRtpStreamStats(std::string id, Timestamp timestamp);
   RTCRemoteInboundRtpStreamStats(std::string id, int64_t timestamp_us);
   RTCRemoteInboundRtpStreamStats(const RTCRemoteInboundRtpStreamStats& other);
   ~RTCRemoteInboundRtpStreamStats() override;
@@ -568,6 +586,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCRemoteOutboundRtpStreamStats(std::string id, Timestamp timestamp);
   RTCRemoteOutboundRtpStreamStats(std::string id, int64_t timestamp_us);
   RTCRemoteOutboundRtpStreamStats(const RTCRemoteOutboundRtpStreamStats& other);
   ~RTCRemoteOutboundRtpStreamStats() override;
@@ -592,6 +611,7 @@
   RTCStatsMember<std::string> kind;
 
  protected:
+  RTCMediaSourceStats(std::string id, Timestamp timestamp);
   RTCMediaSourceStats(std::string id, int64_t timestamp_us);
 };
 
@@ -600,6 +620,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCAudioSourceStats(std::string id, Timestamp timestamp);
   RTCAudioSourceStats(std::string id, int64_t timestamp_us);
   RTCAudioSourceStats(const RTCAudioSourceStats& other);
   ~RTCAudioSourceStats() override;
@@ -616,6 +637,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCVideoSourceStats(std::string id, Timestamp timestamp);
   RTCVideoSourceStats(std::string id, int64_t timestamp_us);
   RTCVideoSourceStats(const RTCVideoSourceStats& other);
   ~RTCVideoSourceStats() override;
@@ -631,6 +653,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCTransportStats(std::string id, Timestamp timestamp);
   RTCTransportStats(std::string id, int64_t timestamp_us);
   RTCTransportStats(const RTCTransportStats& other);
   ~RTCTransportStats() override;
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index f10fd4d..da86afa 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -362,7 +362,7 @@
 // Gets the `codecId` identified by `transport_id` and `codec_params`. If no
 // such `RTCCodecStats` exist yet, create it and add it to `report`.
 std::string GetCodecIdAndMaybeCreateCodecStats(
-    uint64_t timestamp_us,
+    Timestamp timestamp,
     const char direction,
     const std::string& transport_id,
     const RtpCodecParameters& codec_params,
@@ -379,7 +379,7 @@
   }
   // Create the `RTCCodecStats` that we want to reference.
   std::unique_ptr<RTCCodecStats> codec_stats(
-      std::make_unique<RTCCodecStats>(codec_id, timestamp_us));
+      std::make_unique<RTCCodecStats>(codec_id, timestamp));
   codec_stats->payload_type = payload_type;
   codec_stats->mime_type = codec_params.mime_type();
   if (codec_params.clock_rate.has_value()) {
@@ -441,12 +441,12 @@
     const cricket::VoiceReceiverInfo& voice_receiver_info,
     const std::string& transport_id,
     const std::string& mid,
-    int64_t timestamp_us,
+    Timestamp timestamp,
     RTCStatsReport* report) {
   auto inbound_audio = std::make_unique<RTCInboundRTPStreamStats>(
       /*id=*/RTCInboundRTPStreamStatsIDFromSSRC(
           transport_id, cricket::MEDIA_TYPE_AUDIO, voice_receiver_info.ssrc()),
-      timestamp_us);
+      timestamp);
   SetInboundRTPStreamStatsFromMediaReceiverInfo(voice_receiver_info,
                                                 inbound_audio.get());
   inbound_audio->transport_id = transport_id;
@@ -459,7 +459,7 @@
     RTC_DCHECK(codec_param_it != voice_media_info.receive_codecs.end());
     if (codec_param_it != voice_media_info.receive_codecs.end()) {
       inbound_audio->codec_id = GetCodecIdAndMaybeCreateCodecStats(
-          inbound_audio->timestamp_us(), kDirectionInbound, transport_id,
+          inbound_audio->timestamp(), kDirectionInbound, transport_id,
           codec_param_it->second, report);
     }
   }
@@ -532,8 +532,8 @@
   auto stats = std::make_unique<RTCRemoteOutboundRtpStreamStats>(
       /*id=*/RTCRemoteOutboundRTPStreamStatsIDFromSSRC(
           cricket::MEDIA_TYPE_AUDIO, voice_receiver_info.ssrc()),
-      /*timestamp_us=*/rtc::kNumMicrosecsPerMillisec *
-          voice_receiver_info.last_sender_report_timestamp_ms.value());
+      Timestamp::Millis(
+          voice_receiver_info.last_sender_report_timestamp_ms.value()));
 
   // Populate.
   // - RTCRtpStreamStats.
@@ -584,7 +584,7 @@
     RTC_DCHECK(codec_param_it != video_media_info.receive_codecs.end());
     if (codec_param_it != video_media_info.receive_codecs.end()) {
       inbound_video->codec_id = GetCodecIdAndMaybeCreateCodecStats(
-          inbound_video->timestamp_us(), kDirectionInbound, transport_id,
+          inbound_video->timestamp(), kDirectionInbound, transport_id,
           codec_param_it->second, report);
     }
   }
@@ -710,7 +710,7 @@
     RTC_DCHECK(codec_param_it != voice_media_info.send_codecs.end());
     if (codec_param_it != voice_media_info.send_codecs.end()) {
       outbound_audio->codec_id = GetCodecIdAndMaybeCreateCodecStats(
-          outbound_audio->timestamp_us(), kDirectionOutbound, transport_id,
+          outbound_audio->timestamp(), kDirectionOutbound, transport_id,
           codec_param_it->second, report);
     }
   }
@@ -737,7 +737,7 @@
     RTC_DCHECK(codec_param_it != video_media_info.send_codecs.end());
     if (codec_param_it != video_media_info.send_codecs.end()) {
       outbound_video->codec_id = GetCodecIdAndMaybeCreateCodecStats(
-          outbound_video->timestamp_us(), kDirectionOutbound, transport_id,
+          outbound_video->timestamp(), kDirectionOutbound, transport_id,
           codec_param_it->second, report);
     }
   }
@@ -814,7 +814,7 @@
   auto remote_inbound = std::make_unique<RTCRemoteInboundRtpStreamStats>(
       RTCRemoteInboundRtpStreamStatsIdFromSourceSsrc(media_type,
                                                      report_block.source_ssrc),
-      /*timestamp=*/report_block_data.report_block_timestamp_utc_us());
+      Timestamp::Micros(report_block_data.report_block_timestamp_utc_us()));
   remote_inbound->ssrc = report_block.source_ssrc;
   remote_inbound->kind =
       media_type == cricket::MEDIA_TYPE_AUDIO ? "audio" : "video";
@@ -876,7 +876,7 @@
 }
 
 void ProduceCertificateStatsFromSSLCertificateStats(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const rtc::SSLCertificateStats& certificate_stats,
     RTCStatsReport* report) {
   RTCCertificateStats* prev_certificate_stats = nullptr;
@@ -892,7 +892,7 @@
       break;
     }
     RTCCertificateStats* certificate_stats =
-        new RTCCertificateStats(certificate_stats_id, timestamp_us);
+        new RTCCertificateStats(certificate_stats_id, timestamp);
     certificate_stats->fingerprint = s->fingerprint;
     certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm;
     certificate_stats->base64_certificate = s->base64_certificate;
@@ -903,7 +903,7 @@
   }
 }
 
-const std::string& ProduceIceCandidateStats(int64_t timestamp_us,
+const std::string& ProduceIceCandidateStats(Timestamp timestamp,
                                             const cricket::Candidate& candidate,
                                             bool is_local,
                                             const std::string& transport_id,
@@ -914,10 +914,10 @@
     std::unique_ptr<RTCIceCandidateStats> candidate_stats;
     if (is_local)
       candidate_stats =
-          std::make_unique<RTCLocalIceCandidateStats>(id, timestamp_us);
+          std::make_unique<RTCLocalIceCandidateStats>(id, timestamp);
     else
       candidate_stats =
-          std::make_unique<RTCRemoteIceCandidateStats>(id, timestamp_us);
+          std::make_unique<RTCRemoteIceCandidateStats>(id, timestamp);
     candidate_stats->transport_id = transport_id;
     if (is_local) {
       candidate_stats->network_type =
@@ -998,7 +998,7 @@
 
 std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats>
 ProduceMediaStreamTrackStatsFromVoiceSenderInfo(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     AudioTrackInterface& audio_track,
     const cricket::VoiceSenderInfo& voice_sender_info,
     int attachment_id) {
@@ -1006,7 +1006,7 @@
       std::make_unique<DEPRECATED_RTCMediaStreamTrackStats>(
           DEPRECATED_RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
               kDirectionOutbound, attachment_id),
-          timestamp_us, RTCMediaStreamTrackKind::kAudio));
+          timestamp, RTCMediaStreamTrackKind::kAudio));
   SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
       audio_track, audio_track_stats.get());
   audio_track_stats->media_source_id =
@@ -1031,7 +1031,7 @@
 
 std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats>
 ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const AudioTrackInterface& audio_track,
     const cricket::VoiceReceiverInfo& voice_receiver_info,
     int attachment_id) {
@@ -1041,7 +1041,7 @@
       std::make_unique<DEPRECATED_RTCMediaStreamTrackStats>(
           DEPRECATED_RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
               kDirectionInbound, attachment_id),
-          timestamp_us, RTCMediaStreamTrackKind::kAudio));
+          timestamp, RTCMediaStreamTrackKind::kAudio));
   SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
       audio_track, audio_track_stats.get());
   audio_track_stats->remote_source = true;
@@ -1075,7 +1075,7 @@
 
 std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats>
 ProduceMediaStreamTrackStatsFromVideoSenderInfo(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const VideoTrackInterface& video_track,
     const cricket::VideoSenderInfo& video_sender_info,
     int attachment_id) {
@@ -1083,7 +1083,7 @@
       std::make_unique<DEPRECATED_RTCMediaStreamTrackStats>(
           DEPRECATED_RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
               kDirectionOutbound, attachment_id),
-          timestamp_us, RTCMediaStreamTrackKind::kVideo));
+          timestamp, RTCMediaStreamTrackKind::kVideo));
   SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
       video_track, video_track_stats.get());
   video_track_stats->media_source_id =
@@ -1104,7 +1104,7 @@
 
 std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats>
 ProduceMediaStreamTrackStatsFromVideoReceiverInfo(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const VideoTrackInterface& video_track,
     const cricket::VideoReceiverInfo& video_receiver_info,
     int attachment_id) {
@@ -1112,7 +1112,7 @@
       std::make_unique<DEPRECATED_RTCMediaStreamTrackStats>(
           DEPRECATED_RTCMediaStreamTrackStatsIDFromDirectionAndAttachment(
               kDirectionInbound, attachment_id),
-          timestamp_us, RTCMediaStreamTrackKind::kVideo));
+          timestamp, RTCMediaStreamTrackKind::kVideo));
   SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
       video_track, video_track_stats.get());
   video_track_stats->remote_source = true;
@@ -1140,7 +1140,7 @@
 }
 
 void ProduceSenderMediaTrackStats(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const TrackMediaInfoMap& track_media_info_map,
     std::vector<rtc::scoped_refptr<RtpSenderInternal>> senders,
     RTCStatsReport* report) {
@@ -1175,7 +1175,7 @@
       }
       std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats> audio_track_stats =
           ProduceMediaStreamTrackStatsFromVoiceSenderInfo(
-              timestamp_us, *track, *voice_sender_info, sender->AttachmentId());
+              timestamp, *track, *voice_sender_info, sender->AttachmentId());
       report->AddStats(std::move(audio_track_stats));
     } else if (sender->media_type() == cricket::MEDIA_TYPE_VIDEO) {
       VideoTrackInterface* track =
@@ -1202,7 +1202,7 @@
       }
       std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats> video_track_stats =
           ProduceMediaStreamTrackStatsFromVideoSenderInfo(
-              timestamp_us, *track, *video_sender_info, sender->AttachmentId());
+              timestamp, *track, *video_sender_info, sender->AttachmentId());
       report->AddStats(std::move(video_track_stats));
     } else {
       RTC_DCHECK_NOTREACHED();
@@ -1211,7 +1211,7 @@
 }
 
 void ProduceReceiverMediaTrackStats(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const TrackMediaInfoMap& track_media_info_map,
     std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers,
     RTCStatsReport* report) {
@@ -1227,7 +1227,7 @@
       }
       std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats> audio_track_stats =
           ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
-              timestamp_us, *track, *voice_receiver_info,
+              timestamp, *track, *voice_receiver_info,
               receiver->AttachmentId());
       report->AddStats(std::move(audio_track_stats));
     } else if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
@@ -1240,7 +1240,7 @@
       }
       std::unique_ptr<DEPRECATED_RTCMediaStreamTrackStats> video_track_stats =
           ProduceMediaStreamTrackStatsFromVideoReceiverInfo(
-              timestamp_us, *track, *video_receiver_info,
+              timestamp, *track, *video_receiver_info,
               receiver->AttachmentId());
       report->AddStats(std::move(video_track_stats));
     } else {
@@ -1416,7 +1416,7 @@
     // "Now" using a system clock, relative to the UNIX epoch (Jan 1, 1970,
     // UTC), in microseconds. The system clock could be modified and is not
     // necessarily monotonically increasing.
-    int64_t timestamp_us = rtc::TimeUTCMicros();
+    Timestamp timestamp = Timestamp::Micros(rtc::TimeUTCMicros());
 
     num_pending_partial_reports_ = 2;
     partial_report_timestamp_us_ = cache_now_us;
@@ -1430,13 +1430,13 @@
     // `network_report_event_`.
     network_report_event_.Reset();
     rtc::scoped_refptr<RTCStatsCollector> collector(this);
-    network_thread_->PostTask(
-        [collector, sctp_transport_name = pc_->sctp_transport_name(),
-         timestamp_us]() mutable {
-          collector->ProducePartialResultsOnNetworkThread(
-              timestamp_us, std::move(sctp_transport_name));
-        });
-    ProducePartialResultsOnSignalingThread(timestamp_us);
+    network_thread_->PostTask([collector,
+                               sctp_transport_name = pc_->sctp_transport_name(),
+                               timestamp]() mutable {
+      collector->ProducePartialResultsOnNetworkThread(
+          timestamp, std::move(sctp_transport_name));
+    });
+    ProducePartialResultsOnSignalingThread(timestamp);
   }
 }
 
@@ -1455,14 +1455,13 @@
 }
 
 void RTCStatsCollector::ProducePartialResultsOnSignalingThread(
-    int64_t timestamp_us) {
+    Timestamp timestamp) {
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
 
-  partial_report_ = RTCStatsReport::Create(Timestamp::Micros(timestamp_us));
+  partial_report_ = RTCStatsReport::Create(timestamp);
 
-  ProducePartialResultsOnSignalingThreadImpl(timestamp_us,
-                                             partial_report_.get());
+  ProducePartialResultsOnSignalingThreadImpl(timestamp, partial_report_.get());
 
   // ProducePartialResultsOnSignalingThread() is running synchronously on the
   // signaling thread, so it is always the first partial result delivered on the
@@ -1473,20 +1472,20 @@
 }
 
 void RTCStatsCollector::ProducePartialResultsOnSignalingThreadImpl(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     RTCStatsReport* partial_report) {
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
 
-  ProduceDataChannelStats_s(timestamp_us, partial_report);
-  ProduceMediaStreamStats_s(timestamp_us, partial_report);
-  ProduceMediaStreamTrackStats_s(timestamp_us, partial_report);
-  ProduceMediaSourceStats_s(timestamp_us, partial_report);
-  ProducePeerConnectionStats_s(timestamp_us, partial_report);
+  ProduceDataChannelStats_s(timestamp, partial_report);
+  ProduceMediaStreamStats_s(timestamp, partial_report);
+  ProduceMediaStreamTrackStats_s(timestamp, partial_report);
+  ProduceMediaSourceStats_s(timestamp, partial_report);
+  ProducePeerConnectionStats_s(timestamp, partial_report);
 }
 
 void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     absl::optional<std::string> sctp_transport_name) {
   TRACE_EVENT0("webrtc",
                "RTCStatsCollector::ProducePartialResultsOnNetworkThread");
@@ -1495,7 +1494,7 @@
 
   // Touching `network_report_` on this thread is safe by this method because
   // `network_report_event_` is reset before this method is invoked.
-  network_report_ = RTCStatsReport::Create(Timestamp::Micros(timestamp_us));
+  network_report_ = RTCStatsReport::Create(timestamp);
 
   std::set<std::string> transport_names;
   if (sctp_transport_name) {
@@ -1512,9 +1511,9 @@
   std::map<std::string, CertificateStatsPair> transport_cert_stats =
       PrepareTransportCertificateStats_n(transport_stats_by_name);
 
-  ProducePartialResultsOnNetworkThreadImpl(
-      timestamp_us, transport_stats_by_name, transport_cert_stats,
-      network_report_.get());
+  ProducePartialResultsOnNetworkThreadImpl(timestamp, transport_stats_by_name,
+                                           transport_cert_stats,
+                                           network_report_.get());
 
   // Signal that it is now safe to touch `network_report_` on the signaling
   // thread, and post a task to merge it into the final results.
@@ -1525,7 +1524,7 @@
 }
 
 void RTCStatsCollector::ProducePartialResultsOnNetworkThreadImpl(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const std::map<std::string, cricket::TransportStats>&
         transport_stats_by_name,
     const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
@@ -1533,13 +1532,12 @@
   RTC_DCHECK_RUN_ON(network_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
 
-  ProduceCertificateStats_n(timestamp_us, transport_cert_stats, partial_report);
-  ProduceIceCandidateAndPairStats_n(timestamp_us, transport_stats_by_name,
+  ProduceCertificateStats_n(timestamp, transport_cert_stats, partial_report);
+  ProduceIceCandidateAndPairStats_n(timestamp, transport_stats_by_name,
                                     call_stats_, partial_report);
-  ProduceTransportStats_n(timestamp_us, transport_stats_by_name,
+  ProduceTransportStats_n(timestamp, transport_stats_by_name,
                           transport_cert_stats, partial_report);
-  ProduceRTPStreamStats_n(timestamp_us, transceiver_stats_infos_,
-                          partial_report);
+  ProduceRTPStreamStats_n(timestamp, transceiver_stats_infos_, partial_report);
 }
 
 void RTCStatsCollector::MergeNetworkReport_s() {
@@ -1614,7 +1612,7 @@
 }
 
 void RTCStatsCollector::ProduceCertificateStats_n(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(network_thread_);
@@ -1623,17 +1621,17 @@
   for (const auto& transport_cert_stats_pair : transport_cert_stats) {
     if (transport_cert_stats_pair.second.local) {
       ProduceCertificateStatsFromSSLCertificateStats(
-          timestamp_us, *transport_cert_stats_pair.second.local.get(), report);
+          timestamp, *transport_cert_stats_pair.second.local.get(), report);
     }
     if (transport_cert_stats_pair.second.remote) {
       ProduceCertificateStatsFromSSLCertificateStats(
-          timestamp_us, *transport_cert_stats_pair.second.remote.get(), report);
+          timestamp, *transport_cert_stats_pair.second.remote.get(), report);
     }
   }
 }
 
 void RTCStatsCollector::ProduceDataChannelStats_s(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
@@ -1641,7 +1639,7 @@
   for (const auto& stats : data_stats) {
     std::unique_ptr<RTCDataChannelStats> data_channel_stats(
         std::make_unique<RTCDataChannelStats>(
-            "D" + rtc::ToString(stats.internal_id), timestamp_us));
+            "D" + rtc::ToString(stats.internal_id), timestamp));
     data_channel_stats->label = std::move(stats.label);
     data_channel_stats->protocol = std::move(stats.protocol);
     data_channel_stats->data_channel_identifier = stats.id;
@@ -1655,7 +1653,7 @@
 }
 
 void RTCStatsCollector::ProduceIceCandidateAndPairStats_n(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const std::map<std::string, cricket::TransportStats>&
         transport_stats_by_name,
     const Call::Stats& call_stats,
@@ -1673,8 +1671,7 @@
            channel_stats.ice_transport_stats.connection_infos) {
         std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats(
             std::make_unique<RTCIceCandidatePairStats>(
-                RTCIceCandidatePairStatsIDFromConnectionInfo(info),
-                timestamp_us));
+                RTCIceCandidatePairStatsIDFromConnectionInfo(info), timestamp));
 
         candidate_pair_stats->transport_id = transport_id;
         // TODO(hbos): There could be other candidates that are not paired with
@@ -1682,9 +1679,9 @@
         // Port objects, and prflx candidates (both local and remote) are only
         // stored in candidate pairs. https://crbug.com/632723
         candidate_pair_stats->local_candidate_id = ProduceIceCandidateStats(
-            timestamp_us, info.local_candidate, true, transport_id, report);
+            timestamp, info.local_candidate, true, transport_id, report);
         candidate_pair_stats->remote_candidate_id = ProduceIceCandidateStats(
-            timestamp_us, info.remote_candidate, false, transport_id, report);
+            timestamp, info.remote_candidate, false, transport_id, report);
         candidate_pair_stats->state =
             IceCandidatePairStateToRTCStatsIceCandidatePairState(info.state);
         candidate_pair_stats->priority = info.priority;
@@ -1760,7 +1757,7 @@
       for (const auto& candidate_stats :
            channel_stats.ice_transport_stats.candidate_stats_list) {
         const auto& candidate = candidate_stats.candidate();
-        ProduceIceCandidateStats(timestamp_us, candidate, true, transport_id,
+        ProduceIceCandidateStats(timestamp, candidate, true, transport_id,
                                  report);
       }
     }
@@ -1768,7 +1765,7 @@
 }
 
 void RTCStatsCollector::ProduceMediaStreamStats_s(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
@@ -1798,7 +1795,7 @@
   for (auto& it : track_ids) {
     std::unique_ptr<DEPRECATED_RTCMediaStreamStats> stream_stats(
         std::make_unique<DEPRECATED_RTCMediaStreamStats>(
-            "DEPRECATED_S" + it.first, timestamp_us));
+            "DEPRECATED_S" + it.first, timestamp));
     stream_stats->stream_identifier = it.first;
     stream_stats->track_ids = it.second;
     report->AddStats(std::move(stream_stats));
@@ -1806,7 +1803,7 @@
 }
 
 void RTCStatsCollector::ProduceMediaStreamTrackStats_s(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
@@ -1817,21 +1814,21 @@
       senders.push_back(
           rtc::scoped_refptr<RtpSenderInternal>(sender->internal()));
     }
-    ProduceSenderMediaTrackStats(timestamp_us, stats.track_media_info_map,
-                                 senders, report);
+    ProduceSenderMediaTrackStats(timestamp, stats.track_media_info_map, senders,
+                                 report);
 
     std::vector<rtc::scoped_refptr<RtpReceiverInternal>> receivers;
     for (const auto& receiver : stats.transceiver->receivers()) {
       receivers.push_back(
           rtc::scoped_refptr<RtpReceiverInternal>(receiver->internal()));
     }
-    ProduceReceiverMediaTrackStats(timestamp_us, stats.track_media_info_map,
+    ProduceReceiverMediaTrackStats(timestamp, stats.track_media_info_map,
                                    receivers, report);
   }
 }
 
 void RTCStatsCollector::ProduceMediaSourceStats_s(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
@@ -1859,7 +1856,7 @@
         auto audio_source_stats = std::make_unique<RTCAudioSourceStats>(
             RTCMediaSourceStatsIDFromKindAndAttachment(
                 cricket::MEDIA_TYPE_AUDIO, sender_internal->AttachmentId()),
-            timestamp_us);
+            timestamp);
         // TODO(https://crbug.com/webrtc/10771): We shouldn't need to have an
         // SSRC assigned (there shouldn't need to exist a send-stream, created
         // by an O/A exchange) in order to read audio media-source stats.
@@ -1897,7 +1894,7 @@
         auto video_source_stats = std::make_unique<RTCVideoSourceStats>(
             RTCMediaSourceStatsIDFromKindAndAttachment(
                 cricket::MEDIA_TYPE_VIDEO, sender_internal->AttachmentId()),
-            timestamp_us);
+            timestamp);
         auto* video_track = static_cast<VideoTrackInterface*>(track.get());
         auto* video_source = video_track->GetSource();
         VideoTrackSourceInterface::Stats source_stats;
@@ -1930,20 +1927,20 @@
 }
 
 void RTCStatsCollector::ProducePeerConnectionStats_s(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(signaling_thread_);
   rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
 
   std::unique_ptr<RTCPeerConnectionStats> stats(
-      std::make_unique<RTCPeerConnectionStats>("P", timestamp_us));
+      std::make_unique<RTCPeerConnectionStats>("P", timestamp));
   stats->data_channels_opened = internal_record_.data_channels_opened;
   stats->data_channels_closed = internal_record_.data_channels_closed;
   report->AddStats(std::move(stats));
 }
 
 void RTCStatsCollector::ProduceRTPStreamStats_n(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(network_thread_);
@@ -1951,9 +1948,9 @@
 
   for (const RtpTransceiverStatsInfo& stats : transceiver_stats_infos) {
     if (stats.media_type == cricket::MEDIA_TYPE_AUDIO) {
-      ProduceAudioRTPStreamStats_n(timestamp_us, stats, report);
+      ProduceAudioRTPStreamStats_n(timestamp, stats, report);
     } else if (stats.media_type == cricket::MEDIA_TYPE_VIDEO) {
-      ProduceVideoRTPStreamStats_n(timestamp_us, stats, report);
+      ProduceVideoRTPStreamStats_n(timestamp, stats, report);
     } else {
       RTC_DCHECK_NOTREACHED();
     }
@@ -1961,7 +1958,7 @@
 }
 
 void RTCStatsCollector::ProduceAudioRTPStreamStats_n(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const RtpTransceiverStatsInfo& stats,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(network_thread_);
@@ -1984,7 +1981,7 @@
     // Inbound.
     auto inbound_audio = CreateInboundAudioStreamStats(
         stats.track_media_info_map.voice_media_info().value(),
-        voice_receiver_info, transport_id, mid, timestamp_us, report);
+        voice_receiver_info, transport_id, mid, timestamp, report);
     // TODO(hta): This lookup should look for the sender, not the track.
     rtc::scoped_refptr<AudioTrackInterface> audio_track =
         stats.track_media_info_map.GetAudioTrack(voice_receiver_info);
@@ -2028,7 +2025,7 @@
     auto outbound_audio = std::make_unique<RTCOutboundRTPStreamStats>(
         RTCOutboundRTPStreamStatsIDFromSSRC(
             transport_id, cricket::MEDIA_TYPE_AUDIO, voice_sender_info.ssrc()),
-        timestamp_us);
+        timestamp);
     SetOutboundRTPStreamStatsFromVoiceSenderInfo(
         transport_id, mid,
         stats.track_media_info_map.voice_media_info().value(),
@@ -2071,7 +2068,7 @@
 }
 
 void RTCStatsCollector::ProduceVideoRTPStreamStats_n(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const RtpTransceiverStatsInfo& stats,
     RTCStatsReport* report) const {
   RTC_DCHECK_RUN_ON(network_thread_);
@@ -2093,7 +2090,7 @@
         RTCInboundRTPStreamStatsIDFromSSRC(transport_id,
                                            cricket::MEDIA_TYPE_VIDEO,
                                            video_receiver_info.ssrc()),
-        timestamp_us);
+        timestamp);
     SetInboundRTPStreamStatsFromVideoReceiverInfo(
         transport_id, mid,
         stats.track_media_info_map.video_media_info().value(),
@@ -2122,7 +2119,7 @@
     auto outbound_video = std::make_unique<RTCOutboundRTPStreamStats>(
         RTCOutboundRTPStreamStatsIDFromSSRC(
             transport_id, cricket::MEDIA_TYPE_VIDEO, video_sender_info.ssrc()),
-        timestamp_us);
+        timestamp);
     SetOutboundRTPStreamStatsFromVideoSenderInfo(
         transport_id, mid,
         stats.track_media_info_map.video_media_info().value(),
@@ -2165,7 +2162,7 @@
 }
 
 void RTCStatsCollector::ProduceTransportStats_n(
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const std::map<std::string, cricket::TransportStats>&
         transport_stats_by_name,
     const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
@@ -2211,7 +2208,7 @@
           std::make_unique<RTCTransportStats>(
               RTCTransportStatsIDFromTransportChannel(transport_name,
                                                       channel_stats.component),
-              timestamp_us));
+              timestamp));
       transport_stats->packets_sent =
           channel_stats.ice_transport_stats.packets_sent;
       transport_stats->packets_received =
diff --git a/pc/rtc_stats_collector.h b/pc/rtc_stats_collector.h
index 9117528..b3e60ef 100644
--- a/pc/rtc_stats_collector.h
+++ b/pc/rtc_stats_collector.h
@@ -104,10 +104,10 @@
 
   // Stats gathering on a particular thread. Virtual for the sake of testing.
   virtual void ProducePartialResultsOnSignalingThreadImpl(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       RTCStatsReport* partial_report);
   virtual void ProducePartialResultsOnNetworkThreadImpl(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const std::map<std::string, cricket::TransportStats>&
           transport_stats_by_name,
       const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
@@ -178,31 +178,31 @@
 
   // Produces `RTCCertificateStats`.
   void ProduceCertificateStats_n(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
       RTCStatsReport* report) const;
   // Produces `RTCDataChannelStats`.
-  void ProduceDataChannelStats_s(int64_t timestamp_us,
+  void ProduceDataChannelStats_s(Timestamp timestamp,
                                  RTCStatsReport* report) const;
   // Produces `RTCIceCandidatePairStats` and `RTCIceCandidateStats`.
   void ProduceIceCandidateAndPairStats_n(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const std::map<std::string, cricket::TransportStats>&
           transport_stats_by_name,
       const Call::Stats& call_stats,
       RTCStatsReport* report) const;
   // Produces `RTCMediaStreamStats`.
-  void ProduceMediaStreamStats_s(int64_t timestamp_us,
+  void ProduceMediaStreamStats_s(Timestamp timestamp,
                                  RTCStatsReport* report) const;
   // Produces `RTCMediaStreamTrackStats`.
-  void ProduceMediaStreamTrackStats_s(int64_t timestamp_us,
+  void ProduceMediaStreamTrackStats_s(Timestamp timestamp,
                                       RTCStatsReport* report) const;
   // Produces RTCMediaSourceStats, including RTCAudioSourceStats and
   // RTCVideoSourceStats.
-  void ProduceMediaSourceStats_s(int64_t timestamp_us,
+  void ProduceMediaSourceStats_s(Timestamp timestamp,
                                  RTCStatsReport* report) const;
   // Produces `RTCPeerConnectionStats`.
-  void ProducePeerConnectionStats_s(int64_t timestamp_us,
+  void ProducePeerConnectionStats_s(Timestamp timestamp,
                                     RTCStatsReport* report) const;
   // Produces `RTCInboundRTPStreamStats`, `RTCOutboundRTPStreamStats`,
   // `RTCRemoteInboundRtpStreamStats`, `RTCRemoteOutboundRtpStreamStats` and any
@@ -210,18 +210,18 @@
   // have been created because some metrics are calculated through lookup of
   // other metrics.
   void ProduceRTPStreamStats_n(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const std::vector<RtpTransceiverStatsInfo>& transceiver_stats_infos,
       RTCStatsReport* report) const;
-  void ProduceAudioRTPStreamStats_n(int64_t timestamp_us,
+  void ProduceAudioRTPStreamStats_n(Timestamp timestamp,
                                     const RtpTransceiverStatsInfo& stats,
                                     RTCStatsReport* report) const;
-  void ProduceVideoRTPStreamStats_n(int64_t timestamp_us,
+  void ProduceVideoRTPStreamStats_n(Timestamp timestamp,
                                     const RtpTransceiverStatsInfo& stats,
                                     RTCStatsReport* report) const;
   // Produces `RTCTransportStats`.
   void ProduceTransportStats_n(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const std::map<std::string, cricket::TransportStats>&
           transport_stats_by_name,
       const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
@@ -236,9 +236,9 @@
   void PrepareTransceiverStatsInfosAndCallStats_s_w_n();
 
   // Stats gathering on a particular thread.
-  void ProducePartialResultsOnSignalingThread(int64_t timestamp_us);
+  void ProducePartialResultsOnSignalingThread(Timestamp timestamp);
   void ProducePartialResultsOnNetworkThread(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       absl::optional<std::string> sctp_transport_name);
   // Merges `network_report_` into `partial_report_` and completes the request.
   // This is a NO-OP if `network_report_` is null.
diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc
index 3dbf0a0..1916b92 100644
--- a/pc/rtc_stats_collector_unittest.cc
+++ b/pc/rtc_stats_collector_unittest.cc
@@ -648,7 +648,7 @@
         // Ignore remote timestamps.
         continue;
       }
-      EXPECT_LE(stats.timestamp_us(), after);
+      EXPECT_LE(stats.timestamp().us(), after);
     }
     return callback->report();
   }
@@ -668,7 +668,7 @@
       const CertificateInfo& certinfo) {
     for (size_t i = 0; i < certinfo.fingerprints.size(); ++i) {
       RTCCertificateStats expected_certificate_stats(
-          "CF" + certinfo.fingerprints[i], report->timestamp_us());
+          "CF" + certinfo.fingerprints[i], report->timestamp());
       expected_certificate_stats.fingerprint = certinfo.fingerprints[i];
       expected_certificate_stats.fingerprint_algorithm = "sha-1";
       expected_certificate_stats.base64_certificate = certinfo.pems[i];
@@ -1177,7 +1177,7 @@
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
   RTCCodecStats expected_inbound_audio_codec(
-      "CITTransportName1_1_minptime=10;useinbandfec=1", report->timestamp_us());
+      "CITTransportName1_1_minptime=10;useinbandfec=1", report->timestamp());
   expected_inbound_audio_codec.payload_type = 1;
   expected_inbound_audio_codec.mime_type = "audio/opus";
   expected_inbound_audio_codec.clock_rate = 1337;
@@ -1186,7 +1186,7 @@
   expected_inbound_audio_codec.transport_id = "TTransportName1";
 
   RTCCodecStats expected_outbound_audio_codec("COTTransportName1_2",
-                                              report->timestamp_us());
+                                              report->timestamp());
   expected_outbound_audio_codec.payload_type = 2;
   expected_outbound_audio_codec.mime_type = "audio/isac";
   expected_outbound_audio_codec.clock_rate = 1338;
@@ -1196,7 +1196,7 @@
   RTCCodecStats expected_inbound_video_codec(
       "CITTransportName1_3_level-asymmetry-allowed=1;"
       "packetization-mode=1;profile-level-id=42001f",
-      report->timestamp_us());
+      report->timestamp());
   expected_inbound_video_codec.payload_type = 3;
   expected_inbound_video_codec.mime_type = "video/H264";
   expected_inbound_video_codec.clock_rate = 1339;
@@ -1205,7 +1205,7 @@
   expected_inbound_video_codec.transport_id = "TTransportName1";
 
   RTCCodecStats expected_outbound_video_codec("COTTransportName1_4",
-                                              report->timestamp_us());
+                                              report->timestamp());
   expected_outbound_video_codec.payload_type = 4;
   expected_outbound_video_codec.mime_type = "video/VP8";
   expected_outbound_video_codec.clock_rate = 1340;
@@ -1484,10 +1484,10 @@
   ASSERT_TRUE(first_local_cert1);
   ASSERT_TRUE(first_remote_cert0);
   ASSERT_TRUE(first_remote_cert1);
-  EXPECT_EQ(first_local_cert0->timestamp_us(), rtc::TimeMicros());
-  EXPECT_EQ(first_local_cert1->timestamp_us(), rtc::TimeMicros());
-  EXPECT_EQ(first_remote_cert0->timestamp_us(), rtc::TimeMicros());
-  EXPECT_EQ(first_remote_cert1->timestamp_us(), rtc::TimeMicros());
+  EXPECT_EQ(first_local_cert0->timestamp().us(), rtc::TimeMicros());
+  EXPECT_EQ(first_local_cert1->timestamp().us(), rtc::TimeMicros());
+  EXPECT_EQ(first_remote_cert0->timestamp().us(), rtc::TimeMicros());
+  EXPECT_EQ(first_remote_cert1->timestamp().us(), rtc::TimeMicros());
 
   // Replace all certificates.
   std::unique_ptr<CertificateInfo> updated_local_certinfo =
@@ -1536,10 +1536,10 @@
   EXPECT_EQ(*second_remote_cert1->fingerprint,
             initial_remote_certinfo->fingerprints[1]);
   // But timestamps are up-to-date, because this is a fresh stats report.
-  EXPECT_EQ(second_local_cert0->timestamp_us(), rtc::TimeMicros());
-  EXPECT_EQ(second_local_cert1->timestamp_us(), rtc::TimeMicros());
-  EXPECT_EQ(second_remote_cert0->timestamp_us(), rtc::TimeMicros());
-  EXPECT_EQ(second_remote_cert1->timestamp_us(), rtc::TimeMicros());
+  EXPECT_EQ(second_local_cert0->timestamp().us(), rtc::TimeMicros());
+  EXPECT_EQ(second_local_cert1->timestamp().us(), rtc::TimeMicros());
+  EXPECT_EQ(second_remote_cert0->timestamp().us(), rtc::TimeMicros());
+  EXPECT_EQ(second_remote_cert1->timestamp().us(), rtc::TimeMicros());
   // The updated certificates are not part of the report yet.
   EXPECT_FALSE(GetCertificateStatsFromFingerprint(
       second_report, updated_local_certinfo->fingerprints[0]));
@@ -1587,7 +1587,7 @@
   pc_->AddSctpDataChannel(rtc::make_ref_counted<MockSctpDataChannel>(
       0, "MockSctpDataChannel0", DataChannelInterface::kConnecting, "udp", 1, 2,
       3, 4));
-  RTCDataChannelStats expected_data_channel0("D0", 0);
+  RTCDataChannelStats expected_data_channel0("D0", Timestamp::Zero());
   expected_data_channel0.label = "MockSctpDataChannel0";
   expected_data_channel0.protocol = "udp";
   expected_data_channel0.data_channel_identifier = 0;
@@ -1600,7 +1600,7 @@
   pc_->AddSctpDataChannel(rtc::make_ref_counted<MockSctpDataChannel>(
       1, "MockSctpDataChannel1", DataChannelInterface::kOpen, "tcp", 5, 6, 7,
       8));
-  RTCDataChannelStats expected_data_channel1("D1", 0);
+  RTCDataChannelStats expected_data_channel1("D1", Timestamp::Zero());
   expected_data_channel1.label = "MockSctpDataChannel1";
   expected_data_channel1.protocol = "tcp";
   expected_data_channel1.data_channel_identifier = 1;
@@ -1613,7 +1613,7 @@
   pc_->AddSctpDataChannel(rtc::make_ref_counted<MockSctpDataChannel>(
       2, "MockSctpDataChannel2", DataChannelInterface::kClosing, "udp", 9, 10,
       11, 12));
-  RTCDataChannelStats expected_data_channel2("D2", 0);
+  RTCDataChannelStats expected_data_channel2("D2", Timestamp::Zero());
   expected_data_channel2.label = "MockSctpDataChannel2";
   expected_data_channel2.protocol = "udp";
   expected_data_channel2.data_channel_identifier = 2;
@@ -1626,7 +1626,7 @@
   pc_->AddSctpDataChannel(rtc::make_ref_counted<MockSctpDataChannel>(
       3, "MockSctpDataChannel3", DataChannelInterface::kClosed, "tcp", 13, 14,
       15, 16));
-  RTCDataChannelStats expected_data_channel3("D3", 0);
+  RTCDataChannelStats expected_data_channel3("D3", Timestamp::Zero());
   expected_data_channel3.label = "MockSctpDataChannel3";
   expected_data_channel3.protocol = "tcp";
   expected_data_channel3.data_channel_identifier = 3;
@@ -1661,7 +1661,8 @@
   std::unique_ptr<cricket::Candidate> a_local_host = CreateFakeCandidate(
       "1.2.3.4", 5, "a_local_host's protocol", rtc::ADAPTER_TYPE_VPN,
       cricket::LOCAL_PORT_TYPE, 0, rtc::ADAPTER_TYPE_ETHERNET);
-  RTCLocalIceCandidateStats expected_a_local_host("I" + a_local_host->id(), 0);
+  RTCLocalIceCandidateStats expected_a_local_host("I" + a_local_host->id(),
+                                                  Timestamp::Zero());
   expected_a_local_host.transport_id = "Ta0";
   expected_a_local_host.network_type = "vpn";
   expected_a_local_host.ip = "1.2.3.4";
@@ -1679,7 +1680,7 @@
       "6.7.8.9", 10, "remote_srflx's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
       cricket::STUN_PORT_TYPE, 1);
   RTCRemoteIceCandidateStats expected_a_remote_srflx("I" + a_remote_srflx->id(),
-                                                     0);
+                                                     Timestamp::Zero());
   expected_a_remote_srflx.transport_id = "Ta0";
   expected_a_remote_srflx.ip = "6.7.8.9";
   expected_a_remote_srflx.address = "6.7.8.9";
@@ -1694,7 +1695,7 @@
       "11.12.13.14", 15, "a_local_prflx's protocol",
       rtc::ADAPTER_TYPE_CELLULAR_2G, cricket::PRFLX_PORT_TYPE, 2);
   RTCLocalIceCandidateStats expected_a_local_prflx("I" + a_local_prflx->id(),
-                                                   0);
+                                                   Timestamp::Zero());
   expected_a_local_prflx.transport_id = "Ta0";
   expected_a_local_prflx.network_type = "cellular";
   expected_a_local_prflx.ip = "11.12.13.14";
@@ -1713,7 +1714,7 @@
       "16.17.18.19", 20, "a_remote_relay's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
       cricket::RELAY_PORT_TYPE, 3);
   RTCRemoteIceCandidateStats expected_a_remote_relay("I" + a_remote_relay->id(),
-                                                     0);
+                                                     Timestamp::Zero());
   expected_a_remote_relay.transport_id = "Ta0";
   expected_a_remote_relay.ip = "16.17.18.19";
   expected_a_remote_relay.address = "16.17.18.19";
@@ -1731,7 +1732,7 @@
   a_local_relay->set_url("turn:url1");
 
   RTCLocalIceCandidateStats expected_a_local_relay("I" + a_local_relay->id(),
-                                                   0);
+                                                   Timestamp::Zero());
   expected_a_local_relay.transport_id = "Ta0";
   expected_a_local_relay.network_type = "unknown";
   expected_a_local_relay.ip = "16.17.18.19";
@@ -1753,7 +1754,7 @@
   a_local_relay_prflx->set_relay_protocol("udp");
 
   RTCLocalIceCandidateStats expected_a_local_relay_prflx(
-      "I" + a_local_relay_prflx->id(), 0);
+      "I" + a_local_relay_prflx->id(), Timestamp::Zero());
   expected_a_local_relay_prflx.transport_id = "Ta0";
   expected_a_local_relay_prflx.network_type = "unknown";
   expected_a_local_relay_prflx.ip = "11.12.13.20";
@@ -1775,7 +1776,7 @@
                           rtc::ADAPTER_TYPE_VPN, cricket::LOCAL_PORT_TYPE, 0,
                           rtc::ADAPTER_TYPE_ETHERNET);
   RTCLocalIceCandidateStats expected_a_local_host_not_paired(
-      "I" + a_local_host_not_paired->id(), 0);
+      "I" + a_local_host_not_paired->id(), Timestamp::Zero());
   expected_a_local_host_not_paired.transport_id = "Ta0";
   expected_a_local_host_not_paired.network_type = "vpn";
   expected_a_local_host_not_paired.ip = "1.2.3.4";
@@ -1795,7 +1796,8 @@
   std::unique_ptr<cricket::Candidate> b_local =
       CreateFakeCandidate("42.42.42.42", 42, "b_local's protocol",
                           rtc::ADAPTER_TYPE_WIFI, cricket::LOCAL_PORT_TYPE, 42);
-  RTCLocalIceCandidateStats expected_b_local("I" + b_local->id(), 0);
+  RTCLocalIceCandidateStats expected_b_local("I" + b_local->id(),
+                                             Timestamp::Zero());
   expected_b_local.transport_id = "Tb0";
   expected_b_local.network_type = "wifi";
   expected_b_local.ip = "42.42.42.42";
@@ -1812,7 +1814,8 @@
   std::unique_ptr<cricket::Candidate> b_remote = CreateFakeCandidate(
       "42.42.42.42", 42, "b_remote's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
       cricket::LOCAL_PORT_TYPE, 42);
-  RTCRemoteIceCandidateStats expected_b_remote("I" + b_remote->id(), 0);
+  RTCRemoteIceCandidateStats expected_b_remote("I" + b_remote->id(),
+                                               Timestamp::Zero());
   expected_b_remote.transport_id = "Tb0";
   expected_b_remote.ip = "42.42.42.42";
   expected_b_remote.address = "42.42.42.42";
@@ -1956,7 +1959,7 @@
 
   RTCIceCandidatePairStats expected_pair(
       "CP" + local_candidate->id() + "_" + remote_candidate->id(),
-      report->timestamp_us());
+      report->timestamp());
   expected_pair.transport_id =
       "Ttransport" + rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTP);
   expected_pair.local_candidate_id = "I" + local_candidate->id();
@@ -2048,7 +2051,7 @@
   EXPECT_TRUE(report->Get(*expected_pair.transport_id));
 
   RTCLocalIceCandidateStats expected_local_candidate(
-      *expected_pair.local_candidate_id, report->timestamp_us());
+      *expected_pair.local_candidate_id, report->timestamp());
   expected_local_candidate.transport_id = *expected_pair.transport_id;
   expected_local_candidate.network_type = "wifi";
   expected_local_candidate.ip = "42.42.42.42";
@@ -2067,7 +2070,7 @@
                 ->cast_to<RTCLocalIceCandidateStats>());
 
   RTCRemoteIceCandidateStats expected_remote_candidate(
-      *expected_pair.remote_candidate_id, report->timestamp_us());
+      *expected_pair.remote_candidate_id, report->timestamp());
   expected_remote_candidate.transport_id = *expected_pair.transport_id;
   expected_remote_candidate.ip = "42.42.42.42";
   expected_remote_candidate.address = "42.42.42.42";
@@ -2088,7 +2091,7 @@
 TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) {
   {
     rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
-    RTCPeerConnectionStats expected("P", report->timestamp_us());
+    RTCPeerConnectionStats expected("P", report->timestamp());
     expected.data_channels_opened = 0;
     expected.data_channels_closed = 0;
     ASSERT_TRUE(report->Get("P"));
@@ -2113,7 +2116,7 @@
   {
     rtc::scoped_refptr<const RTCStatsReport> report =
         stats_->GetFreshStatsReport();
-    RTCPeerConnectionStats expected("P", report->timestamp_us());
+    RTCPeerConnectionStats expected("P", report->timestamp());
     expected.data_channels_opened = 1;
     expected.data_channels_closed = 0;
     ASSERT_TRUE(report->Get("P"));
@@ -2126,7 +2129,7 @@
   {
     rtc::scoped_refptr<const RTCStatsReport> report =
         stats_->GetFreshStatsReport();
-    RTCPeerConnectionStats expected("P", report->timestamp_us());
+    RTCPeerConnectionStats expected("P", report->timestamp());
     expected.data_channels_opened = 2;
     expected.data_channels_closed = 1;
     ASSERT_TRUE(report->Get("P"));
@@ -2140,7 +2143,7 @@
   {
     rtc::scoped_refptr<const RTCStatsReport> report =
         stats_->GetFreshStatsReport();
-    RTCPeerConnectionStats expected("P", report->timestamp_us());
+    RTCPeerConnectionStats expected("P", report->timestamp());
     expected.data_channels_opened = 3;
     expected.data_channels_closed = 1;
     ASSERT_TRUE(report->Get("P"));
@@ -2153,7 +2156,7 @@
   {
     rtc::scoped_refptr<const RTCStatsReport> report =
         stats_->GetFreshStatsReport();
-    RTCPeerConnectionStats expected("P", report->timestamp_us());
+    RTCPeerConnectionStats expected("P", report->timestamp());
     expected.data_channels_opened = 3;
     expected.data_channels_closed = 3;
     ASSERT_TRUE(report->Get("P"));
@@ -2188,7 +2191,7 @@
 
   DEPRECATED_RTCMediaStreamStats expected_local_stream(
       IdForType<DEPRECATED_RTCMediaStreamStats>(report.get()),
-      report->timestamp_us());
+      report->timestamp());
   expected_local_stream.stream_identifier = local_stream->id();
   expected_local_stream.track_ids = {
       IdForType<DEPRECATED_RTCMediaStreamTrackStats>(report.get())};
@@ -2201,7 +2204,7 @@
 
   DEPRECATED_RTCMediaStreamTrackStats expected_local_audio_track_ssrc1(
       IdForType<DEPRECATED_RTCMediaStreamTrackStats>(report.get()),
-      report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
+      report->timestamp(), RTCMediaStreamTrackKind::kAudio);
   expected_local_audio_track_ssrc1.track_identifier = local_audio_track->id();
   expected_local_audio_track_ssrc1.media_source_id =
       "SA11";  // Attachment ID = SSRC + 10
@@ -2254,7 +2257,7 @@
 
   DEPRECATED_RTCMediaStreamStats expected_remote_stream(
       IdForType<DEPRECATED_RTCMediaStreamStats>(report.get()),
-      report->timestamp_us());
+      report->timestamp());
   expected_remote_stream.stream_identifier = remote_stream->id();
   expected_remote_stream.track_ids = std::vector<std::string>(
       {IdForType<DEPRECATED_RTCMediaStreamTrackStats>(report.get())});
@@ -2267,7 +2270,7 @@
 
   DEPRECATED_RTCMediaStreamTrackStats expected_remote_audio_track(
       IdForType<DEPRECATED_RTCMediaStreamTrackStats>(report.get()),
-      report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
+      report->timestamp(), RTCMediaStreamTrackKind::kAudio);
   expected_remote_audio_track.track_identifier = remote_audio_track->id();
   // `expected_remote_audio_track.media_source_id` should be undefined
   // because the track is remote.
@@ -2328,7 +2331,7 @@
       << "Wrong number of tracks in " << report->ToJson();
 
   DEPRECATED_RTCMediaStreamStats expected_local_stream(
-      stats_of_my_type[0]->id(), report->timestamp_us());
+      stats_of_my_type[0]->id(), report->timestamp());
   expected_local_stream.stream_identifier = local_stream->id();
   expected_local_stream.track_ids =
       std::vector<std::string>({stats_of_track_type[0]->id()});
@@ -2338,7 +2341,7 @@
                 ->cast_to<DEPRECATED_RTCMediaStreamStats>());
 
   DEPRECATED_RTCMediaStreamTrackStats expected_local_video_track_ssrc1(
-      stats_of_track_type[0]->id(), report->timestamp_us(),
+      stats_of_track_type[0]->id(), report->timestamp(),
       RTCMediaStreamTrackKind::kVideo);
   expected_local_video_track_ssrc1.track_identifier = local_video_track->id();
   expected_local_video_track_ssrc1.media_source_id =
@@ -2399,7 +2402,7 @@
   ASSERT_TRUE(*(stats_of_track_type[0]->remote_source));
 
   DEPRECATED_RTCMediaStreamStats expected_remote_stream(
-      stats_of_my_type[0]->id(), report->timestamp_us());
+      stats_of_my_type[0]->id(), report->timestamp());
   expected_remote_stream.stream_identifier = remote_stream->id();
   expected_remote_stream.track_ids =
       std::vector<std::string>({stats_of_track_type[0]->id()});
@@ -2409,7 +2412,7 @@
                 ->cast_to<DEPRECATED_RTCMediaStreamStats>());
 
   DEPRECATED_RTCMediaStreamTrackStats expected_remote_video_track_ssrc3(
-      stats_of_track_type[0]->id(), report->timestamp_us(),
+      stats_of_track_type[0]->id(), report->timestamp(),
       RTCMediaStreamTrackKind::kVideo);
   expected_remote_video_track_ssrc3.track_identifier =
       remote_video_track_ssrc3->id();
@@ -2491,7 +2494,7 @@
   ASSERT_EQ(1U, stats_of_track_type.size());
 
   RTCInboundRTPStreamStats expected_audio("ITTransportName1A1",
-                                          report->timestamp_us());
+                                          report->timestamp());
   expected_audio.ssrc = 1;
   expected_audio.media_type = "audio";
   expected_audio.kind = "audio";
@@ -2621,7 +2624,7 @@
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
   RTCInboundRTPStreamStats expected_video("ITTransportName1V1",
-                                          report->timestamp_us());
+                                          report->timestamp());
   expected_video.ssrc = 1;
   expected_video.media_type = "video";
   expected_video.kind = "video";
@@ -2765,7 +2768,7 @@
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
   RTCOutboundRTPStreamStats expected_audio("OTTransportName1A1",
-                                           report->timestamp_us());
+                                           report->timestamp());
   expected_audio.media_source_id = "SA50";
   // `expected_audio.remote_id` should be undefined.
   expected_audio.mid = "AudioMid";
@@ -2861,7 +2864,7 @@
   ASSERT_EQ(1U, stats_of_track_type.size());
 
   RTCOutboundRTPStreamStats expected_video(stats_of_my_type[0]->id(),
-                                           report->timestamp_us());
+                                           report->timestamp());
   expected_video.media_source_id = "SV50";
   // `expected_video.remote_id` should be undefined.
   expected_video.mid = "VideoMid";
@@ -2978,7 +2981,7 @@
 
   RTCTransportStats expected_rtp_transport(
       "Ttransport" + rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTP),
-      report->timestamp_us());
+      report->timestamp());
   expected_rtp_transport.bytes_sent = 42;
   expected_rtp_transport.packets_sent = 1;
   expected_rtp_transport.bytes_received = 1337;
@@ -3026,7 +3029,7 @@
 
   RTCTransportStats expected_rtcp_transport(
       "Ttransport" + rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTCP),
-      report->timestamp_us());
+      report->timestamp());
   expected_rtcp_transport.bytes_sent = 1337;
   expected_rtcp_transport.packets_sent = 1;
   expected_rtcp_transport.bytes_received = 42;
@@ -3151,7 +3154,7 @@
 
   RTCTransportStats expected_rtp_transport(
       "Ttransport" + rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTP),
-      report->timestamp_us());
+      report->timestamp());
   expected_rtp_transport.dtls_state = RTCDtlsTransportState::kConnected;
   expected_rtp_transport.selected_candidate_pair_changes = 1;
   expected_rtp_transport.ice_role = RTCIceRole::kUnknown;
@@ -3207,7 +3210,7 @@
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
   RTCOutboundRTPStreamStats expected_audio("OTTransportName1A1",
-                                           report->timestamp_us());
+                                           report->timestamp());
   expected_audio.media_source_id = "SA50";
   expected_audio.mid = "AudioMid";
   expected_audio.ssrc = 1;
@@ -3256,7 +3259,7 @@
 
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
-  RTCAudioSourceStats expected_audio("SA42", report->timestamp_us());
+  RTCAudioSourceStats expected_audio("SA42", report->timestamp());
   expected_audio.track_identifier = "LocalAudioTrackID";
   expected_audio.kind = "audio";
   expected_audio.audio_level = 1.0;  // [0,1]
@@ -3301,7 +3304,7 @@
 
   rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
 
-  RTCVideoSourceStats expected_video("SV42", report->timestamp_us());
+  RTCVideoSourceStats expected_video("SV42", report->timestamp());
   expected_video.track_identifier = "LocalVideoTrackID";
   expected_video.kind = "video";
   expected_video.width = kVideoSourceWidth;
@@ -3528,7 +3531,8 @@
   for (auto ssrc : ssrcs) {
     std::string stream_id = "" + std::to_string(ssrc);
     RTCRemoteInboundRtpStreamStats expected_remote_inbound_rtp(
-        "RI" + MediaTypeCharStr() + stream_id, kReportBlockTimestampUtcUs);
+        "RI" + MediaTypeCharStr() + stream_id,
+        Timestamp::Micros(kReportBlockTimestampUtcUs));
     expected_remote_inbound_rtp.ssrc = ssrc;
     expected_remote_inbound_rtp.fraction_lost =
         static_cast<double>(kFractionLost) / (1 << 8);
@@ -3613,8 +3617,10 @@
 
   // Even though the report time is different, the remote-inbound-rtp timestamp
   // is of the time that the report block was received.
-  EXPECT_EQ(kReportBlockTimestampUtcUs + 1234, report->timestamp_us());
-  EXPECT_EQ(kReportBlockTimestampUtcUs, remote_inbound_rtp.timestamp_us());
+  EXPECT_EQ(Timestamp::Micros(kReportBlockTimestampUtcUs + 1234),
+            report->timestamp());
+  EXPECT_EQ(Timestamp::Micros(kReportBlockTimestampUtcUs),
+            remote_inbound_rtp.timestamp());
 }
 
 TEST_P(RTCStatsCollectorTestWithParamKind,
@@ -3722,8 +3728,8 @@
   const auto& remote_outbound_rtp =
       graph.full_report->Get(graph.remote_outbound_rtp_id)
           ->cast_to<RTCRemoteOutboundRtpStreamStats>();
-  EXPECT_EQ(remote_outbound_rtp.timestamp_us(),
-            kRemoteOutboundStatsTimestampMs * rtc::kNumMicrosecsPerMillisec);
+  EXPECT_EQ(remote_outbound_rtp.timestamp(),
+            Timestamp::Millis(kRemoteOutboundStatsTimestampMs));
   EXPECT_FLOAT_EQ(*remote_outbound_rtp.remote_timestamp,
                   static_cast<double>(kRemoteOutboundStatsRemoteTimestampMs));
   EXPECT_EQ(*remote_outbound_rtp.packets_sent, kRemoteOutboundStatsPacketsSent);
@@ -3781,7 +3787,7 @@
 
   DEPRECATED_RTCMediaStreamTrackStats expected_local_audio_track_ssrc1(
       IdForType<DEPRECATED_RTCMediaStreamTrackStats>(report.get()),
-      report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
+      report->timestamp(), RTCMediaStreamTrackKind::kAudio);
   expected_local_audio_track_ssrc1.track_identifier = local_audio_track->id();
   expected_local_audio_track_ssrc1.media_source_id =
       "SA11";  // Attachment ID = SSRC + 10
@@ -3797,7 +3803,7 @@
             report->Get(expected_local_audio_track_ssrc1.id())
                 ->cast_to<DEPRECATED_RTCMediaStreamTrackStats>());
 
-  RTCAudioSourceStats expected_audio("SA11", report->timestamp_us());
+  RTCAudioSourceStats expected_audio("SA11", report->timestamp());
   expected_audio.track_identifier = "LocalAudioTrackID";
   expected_audio.kind = "audio";
   expected_audio.audio_level = 0;
@@ -3827,7 +3833,7 @@
   rtc::scoped_refptr<const RTCStatsReport> sender_report =
       stats_->GetStatsReportWithSenderSelector(graph.sender);
   EXPECT_TRUE(sender_report);
-  EXPECT_EQ(sender_report->timestamp_us(), graph.full_report->timestamp_us());
+  EXPECT_EQ(sender_report->timestamp(), graph.full_report->timestamp());
   EXPECT_EQ(sender_report->size(), 5u);
   EXPECT_TRUE(sender_report->Get(graph.send_codec_id));
   EXPECT_FALSE(sender_report->Get(graph.recv_codec_id));
@@ -3856,7 +3862,7 @@
       stats_->GetStatsReportWithReceiverSelector(graph.receiver);
   EXPECT_TRUE(receiver_report);
   EXPECT_EQ(receiver_report->size(), 4u);
-  EXPECT_EQ(receiver_report->timestamp_us(), graph.full_report->timestamp_us());
+  EXPECT_EQ(receiver_report->timestamp(), graph.full_report->timestamp());
   EXPECT_FALSE(receiver_report->Get(graph.send_codec_id));
   EXPECT_TRUE(receiver_report->Get(graph.recv_codec_id));
   EXPECT_FALSE(receiver_report->Get(graph.outbound_rtp_id));
@@ -3874,7 +3880,7 @@
   rtc::scoped_refptr<const RTCStatsReport> empty_report =
       stats_->GetStatsReportWithSenderSelector(nullptr);
   EXPECT_TRUE(empty_report);
-  EXPECT_EQ(empty_report->timestamp_us(), graph.full_report->timestamp_us());
+  EXPECT_EQ(empty_report->timestamp(), graph.full_report->timestamp());
   EXPECT_EQ(empty_report->size(), 0u);
 }
 
@@ -3883,7 +3889,7 @@
   rtc::scoped_refptr<const RTCStatsReport> empty_report =
       stats_->GetStatsReportWithReceiverSelector(nullptr);
   EXPECT_TRUE(empty_report);
-  EXPECT_EQ(empty_report->timestamp_us(), graph.full_report->timestamp_us());
+  EXPECT_EQ(empty_report->timestamp(), graph.full_report->timestamp());
   EXPECT_EQ(empty_report->size(), 0u);
 }
 
@@ -3960,8 +3966,8 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
-  RTCTestStats(const std::string& id, int64_t timestamp_us)
-      : RTCStats(id, timestamp_us), dummy_stat("dummyStat") {}
+  RTCTestStats(const std::string& id, Timestamp timestamp)
+      : RTCStats(id, timestamp), dummy_stat("dummyStat") {}
 
   RTCStatsMember<int32_t> dummy_stat;
 };
@@ -4029,7 +4035,7 @@
         network_thread_(pc->network_thread()) {}
 
   void ProducePartialResultsOnSignalingThreadImpl(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       RTCStatsReport* partial_report) override {
     EXPECT_TRUE(signaling_thread_->IsCurrent());
     {
@@ -4039,10 +4045,10 @@
     }
 
     partial_report->AddStats(std::unique_ptr<const RTCStats>(
-        new RTCTestStats("SignalingThreadStats", timestamp_us)));
+        new RTCTestStats("SignalingThreadStats", timestamp)));
   }
   void ProducePartialResultsOnNetworkThreadImpl(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const std::map<std::string, cricket::TransportStats>&
           transport_stats_by_name,
       const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
@@ -4055,7 +4061,7 @@
     }
 
     partial_report->AddStats(std::unique_ptr<const RTCStats>(
-        new RTCTestStats("NetworkThreadStats", timestamp_us)));
+        new RTCTestStats("NetworkThreadStats", timestamp)));
   }
 
  private:
diff --git a/pc/rtc_stats_traversal_unittest.cc b/pc/rtc_stats_traversal_unittest.cc
index efc7bbc..72ad255 100644
--- a/pc/rtc_stats_traversal_unittest.cc
+++ b/pc/rtc_stats_traversal_unittest.cc
@@ -24,10 +24,13 @@
 class RTCStatsTraversalTest : public ::testing::Test {
  public:
   RTCStatsTraversalTest() {
-    transport_ = new RTCTransportStats("transport", 0);
-    candidate_pair_ = new RTCIceCandidatePairStats("candidate-pair", 0);
-    local_candidate_ = new RTCLocalIceCandidateStats("local-candidate", 0);
-    remote_candidate_ = new RTCRemoteIceCandidateStats("remote-candidate", 0);
+    transport_ = new RTCTransportStats("transport", Timestamp::Zero());
+    candidate_pair_ =
+        new RTCIceCandidatePairStats("candidate-pair", Timestamp::Zero());
+    local_candidate_ =
+        new RTCLocalIceCandidateStats("local-candidate", Timestamp::Zero());
+    remote_candidate_ =
+        new RTCRemoteIceCandidateStats("remote-candidate", Timestamp::Zero());
     initial_report_ = RTCStatsReport::Create(Timestamp::Zero());
     initial_report_->AddStats(std::unique_ptr<const RTCStats>(transport_));
     initial_report_->AddStats(std::unique_ptr<const RTCStats>(candidate_pair_));
diff --git a/sdk/android/src/jni/pc/rtc_stats_collector_callback_wrapper.cc b/sdk/android/src/jni/pc/rtc_stats_collector_callback_wrapper.cc
index b8eae73..578518c 100644
--- a/sdk/android/src/jni/pc/rtc_stats_collector_callback_wrapper.cc
+++ b/sdk/android/src/jni/pc/rtc_stats_collector_callback_wrapper.cc
@@ -126,7 +126,7 @@
                 MemberToJava(env, *member));
   }
   return Java_RTCStats_create(
-      env, stats.timestamp_us(), NativeToJavaString(env, stats.type()),
+      env, stats.timestamp().us(), NativeToJavaString(env, stats.type()),
       NativeToJavaString(env, stats.id()), builder.GetJavaMap());
 }
 
@@ -138,7 +138,7 @@
         return std::make_pair(NativeToJavaString(env, stats.id()),
                               NativeToJavaRtcStats(env, stats));
       });
-  return Java_RTCStatsReport_create(env, report->timestamp_us(), j_stats_map);
+  return Java_RTCStatsReport_create(env, report->timestamp().us(), j_stats_map);
 }
 
 }  // namespace
diff --git a/sdk/objc/api/peerconnection/RTCStatisticsReport.mm b/sdk/objc/api/peerconnection/RTCStatisticsReport.mm
index 28ef326..bfe2424 100644
--- a/sdk/objc/api/peerconnection/RTCStatisticsReport.mm
+++ b/sdk/objc/api/peerconnection/RTCStatisticsReport.mm
@@ -130,7 +130,7 @@
 - (instancetype)initWithStatistics:(const webrtc::RTCStats &)statistics {
   if (self = [super init]) {
     _id = [NSString stringForStdString:statistics.id()];
-    _timestamp_us = statistics.timestamp_us();
+    _timestamp_us = statistics.timestamp().us();
     _type = [NSString stringWithCString:statistics.type() encoding:NSUTF8StringEncoding];
 
     NSMutableDictionary<NSString *, NSObject *> *values = [NSMutableDictionary dictionary];
@@ -175,7 +175,7 @@
 
 - (instancetype)initWithReport : (const webrtc::RTCStatsReport &)report {
   if (self = [super init]) {
-    _timestamp_us = report.timestamp_us();
+    _timestamp_us = report.timestamp().us();
 
     NSMutableDictionary *statisticsById =
         [NSMutableDictionary dictionaryWithCapacity:report.size()];
diff --git a/stats/rtc_stats.cc b/stats/rtc_stats.cc
index ae352fa..421d969 100644
--- a/stats/rtc_stats.cc
+++ b/stats/rtc_stats.cc
@@ -147,7 +147,7 @@
      << id_
      << "\","
         "\"timestamp\":"
-     << timestamp_us_;
+     << timestamp_.us();
   for (const RTCStatsMemberInterface* member : Members()) {
     if (member->is_defined()) {
       sb << ",\"" << member->name() << "\":";
diff --git a/stats/rtc_stats_report_unittest.cc b/stats/rtc_stats_report_unittest.cc
index 8af6dbe..b69da62 100644
--- a/stats/rtc_stats_report_unittest.cc
+++ b/stats/rtc_stats_report_unittest.cc
@@ -20,8 +20,8 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
-  RTCTestStats1(const std::string& id, int64_t timestamp_us)
-      : RTCStats(id, timestamp_us), integer("integer") {}
+  RTCTestStats1(const std::string& id, Timestamp timestamp)
+      : RTCStats(id, timestamp), integer("integer") {}
 
   RTCStatsMember<int32_t> integer;
 };
@@ -32,8 +32,8 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
-  RTCTestStats2(const std::string& id, int64_t timestamp_us)
-      : RTCStats(id, timestamp_us), number("number") {}
+  RTCTestStats2(const std::string& id, Timestamp timestamp)
+      : RTCStats(id, timestamp), number("number") {}
 
   RTCStatsMember<double> number;
 };
@@ -44,8 +44,8 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
-  RTCTestStats3(const std::string& id, int64_t timestamp_us)
-      : RTCStats(id, timestamp_us), string("string") {}
+  RTCTestStats3(const std::string& id, Timestamp timestamp)
+      : RTCStats(id, timestamp), string("string") {}
 
   RTCStatsMember<std::string> string;
 };
@@ -58,12 +58,18 @@
   EXPECT_EQ(report->timestamp_us(), 1337u);
   EXPECT_EQ(report->timestamp().us_or(-1), 1337u);
   EXPECT_EQ(report->size(), static_cast<size_t>(0));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("a0", 1)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("a1", 2)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("b0", 4)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("b1", 8)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("a2", 16)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("b2", 32)));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("a0", Timestamp::Micros(1))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("a1", Timestamp::Micros(2))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats2("b0", Timestamp::Micros(4))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats2("b1", Timestamp::Micros(8))));
+  report->AddStats(std::unique_ptr<RTCStats>(
+      new RTCTestStats1("a2", Timestamp::Micros(16))));
+  report->AddStats(std::unique_ptr<RTCStats>(
+      new RTCTestStats2("b2", Timestamp::Micros(32))));
   EXPECT_EQ(report->size(), static_cast<size_t>(6));
 
   EXPECT_EQ(report->Get("missing"), nullptr);
@@ -74,14 +80,14 @@
   EXPECT_EQ(a.size(), static_cast<size_t>(3));
   int64_t mask = 0;
   for (const RTCTestStats1* stats : a)
-    mask |= stats->timestamp_us();
+    mask |= stats->timestamp().us();
   EXPECT_EQ(mask, static_cast<int64_t>(1 | 2 | 16));
 
   std::vector<const RTCTestStats2*> b = report->GetStatsOfType<RTCTestStats2>();
   EXPECT_EQ(b.size(), static_cast<size_t>(3));
   mask = 0;
   for (const RTCTestStats2* stats : b)
-    mask |= stats->timestamp_us();
+    mask |= stats->timestamp().us();
   EXPECT_EQ(mask, static_cast<int64_t>(4 | 8 | 32));
 
   EXPECT_EQ(report->GetStatsOfType<RTCTestStats3>().size(),
@@ -91,18 +97,25 @@
 TEST(RTCStatsReport, StatsOrder) {
   rtc::scoped_refptr<RTCStatsReport> report =
       RTCStatsReport::Create(Timestamp::Micros(1337));
-  EXPECT_EQ(report->timestamp_us(), 1337u);
+  EXPECT_EQ(report->timestamp().us(), 1337u);
   EXPECT_EQ(report->timestamp().us_or(-1), 1337u);
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("C", 2)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("D", 3)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("B", 1)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("A", 0)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("E", 4)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("F", 5)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats2("G", 6)));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("C", Timestamp::Micros(2))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("D", Timestamp::Micros(3))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats2("B", Timestamp::Micros(1))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats2("A", Timestamp::Micros(0))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats2("E", Timestamp::Micros(4))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats2("F", Timestamp::Micros(5))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats2("G", Timestamp::Micros(6))));
   int64_t i = 0;
   for (const RTCStats& stats : *report) {
-    EXPECT_EQ(stats.timestamp_us(), i);
+    EXPECT_EQ(stats.timestamp().us(), i);
     ++i;
   }
   EXPECT_EQ(i, static_cast<int64_t>(7));
@@ -111,8 +124,10 @@
 TEST(RTCStatsReport, Take) {
   rtc::scoped_refptr<RTCStatsReport> report =
       RTCStatsReport::Create(Timestamp::Zero());
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("A", 1)));
-  report->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("B", 2)));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("A", Timestamp::Micros(1))));
+  report->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("B", Timestamp::Micros(2))));
   EXPECT_TRUE(report->Get("A"));
   EXPECT_EQ(report->size(), 2u);
   auto a = report->Take("A");
@@ -125,24 +140,30 @@
 TEST(RTCStatsReport, TakeMembersFrom) {
   rtc::scoped_refptr<RTCStatsReport> a =
       RTCStatsReport::Create(Timestamp::Micros(1337));
-  EXPECT_EQ(a->timestamp_us(), 1337u);
+  EXPECT_EQ(a->timestamp().us(), 1337u);
   EXPECT_EQ(a->timestamp().us_or(-1), 1337u);
-  a->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("B", 1)));
-  a->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("C", 2)));
-  a->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("E", 4)));
+  a->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("B", Timestamp::Micros(1))));
+  a->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("C", Timestamp::Micros(2))));
+  a->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("E", Timestamp::Micros(4))));
   rtc::scoped_refptr<RTCStatsReport> b =
       RTCStatsReport::Create(Timestamp::Micros(1338));
   EXPECT_EQ(b->timestamp_us(), 1338u);
   EXPECT_EQ(b->timestamp().us_or(-1), 1338u);
-  b->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("A", 0)));
-  b->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("D", 3)));
-  b->AddStats(std::unique_ptr<RTCStats>(new RTCTestStats1("F", 5)));
+  b->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("A", Timestamp::Micros(0))));
+  b->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("D", Timestamp::Micros(3))));
+  b->AddStats(
+      std::unique_ptr<RTCStats>(new RTCTestStats1("F", Timestamp::Micros(5))));
 
   a->TakeMembersFrom(b);
   EXPECT_EQ(b->size(), static_cast<size_t>(0));
   int64_t i = 0;
   for (const RTCStats& stats : *a) {
-    EXPECT_EQ(stats.timestamp_us(), i);
+    EXPECT_EQ(stats.timestamp().us(), i);
     ++i;
   }
   EXPECT_EQ(i, static_cast<int64_t>(6));
diff --git a/stats/rtc_stats_unittest.cc b/stats/rtc_stats_unittest.cc
index 5d3857f..84b9a63 100644
--- a/stats/rtc_stats_unittest.cc
+++ b/stats/rtc_stats_unittest.cc
@@ -43,8 +43,8 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
-  RTCChildStats(const std::string& id, int64_t timestamp_us)
-      : RTCStats(id, timestamp_us), child_int("childInt") {}
+  RTCChildStats(const std::string& id, Timestamp timestamp)
+      : RTCStats(id, timestamp), child_int("childInt") {}
 
   RTCStatsMember<int32_t> child_int;
 };
@@ -55,8 +55,8 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
-  RTCGrandChildStats(const std::string& id, int64_t timestamp_us)
-      : RTCChildStats(id, timestamp_us), grandchild_int("grandchildInt") {}
+  RTCGrandChildStats(const std::string& id, Timestamp timestamp)
+      : RTCChildStats(id, timestamp), grandchild_int("grandchildInt") {}
 
   RTCStatsMember<int32_t> grandchild_int;
 };
@@ -67,9 +67,9 @@
                      &grandchild_int)
 
 TEST(RTCStatsTest, RTCStatsAndMembers) {
-  RTCTestStats stats("testId", 42);
+  RTCTestStats stats("testId", Timestamp::Micros(42));
   EXPECT_EQ(stats.id(), "testId");
-  EXPECT_EQ(stats.timestamp_us(), static_cast<int64_t>(42));
+  EXPECT_EQ(stats.timestamp().us(), static_cast<int64_t>(42));
   std::vector<const RTCStatsMemberInterface*> members = stats.Members();
   EXPECT_EQ(members.size(), static_cast<size_t>(16));
   for (const RTCStatsMemberInterface* member : members) {
@@ -141,7 +141,7 @@
 }
 
 TEST(RTCStatsTest, EqualityOperator) {
-  RTCTestStats empty_stats("testId", 123);
+  RTCTestStats empty_stats("testId", Timestamp::Micros(123));
   EXPECT_EQ(empty_stats, empty_stats);
 
   RTCTestStats stats_with_all_values = empty_stats;
@@ -195,24 +195,25 @@
     EXPECT_NE(stats_with_all_values, one_member_different[i]);
   }
 
-  RTCTestStats empty_stats_different_id("testId2", 123);
+  RTCTestStats empty_stats_different_id("testId2", Timestamp::Micros(123));
   EXPECT_NE(empty_stats, empty_stats_different_id);
-  RTCTestStats empty_stats_different_timestamp("testId", 321);
+  RTCTestStats empty_stats_different_timestamp("testId",
+                                               Timestamp::Micros(321));
   EXPECT_EQ(empty_stats, empty_stats_different_timestamp);
 
-  RTCChildStats child("childId", 42);
-  RTCGrandChildStats grandchild("grandchildId", 42);
+  RTCChildStats child("childId", Timestamp::Micros(42));
+  RTCGrandChildStats grandchild("grandchildId", Timestamp::Micros(42));
   EXPECT_NE(child, grandchild);
 
-  RTCChildStats stats_with_defined_member("leId", 0);
+  RTCChildStats stats_with_defined_member("leId", Timestamp::Micros(0));
   stats_with_defined_member.child_int = 0;
-  RTCChildStats stats_with_undefined_member("leId", 0);
+  RTCChildStats stats_with_undefined_member("leId", Timestamp::Micros(0));
   EXPECT_NE(stats_with_defined_member, stats_with_undefined_member);
   EXPECT_NE(stats_with_undefined_member, stats_with_defined_member);
 }
 
 TEST(RTCStatsTest, RTCStatsGrandChild) {
-  RTCGrandChildStats stats("grandchild", 0.0);
+  RTCGrandChildStats stats("grandchild", Timestamp::Micros(0.0));
   stats.child_int = 1;
   stats.grandchild_int = 2;
   int32_t sum = 0;
@@ -254,7 +255,7 @@
   std::map<std::string, double> map_string_double{
       {"three", 123.4567890123456499}, {"thirteen", 123.4567890123456499}};
 
-  RTCTestStats stats(id, timestamp);
+  RTCTestStats stats(id, Timestamp::Micros(timestamp));
   stats.m_bool = m_bool;
   stats.m_int32 = m_int32;
   stats.m_int64 = m_int64;
@@ -312,7 +313,7 @@
   }
 
   EXPECT_EQ(id, stats.id());
-  EXPECT_EQ(timestamp, stats.timestamp_us());
+  EXPECT_EQ(timestamp, stats.timestamp().us());
   EXPECT_EQ(m_bool, *stats.m_bool);
   EXPECT_EQ(m_int32, *stats.m_int32);
   EXPECT_EQ(m_string, *stats.m_string);
@@ -394,7 +395,7 @@
 }
 
 TEST(RTCStatsTest, IsSequence) {
-  RTCTestStats stats("statsId", 42);
+  RTCTestStats stats("statsId", Timestamp::Micros(42));
   EXPECT_FALSE(stats.m_bool.is_sequence());
   EXPECT_FALSE(stats.m_int32.is_sequence());
   EXPECT_FALSE(stats.m_uint32.is_sequence());
@@ -414,7 +415,7 @@
 }
 
 TEST(RTCStatsTest, Type) {
-  RTCTestStats stats("statsId", 42);
+  RTCTestStats stats("statsId", Timestamp::Micros(42));
   EXPECT_EQ(RTCStatsMemberInterface::kBool, stats.m_bool.type());
   EXPECT_EQ(RTCStatsMemberInterface::kInt32, stats.m_int32.type());
   EXPECT_EQ(RTCStatsMemberInterface::kUint32, stats.m_uint32.type());
@@ -443,7 +444,7 @@
 }
 
 TEST(RTCStatsTest, IsString) {
-  RTCTestStats stats("statsId", 42);
+  RTCTestStats stats("statsId", Timestamp::Micros(42));
   EXPECT_TRUE(stats.m_string.is_string());
   EXPECT_FALSE(stats.m_bool.is_string());
   EXPECT_FALSE(stats.m_int32.is_string());
@@ -463,7 +464,7 @@
 }
 
 TEST(RTCStatsTest, ValueToString) {
-  RTCTestStats stats("statsId", 42);
+  RTCTestStats stats("statsId", Timestamp::Micros(42));
   stats.m_bool = true;
   EXPECT_EQ("true", stats.m_bool.ValueToString());
 
@@ -533,13 +534,13 @@
 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
 
 TEST(RTCStatsDeathTest, ValueOfUndefinedMember) {
-  RTCTestStats stats("testId", 0.0);
+  RTCTestStats stats("testId", Timestamp::Micros(0));
   EXPECT_FALSE(stats.m_int32.is_defined());
   EXPECT_DEATH(*stats.m_int32, "");
 }
 
 TEST(RTCStatsDeathTest, InvalidCasting) {
-  RTCGrandChildStats stats("grandchild", 0.0);
+  RTCGrandChildStats stats("grandchild", Timestamp::Micros(0.0));
   EXPECT_DEATH(stats.cast_to<RTCChildStats>(), "");
 }
 
diff --git a/stats/rtcstats_objects.cc b/stats/rtcstats_objects.cc
index 9d9498e..5051475 100644
--- a/stats/rtcstats_objects.cc
+++ b/stats/rtcstats_objects.cc
@@ -89,12 +89,14 @@
     &issuer_certificate_id)
 // clang-format on
 
-RTCCertificateStats::RTCCertificateStats(std::string id, int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+RTCCertificateStats::RTCCertificateStats(std::string id, Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       fingerprint("fingerprint"),
       fingerprint_algorithm("fingerprintAlgorithm"),
       base64_certificate("base64Certificate"),
       issuer_certificate_id("issuerCertificateId") {}
+RTCCertificateStats::RTCCertificateStats(std::string id, int64_t timestamp_us)
+    : RTCCertificateStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCCertificateStats::RTCCertificateStats(const RTCCertificateStats& other) =
     default;
@@ -110,14 +112,16 @@
     &sdp_fmtp_line)
 // clang-format on
 
-RTCCodecStats::RTCCodecStats(std::string id, int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+RTCCodecStats::RTCCodecStats(std::string id, Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       transport_id("transportId"),
       payload_type("payloadType"),
       mime_type("mimeType"),
       clock_rate("clockRate"),
       channels("channels"),
       sdp_fmtp_line("sdpFmtpLine") {}
+RTCCodecStats::RTCCodecStats(std::string id, int64_t timestamp_us)
+    : RTCCodecStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCCodecStats::RTCCodecStats(const RTCCodecStats& other) = default;
 
@@ -135,8 +139,8 @@
     &bytes_received)
 // clang-format on
 
-RTCDataChannelStats::RTCDataChannelStats(std::string id, int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+RTCDataChannelStats::RTCDataChannelStats(std::string id, Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       label("label"),
       protocol("protocol"),
       data_channel_identifier("dataChannelIdentifier"),
@@ -145,6 +149,8 @@
       bytes_sent("bytesSent"),
       messages_received("messagesReceived"),
       bytes_received("bytesReceived") {}
+RTCDataChannelStats::RTCDataChannelStats(std::string id, int64_t timestamp_us)
+    : RTCDataChannelStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCDataChannelStats::RTCDataChannelStats(const RTCDataChannelStats& other) =
     default;
@@ -180,8 +186,8 @@
 // clang-format on
 
 RTCIceCandidatePairStats::RTCIceCandidatePairStats(std::string id,
-                                                   int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+                                                   Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       transport_id("transportId"),
       local_candidate_id("localCandidateId"),
       remote_candidate_id("remoteCandidateId"),
@@ -206,6 +212,10 @@
       bytes_discarded_on_send("bytesDiscardedOnSend"),
       last_packet_received_timestamp("lastPacketReceivedTimestamp"),
       last_packet_sent_timestamp("lastPacketSentTimestamp") {}
+RTCIceCandidatePairStats::RTCIceCandidatePairStats(std::string id,
+                                                   int64_t timestamp_us)
+    : RTCIceCandidatePairStats(std::move(id), Timestamp::Micros(timestamp_us)) {
+}
 
 RTCIceCandidatePairStats::RTCIceCandidatePairStats(
     const RTCIceCandidatePairStats& other) = default;
@@ -235,9 +245,9 @@
 // clang-format on
 
 RTCIceCandidateStats::RTCIceCandidateStats(std::string id,
-                                           int64_t timestamp_us,
+                                           Timestamp timestamp,
                                            bool is_remote)
-    : RTCStats(std::move(id), timestamp_us),
+    : RTCStats(std::move(id), timestamp),
       transport_id("transportId"),
       is_remote("isRemote", is_remote),
       network_type("networkType"),
@@ -256,6 +266,12 @@
       tcp_type("tcpType"),
       vpn("vpn"),
       network_adapter_type("networkAdapterType") {}
+RTCIceCandidateStats::RTCIceCandidateStats(std::string id,
+                                           int64_t timestamp_us,
+                                           bool is_remote)
+    : RTCIceCandidateStats(std::move(id),
+                           Timestamp::Micros(timestamp_us),
+                           is_remote) {}
 
 RTCIceCandidateStats::RTCIceCandidateStats(const RTCIceCandidateStats& other) =
     default;
@@ -265,8 +281,12 @@
 const char RTCLocalIceCandidateStats::kType[] = "local-candidate";
 
 RTCLocalIceCandidateStats::RTCLocalIceCandidateStats(std::string id,
+                                                     Timestamp timestamp)
+    : RTCIceCandidateStats(std::move(id), timestamp, false) {}
+RTCLocalIceCandidateStats::RTCLocalIceCandidateStats(std::string id,
                                                      int64_t timestamp_us)
-    : RTCIceCandidateStats(std::move(id), timestamp_us, false) {}
+    : RTCLocalIceCandidateStats(std::move(id),
+                                Timestamp::Micros(timestamp_us)) {}
 
 std::unique_ptr<RTCStats> RTCLocalIceCandidateStats::copy() const {
   return std::make_unique<RTCLocalIceCandidateStats>(*this);
@@ -279,8 +299,12 @@
 const char RTCRemoteIceCandidateStats::kType[] = "remote-candidate";
 
 RTCRemoteIceCandidateStats::RTCRemoteIceCandidateStats(std::string id,
+                                                       Timestamp timestamp)
+    : RTCIceCandidateStats(std::move(id), timestamp, true) {}
+RTCRemoteIceCandidateStats::RTCRemoteIceCandidateStats(std::string id,
                                                        int64_t timestamp_us)
-    : RTCIceCandidateStats(std::move(id), timestamp_us, true) {}
+    : RTCRemoteIceCandidateStats(std::move(id),
+                                 Timestamp::Micros(timestamp_us)) {}
 
 std::unique_ptr<RTCStats> RTCRemoteIceCandidateStats::copy() const {
   return std::make_unique<RTCRemoteIceCandidateStats>(*this);
@@ -298,10 +322,15 @@
 
 DEPRECATED_RTCMediaStreamStats::DEPRECATED_RTCMediaStreamStats(
     std::string id,
-    int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+    Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       stream_identifier("streamIdentifier"),
       track_ids("trackIds") {}
+DEPRECATED_RTCMediaStreamStats::DEPRECATED_RTCMediaStreamStats(
+    std::string id,
+    int64_t timestamp_us)
+    : DEPRECATED_RTCMediaStreamStats(std::move(id),
+                                     Timestamp::Micros(timestamp_us)) {}
 
 DEPRECATED_RTCMediaStreamStats::DEPRECATED_RTCMediaStreamStats(
     const DEPRECATED_RTCMediaStreamStats& other) = default;
@@ -340,9 +369,9 @@
 
 DEPRECATED_RTCMediaStreamTrackStats::DEPRECATED_RTCMediaStreamTrackStats(
     std::string id,
-    int64_t timestamp_us,
+    Timestamp timestamp,
     const char* kind)
-    : RTCStats(std::move(id), timestamp_us),
+    : RTCStats(std::move(id), timestamp),
       track_identifier("trackIdentifier"),
       media_source_id("mediaSourceId"),
       remote_source("remoteSource"),
@@ -372,6 +401,13 @@
   RTC_DCHECK(kind == RTCMediaStreamTrackKind::kAudio ||
              kind == RTCMediaStreamTrackKind::kVideo);
 }
+DEPRECATED_RTCMediaStreamTrackStats::DEPRECATED_RTCMediaStreamTrackStats(
+    std::string id,
+    int64_t timestamp_us,
+    const char* kind)
+    : DEPRECATED_RTCMediaStreamTrackStats(std::move(id),
+                                          Timestamp::Micros(timestamp_us),
+                                          kind) {}
 
 DEPRECATED_RTCMediaStreamTrackStats::DEPRECATED_RTCMediaStreamTrackStats(
     const DEPRECATED_RTCMediaStreamTrackStats& other) = default;
@@ -385,10 +421,13 @@
 // clang-format on
 
 RTCPeerConnectionStats::RTCPeerConnectionStats(std::string id,
-                                               int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+                                               Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       data_channels_opened("dataChannelsOpened"),
       data_channels_closed("dataChannelsClosed") {}
+RTCPeerConnectionStats::RTCPeerConnectionStats(std::string id,
+                                               int64_t timestamp_us)
+    : RTCPeerConnectionStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCPeerConnectionStats::RTCPeerConnectionStats(
     const RTCPeerConnectionStats& other) = default;
@@ -405,14 +444,16 @@
     &media_type)
 // clang-format on
 
-RTCRTPStreamStats::RTCRTPStreamStats(std::string id, int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+RTCRTPStreamStats::RTCRTPStreamStats(std::string id, Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       ssrc("ssrc"),
       kind("kind"),
       track_id("trackId"),
       transport_id("transportId"),
       codec_id("codecId"),
       media_type("mediaType") {}
+RTCRTPStreamStats::RTCRTPStreamStats(std::string id, int64_t timestamp_us)
+    : RTCRTPStreamStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCRTPStreamStats::RTCRTPStreamStats(const RTCRTPStreamStats& other) = default;
 
@@ -426,10 +467,14 @@
 // clang-format on
 
 RTCReceivedRtpStreamStats::RTCReceivedRtpStreamStats(std::string id,
-                                                     int64_t timestamp_us)
-    : RTCRTPStreamStats(std::move(id), timestamp_us),
+                                                     Timestamp timestamp)
+    : RTCRTPStreamStats(std::move(id), timestamp),
       jitter("jitter"),
       packets_lost("packetsLost") {}
+RTCReceivedRtpStreamStats::RTCReceivedRtpStreamStats(std::string id,
+                                                     int64_t timestamp_us)
+    : RTCReceivedRtpStreamStats(std::move(id),
+                                Timestamp::Micros(timestamp_us)) {}
 
 RTCReceivedRtpStreamStats::RTCReceivedRtpStreamStats(
     const RTCReceivedRtpStreamStats& other) = default;
@@ -444,10 +489,13 @@
 // clang-format on
 
 RTCSentRtpStreamStats::RTCSentRtpStreamStats(std::string id,
-                                             int64_t timestamp_us)
-    : RTCRTPStreamStats(std::move(id), timestamp_us),
+                                             Timestamp timestamp)
+    : RTCRTPStreamStats(std::move(id), timestamp),
       packets_sent("packetsSent"),
       bytes_sent("bytesSent") {}
+RTCSentRtpStreamStats::RTCSentRtpStreamStats(std::string(id),
+                                             int64_t timestamp_us)
+    : RTCSentRtpStreamStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCSentRtpStreamStats::RTCSentRtpStreamStats(
     const RTCSentRtpStreamStats& other) = default;
@@ -515,8 +563,8 @@
 // clang-format on
 
 RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string id,
-                                                   int64_t timestamp_us)
-    : RTCReceivedRtpStreamStats(std::move(id), timestamp_us),
+                                                   Timestamp timestamp)
+    : RTCReceivedRtpStreamStats(std::move(id), timestamp),
       track_identifier("trackIdentifier"),
       mid("mid"),
       remote_id("remoteId"),
@@ -580,6 +628,10 @@
       interruption_count("interruptionCount"),
       total_interruption_duration("totalInterruptionDuration"),
       min_playout_delay("minPlayoutDelay") {}
+RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string id,
+                                                   int64_t timestamp_us)
+    : RTCInboundRTPStreamStats(std::move(id), Timestamp::Micros(timestamp_us)) {
+}
 
 RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(
     const RTCInboundRTPStreamStats& other) = default;
@@ -623,8 +675,8 @@
 // clang-format on
 
 RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(std::string id,
-                                                     int64_t timestamp_us)
-    : RTCRTPStreamStats(std::move(id), timestamp_us),
+                                                     Timestamp timestamp)
+    : RTCRTPStreamStats(std::move(id), timestamp),
       media_source_id("mediaSourceId"),
       remote_id("remoteId"),
       mid("mid"),
@@ -658,6 +710,10 @@
       active("active"),
       power_efficient_encoder("powerEfficientEncoder"),
       scalability_mode("scalabilityMode") {}
+RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(std::string id,
+                                                     int64_t timestamp_us)
+    : RTCOutboundRTPStreamStats(std::move(id),
+                                Timestamp::Micros(timestamp_us)) {}
 
 RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(
     const RTCOutboundRTPStreamStats& other) = default;
@@ -677,13 +733,18 @@
 
 RTCRemoteInboundRtpStreamStats::RTCRemoteInboundRtpStreamStats(
     std::string id,
-    int64_t timestamp_us)
-    : RTCReceivedRtpStreamStats(std::move(id), timestamp_us),
+    Timestamp timestamp)
+    : RTCReceivedRtpStreamStats(std::move(id), timestamp),
       local_id("localId"),
       round_trip_time("roundTripTime"),
       fraction_lost("fractionLost"),
       total_round_trip_time("totalRoundTripTime"),
       round_trip_time_measurements("roundTripTimeMeasurements") {}
+RTCRemoteInboundRtpStreamStats::RTCRemoteInboundRtpStreamStats(
+    std::string id,
+    int64_t timestamp_us)
+    : RTCRemoteInboundRtpStreamStats(std::move(id),
+                                     Timestamp::Micros(timestamp_us)) {}
 
 RTCRemoteInboundRtpStreamStats::RTCRemoteInboundRtpStreamStats(
     const RTCRemoteInboundRtpStreamStats& other) = default;
@@ -704,14 +765,19 @@
 
 RTCRemoteOutboundRtpStreamStats::RTCRemoteOutboundRtpStreamStats(
     std::string id,
-    int64_t timestamp_us)
-    : RTCSentRtpStreamStats(std::move(id), timestamp_us),
+    Timestamp timestamp)
+    : RTCSentRtpStreamStats(std::move(id), timestamp),
       local_id("localId"),
       remote_timestamp("remoteTimestamp"),
       reports_sent("reportsSent"),
       round_trip_time("roundTripTime"),
       round_trip_time_measurements("roundTripTimeMeasurements"),
       total_round_trip_time("totalRoundTripTime") {}
+RTCRemoteOutboundRtpStreamStats::RTCRemoteOutboundRtpStreamStats(
+    std::string id,
+    int64_t timestamp)
+    : RTCRemoteOutboundRtpStreamStats(std::move(id),
+                                      Timestamp::Micros(timestamp)) {}
 
 RTCRemoteOutboundRtpStreamStats::RTCRemoteOutboundRtpStreamStats(
     const RTCRemoteOutboundRtpStreamStats& other) = default;
@@ -724,10 +790,12 @@
     &kind)
 // clang-format on
 
-RTCMediaSourceStats::RTCMediaSourceStats(std::string id, int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+RTCMediaSourceStats::RTCMediaSourceStats(std::string id, Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       track_identifier("trackIdentifier"),
       kind("kind") {}
+RTCMediaSourceStats::RTCMediaSourceStats(std::string id, int64_t timestamp_us)
+    : RTCMediaSourceStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCMediaSourceStats::RTCMediaSourceStats(const RTCMediaSourceStats& other) =
     default;
@@ -743,13 +811,15 @@
     &echo_return_loss_enhancement)
 // clang-format on
 
-RTCAudioSourceStats::RTCAudioSourceStats(std::string id, int64_t timestamp_us)
-    : RTCMediaSourceStats(std::move(id), timestamp_us),
+RTCAudioSourceStats::RTCAudioSourceStats(std::string id, Timestamp timestamp)
+    : RTCMediaSourceStats(std::move(id), timestamp),
       audio_level("audioLevel"),
       total_audio_energy("totalAudioEnergy"),
       total_samples_duration("totalSamplesDuration"),
       echo_return_loss("echoReturnLoss"),
       echo_return_loss_enhancement("echoReturnLossEnhancement") {}
+RTCAudioSourceStats::RTCAudioSourceStats(std::string id, int64_t timestamp_us)
+    : RTCAudioSourceStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCAudioSourceStats::RTCAudioSourceStats(const RTCAudioSourceStats& other) =
     default;
@@ -764,12 +834,14 @@
     &frames_per_second)
 // clang-format on
 
-RTCVideoSourceStats::RTCVideoSourceStats(std::string id, int64_t timestamp_us)
-    : RTCMediaSourceStats(std::move(id), timestamp_us),
+RTCVideoSourceStats::RTCVideoSourceStats(std::string id, Timestamp timestamp)
+    : RTCMediaSourceStats(std::move(id), timestamp),
       width("width"),
       height("height"),
       frames("frames"),
       frames_per_second("framesPerSecond") {}
+RTCVideoSourceStats::RTCVideoSourceStats(std::string id, int64_t timestamp_us)
+    : RTCVideoSourceStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCVideoSourceStats::RTCVideoSourceStats(const RTCVideoSourceStats& other) =
     default;
@@ -797,8 +869,8 @@
     &ice_state)
 // clang-format on
 
-RTCTransportStats::RTCTransportStats(std::string id, int64_t timestamp_us)
-    : RTCStats(std::move(id), timestamp_us),
+RTCTransportStats::RTCTransportStats(std::string id, Timestamp timestamp)
+    : RTCStats(std::move(id), timestamp),
       bytes_sent("bytesSent"),
       packets_sent("packetsSent"),
       bytes_received("bytesReceived"),
@@ -816,6 +888,8 @@
       ice_role("iceRole"),
       ice_local_username_fragment("iceLocalUsernameFragment"),
       ice_state("iceState") {}
+RTCTransportStats::RTCTransportStats(std::string id, int64_t timestamp_us)
+    : RTCTransportStats(std::move(id), Timestamp::Micros(timestamp_us)) {}
 
 RTCTransportStats::RTCTransportStats(const RTCTransportStats& other) = default;
 
diff --git a/stats/test/rtc_test_stats.cc b/stats/test/rtc_test_stats.cc
index e73da76..30d5ce0 100644
--- a/stats/test/rtc_test_stats.cc
+++ b/stats/test/rtc_test_stats.cc
@@ -34,8 +34,8 @@
                      &m_map_string_uint64,
                      &m_map_string_double)
 
-RTCTestStats::RTCTestStats(const std::string& id, int64_t timestamp_us)
-    : RTCStats(id, timestamp_us),
+RTCTestStats::RTCTestStats(const std::string& id, Timestamp timestamp)
+    : RTCStats(id, timestamp),
       m_bool("mBool"),
       m_int32("mInt32"),
       m_uint32("mUint32"),
@@ -53,8 +53,11 @@
       m_map_string_uint64("mMapStringUint64"),
       m_map_string_double("mMapStringDouble") {}
 
+RTCTestStats::RTCTestStats(const std::string& id, int64_t timestamp_us)
+    : RTCTestStats(id, Timestamp::Micros(timestamp_us)) {}
+
 RTCTestStats::RTCTestStats(const RTCTestStats& other)
-    : RTCStats(other.id(), other.timestamp_us()),
+    : RTCStats(other.id(), other.timestamp()),
       m_bool(other.m_bool),
       m_int32(other.m_int32),
       m_uint32(other.m_uint32),
diff --git a/stats/test/rtc_test_stats.h b/stats/test/rtc_test_stats.h
index 0feb07e..dea432e 100644
--- a/stats/test/rtc_test_stats.h
+++ b/stats/test/rtc_test_stats.h
@@ -25,6 +25,7 @@
  public:
   WEBRTC_RTCSTATS_DECL();
 
+  RTCTestStats(const std::string& id, Timestamp timestamp);
   RTCTestStats(const std::string& id, int64_t timestamp_us);
   RTCTestStats(const RTCTestStats& other);
   ~RTCTestStats() override;
diff --git a/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc b/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
index fa7f5b1..8049af3 100644
--- a/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
+++ b/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
@@ -77,8 +77,8 @@
     if (!(*s->kind == RTCMediaStreamTrackKind::kVideo)) {
       continue;
     }
-    if (s->timestamp_us() > sample.sample_time.us()) {
-      sample.sample_time = Timestamp::Micros(s->timestamp_us());
+    if (s->timestamp() > sample.sample_time) {
+      sample.sample_time = s->timestamp();
     }
     sample.retransmitted_bytes_sent +=
         DataSize::Bytes(s->retransmitted_bytes_sent.ValueOrDefault(0ul));