Encode remote link capacity estimates in legacy RTC event log format

Bug: None
Change-Id: I36037d0c654e773d5e1c6e9821031eafea54fe0d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/271162
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37749}
diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc
index 422e2c4..9bc7708 100644
--- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc
+++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc
@@ -32,6 +32,7 @@
 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
+#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
@@ -331,6 +332,11 @@
       return EncodeProbeResultSuccess(rtc_event);
     }
 
+    case RtcEvent::Type::RemoteEstimateEvent: {
+      auto& rtc_event = static_cast<const RtcEventRemoteEstimate&>(event);
+      return EncodeRemoteEstimate(rtc_event);
+    }
+
     case RtcEvent::Type::RtcpPacketIncoming: {
       auto& rtc_event = static_cast<const RtcEventRtcpPacketIncoming&>(event);
       return EncodeRtcpPacketIncoming(rtc_event);
@@ -369,7 +375,6 @@
       RTC_DCHECK_NOTREACHED();
       break;
     case RtcEvent::Type::RouteChangeEvent:
-    case RtcEvent::Type::RemoteEstimateEvent:
     case RtcEvent::Type::GenericPacketReceived:
     case RtcEvent::Type::GenericPacketSent:
     case RtcEvent::Type::GenericAckReceived:
@@ -587,6 +592,23 @@
   return Serialize(&rtclog_event);
 }
 
+std::string RtcEventLogEncoderLegacy::EncodeRemoteEstimate(
+    const RtcEventRemoteEstimate& event) {
+  rtclog::Event rtclog_event;
+  rtclog_event.set_timestamp_us(event.timestamp_us());
+  rtclog_event.set_type(rtclog::Event::REMOTE_ESTIMATE);
+
+  auto* remote_estimate = rtclog_event.mutable_remote_estimate();
+  if (event.link_capacity_lower_.IsFinite())
+    remote_estimate->set_link_capacity_lower_kbps(
+        event.link_capacity_lower_.kbps<uint32_t>());
+  if (event.link_capacity_upper_.IsFinite())
+    remote_estimate->set_link_capacity_upper_kbps(
+        event.link_capacity_upper_.kbps<uint32_t>());
+
+  return Serialize(&rtclog_event);
+}
+
 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketIncoming(
     const RtcEventRtcpPacketIncoming& event) {
   return EncodeRtcpPacket(event.timestamp_us(), event.packet(), true);
diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h
index 37296e7..33c5307 100644
--- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h
+++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h
@@ -25,6 +25,7 @@
 class Event;  // Auto-generated from protobuf.
 }  // namespace rtclog
 
+class RtcEventAlrState;
 class RtcEventAudioNetworkAdaptation;
 class RtcEventAudioPlayout;
 class RtcEventAudioReceiveStreamConfig;
@@ -38,13 +39,13 @@
 class RtcEventProbeClusterCreated;
 class RtcEventProbeResultFailure;
 class RtcEventProbeResultSuccess;
+class RtcEventRemoteEstimate;
 class RtcEventRtcpPacketIncoming;
 class RtcEventRtcpPacketOutgoing;
 class RtcEventRtpPacketIncoming;
 class RtcEventRtpPacketOutgoing;
 class RtcEventVideoReceiveStreamConfig;
 class RtcEventVideoSendStreamConfig;
-class RtcEventAlrState;
 class RtpPacket;
 
 class RtcEventLogEncoderLegacy final : public RtcEventLogEncoder {
@@ -81,6 +82,7 @@
       const RtcEventProbeClusterCreated& event);
   std::string EncodeProbeResultFailure(const RtcEventProbeResultFailure& event);
   std::string EncodeProbeResultSuccess(const RtcEventProbeResultSuccess&);
+  std::string EncodeRemoteEstimate(const RtcEventRemoteEstimate& event);
   std::string EncodeRtcpPacketIncoming(const RtcEventRtcpPacketIncoming& event);
   std::string EncodeRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing& event);
   std::string EncodeRtpPacketIncoming(const RtcEventRtpPacketIncoming& event);
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 be9352a..c910003 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
@@ -251,9 +251,6 @@
 }
 
 TEST_P(RtcEventLogEncoderTest, RtcEventRemoteEstimate) {
-  if (encoding_type_ == RtcEventLog::EncodingType::Legacy) {
-    return;
-  }
   std::vector<std::unique_ptr<RtcEventRemoteEstimate>> events(event_count_);
   for (size_t i = 0; i < event_count_; ++i) {
     events[i] = (i == 0 || !force_repeated_fields_)
diff --git a/logging/rtc_event_log/rtc_event_log.proto b/logging/rtc_event_log/rtc_event_log.proto
index 94e288e..12baa49 100644
--- a/logging/rtc_event_log/rtc_event_log.proto
+++ b/logging/rtc_event_log/rtc_event_log.proto
@@ -43,6 +43,7 @@
     ALR_STATE_EVENT = 19;
     ICE_CANDIDATE_PAIR_CONFIG = 20;
     ICE_CANDIDATE_PAIR_EVENT = 21;
+    REMOTE_ESTIMATE = 22;
   }
 
   // required - Indicates the type of this event
@@ -93,6 +94,9 @@
 
     // required if type == ICE_CANDIDATE_PAIR_EVENT
     IceCandidatePairEvent ice_candidate_pair_event = 21;
+
+    // required if type == REMOTE_ESTIMATE
+    RemoteEstimate remote_estimate = 22;
   }
 }
 
