Reland "Deprecate microsecond timestamps in RTC event log."

This is a reland of e6ee8fab7eac915b2b6abc9b71b6d33ad086f3d1

Original change's description:
> Deprecate microsecond timestamps in RTC event log.
>
> (Microsecond timestamps are only used in the legacy wire-format,
> and the clocks only have microsecond resolution on some platforms.)
>
> Also convert structs on the parsing side to use a Timestamp instead
> of a uint64_t to represent the log time.
>
> Bug: webrtc:11933
> Change-Id: Ide5a0217d99f13f2e243115b163f13e0525648c7
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219467
> Commit-Queue: Björn Terelius <terelius@webrtc.org>
> Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
> Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#34097}

Bug: webrtc:11933
Change-Id: I295be966ee96b50719ceb4690dad7e7ce958dbac
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/221361
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34321}
diff --git a/api/rtc_event_log/rtc_event.cc b/api/rtc_event_log/rtc_event.cc
index 81e6a4e..631188b 100644
--- a/api/rtc_event_log/rtc_event.cc
+++ b/api/rtc_event_log/rtc_event.cc
@@ -14,6 +14,6 @@
 
 namespace webrtc {
 
-RtcEvent::RtcEvent() : timestamp_us_(rtc::TimeMicros()) {}
+RtcEvent::RtcEvent() : timestamp_us_(rtc::TimeMillis() * 1000) {}
 
 }  // namespace webrtc
diff --git a/logging/BUILD.gn b/logging/BUILD.gn
index 519f357..90a05f7 100644
--- a/logging/BUILD.gn
+++ b/logging/BUILD.gn
@@ -53,6 +53,7 @@
   deps = [
     "../api:scoped_refptr",
     "../api/rtc_event_log",
+    "../api/units:timestamp",
   ]
   absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
 }
@@ -73,6 +74,7 @@
     ":rtc_stream_config",
     "../api:scoped_refptr",
     "../api/rtc_event_log",
+    "../api/units:timestamp",
     "../modules/audio_coding:audio_network_adaptor_config",
     "../rtc_base:checks",
   ]
@@ -101,6 +103,7 @@
     "../api:scoped_refptr",
     "../api/rtc_event_log",
     "../api/units:data_rate",
+    "../api/units:timestamp",
   ]
   absl_deps = [
     "//third_party/abseil-cpp/absl/memory",
@@ -115,6 +118,7 @@
   ]
   deps = [
     "../api/rtc_event_log",
+    "../api/units:timestamp",
     "../api/video:video_frame",
     "../rtc_base:timeutils",
   ]
@@ -136,6 +140,7 @@
   ]
   deps = [
     "../api/rtc_event_log",
+    "../api/units:timestamp",
     "../rtc_base:timeutils",
   ]
   absl_deps = [
@@ -179,6 +184,7 @@
     ":rtc_stream_config",
     "../api:scoped_refptr",
     "../api/rtc_event_log",
+    "../api/units:timestamp",
     "../rtc_base:checks",
   ]
   absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
@@ -452,6 +458,7 @@
     "../api:libjingle_logging_api",
     "../api:libjingle_peerconnection_api",  # For api/dtls_transport_interface.h
     "../api/rtc_event_log",
+    "../api/units:timestamp",
     "../rtc_base:rtc_base_approved",
   ]
   absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc
index cd6e1b3..063d425 100644
--- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc
+++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc
@@ -721,33 +721,35 @@
 }
 
 TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) {
-  const int64_t timestamp_us = rtc::TimeMicros();
-  const int64_t utc_time_us = rtc::TimeUTCMicros();
+  const int64_t timestamp_ms = prng_.Rand(1'000'000'000);
+  const int64_t utc_time_ms = prng_.Rand(1'000'000'000);
 
   // Overwrite the previously encoded LogStart event.
-  encoded_ = encoder_->EncodeLogStart(timestamp_us, utc_time_us);
+  encoded_ = encoder_->EncodeLogStart(timestamp_ms * 1000, utc_time_ms * 1000);
   ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
   const auto& start_log_events = parsed_log_.start_log_events();
 
   ASSERT_EQ(start_log_events.size(), 1u);
-  verifier_.VerifyLoggedStartEvent(timestamp_us, utc_time_us,
+  verifier_.VerifyLoggedStartEvent(timestamp_ms * 1000, utc_time_ms * 1000,
                                    start_log_events[0]);
 }
 
 TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) {
-  const int64_t start_timestamp_us = rtc::TimeMicros();
-  const int64_t start_utc_time_us = rtc::TimeUTCMicros();
+  const int64_t start_timestamp_ms = prng_.Rand(1'000'000'000);
+  const int64_t start_utc_time_ms = prng_.Rand(1'000'000'000);
 
   // Overwrite the previously encoded LogStart event.
-  encoded_ = encoder_->EncodeLogStart(start_timestamp_us, start_utc_time_us);
+  encoded_ = encoder_->EncodeLogStart(start_timestamp_ms * 1000,
+                                      start_utc_time_ms * 1000);
 
-  const int64_t stop_timestamp_us = rtc::TimeMicros();
-  encoded_ += encoder_->EncodeLogEnd(stop_timestamp_us);
+  const int64_t stop_timestamp_ms =
+      prng_.Rand(start_timestamp_ms, 2'000'000'000);
+  encoded_ += encoder_->EncodeLogEnd(stop_timestamp_ms * 1000);
   ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok());
   const auto& stop_log_events = parsed_log_.stop_log_events();
 
   ASSERT_EQ(stop_log_events.size(), 1u);
-  verifier_.VerifyLoggedStopEvent(stop_timestamp_us, stop_log_events[0]);
+  verifier_.VerifyLoggedStopEvent(stop_timestamp_ms * 1000, stop_log_events[0]);
 }
 
 // TODO(eladalon/terelius): Test with multiple events in the batch.
@@ -854,9 +856,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::ReceiverReport> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewReceiverReport();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -876,7 +878,7 @@
     ASSERT_EQ(receiver_reports.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedReceiverReport(timestamps_us[i], events[i],
+      verifier_.VerifyLoggedReceiverReport(timestamps_ms[i], events[i],
                                            receiver_reports[i]);
     }
   }
@@ -892,9 +894,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::SenderReport> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewSenderReport();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -914,7 +916,7 @@
     ASSERT_EQ(sender_reports.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedSenderReport(timestamps_us[i], events[i],
+      verifier_.VerifyLoggedSenderReport(timestamps_ms[i], events[i],
                                          sender_reports[i]);
     }
   }
@@ -930,9 +932,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::ExtendedReports> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewExtendedReports();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -952,7 +954,7 @@
     ASSERT_EQ(extended_reports.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedExtendedReports(timestamps_us[i], events[i],
+      verifier_.VerifyLoggedExtendedReports(timestamps_ms[i], events[i],
                                             extended_reports[i]);
     }
   }
@@ -968,9 +970,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::Fir> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewFir();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -990,7 +992,7 @@
     ASSERT_EQ(firs.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedFir(timestamps_us[i], events[i], firs[i]);
+      verifier_.VerifyLoggedFir(timestamps_ms[i], events[i], firs[i]);
     }
   }
 }
@@ -1005,9 +1007,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::Pli> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewPli();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -1027,7 +1029,7 @@
     ASSERT_EQ(plis.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedPli(timestamps_us[i], events[i], plis[i]);
+      verifier_.VerifyLoggedPli(timestamps_ms[i], events[i], plis[i]);
     }
   }
 }
@@ -1042,9 +1044,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::Bye> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewBye();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -1064,7 +1066,7 @@
     ASSERT_EQ(byes.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedBye(timestamps_us[i], events[i], byes[i]);
+      verifier_.VerifyLoggedBye(timestamps_ms[i], events[i], byes[i]);
     }
   }
 }
@@ -1079,9 +1081,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::Nack> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewNack();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -1101,7 +1103,7 @@
     ASSERT_EQ(nacks.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedNack(timestamps_us[i], events[i], nacks[i]);
+      verifier_.VerifyLoggedNack(timestamps_ms[i], events[i], nacks[i]);
     }
   }
 }
@@ -1116,9 +1118,9 @@
 
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::Remb> events(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events[i] = gen_.NewRemb();
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -1138,7 +1140,7 @@
     ASSERT_EQ(rembs.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedRemb(timestamps_us[i], events[i], rembs[i]);
+      verifier_.VerifyLoggedRemb(timestamps_ms[i], events[i], rembs[i]);
     }
   }
 }