@@ -327,6 +331,14 @@
   optional int32 bitrate_bps = 3;
 }
 
+message RemoteEstimate {
+  // optional - Lower estimate of link capacity.
+  optional uint32 link_capacity_lower_kbps = 1;
+
+  // optional - Upper estimate of link capacity.
+  optional uint32 link_capacity_upper_kbps = 2;
+}
+
 message AlrState {
   // required - If we are in ALR or not.
   optional bool in_alr = 1;
diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc
index e0a9d99..7e471dd 100644
--- a/logging/rtc_event_log/rtc_event_log_parser.cc
+++ b/logging/rtc_event_log/rtc_event_log_parser.cc
@@ -1770,6 +1770,12 @@
       ice_candidate_pair_events_.push_back(status_or_value.value());
       break;
     }
+    case rtclog::Event::REMOTE_ESTIMATE: {
+      auto status_or_value = GetRemoteEstimateEvent(event);
+      RTC_RETURN_IF_ERROR(status_or_value.status());
+      remote_estimate_events_.push_back(status_or_value.value());
+      break;
+    }
     case rtclog::Event::UNKNOWN_EVENT: {
       break;
     }
@@ -2144,7 +2150,7 @@
   LoggedIceCandidatePairConfig res;
   const rtclog::IceCandidatePairConfig& config =
       rtc_event.ice_candidate_pair_config();
-  RTC_CHECK(rtc_event.has_timestamp_us());
+  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_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());
@@ -2183,7 +2189,7 @@
   LoggedIceCandidatePairEvent res;
   const rtclog::IceCandidatePairEvent& event =
       rtc_event.ice_candidate_pair_event();
-  RTC_CHECK(rtc_event.has_timestamp_us());
+  RTC_PARSE_CHECK_OR_RETURN(rtc_event.has_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());
@@ -2194,6 +2200,23 @@
   return res;
 }
 
+ParsedRtcEventLog::ParseStatusOr<LoggedRemoteEstimateEvent>
+ParsedRtcEventLog::GetRemoteEstimateEvent(const rtclog::Event& event) const {
+  RTC_PARSE_CHECK_OR_RETURN(event.has_type());
+  RTC_PARSE_CHECK_OR_RETURN_EQ(event.type(), rtclog::Event::REMOTE_ESTIMATE);
+  LoggedRemoteEstimateEvent res;
+  const rtclog::RemoteEstimate& remote_estimate_event = event.remote_estimate();
+  RTC_PARSE_CHECK_OR_RETURN(event.has_timestamp_us());
+  res.timestamp = Timestamp::Micros(event.timestamp_us());
+  if (remote_estimate_event.has_link_capacity_lower_kbps())
+    res.link_capacity_lower = DataRate::KilobitsPerSec(
+        remote_estimate_event.link_capacity_lower_kbps());
+  if (remote_estimate_event.has_link_capacity_upper_kbps())
+    res.link_capacity_upper = DataRate::KilobitsPerSec(
+        remote_estimate_event.link_capacity_upper_kbps());
+  return res;
+}
+
 // Returns the MediaType for registered SSRCs. Search from the end to use last
 // registered types first.
 ParsedRtcEventLog::MediaType ParsedRtcEventLog::GetMediaType(
diff --git a/logging/rtc_event_log/rtc_event_log_parser.h b/logging/rtc_event_log/rtc_event_log_parser.h
index 8b1cba2..ae2d4fe 100644
--- a/logging/rtc_event_log/rtc_event_log_parser.h
+++ b/logging/rtc_event_log/rtc_event_log_parser.h
@@ -725,6 +725,9 @@
   ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairEvent>
   GetIceCandidatePairEvent(const rtclog::Event& event) const;
 
+  ParsedRtcEventLog::ParseStatusOr<LoggedRemoteEstimateEvent>
+  GetRemoteEstimateEvent(const rtclog::Event& event) const;
+
   // Parsing functions for new format.
   ParseStatus StoreAlrStateEvent(const rtclog2::AlrState& proto);
   ParseStatus StoreAudioNetworkAdaptationEvent(