@@ -1154,9 +1156,9 @@
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::TransportFeedback> events;
     events.reserve(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events.emplace_back(gen_.NewTransportFeedback());
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -1177,7 +1179,7 @@
     ASSERT_EQ(transport_feedbacks.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedTransportFeedback(timestamps_us[i], events[i],
+      verifier_.VerifyLoggedTransportFeedback(timestamps_ms[i], events[i],
                                               transport_feedbacks[i]);
     }
   }
@@ -1194,9 +1196,9 @@
   for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
     std::vector<rtcp::LossNotification> events;
     events.reserve(event_count_);
-    std::vector<int64_t> timestamps_us(event_count_);
+    std::vector<int64_t> timestamps_ms(event_count_);
     for (size_t i = 0; i < event_count_; ++i) {
-      timestamps_us[i] = rtc::TimeMicros();
+      timestamps_ms[i] = rtc::TimeMillis();
       events.emplace_back(gen_.NewLossNotification());
       rtc::Buffer buffer = events[i].Build();
       if (direction == kIncomingPacket) {
@@ -1216,7 +1218,7 @@
     ASSERT_EQ(loss_notifications.size(), event_count_);
 
     for (size_t i = 0; i < event_count_; ++i) {
-      verifier_.VerifyLoggedLossNotification(timestamps_us[i], events[i],
+      verifier_.VerifyLoggedLossNotification(timestamps_ms[i], events[i],
                                              loss_notifications[i]);
     }
   }
diff --git a/logging/rtc_event_log/events/rtc_event_alr_state.h b/logging/rtc_event_log/events/rtc_event_alr_state.h
index 3ad0f00..74d6601 100644
--- a/logging/rtc_event_log/events/rtc_event_alr_state.h
+++ b/logging/rtc_event_log/events/rtc_event_alr_state.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -39,13 +40,13 @@
 
 struct LoggedAlrStateEvent {
   LoggedAlrStateEvent() = default;
-  LoggedAlrStateEvent(int64_t timestamp_us, bool in_alr)
-      : timestamp_us(timestamp_us), in_alr(in_alr) {}
+  LoggedAlrStateEvent(Timestamp timestamp, bool in_alr)
+      : timestamp(timestamp), in_alr(in_alr) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   bool in_alr;
 };
 
diff --git a/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h b/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h
index 2b183bb..aeeb28e 100644
--- a/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h
+++ b/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
 
 namespace webrtc {
@@ -43,14 +44,14 @@
 
 struct LoggedAudioNetworkAdaptationEvent {
   LoggedAudioNetworkAdaptationEvent() = default;
-  LoggedAudioNetworkAdaptationEvent(int64_t timestamp_us,
+  LoggedAudioNetworkAdaptationEvent(Timestamp timestamp,
                                     const AudioEncoderRuntimeConfig& config)
-      : timestamp_us(timestamp_us), config(config) {}
+      : timestamp(timestamp), config(config) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   AudioEncoderRuntimeConfig config;
 };
 
diff --git a/logging/rtc_event_log/events/rtc_event_audio_playout.h b/logging/rtc_event_log/events/rtc_event_audio_playout.h
index 8382521..00d07a6 100644
--- a/logging/rtc_event_log/events/rtc_event_audio_playout.h
+++ b/logging/rtc_event_log/events/rtc_event_audio_playout.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -41,13 +42,13 @@
 
 struct LoggedAudioPlayoutEvent {
   LoggedAudioPlayoutEvent() = default;
-  LoggedAudioPlayoutEvent(int64_t timestamp_us, uint32_t ssrc)
-      : timestamp_us(timestamp_us), ssrc(ssrc) {}
+  LoggedAudioPlayoutEvent(Timestamp timestamp, uint32_t ssrc)
+      : timestamp(timestamp), ssrc(ssrc) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   uint32_t ssrc;
 };
 
diff --git a/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h b/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h
index 1edd8e1..ccf7602 100644
--- a/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h
+++ b/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 #include "logging/rtc_event_log/rtc_stream_config.h"
 
 namespace webrtc {
@@ -42,13 +43,13 @@
 
 struct LoggedAudioRecvConfig {
   LoggedAudioRecvConfig() = default;
-  LoggedAudioRecvConfig(int64_t timestamp_us, const rtclog::StreamConfig config)
-      : timestamp_us(timestamp_us), config(config) {}
+  LoggedAudioRecvConfig(Timestamp timestamp, const rtclog::StreamConfig config)
+      : timestamp(timestamp), config(config) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtclog::StreamConfig config;
 };
 
diff --git a/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h b/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h
index d3c6068..4e93871 100644
--- a/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h
+++ b/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h
@@ -41,13 +41,13 @@
 
 struct LoggedAudioSendConfig {
   LoggedAudioSendConfig() = default;
-  LoggedAudioSendConfig(int64_t timestamp_us, const rtclog::StreamConfig config)
-      : timestamp_us(timestamp_us), config(config) {}
+  LoggedAudioSendConfig(Timestamp timestamp, const rtclog::StreamConfig config)
+      : timestamp(timestamp), config(config) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtclog::StreamConfig config;
 };
 }  // namespace webrtc
diff --git a/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h b/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h
index a83ea8b..522f98f 100644
--- a/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h
+++ b/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h
@@ -17,6 +17,7 @@
 
 #include "api/network_state_predictor.h"
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -45,17 +46,17 @@
 
 struct LoggedBweDelayBasedUpdate {
   LoggedBweDelayBasedUpdate() = default;
-  LoggedBweDelayBasedUpdate(int64_t timestamp_us,
+  LoggedBweDelayBasedUpdate(Timestamp timestamp,
                             int32_t bitrate_bps,
                             BandwidthUsage detector_state)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         bitrate_bps(bitrate_bps),
         detector_state(detector_state) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int32_t bitrate_bps;
   BandwidthUsage detector_state;
 };
diff --git a/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h b/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h
index b638f1a..b031658 100644
--- a/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h
+++ b/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -47,19 +48,19 @@
 
 struct LoggedBweLossBasedUpdate {
   LoggedBweLossBasedUpdate() = default;
-  LoggedBweLossBasedUpdate(int64_t timestamp_us,
+  LoggedBweLossBasedUpdate(Timestamp timestamp,
                            int32_t bitrate_bps,
                            uint8_t fraction_lost,
                            int32_t expected_packets)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         bitrate_bps(bitrate_bps),
         fraction_lost(fraction_lost),
         expected_packets(expected_packets) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int32_t bitrate_bps;
   uint8_t fraction_lost;
   int32_t expected_packets;
diff --git a/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h b/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
index af35a3f..9a3eecb 100644
--- a/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
+++ b/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
@@ -15,6 +15,7 @@
 
 #include "api/dtls_transport_interface.h"
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -41,10 +42,10 @@
 };
 
 struct LoggedDtlsTransportState {
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   DtlsTransportState dtls_transport_state;
 };
 
diff --git a/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h b/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h
index c3ecce0..c0cc5b8 100644
--- a/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h
+++ b/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -41,10 +42,10 @@
   LoggedDtlsWritableState() = default;
   explicit LoggedDtlsWritableState(bool writable) : writable(writable) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   bool writable;
 };
 
diff --git a/logging/rtc_event_log/events/rtc_event_frame_decoded.h b/logging/rtc_event_log/events/rtc_event_frame_decoded.h
index c549aa883..4a6bb90 100644
--- a/logging/rtc_event_log/events/rtc_event_frame_decoded.h
+++ b/logging/rtc_event_log/events/rtc_event_frame_decoded.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 #include "api/video/video_codec_type.h"
 
 namespace webrtc {
@@ -56,10 +57,10 @@
 };
 
 struct LoggedFrameDecoded {
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int64_t render_time_ms;
   uint32_t ssrc;
   int width;
diff --git a/logging/rtc_event_log/events/rtc_event_generic_ack_received.h b/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
index 76e3cc2..75fc83c 100644
--- a/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
+++ b/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
@@ -16,6 +16,7 @@
 
 #include "absl/types/optional.h"
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -77,19 +78,19 @@
 
 struct LoggedGenericAckReceived {
   LoggedGenericAckReceived() = default;
-  LoggedGenericAckReceived(int64_t timestamp_us,
+  LoggedGenericAckReceived(Timestamp timestamp,
                            int64_t packet_number,
                            int64_t acked_packet_number,
                            absl::optional<int64_t> receive_acked_packet_time_ms)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         packet_number(packet_number),
         acked_packet_number(acked_packet_number),
         receive_acked_packet_time_ms(receive_acked_packet_time_ms) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int64_t packet_number;
   int64_t acked_packet_number;
   absl::optional<int64_t> receive_acked_packet_time_ms;
diff --git a/logging/rtc_event_log/events/rtc_event_generic_packet_received.h b/logging/rtc_event_log/events/rtc_event_generic_packet_received.h
index 45e5e4c..428e7b3 100644
--- a/logging/rtc_event_log/events/rtc_event_generic_packet_received.h
+++ b/logging/rtc_event_log/events/rtc_event_generic_packet_received.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -45,17 +46,17 @@
 
 struct LoggedGenericPacketReceived {
   LoggedGenericPacketReceived() = default;
-  LoggedGenericPacketReceived(int64_t timestamp_us,
+  LoggedGenericPacketReceived(Timestamp timestamp,
                               int64_t packet_number,
                               int packet_length)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         packet_number(packet_number),
         packet_length(packet_length) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int64_t packet_number;
   int packet_length;
 };
diff --git a/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h b/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h
index 9ebafbe..6e626e6 100644
--- a/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h
+++ b/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -62,24 +63,24 @@
 
 struct LoggedGenericPacketSent {
   LoggedGenericPacketSent() = default;
-  LoggedGenericPacketSent(int64_t timestamp_us,
+  LoggedGenericPacketSent(Timestamp timestamp,
                           int64_t packet_number,
                           size_t overhead_length,
                           size_t payload_length,
                           size_t padding_length)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         packet_number(packet_number),
         overhead_length(overhead_length),
         payload_length(payload_length),
         padding_length(padding_length) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
   size_t packet_length() const {
     return payload_length + padding_length + overhead_length;
   }
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int64_t packet_number;
   size_t overhead_length;
   size_t payload_length;
diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h
index 717ddf3..1f4d825 100644
--- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h
+++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -56,19 +57,19 @@
 
 struct LoggedIceCandidatePairEvent {
   LoggedIceCandidatePairEvent() = default;
-  LoggedIceCandidatePairEvent(int64_t timestamp_us,
+  LoggedIceCandidatePairEvent(Timestamp timestamp,
                               IceCandidatePairEventType type,
                               uint32_t candidate_pair_id,
                               uint32_t transaction_id)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         type(type),
         candidate_pair_id(candidate_pair_id),
         transaction_id(transaction_id) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   IceCandidatePairEventType type;
   uint32_t candidate_pair_id;
   uint32_t transaction_id;
diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h
index ab2eaf2..465a799 100644
--- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h
+++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -113,10 +114,10 @@
 };
 
 struct LoggedIceCandidatePairConfig {
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   IceCandidatePairConfigType type;
   uint32_t candidate_pair_id;
   IceCandidateType local_candidate_type;
diff --git a/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h b/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h
index f3221b9..974a0c9 100644
--- a/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h
+++ b/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -50,21 +51,21 @@
 
 struct LoggedBweProbeClusterCreatedEvent {
   LoggedBweProbeClusterCreatedEvent() = default;
-  LoggedBweProbeClusterCreatedEvent(int64_t timestamp_us,
+  LoggedBweProbeClusterCreatedEvent(Timestamp timestamp,
                                     int32_t id,
                                     int32_t bitrate_bps,
                                     uint32_t min_packets,
                                     uint32_t min_bytes)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         id(id),
         bitrate_bps(bitrate_bps),
         min_packets(min_packets),
         min_bytes(min_bytes) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int32_t id;
   int32_t bitrate_bps;
   uint32_t min_packets;
diff --git a/logging/rtc_event_log/events/rtc_event_probe_result_failure.h b/logging/rtc_event_log/events/rtc_event_probe_result_failure.h
index 868c30b..fa61b31 100644
--- a/logging/rtc_event_log/events/rtc_event_probe_result_failure.h
+++ b/logging/rtc_event_log/events/rtc_event_probe_result_failure.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -50,15 +51,15 @@
 
 struct LoggedBweProbeFailureEvent {
   LoggedBweProbeFailureEvent() = default;
-  LoggedBweProbeFailureEvent(int64_t timestamp_us,
+  LoggedBweProbeFailureEvent(Timestamp timestamp,
                              int32_t id,
                              ProbeFailureReason failure_reason)
-      : timestamp_us(timestamp_us), id(id), failure_reason(failure_reason) {}
+      : timestamp(timestamp), id(id), failure_reason(failure_reason) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int32_t id;
   ProbeFailureReason failure_reason;
 };
diff --git a/logging/rtc_event_log/events/rtc_event_probe_result_success.h b/logging/rtc_event_log/events/rtc_event_probe_result_success.h
index e374668..d00cfa8 100644
--- a/logging/rtc_event_log/events/rtc_event_probe_result_success.h
+++ b/logging/rtc_event_log/events/rtc_event_probe_result_success.h
@@ -16,6 +16,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -43,15 +44,15 @@
 
 struct LoggedBweProbeSuccessEvent {
   LoggedBweProbeSuccessEvent() = default;
-  LoggedBweProbeSuccessEvent(int64_t timestamp_us,
+  LoggedBweProbeSuccessEvent(Timestamp timestamp,
                              int32_t id,
                              int32_t bitrate_bps)
-      : timestamp_us(timestamp_us), id(id), bitrate_bps(bitrate_bps) {}
+      : timestamp(timestamp), id(id), bitrate_bps(bitrate_bps) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   int32_t id;
   int32_t bitrate_bps;
 };
diff --git a/logging/rtc_event_log/events/rtc_event_remote_estimate.h b/logging/rtc_event_log/events/rtc_event_remote_estimate.h
index 29b0c47..956e05f 100644
--- a/logging/rtc_event_log/events/rtc_event_remote_estimate.h
+++ b/logging/rtc_event_log/events/rtc_event_remote_estimate.h
@@ -15,6 +15,7 @@
 #include "absl/types/optional.h"
 #include "api/rtc_event_log/rtc_event.h"
 #include "api/units/data_rate.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -37,10 +38,10 @@
 struct LoggedRemoteEstimateEvent {
   LoggedRemoteEstimateEvent() = default;
 
-  int64_t log_time_us() const { return timestamp_ms * 1000; }
-  int64_t log_time_ms() const { return timestamp_ms; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_ms;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   absl::optional<DataRate> link_capacity_lower;
   absl::optional<DataRate> link_capacity_upper;
 };
diff --git a/logging/rtc_event_log/events/rtc_event_route_change.h b/logging/rtc_event_log/events/rtc_event_route_change.h
index 455a832..4a4e9ae 100644
--- a/logging/rtc_event_log/events/rtc_event_route_change.h
+++ b/logging/rtc_event_log/events/rtc_event_route_change.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 
 namespace webrtc {
 
@@ -41,15 +42,13 @@
 
 struct LoggedRouteChangeEvent {
   LoggedRouteChangeEvent() = default;
-  LoggedRouteChangeEvent(int64_t timestamp_ms,
-                         bool connected,
-                         uint32_t overhead)
-      : timestamp_ms(timestamp_ms), connected(connected), overhead(overhead) {}
+  LoggedRouteChangeEvent(Timestamp timestamp, bool connected, uint32_t overhead)
+      : timestamp(timestamp), connected(connected), overhead(overhead) {}
 
-  int64_t log_time_us() const { return timestamp_ms * 1000; }
-  int64_t log_time_ms() const { return timestamp_ms; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_ms;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   bool connected;
   uint32_t overhead;
 };
diff --git a/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h b/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h
index 2bf5247..e7b9061 100644
--- a/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h
+++ b/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 #include "logging/rtc_event_log/rtc_stream_config.h"
 
 namespace webrtc {
@@ -42,13 +43,13 @@
 
 struct LoggedVideoRecvConfig {
   LoggedVideoRecvConfig() = default;
-  LoggedVideoRecvConfig(int64_t timestamp_us, const rtclog::StreamConfig config)
-      : timestamp_us(timestamp_us), config(config) {}
+  LoggedVideoRecvConfig(Timestamp timestamp, const rtclog::StreamConfig config)
+      : timestamp(timestamp), config(config) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtclog::StreamConfig config;
 };
 
diff --git a/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h b/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h
index cf95afc..e72e75e 100644
--- a/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h
+++ b/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h
@@ -14,6 +14,7 @@
 #include <memory>
 
 #include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
 #include "logging/rtc_event_log/rtc_stream_config.h"
 
 namespace webrtc {
@@ -41,13 +42,13 @@
 
 struct LoggedVideoSendConfig {
   LoggedVideoSendConfig() = default;
-  LoggedVideoSendConfig(int64_t timestamp_us, const rtclog::StreamConfig config)
-      : timestamp_us(timestamp_us), config(config) {}
+  LoggedVideoSendConfig(Timestamp timestamp, const rtclog::StreamConfig config)
+      : timestamp(timestamp), config(config) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtclog::StreamConfig config;
 };
 }  // namespace webrtc
diff --git a/logging/rtc_event_log/logged_events.cc b/logging/rtc_event_log/logged_events.cc
index dd0a8aa..5ef3de1 100644
--- a/logging/rtc_event_log/logged_events.cc
+++ b/logging/rtc_event_log/logged_events.cc
@@ -40,13 +40,13 @@
 
 LoggedPacketInfo::~LoggedPacketInfo() {}
 
-LoggedRtcpPacket::LoggedRtcpPacket(int64_t timestamp_us,
+LoggedRtcpPacket::LoggedRtcpPacket(Timestamp timestamp,
                                    const std::vector<uint8_t>& packet)
-    : timestamp_us(timestamp_us), raw_data(packet) {}
+    : timestamp(timestamp), raw_data(packet) {}
 
-LoggedRtcpPacket::LoggedRtcpPacket(int64_t timestamp_us,
+LoggedRtcpPacket::LoggedRtcpPacket(Timestamp timestamp,
                                    const std::string& packet)
-    : timestamp_us(timestamp_us), raw_data(packet.size()) {
+    : timestamp(timestamp), raw_data(packet.size()) {
   memcpy(raw_data.data(), packet.data(), packet.size());
 }
 
diff --git a/logging/rtc_event_log/logged_events.h b/logging/rtc_event_log/logged_events.h
index 3824494..5bce658 100644
--- a/logging/rtc_event_log/logged_events.h
+++ b/logging/rtc_event_log/logged_events.h
@@ -37,19 +37,19 @@
 // adding a vptr.
 
 struct LoggedRtpPacket {
-  LoggedRtpPacket(int64_t timestamp_us,
+  LoggedRtpPacket(Timestamp timestamp,
                   RTPHeader header,
                   size_t header_length,
                   size_t total_length)
-      : timestamp_us(timestamp_us),
+      : timestamp(timestamp),
         header(header),
         header_length(header_length),
         total_length(total_length) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp;
   // TODO(terelius): This allocates space for 15 CSRCs even if none are used.
   RTPHeader header;
   size_t header_length;
@@ -57,145 +57,145 @@
 };
 
 struct LoggedRtpPacketIncoming {
-  LoggedRtpPacketIncoming(int64_t timestamp_us,
+  LoggedRtpPacketIncoming(Timestamp timestamp,
                           RTPHeader header,
                           size_t header_length,
                           size_t total_length)
-      : rtp(timestamp_us, header, header_length, total_length) {}
-  int64_t log_time_us() const { return rtp.timestamp_us; }
-  int64_t log_time_ms() const { return rtp.timestamp_us / 1000; }
+      : rtp(timestamp, header, header_length, total_length) {}
+  int64_t log_time_us() const { return rtp.timestamp.us(); }
+  int64_t log_time_ms() const { return rtp.timestamp.ms(); }
 
   LoggedRtpPacket rtp;
 };
 
 struct LoggedRtpPacketOutgoing {
-  LoggedRtpPacketOutgoing(int64_t timestamp_us,
+  LoggedRtpPacketOutgoing(Timestamp timestamp,
                           RTPHeader header,
                           size_t header_length,
                           size_t total_length)
-      : rtp(timestamp_us, header, header_length, total_length) {}
-  int64_t log_time_us() const { return rtp.timestamp_us; }
-  int64_t log_time_ms() const { return rtp.timestamp_us / 1000; }
+      : rtp(timestamp, header, header_length, total_length) {}
+  int64_t log_time_us() const { return rtp.timestamp.us(); }
+  int64_t log_time_ms() const { return rtp.timestamp.ms(); }
 
   LoggedRtpPacket rtp;
 };
 
 struct LoggedRtcpPacket {
-  LoggedRtcpPacket(int64_t timestamp_us, const std::vector<uint8_t>& packet);
-  LoggedRtcpPacket(int64_t timestamp_us, const std::string& packet);
+  LoggedRtcpPacket(Timestamp timestamp, const std::vector<uint8_t>& packet);
+  LoggedRtcpPacket(Timestamp timestamp, const std::string& packet);
   LoggedRtcpPacket(const LoggedRtcpPacket&);
   ~LoggedRtcpPacket();
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp;
   std::vector<uint8_t> raw_data;
 };
 
 struct LoggedRtcpPacketIncoming {
-  LoggedRtcpPacketIncoming(int64_t timestamp_us,
+  LoggedRtcpPacketIncoming(Timestamp timestamp,
                            const std::vector<uint8_t>& packet)
-      : rtcp(timestamp_us, packet) {}
-  LoggedRtcpPacketIncoming(uint64_t timestamp_us, const std::string& packet)
-      : rtcp(timestamp_us, packet) {}
+      : rtcp(timestamp, packet) {}
+  LoggedRtcpPacketIncoming(Timestamp timestamp, const std::string& packet)
+      : rtcp(timestamp, packet) {}
 
-  int64_t log_time_us() const { return rtcp.timestamp_us; }
-  int64_t log_time_ms() const { return rtcp.timestamp_us / 1000; }
+  int64_t log_time_us() const { return rtcp.timestamp.us(); }
+  int64_t log_time_ms() const { return rtcp.timestamp.ms(); }
 
   LoggedRtcpPacket rtcp;
 };
 
 struct LoggedRtcpPacketOutgoing {
-  LoggedRtcpPacketOutgoing(int64_t timestamp_us,
+  LoggedRtcpPacketOutgoing(Timestamp timestamp,
                            const std::vector<uint8_t>& packet)
-      : rtcp(timestamp_us, packet) {}
-  LoggedRtcpPacketOutgoing(uint64_t timestamp_us, const std::string& packet)
-      : rtcp(timestamp_us, packet) {}
+      : rtcp(timestamp, packet) {}
+  LoggedRtcpPacketOutgoing(Timestamp timestamp, const std::string& packet)
+      : rtcp(timestamp, packet) {}
 
-  int64_t log_time_us() const { return rtcp.timestamp_us; }
-  int64_t log_time_ms() const { return rtcp.timestamp_us / 1000; }
+  int64_t log_time_us() const { return rtcp.timestamp.us(); }
+  int64_t log_time_ms() const { return rtcp.timestamp.ms(); }
 
   LoggedRtcpPacket rtcp;
 };
 
 struct LoggedRtcpPacketReceiverReport {
   LoggedRtcpPacketReceiverReport() = default;
-  LoggedRtcpPacketReceiverReport(int64_t timestamp_us,
+  LoggedRtcpPacketReceiverReport(Timestamp timestamp,
                                  const rtcp::ReceiverReport& rr)
-      : timestamp_us(timestamp_us), rr(rr) {}
+      : timestamp(timestamp), rr(rr) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::ReceiverReport rr;
 };
 
 struct LoggedRtcpPacketSenderReport {
   LoggedRtcpPacketSenderReport() = default;
-  LoggedRtcpPacketSenderReport(int64_t timestamp_us,
+  LoggedRtcpPacketSenderReport(Timestamp timestamp,
                                const rtcp::SenderReport& sr)
-      : timestamp_us(timestamp_us), sr(sr) {}
+      : timestamp(timestamp), sr(sr) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::SenderReport sr;
 };
 
 struct LoggedRtcpPacketExtendedReports {
   LoggedRtcpPacketExtendedReports() = default;
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::ExtendedReports xr;
 };
 
 struct LoggedRtcpPacketRemb {
   LoggedRtcpPacketRemb() = default;
-  LoggedRtcpPacketRemb(int64_t timestamp_us, const rtcp::Remb& remb)
-      : timestamp_us(timestamp_us), remb(remb) {}
+  LoggedRtcpPacketRemb(Timestamp timestamp, const rtcp::Remb& remb)
+      : timestamp(timestamp), remb(remb) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::Remb remb;
 };
 
 struct LoggedRtcpPacketNack {
   LoggedRtcpPacketNack() = default;
-  LoggedRtcpPacketNack(int64_t timestamp_us, const rtcp::Nack& nack)
-      : timestamp_us(timestamp_us), nack(nack) {}
+  LoggedRtcpPacketNack(Timestamp timestamp, const rtcp::Nack& nack)
+      : timestamp(timestamp), nack(nack) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::Nack nack;
 };
 
 struct LoggedRtcpPacketFir {
   LoggedRtcpPacketFir() = default;
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::Fir fir;
 };
 
 struct LoggedRtcpPacketPli {
   LoggedRtcpPacketPli() = default;
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::Pli pli;
 };
 
@@ -204,64 +204,64 @@
       : transport_feedback(/*include_timestamps=*/true, /*include_lost*/ true) {
   }
   LoggedRtcpPacketTransportFeedback(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const rtcp::TransportFeedback& transport_feedback)
-      : timestamp_us(timestamp_us), transport_feedback(transport_feedback) {}
+      : timestamp(timestamp), transport_feedback(transport_feedback) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::TransportFeedback transport_feedback;
 };
 
 struct LoggedRtcpPacketLossNotification {
   LoggedRtcpPacketLossNotification() = default;
   LoggedRtcpPacketLossNotification(
-      int64_t timestamp_us,
+      Timestamp timestamp,
       const rtcp::LossNotification& loss_notification)
-      : timestamp_us(timestamp_us), loss_notification(loss_notification) {}
+      : timestamp(timestamp), loss_notification(loss_notification) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::LossNotification loss_notification;
 };
 
 struct LoggedRtcpPacketBye {
   LoggedRtcpPacketBye() = default;
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp = Timestamp::MinusInfinity();
   rtcp::Bye bye;
 };
 
 struct LoggedStartEvent {
-  explicit LoggedStartEvent(int64_t timestamp_us)
-      : LoggedStartEvent(timestamp_us, timestamp_us / 1000) {}
+  explicit LoggedStartEvent(Timestamp timestamp)
+      : LoggedStartEvent(timestamp, timestamp) {}
 
-  LoggedStartEvent(int64_t timestamp_us, int64_t utc_start_time_ms)
-      : timestamp_us(timestamp_us), utc_start_time_ms(utc_start_time_ms) {}
+  LoggedStartEvent(Timestamp timestamp, Timestamp utc_start_time)
+      : timestamp(timestamp), utc_start_time(utc_start_time) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  Timestamp utc_time() const { return Timestamp::Millis(utc_start_time_ms); }
+  Timestamp utc_time() const { return utc_start_time; }
 
-  int64_t timestamp_us;
-  int64_t utc_start_time_ms;
+  Timestamp timestamp;
+  Timestamp utc_start_time;
 };
 
 struct LoggedStopEvent {
-  explicit LoggedStopEvent(int64_t timestamp_us) : timestamp_us(timestamp_us) {}
+  explicit LoggedStopEvent(Timestamp timestamp) : timestamp(timestamp) {}
 
-  int64_t log_time_us() const { return timestamp_us; }
-  int64_t log_time_ms() const { return timestamp_us / 1000; }
+  int64_t log_time_us() const { return timestamp.us(); }
+  int64_t log_time_ms() const { return timestamp.ms(); }
 
-  int64_t timestamp_us;
+  Timestamp timestamp;
 };
 
 struct InferredRouteChangeEvent {
@@ -339,8 +339,5 @@
 };
 
 
-
-
-
 }  // namespace webrtc
 #endif  // LOGGING_RTC_EVENT_LOG_LOGGED_EVENTS_H_
diff --git a/logging/rtc_event_log/rtc_event_log_impl.cc b/logging/rtc_event_log/rtc_event_log_impl.cc
index 4a272f0..700f639 100644
--- a/logging/rtc_event_log/rtc_event_log_impl.cc
+++ b/logging/rtc_event_log/rtc_event_log_impl.cc
@@ -90,8 +90,8 @@
     return false;
   }
 
-  const int64_t timestamp_us = rtc::TimeMicros();
-  const int64_t utc_time_us = rtc::TimeUTCMicros();
+  const int64_t timestamp_us = rtc::TimeMillis() * 1000;
+  const int64_t utc_time_us = rtc::TimeUTCMillis() * 1000;
   RTC_LOG(LS_INFO) << "Starting WebRTC event log. (Timestamp, UTC) = "
                       "("
                    << timestamp_us << ", " << utc_time_us << ").";
@@ -253,7 +253,7 @@
 void RtcEventLogImpl::StopLoggingInternal() {
   if (event_output_) {
     RTC_DCHECK(event_output_->IsActive());
-    const int64_t timestamp_us = rtc::TimeMicros();
+    const int64_t timestamp_us = rtc::TimeMillis() * 1000;
     event_output_->Write(event_encoder_->EncodeLogEnd(timestamp_us));
   }
   StopOutput();
diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc
index 6cdaa75..d10e4f9 100644
--- a/logging/rtc_event_log/rtc_event_log_parser.cc
+++ b/logging/rtc_event_log/rtc_event_log_parser.cc
@@ -390,7 +390,7 @@
       RTC_PARSE_CHECK_OR_RETURN(!proto.has_voice_activity());
     }
     (*rtp_packets_map)[header.ssrc].emplace_back(
-        proto.timestamp_ms() * 1000, header, proto.header_size(),
+        Timestamp::Millis(proto.timestamp_ms()), header, proto.header_size(),
         proto.payload_size() + header.headerLength + header.paddingLength);
   }
 
@@ -592,7 +592,7 @@
                                 !voice_activity_values[i].has_value());
     }
     (*rtp_packets_map)[header.ssrc].emplace_back(
-        1000 * timestamp_ms, header, header.headerLength,
+        Timestamp::Millis(timestamp_ms), header, header.headerLength,
         payload_size_values[i].value() + header.headerLength +
             header.paddingLength);
   }
@@ -615,7 +615,8 @@
       !IdenticalRtcpContents(rtcp_packets->back().rtcp.raw_data,
                              proto.raw_packet())) {
     // Base event
-    rtcp_packets->emplace_back(proto.timestamp_ms() * 1000, proto.raw_packet());
+    rtcp_packets->emplace_back(Timestamp::Millis(proto.timestamp_ms()),
+                               proto.raw_packet());
   }
 
   const size_t number_of_deltas =
@@ -653,7 +654,7 @@
       continue;
     }
     std::string data(raw_packet_values[i]);
-    rtcp_packets->emplace_back(1000 * timestamp_ms, data);
+    rtcp_packets->emplace_back(Timestamp::Millis(timestamp_ms), data);
   }
   return ParsedRtcEventLog::ParseStatus::Success();
 }
@@ -672,6 +673,7 @@
     std::vector<LoggedRtcpPacketBye>* bye_list,
     std::vector<LoggedRtcpPacketTransportFeedback>* transport_feedback_list,
     std::vector<LoggedRtcpPacketLossNotification>* loss_notification_list) {
+  Timestamp timestamp = Timestamp::Micros(timestamp_us);
   rtcp::CommonHeader header;
   for (const uint8_t* block = packet_begin; block < packet_end;
        block = header.NextPacket()) {
@@ -679,44 +681,44 @@
     if (header.type() == rtcp::TransportFeedback::kPacketType &&
         header.fmt() == rtcp::TransportFeedback::kFeedbackMessageType) {
       LoggedRtcpPacketTransportFeedback parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.transport_feedback.Parse(header))
         transport_feedback_list->push_back(std::move(parsed_block));
     } else if (header.type() == rtcp::SenderReport::kPacketType) {
       LoggedRtcpPacketSenderReport parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.sr.Parse(header)) {
         sr_list->push_back(std::move(parsed_block));
       }
     } else if (header.type() == rtcp::ReceiverReport::kPacketType) {
       LoggedRtcpPacketReceiverReport parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.rr.Parse(header)) {
         rr_list->push_back(std::move(parsed_block));
       }
     } else if (header.type() == rtcp::ExtendedReports::kPacketType) {
       LoggedRtcpPacketExtendedReports parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.xr.Parse(header)) {
         xr_list->push_back(std::move(parsed_block));
       }
     } else if (header.type() == rtcp::Fir::kPacketType &&
                header.fmt() == rtcp::Fir::kFeedbackMessageType) {
       LoggedRtcpPacketFir parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.fir.Parse(header)) {
         fir_list->push_back(std::move(parsed_block));
       }
     } else if (header.type() == rtcp::Pli::kPacketType &&
                header.fmt() == rtcp::Pli::kFeedbackMessageType) {
       LoggedRtcpPacketPli parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.pli.Parse(header)) {
         pli_list->push_back(std::move(parsed_block));
       }
     } else if (header.type() == rtcp::Bye::kPacketType) {
       LoggedRtcpPacketBye parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.bye.Parse(header)) {
         bye_list->push_back(std::move(parsed_block));
       }
@@ -725,7 +727,7 @@
       bool type_found = false;
       if (!type_found) {
         LoggedRtcpPacketRemb parsed_block;
-        parsed_block.timestamp_us = timestamp_us;
+        parsed_block.timestamp = timestamp;
         if (parsed_block.remb.Parse(header)) {
           remb_list->push_back(std::move(parsed_block));
           type_found = true;
@@ -733,7 +735,7 @@
       }
       if (!type_found) {
         LoggedRtcpPacketLossNotification parsed_block;
-        parsed_block.timestamp_us = timestamp_us;
+        parsed_block.timestamp = timestamp;
         if (parsed_block.loss_notification.Parse(header)) {
           loss_notification_list->push_back(std::move(parsed_block));
           type_found = true;
@@ -742,7 +744,7 @@
     } else if (header.type() == rtcp::Nack::kPacketType &&
                header.fmt() == rtcp::Nack::kFeedbackMessageType) {
       LoggedRtcpPacketNack parsed_block;
-      parsed_block.timestamp_us = timestamp_us;
+      parsed_block.timestamp = timestamp;
       if (parsed_block.nack.Parse(header)) {
         nack_list->push_back(std::move(parsed_block));
       }
@@ -1170,7 +1172,7 @@
 
   // Set up convenience wrappers around the most commonly used RTCP types.
   for (const auto& incoming : incoming_rtcp_packets_) {
-    const int64_t timestamp_us = incoming.rtcp.timestamp_us;
+    const int64_t timestamp_us = incoming.rtcp.timestamp.us();
     const uint8_t* packet_begin = incoming.rtcp.raw_data.data();
     const uint8_t* packet_end = packet_begin + incoming.rtcp.raw_data.size();
     auto status = StoreRtcpBlocks(
@@ -1182,7 +1184,7 @@
   }
 
   for (const auto& outgoing : outgoing_rtcp_packets_) {
-    const int64_t timestamp_us = outgoing.rtcp.timestamp_us;
+    const int64_t timestamp_us = outgoing.rtcp.timestamp.us();
     const uint8_t* packet_begin = outgoing.rtcp.raw_data.data();
     const uint8_t* packet_end = packet_begin + outgoing.rtcp.raw_data.size();
     auto status = StoreRtcpBlocks(
@@ -1374,7 +1376,8 @@
 
       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
       int64_t timestamp_us = event.timestamp_us();
-      video_recv_configs_.emplace_back(timestamp_us, config.value());
+      video_recv_configs_.emplace_back(Timestamp::Micros(timestamp_us),
+                                       config.value());
       incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
           RtpHeaderExtensionMap(config.value().rtp_extensions);
       incoming_rtp_extensions_maps_[config.value().rtx_ssrc] =
@@ -1388,7 +1391,8 @@
 
       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
       int64_t timestamp_us = event.timestamp_us();
-      video_send_configs_.emplace_back(timestamp_us, config.value());
+      video_send_configs_.emplace_back(Timestamp::Micros(timestamp_us),
+                                       config.value());
       outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
           RtpHeaderExtensionMap(config.value().rtp_extensions);
       outgoing_rtp_extensions_maps_[config.value().rtx_ssrc] =
@@ -1402,7 +1406,8 @@
 
       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
       int64_t timestamp_us = event.timestamp_us();
-      audio_recv_configs_.emplace_back(timestamp_us, config.value());
+      audio_recv_configs_.emplace_back(Timestamp::Micros(timestamp_us),
+                                       config.value());
       incoming_rtp_extensions_maps_[config.value().remote_ssrc] =
           RtpHeaderExtensionMap(config.value().rtp_extensions);
       break;
@@ -1413,7 +1418,8 @@
         return config.status();
       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
       int64_t timestamp_us = event.timestamp_us();
-      audio_send_configs_.emplace_back(timestamp_us, config.value());
+      audio_send_configs_.emplace_back(Timestamp::Micros(timestamp_us),
+                                       config.value());
       outgoing_rtp_extensions_maps_[config.value().local_ssrc] =
           RtpHeaderExtensionMap(config.value().rtp_extensions);
       break;
@@ -1446,11 +1452,13 @@
       int64_t timestamp_us = event.timestamp_us();
       if (direction == kIncomingPacket) {
         incoming_rtp_packets_map_[parsed_header.ssrc].push_back(
-            LoggedRtpPacketIncoming(timestamp_us, parsed_header, header_length,
+            LoggedRtpPacketIncoming(Timestamp::Micros(timestamp_us),
+                                    parsed_header, header_length,
                                     total_length));
       } else {
         outgoing_rtp_packets_map_[parsed_header.ssrc].push_back(
-            LoggedRtpPacketOutgoing(timestamp_us, parsed_header, header_length,
+            LoggedRtpPacketOutgoing(Timestamp::Micros(timestamp_us),
+                                    parsed_header, header_length,
                                     total_length));
       }
       break;
@@ -1469,24 +1477,26 @@
         if (packet == last_incoming_rtcp_packet_)
           break;
         incoming_rtcp_packets_.push_back(
-            LoggedRtcpPacketIncoming(timestamp_us, packet));
+            LoggedRtcpPacketIncoming(Timestamp::Micros(timestamp_us), packet));
         last_incoming_rtcp_packet_ = packet;
       } else {
         outgoing_rtcp_packets_.push_back(
-            LoggedRtcpPacketOutgoing(timestamp_us, packet));
+            LoggedRtcpPacketOutgoing(Timestamp::Micros(timestamp_us), packet));
       }
       break;
     }
     case rtclog::Event::LOG_START: {
       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
       int64_t timestamp_us = event.timestamp_us();
-      start_log_events_.push_back(LoggedStartEvent(timestamp_us));
+      start_log_events_.push_back(
+          LoggedStartEvent(Timestamp::Micros(timestamp_us)));
       break;
     }
     case rtclog::Event::LOG_END: {
       RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
       int64_t timestamp_us = event.timestamp_us();
-      stop_log_events_.push_back(LoggedStopEvent(timestamp_us));
+      stop_log_events_.push_back(
+          LoggedStopEvent(Timestamp::Micros(timestamp_us)));
       break;
     }
     case rtclog::Event::AUDIO_PLAYOUT_EVENT: {
@@ -1805,7 +1815,7 @@
   const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event();
   LoggedAudioPlayoutEvent res;
   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
-  res.timestamp_us = event.timestamp_us();
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(playout_event.has_local_ssrc());
   res.ssrc = playout_event.local_ssrc();
   return res;
@@ -1821,7 +1831,7 @@
 
   LoggedBweLossBasedUpdate bwe_update;
   RTC_CHECK(event.has_timestamp_us());
-  bwe_update.timestamp_us = event.timestamp_us();
+  bwe_update.timestamp = Timestamp::Micros(event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(loss_event.has_bitrate_bps());
   bwe_update.bitrate_bps = loss_event.bitrate_bps();
   RTC_PARSE_CHECK_OR_RETURN(loss_event.has_fraction_loss());
@@ -1842,7 +1852,7 @@
 
   LoggedBweDelayBasedUpdate res;
   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
-  res.timestamp_us = event.timestamp_us();
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(delay_event.has_bitrate_bps());
   res.bitrate_bps = delay_event.bitrate_bps();
   RTC_PARSE_CHECK_OR_RETURN(delay_event.has_detector_state());
@@ -1861,7 +1871,7 @@
 
   LoggedAudioNetworkAdaptationEvent res;
   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
-  res.timestamp_us = event.timestamp_us();
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
   if (ana_event.has_bitrate_bps())
     res.config.bitrate_bps = ana_event.bitrate_bps();
   if (ana_event.has_enable_fec())
@@ -1887,7 +1897,7 @@
   const rtclog::BweProbeCluster& pcc_event = event.probe_cluster();
   LoggedBweProbeClusterCreatedEvent res;
   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
-  res.timestamp_us = event.timestamp_us();
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_id());
   res.id = pcc_event.id();
   RTC_PARSE_CHECK_OR_RETURN(pcc_event.has_bitrate_bps());
@@ -1912,7 +1922,7 @@
 
   LoggedBweProbeFailureEvent res;
   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
-  res.timestamp_us = event.timestamp_us();
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(pr_event.has_id());
   res.id = pr_event.id();
   RTC_PARSE_CHECK_OR_RETURN(pr_event.has_result());
@@ -1945,7 +1955,7 @@
 
   LoggedBweProbeSuccessEvent res;
   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
-  res.timestamp_us = event.timestamp_us();
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(pr_event.has_id());
   res.id = pr_event.id();
   RTC_PARSE_CHECK_OR_RETURN(pr_event.has_bitrate_bps());
@@ -1962,7 +1972,7 @@
   const rtclog::AlrState& alr_event = event.alr_state();
   LoggedAlrStateEvent res;
   RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
-  res.timestamp_us = event.timestamp_us();
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(alr_event.has_in_alr());
   res.in_alr = alr_event.in_alr();
 
@@ -1979,7 +1989,7 @@
   const rtclog::IceCandidatePairConfig& config =
       rtc_event.ice_candidate_pair_config();
   RTC_CHECK(rtc_event.has_timestamp_us());
-  res.timestamp_us = rtc_event.timestamp_us();
+  res.timestamp = Timestamp::Micros(rtc_event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(config.has_config_type());
   res.type = GetRuntimeIceCandidatePairConfigType(config.config_type());
   RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_id());
@@ -2018,7 +2028,7 @@
   const rtclog::IceCandidatePairEvent& event =
       rtc_event.ice_candidate_pair_event();
   RTC_CHECK(rtc_event.has_timestamp_us());
-  res.timestamp_us = rtc_event.timestamp_us();
+  res.timestamp = Timestamp::Micros(rtc_event.timestamp_us());
   RTC_PARSE_CHECK_OR_RETURN(event.has_event_type());
   res.type = GetRuntimeIceCandidatePairEventType(event.event_type());
   RTC_PARSE_CHECK_OR_RETURN(event.has_candidate_pair_id());
@@ -2404,7 +2414,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_in_alr());
   LoggedAlrStateEvent alr_event;
-  alr_event.timestamp_us = proto.timestamp_ms() * 1000;
+  alr_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
   alr_event.in_alr = proto.in_alr();
 
   alr_state_events_.push_back(alr_event);
@@ -2418,7 +2428,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_connected());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_overhead());
   LoggedRouteChangeEvent route_event;
-  route_event.timestamp_ms = proto.timestamp_ms();
+  route_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
   route_event.connected = proto.connected();
   route_event.overhead = proto.overhead();
 
@@ -2432,7 +2442,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
   // Base event
   LoggedRemoteEstimateEvent base_event;
-  base_event.timestamp_ms = proto.timestamp_ms();
+  base_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
 
   absl::optional<uint64_t> base_link_capacity_lower_kbps;
   if (proto.has_link_capacity_lower_kbps()) {
@@ -2480,7 +2490,7 @@
   for (size_t i = 0; i < number_of_deltas; ++i) {
     LoggedRemoteEstimateEvent event;
     RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
-    event.timestamp_ms = *timestamp_ms_values[i];
+    event.timestamp = Timestamp::Millis(*timestamp_ms_values[i]);
     if (link_capacity_lower_kbps_values[i])
       event.link_capacity_lower =
           DataRate::KilobitsPerSec(*link_capacity_lower_kbps_values[i]);
@@ -2499,7 +2509,7 @@
 
   // Base event
   audio_playout_events_[proto.local_ssrc()].emplace_back(
-      1000 * proto.timestamp_ms(), proto.local_ssrc());
+      Timestamp::Millis(proto.timestamp_ms()), proto.local_ssrc());
 
   const size_t number_of_deltas =
       proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
@@ -2531,8 +2541,8 @@
 
     const uint32_t local_ssrc =
         static_cast<uint32_t>(local_ssrc_values[i].value());
-    audio_playout_events_[local_ssrc].emplace_back(1000 * timestamp_ms,
-                                                   local_ssrc);
+    audio_playout_events_[local_ssrc].emplace_back(
+        Timestamp::Millis(timestamp_ms), local_ssrc);
   }
   return ParseStatus::Success();
 }
@@ -2565,8 +2575,8 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_version());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_utc_time_ms());
   RTC_PARSE_CHECK_OR_RETURN_EQ(proto.version(), 2);
-  LoggedStartEvent start_event(proto.timestamp_ms() * 1000,
-                               proto.utc_time_ms());
+  LoggedStartEvent start_event(Timestamp::Millis(proto.timestamp_ms()),
+                               Timestamp::Millis(proto.utc_time_ms()));
 
   start_log_events_.push_back(start_event);
   return ParseStatus::Success();
@@ -2575,7 +2585,7 @@
 ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreStopEvent(
     const rtclog2::EndLogEvent& proto) {
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  LoggedStopEvent stop_event(proto.timestamp_ms() * 1000);
+  LoggedStopEvent stop_event(Timestamp::Millis(proto.timestamp_ms()));
 
   stop_log_events_.push_back(stop_event);
   return ParseStatus::Success();
@@ -2589,7 +2599,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_total_packets());
 
   // Base event
-  bwe_loss_updates_.emplace_back(1000 * proto.timestamp_ms(),
+  bwe_loss_updates_.emplace_back(Timestamp::Millis(proto.timestamp_ms()),
                                  proto.bitrate_bps(), proto.fraction_loss(),
                                  proto.total_packets());
 
@@ -2645,7 +2655,7 @@
     const uint32_t total_packets =
         static_cast<uint32_t>(total_packets_values[i].value());
 
-    bwe_loss_updates_.emplace_back(1000 * timestamp_ms, bitrate_bps,
+    bwe_loss_updates_.emplace_back(Timestamp::Millis(timestamp_ms), bitrate_bps,
                                    fraction_loss, total_packets);
   }
   return ParseStatus::Success();
@@ -2660,7 +2670,7 @@
   // Base event
   const BandwidthUsage base_detector_state =
       GetRuntimeDetectorState(proto.detector_state());
-  bwe_delay_updates_.emplace_back(1000 * proto.timestamp_ms(),
+  bwe_delay_updates_.emplace_back(Timestamp::Millis(proto.timestamp_ms()),
                                   proto.bitrate_bps(), base_detector_state);
 
   const size_t number_of_deltas =
@@ -2704,7 +2714,8 @@
         static_cast<rtclog2::DelayBasedBweUpdates::DetectorState>(
             detector_state_values[i].value());
 
-    bwe_delay_updates_.emplace_back(1000 * timestamp_ms, bitrate_bps,
+    bwe_delay_updates_.emplace_back(Timestamp::Millis(timestamp_ms),
+                                    bitrate_bps,
                                     GetRuntimeDetectorState(detector_state));
   }
   return ParseStatus::Success();
@@ -2714,7 +2725,7 @@
     const rtclog2::BweProbeCluster& proto) {
   LoggedBweProbeClusterCreatedEvent probe_cluster;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  probe_cluster.timestamp_us = proto.timestamp_ms() * 1000;
+  probe_cluster.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
   probe_cluster.id = proto.id();
   RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
@@ -2734,7 +2745,7 @@
     const rtclog2::BweProbeResultSuccess& proto) {
   LoggedBweProbeSuccessEvent probe_result;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  probe_result.timestamp_us = proto.timestamp_ms() * 1000;
+  probe_result.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
   probe_result.id = proto.id();
   RTC_PARSE_CHECK_OR_RETURN(proto.has_bitrate_bps());
@@ -2750,7 +2761,7 @@
     const rtclog2::BweProbeResultFailure& proto) {
   LoggedBweProbeFailureEvent probe_result;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  probe_result.timestamp_us = proto.timestamp_ms() * 1000;
+  probe_result.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_id());
   probe_result.id = proto.id();
   RTC_PARSE_CHECK_OR_RETURN(proto.has_failure());
@@ -2773,7 +2784,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_qp());
 
   LoggedFrameDecoded base_frame;
-  base_frame.timestamp_us = 1000 * proto.timestamp_ms();
+  base_frame.timestamp = Timestamp::Millis(proto.timestamp_ms());
   base_frame.ssrc = proto.ssrc();
   base_frame.render_time_ms = proto.render_time_ms();
   base_frame.width = proto.width();
@@ -2836,7 +2847,7 @@
     RTC_PARSE_CHECK_OR_RETURN(timestamp_ms_values[i].has_value());
     RTC_PARSE_CHECK_OR_RETURN(
         ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
-    frame.timestamp_us = 1000 * timestamp_ms;
+    frame.timestamp = Timestamp::Millis(timestamp_ms);
 
     RTC_PARSE_CHECK_OR_RETURN(ssrc_values[i].has_value());
     RTC_PARSE_CHECK_OR_RETURN_LE(ssrc_values[i].value(),
@@ -2881,7 +2892,7 @@
     base_receive_acked_packet_time_ms = proto.receive_acked_packet_time_ms();
   }
   generic_acks_received_.push_back(
-      {proto.timestamp_ms() * 1000, proto.packet_number(),
+      {Timestamp::Millis(proto.timestamp_ms()), proto.packet_number(),
        proto.acked_packet_number(), base_receive_acked_packet_time_ms});
 
   const size_t number_of_deltas =
@@ -2940,8 +2951,8 @@
           ToSigned(receive_acked_packet_time_ms_values[i].value(), &value));
       receive_acked_packet_time_ms = value;
     }
-    generic_acks_received_.push_back({timestamp_ms * 1000, packet_number,
-                                      acked_packet_number,
+    generic_acks_received_.push_back({Timestamp::Millis(timestamp_ms),
+                                      packet_number, acked_packet_number,
                                       receive_acked_packet_time_ms});
   }
   return ParseStatus::Success();
@@ -2958,7 +2969,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_padding_length());
 
   generic_packets_sent_.push_back(
-      {proto.timestamp_ms() * 1000, proto.packet_number(),
+      {Timestamp::Millis(proto.timestamp_ms()), proto.packet_number(),
        static_cast<size_t>(proto.overhead_length()),
        static_cast<size_t>(proto.payload_length()),
        static_cast<size_t>(proto.padding_length())});
@@ -3005,7 +3016,7 @@
     RTC_PARSE_CHECK_OR_RETURN(payload_length_values[i].has_value());
     RTC_PARSE_CHECK_OR_RETURN(padding_length_values[i].has_value());
     generic_packets_sent_.push_back(
-        {timestamp_ms * 1000, packet_number,
+        {Timestamp::Millis(timestamp_ms), packet_number,
          static_cast<size_t>(overhead_length_values[i].value()),
          static_cast<size_t>(payload_length_values[i].value()),
          static_cast<size_t>(padding_length_values[i].value())});
@@ -3022,7 +3033,7 @@
   RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_number());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_packet_length());
 
-  generic_packets_received_.push_back({proto.timestamp_ms() * 1000,
+  generic_packets_received_.push_back({Timestamp::Millis(proto.timestamp_ms()),
                                        proto.packet_number(),
                                        proto.packet_length()});
 
@@ -3060,7 +3071,7 @@
     int32_t packet_length =
         static_cast<int32_t>(packet_length_values[i].value());
     generic_packets_received_.push_back(
-        {timestamp_ms * 1000, packet_number, packet_length});
+        {Timestamp::Millis(timestamp_ms), packet_number, packet_length});
   }
   return ParseStatus::Success();
 }
@@ -3095,8 +3106,8 @@
       // Note: Encoding N as N-1 only done for |num_channels_deltas|.
       runtime_config.num_channels = proto.num_channels();
     }
-    audio_network_adaptation_events_.emplace_back(1000 * proto.timestamp_ms(),
-                                                  runtime_config);
+    audio_network_adaptation_events_.emplace_back(
+        Timestamp::Millis(proto.timestamp_ms()), runtime_config);
   }
 
   const size_t number_of_deltas =
@@ -3217,8 +3228,8 @@
       runtime_config.num_channels =
           rtc::checked_cast<size_t>(num_channels_values[i].value());
     }
-    audio_network_adaptation_events_.emplace_back(1000 * timestamp_ms,
-                                                  runtime_config);
+    audio_network_adaptation_events_.emplace_back(
+        Timestamp::Millis(timestamp_ms), runtime_config);
   }
   return ParseStatus::Success();
 }
@@ -3227,7 +3238,7 @@
     const rtclog2::DtlsTransportStateEvent& proto) {
   LoggedDtlsTransportState dtls_state;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  dtls_state.timestamp_us = proto.timestamp_ms() * 1000;
+  dtls_state.timestamp = Timestamp::Millis(proto.timestamp_ms());
 
   RTC_PARSE_CHECK_OR_RETURN(proto.has_dtls_transport_state());
   dtls_state.dtls_transport_state =
@@ -3241,7 +3252,7 @@
     const rtclog2::DtlsWritableState& proto) {
   LoggedDtlsWritableState dtls_writable_state;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  dtls_writable_state.timestamp_us = proto.timestamp_ms() * 1000;
+  dtls_writable_state.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_writable());
   dtls_writable_state.writable = proto.writable();
 
@@ -3253,7 +3264,7 @@
     const rtclog2::IceCandidatePairConfig& proto) {
   LoggedIceCandidatePairConfig ice_config;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  ice_config.timestamp_us = proto.timestamp_ms() * 1000;
+  ice_config.timestamp = Timestamp::Millis(proto.timestamp_ms());
 
   RTC_PARSE_CHECK_OR_RETURN(proto.has_config_type());
   ice_config.type = GetRuntimeIceCandidatePairConfigType(proto.config_type());
@@ -3291,7 +3302,7 @@
     const rtclog2::IceCandidatePairEvent& proto) {
   LoggedIceCandidatePairEvent ice_event;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  ice_event.timestamp_us = proto.timestamp_ms() * 1000;
+  ice_event.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_event_type());
   ice_event.type = GetRuntimeIceCandidatePairEventType(proto.event_type());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id());
@@ -3311,7 +3322,7 @@
     const rtclog2::VideoRecvStreamConfig& proto) {
   LoggedVideoRecvConfig stream;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  stream.timestamp_us = proto.timestamp_ms() * 1000;
+  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
   stream.config.remote_ssrc = proto.remote_ssrc();
   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
@@ -3331,7 +3342,7 @@
     const rtclog2::VideoSendStreamConfig& proto) {
   LoggedVideoSendConfig stream;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  stream.timestamp_us = proto.timestamp_ms() * 1000;
+  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
   stream.config.local_ssrc = proto.ssrc();
   if (proto.has_rtx_ssrc()) {
@@ -3349,7 +3360,7 @@
     const rtclog2::AudioRecvStreamConfig& proto) {
   LoggedAudioRecvConfig stream;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  stream.timestamp_us = proto.timestamp_ms() * 1000;
+  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_ssrc());
   stream.config.remote_ssrc = proto.remote_ssrc();
   RTC_PARSE_CHECK_OR_RETURN(proto.has_local_ssrc());
@@ -3366,7 +3377,7 @@
     const rtclog2::AudioSendStreamConfig& proto) {
   LoggedAudioSendConfig stream;
   RTC_PARSE_CHECK_OR_RETURN(proto.has_timestamp_ms());
-  stream.timestamp_us = proto.timestamp_ms() * 1000;
+  stream.timestamp = Timestamp::Millis(proto.timestamp_ms());
   RTC_PARSE_CHECK_OR_RETURN(proto.has_ssrc());
   stream.config.local_ssrc = proto.ssrc();
   if (proto.has_header_extensions()) {
diff --git a/logging/rtc_event_log/rtc_event_log_unittest.cc b/logging/rtc_event_log/rtc_event_log_unittest.cc
index dca7fb7..5535bec 100644
--- a/logging/rtc_event_log/rtc_event_log_unittest.cc
+++ b/logging/rtc_event_log/rtc_event_log_unittest.cc
@@ -944,7 +944,7 @@
   EXPECT_LT(probe_success_events.size(), kNumEvents);
 
   ASSERT_GT(probe_success_events.size(), 1u);
-  int64_t first_timestamp_us = probe_success_events[0].timestamp_us;
+  int64_t first_timestamp_ms = probe_success_events[0].timestamp.ms();
   uint32_t first_id = probe_success_events[0].id;
   int32_t first_bitrate_bps = probe_success_events[0].bitrate_bps;
   // We want to reset the time to what we used when generating the events, but
@@ -953,7 +953,7 @@
   // destroyed before the new one is created, so we have to reset() first.
   fake_clock.reset();
   fake_clock = std::make_unique<rtc::ScopedFakeClock>();
-  fake_clock->SetTime(Timestamp::Micros(first_timestamp_us));
+  fake_clock->SetTime(Timestamp::Millis(first_timestamp_ms));
   for (size_t i = 1; i < probe_success_events.size(); i++) {
     fake_clock->AdvanceTime(TimeDelta::Millis(10));
     verifier_.VerifyLoggedBweProbeSuccessEvent(
diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
index cefd4a6..0960c98 100644
--- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
+++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
@@ -1124,10 +1124,10 @@
 }
 
 void EventVerifier::VerifyLoggedSenderReport(
-    int64_t log_time_us,
+    int64_t log_time_ms,
     const rtcp::SenderReport& original_sr,
     const LoggedRtcpPacketSenderReport& logged_sr) {
-  EXPECT_EQ(log_time_us, logged_sr.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_sr.log_time_ms());
   EXPECT_EQ(original_sr.sender_ssrc(), logged_sr.sr.sender_ssrc());
   EXPECT_EQ(original_sr.ntp(), logged_sr.sr.ntp());
   EXPECT_EQ(original_sr.rtp_timestamp(), logged_sr.sr.rtp_timestamp());
@@ -1144,10 +1144,10 @@
 }
 
 void EventVerifier::VerifyLoggedReceiverReport(
-    int64_t log_time_us,
+    int64_t log_time_ms,
     const rtcp::ReceiverReport& original_rr,
     const LoggedRtcpPacketReceiverReport& logged_rr) {
-  EXPECT_EQ(log_time_us, logged_rr.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_rr.log_time_ms());
   EXPECT_EQ(original_rr.sender_ssrc(), logged_rr.rr.sender_ssrc());
   ASSERT_EQ(original_rr.report_blocks().size(),
             logged_rr.rr.report_blocks().size());
@@ -1158,10 +1158,10 @@
 }
 
 void EventVerifier::VerifyLoggedExtendedReports(
-    int64_t log_time_us,
+    int64_t log_time_ms,
     const rtcp::ExtendedReports& original_xr,
     const LoggedRtcpPacketExtendedReports& logged_xr) {
-  EXPECT_EQ(log_time_us, logged_xr.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_xr.log_time_ms());
   EXPECT_EQ(original_xr.sender_ssrc(), logged_xr.xr.sender_ssrc());
 
   EXPECT_EQ(original_xr.rrtr().has_value(), logged_xr.xr.rrtr().has_value());
@@ -1199,10 +1199,10 @@
   }
 }
 
-void EventVerifier::VerifyLoggedFir(int64_t log_time_us,
+void EventVerifier::VerifyLoggedFir(int64_t log_time_ms,
                                     const rtcp::Fir& original_fir,
                                     const LoggedRtcpPacketFir& logged_fir) {
-  EXPECT_EQ(log_time_us, logged_fir.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_fir.log_time_ms());
   EXPECT_EQ(original_fir.sender_ssrc(), logged_fir.fir.sender_ssrc());
   const auto& original_requests = original_fir.requests();
   const auto& logged_requests = logged_fir.fir.requests();
@@ -1213,35 +1213,35 @@
   }
 }
 
-void EventVerifier::VerifyLoggedPli(int64_t log_time_us,
+void EventVerifier::VerifyLoggedPli(int64_t log_time_ms,
                                     const rtcp::Pli& original_pli,
                                     const LoggedRtcpPacketPli& logged_pli) {
-  EXPECT_EQ(log_time_us, logged_pli.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_pli.log_time_ms());
   EXPECT_EQ(original_pli.sender_ssrc(), logged_pli.pli.sender_ssrc());
   EXPECT_EQ(original_pli.media_ssrc(), logged_pli.pli.media_ssrc());
 }
 
-void EventVerifier::VerifyLoggedBye(int64_t log_time_us,
+void EventVerifier::VerifyLoggedBye(int64_t log_time_ms,
                                     const rtcp::Bye& original_bye,
                                     const LoggedRtcpPacketBye& logged_bye) {
-  EXPECT_EQ(log_time_us, logged_bye.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_bye.log_time_ms());
   EXPECT_EQ(original_bye.sender_ssrc(), logged_bye.bye.sender_ssrc());
   EXPECT_EQ(original_bye.csrcs(), logged_bye.bye.csrcs());
   EXPECT_EQ(original_bye.reason(), logged_bye.bye.reason());
 }
 
-void EventVerifier::VerifyLoggedNack(int64_t log_time_us,
+void EventVerifier::VerifyLoggedNack(int64_t log_time_ms,
                                      const rtcp::Nack& original_nack,
                                      const LoggedRtcpPacketNack& logged_nack) {
-  EXPECT_EQ(log_time_us, logged_nack.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_nack.log_time_ms());
   EXPECT_EQ(original_nack.packet_ids(), logged_nack.nack.packet_ids());
 }
 
 void EventVerifier::VerifyLoggedTransportFeedback(
-    int64_t log_time_us,
+    int64_t log_time_ms,
     const rtcp::TransportFeedback& original_transport_feedback,
     const LoggedRtcpPacketTransportFeedback& logged_transport_feedback) {
-  EXPECT_EQ(log_time_us, logged_transport_feedback.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_transport_feedback.log_time_ms());
   ASSERT_EQ(
       original_transport_feedback.GetReceivedPackets().size(),
       logged_transport_feedback.transport_feedback.GetReceivedPackets().size());
@@ -1258,19 +1258,19 @@
   }
 }
 
-void EventVerifier::VerifyLoggedRemb(int64_t log_time_us,
+void EventVerifier::VerifyLoggedRemb(int64_t log_time_ms,
                                      const rtcp::Remb& original_remb,
                                      const LoggedRtcpPacketRemb& logged_remb) {
-  EXPECT_EQ(log_time_us, logged_remb.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_remb.log_time_ms());
   EXPECT_EQ(original_remb.ssrcs(), logged_remb.remb.ssrcs());
   EXPECT_EQ(original_remb.bitrate_bps(), logged_remb.remb.bitrate_bps());
 }
 
 void EventVerifier::VerifyLoggedLossNotification(
-    int64_t log_time_us,
+    int64_t log_time_ms,
     const rtcp::LossNotification& original_loss_notification,
     const LoggedRtcpPacketLossNotification& logged_loss_notification) {
-  EXPECT_EQ(log_time_us, logged_loss_notification.log_time_us());
+  EXPECT_EQ(log_time_ms, logged_loss_notification.log_time_ms());
   EXPECT_EQ(original_loss_notification.last_decoded(),
             logged_loss_notification.loss_notification.last_decoded());
   EXPECT_EQ(original_loss_notification.last_received(),
@@ -1285,7 +1285,7 @@
     const LoggedStartEvent& logged_event) const {
   EXPECT_EQ(start_time_us / 1000, logged_event.log_time_ms());
   if (encoding_type_ == RtcEventLog::EncodingType::NewFormat) {
-    EXPECT_EQ(utc_start_time_us / 1000, logged_event.utc_start_time_ms);
+    EXPECT_EQ(utc_start_time_us / 1000, logged_event.utc_start_time.ms());
   }
 }
 
diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.h b/logging/rtc_event_log/rtc_event_log_unittest_helper.h
index 94cf3d5..eb16592 100644
--- a/logging/rtc_event_log/rtc_event_log_unittest_helper.h
+++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.h
@@ -260,38 +260,38 @@
       const RtcEventRtcpPacketOutgoing& original_event,
       const LoggedRtcpPacketOutgoing& logged_event) const;
 
-  void VerifyLoggedSenderReport(int64_t log_time_us,
+  void VerifyLoggedSenderReport(int64_t log_time_ms,
                                 const rtcp::SenderReport& original_sr,
                                 const LoggedRtcpPacketSenderReport& logged_sr);
   void VerifyLoggedReceiverReport(
-      int64_t log_time_us,
+      int64_t log_time_ms,
       const rtcp::ReceiverReport& original_rr,
       const LoggedRtcpPacketReceiverReport& logged_rr);
   void VerifyLoggedExtendedReports(
-      int64_t log_time_us,
+      int64_t log_time_ms,
       const rtcp::ExtendedReports& original_xr,
       const LoggedRtcpPacketExtendedReports& logged_xr);
-  void VerifyLoggedFir(int64_t log_time_us,
+  void VerifyLoggedFir(int64_t log_time_ms,
                        const rtcp::Fir& original_fir,
                        const LoggedRtcpPacketFir& logged_fir);
-  void VerifyLoggedPli(int64_t log_time_us,
+  void VerifyLoggedPli(int64_t log_time_ms,
                        const rtcp::Pli& original_pli,
                        const LoggedRtcpPacketPli& logged_pli);
-  void VerifyLoggedBye(int64_t log_time_us,
+  void VerifyLoggedBye(int64_t log_time_ms,
                        const rtcp::Bye& original_bye,
                        const LoggedRtcpPacketBye& logged_bye);
-  void VerifyLoggedNack(int64_t log_time_us,
+  void VerifyLoggedNack(int64_t log_time_ms,
                         const rtcp::Nack& original_nack,
                         const LoggedRtcpPacketNack& logged_nack);
   void VerifyLoggedTransportFeedback(
-      int64_t log_time_us,
+      int64_t log_time_ms,
       const rtcp::TransportFeedback& original_transport_feedback,
       const LoggedRtcpPacketTransportFeedback& logged_transport_feedback);
-  void VerifyLoggedRemb(int64_t log_time_us,
+  void VerifyLoggedRemb(int64_t log_time_ms,
                         const rtcp::Remb& original_remb,
                         const LoggedRtcpPacketRemb& logged_remb);
   void VerifyLoggedLossNotification(
-      int64_t log_time_us,
+      int64_t log_time_ms,
       const rtcp::LossNotification& original_loss_notification,
       const LoggedRtcpPacketLossNotification& logged_loss_notification);
 
diff --git a/logging/rtc_event_log/rtc_event_processor_unittest.cc b/logging/rtc_event_log/rtc_event_processor_unittest.cc
index 4ec5abe..b0cec25 100644
--- a/logging/rtc_event_log/rtc_event_processor_unittest.cc
+++ b/logging/rtc_event_log/rtc_event_processor_unittest.cc
@@ -29,7 +29,7 @@
     std::initializer_list<int64_t> timestamp_list) {
   std::vector<LoggedStartEvent> v;
   for (int64_t timestamp_ms : timestamp_list) {
-    v.emplace_back(timestamp_ms * 1000);  // Convert ms to us.
+    v.emplace_back(Timestamp::Millis(timestamp_ms));
   }
   return v;
 }
@@ -41,7 +41,7 @@
   for (size_t elem = 0; elem < num_elements; elem++) {
     uint32_t i = prng.Rand(0u, num_lists - 1);
     int64_t timestamp_ms = elem;
-    lists[i].emplace_back(timestamp_ms * 1000);
+    lists[i].emplace_back(Timestamp::Millis(timestamp_ms));
   }
   return lists;
 }
@@ -146,8 +146,8 @@
     result.push_back(elem.log_time_ms());
   };
 
-  std::vector<LoggedStartEvent> events1{LoggedStartEvent(2000)};
-  std::vector<LoggedStopEvent> events2{LoggedStopEvent(1000)};
+  std::vector<LoggedStartEvent> events1{LoggedStartEvent(Timestamp::Millis(2))};
+  std::vector<LoggedStopEvent> events2{LoggedStopEvent(Timestamp::Millis(1))};
   RtcEventProcessor processor;
   processor.AddEvents(events1, f1);
   processor.AddEvents(events2, f2);