summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/logging/rtc_event_log/events
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/logging/rtc_event_log/events')
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc137
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h96
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h259
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.cc38
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.h78
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc39
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h78
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.cc32
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.h88
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc40
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h76
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc40
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h74
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.cc73
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.h74
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc43
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h136
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc39
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h89
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_definition.h152
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.cc33
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h72
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.cc32
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h72
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.cc58
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.h64
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.cc299
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.h179
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc398
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h291
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc886
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.cc60
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.h84
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction_unittest.cc97
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.cc44
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.h93
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc55
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.h118
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.cc32
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.h84
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.cc36
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h110
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc40
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h98
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc63
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h152
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.cc31
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h70
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc40
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h95
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc34
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.h87
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.cc33
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.h80
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_remote_estimate.h68
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.cc31
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.h75
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc34
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h64
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc34
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h64
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc35
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h89
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc38
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h93
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc39
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h76
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc36
-rw-r--r--third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h75
69 files changed, 6552 insertions, 0 deletions
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc b/third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc
new file mode 100644
index 0000000000..0c93e6226d
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.cc
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h"
+
+#include <algorithm>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+#include "rtc_base/logging.h"
+
+using webrtc_event_logging::MaxUnsignedValueOfBitWidth;
+using webrtc_event_logging::SignedBitWidth;
+using webrtc_event_logging::UnsignedBitWidth;
+using webrtc_event_logging::UnsignedDelta;
+
+namespace webrtc {
+
+FixedLengthEncodingParametersV3
+FixedLengthEncodingParametersV3::CalculateParameters(
+ uint64_t base,
+ const rtc::ArrayView<const uint64_t> values,
+ uint64_t value_bit_width,
+ bool values_optional) {
+ // As a special case, if all of the elements are identical to the base
+ // we just encode the base value with a special delta header.
+ if (std::all_of(values.cbegin(), values.cend(),
+ [base](uint64_t val) { return val == base; })) {
+ // Delta header with signed=true and delta_bitwidth=64
+ return FixedLengthEncodingParametersV3(/*delta_bit_width=*/64,
+ /*signed_deltas=*/true,
+ values_optional, value_bit_width);
+ }
+
+ const uint64_t bit_mask = MaxUnsignedValueOfBitWidth(value_bit_width);
+
+ // Calculate the bitwidth required to encode all deltas when using a
+ // unsigned or signed represenation, respectively. For the unsigned
+ // representation, we just track the largest delta. For the signed
+ // representation, we have two possibilities for each delta; either
+ // going "forward" (i.e. current - previous) or "backwards"
+ // (i.e. previous - current) where both values are calculated with
+ // wrap around. We then track the largest positive and negative
+ // magnitude across the batch, assuming that we choose the smaller
+ // delta for each element.
+ uint64_t max_unsigned_delta = 0;
+ uint64_t max_positive_signed_delta = 0;
+ uint64_t min_negative_signed_delta = 0;
+ uint64_t prev = base;
+ for (uint64_t current : values) {
+ uint64_t positive_delta = UnsignedDelta(prev, current, bit_mask);
+ uint64_t negative_delta = UnsignedDelta(current, prev, bit_mask);
+
+ max_unsigned_delta = std::max(max_unsigned_delta, positive_delta);
+
+ if (positive_delta < negative_delta) {
+ max_positive_signed_delta =
+ std::max(max_positive_signed_delta, positive_delta);
+ } else {
+ min_negative_signed_delta =
+ std::max(min_negative_signed_delta, negative_delta);
+ }
+
+ prev = current;
+ }
+
+ // We now know the largest unsigned delta and the largest magnitudes of
+ // positive and negative signed deltas. Get the bitwidths required for
+ // each of the two encodings.
+ const uint64_t unsigned_delta_bit_width =
+ UnsignedBitWidth(max_unsigned_delta);
+ const uint64_t signed_delta_bit_width =
+ SignedBitWidth(max_positive_signed_delta, min_negative_signed_delta);
+
+ // Note: Preference for unsigned if the two have the same width (efficiency).
+ bool use_signed_deltas = signed_delta_bit_width < unsigned_delta_bit_width;
+ uint64_t delta_bit_width =
+ use_signed_deltas ? signed_delta_bit_width : unsigned_delta_bit_width;
+
+ // use_signed_deltas && delta_bit_width==64 is reserved for "all values
+ // equal".
+ RTC_DCHECK(!use_signed_deltas || delta_bit_width < 64);
+
+ RTC_DCHECK(ValidParameters(delta_bit_width, use_signed_deltas,
+ values_optional, value_bit_width));
+ return FixedLengthEncodingParametersV3(delta_bit_width, use_signed_deltas,
+ values_optional, value_bit_width);
+}
+
+uint64_t FixedLengthEncodingParametersV3::DeltaHeaderAsInt() const {
+ uint64_t header = delta_bit_width_ - 1;
+ RTC_CHECK_LT(header, 1u << 6);
+ if (signed_deltas_) {
+ header += 1u << 6;
+ }
+ RTC_CHECK_LT(header, 1u << 7);
+ if (values_optional_) {
+ header += 1u << 7;
+ }
+ return header;
+}
+
+absl::optional<FixedLengthEncodingParametersV3>
+FixedLengthEncodingParametersV3::ParseDeltaHeader(uint64_t header,
+ uint64_t value_bit_width) {
+ uint64_t delta_bit_width = (header & ((1u << 6) - 1)) + 1;
+ bool signed_deltas = header & (1u << 6);
+ bool values_optional = header & (1u << 7);
+
+ if (header >= (1u << 8)) {
+ RTC_LOG(LS_ERROR) << "Failed to parse delta header; unread bits remaining.";
+ return absl::nullopt;
+ }
+
+ if (!ValidParameters(delta_bit_width, signed_deltas, values_optional,
+ value_bit_width)) {
+ RTC_LOG(LS_ERROR) << "Failed to parse delta header. Invalid combination of "
+ "values: delta_bit_width="
+ << delta_bit_width << " signed_deltas=" << signed_deltas
+ << " values_optional=" << values_optional
+ << " value_bit_width=" << value_bit_width;
+ return absl::nullopt;
+ }
+
+ return FixedLengthEncodingParametersV3(delta_bit_width, signed_deltas,
+ values_optional, value_bit_width);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h b/third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h
new file mode 100644
index 0000000000..666fae1c63
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_FIXED_LENGTH_ENCODING_PARAMETERS_V3_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_FIXED_LENGTH_ENCODING_PARAMETERS_V3_H_
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+
+namespace webrtc {
+
+// Parameters for fixed-size delta-encoding/decoding.
+// These are tailored for the sequence which will be encoded (e.g. widths).
+class FixedLengthEncodingParametersV3 final {
+ public:
+ static bool ValidParameters(uint64_t delta_bit_width,
+ bool signed_deltas,
+ bool values_optional,
+ uint64_t value_bit_width) {
+ return (1 <= delta_bit_width && delta_bit_width <= 64 &&
+ 1 <= value_bit_width && value_bit_width <= 64 &&
+ (delta_bit_width <= value_bit_width ||
+ (signed_deltas && delta_bit_width == 64)));
+ }
+
+ static FixedLengthEncodingParametersV3 CalculateParameters(
+ uint64_t base,
+ rtc::ArrayView<const uint64_t> values,
+ uint64_t value_bit_width,
+ bool values_optional);
+ static absl::optional<FixedLengthEncodingParametersV3> ParseDeltaHeader(
+ uint64_t header,
+ uint64_t value_bit_width);
+
+ uint64_t DeltaHeaderAsInt() const;
+
+ // Number of bits necessary to hold the widest(*) of the deltas between the
+ // values in the sequence.
+ // (*) - Widest might not be the largest, if signed deltas are used.
+ uint64_t delta_bit_width() const { return delta_bit_width_; }
+
+ // Whether deltas are signed.
+ bool signed_deltas() const { return signed_deltas_; }
+
+ // Whether the values of the sequence are optional. That is, it may be
+ // that some of them do not have a value (not even a sentinel value indicating
+ // invalidity).
+ bool values_optional() const { return values_optional_; }
+
+ // Whether all values are equal. 64-bit signed deltas are assumed to not
+ // occur, since those could equally well be represented using 64 bit unsigned
+ // deltas.
+ bool values_equal() const {
+ return delta_bit_width() == 64 && signed_deltas();
+ }
+
+ // Number of bits necessary to hold the largest value in the sequence.
+ uint64_t value_bit_width() const { return value_bit_width_; }
+
+ // Masks where only the bits relevant to the deltas/values are turned on.
+ uint64_t delta_mask() const { return delta_mask_; }
+ uint64_t value_mask() const { return value_mask_; }
+
+ private:
+ FixedLengthEncodingParametersV3(uint64_t delta_bit_width,
+ bool signed_deltas,
+ bool values_optional,
+ uint64_t value_bit_width)
+ : delta_bit_width_(delta_bit_width),
+ signed_deltas_(signed_deltas),
+ values_optional_(values_optional),
+ value_bit_width_(value_bit_width),
+ delta_mask_(
+ webrtc_event_logging::MaxUnsignedValueOfBitWidth(delta_bit_width_)),
+ value_mask_(webrtc_event_logging::MaxUnsignedValueOfBitWidth(
+ value_bit_width_)) {}
+
+ uint64_t delta_bit_width_;
+ bool signed_deltas_;
+ bool values_optional_;
+ uint64_t value_bit_width_;
+
+ uint64_t delta_mask_;
+ uint64_t value_mask_;
+};
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_FIXED_LENGTH_ENCODING_PARAMETERS_V3_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h b/third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h
new file mode 100644
index 0000000000..c441dea1a4
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/logged_rtp_rtcp.h
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_LOGGED_RTP_RTCP_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_LOGGED_RTP_RTCP_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtp_headers.h"
+#include "api/units/timestamp.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
+#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
+
+namespace webrtc {
+
+struct LoggedRtpPacket {
+ LoggedRtpPacket(Timestamp timestamp,
+ RTPHeader header,
+ size_t header_length,
+ size_t total_length)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp;
+ // TODO(terelius): This allocates space for 15 CSRCs even if none are used.
+ RTPHeader header;
+ size_t header_length;
+ size_t total_length;
+};
+
+struct LoggedRtpPacketIncoming {
+ LoggedRtpPacketIncoming(Timestamp timestamp,
+ RTPHeader header,
+ size_t header_length,
+ size_t total_length)
+ : 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(); }
+ Timestamp log_time() const { return rtp.timestamp; }
+
+ LoggedRtpPacket rtp;
+};
+
+struct LoggedRtpPacketOutgoing {
+ LoggedRtpPacketOutgoing(Timestamp timestamp,
+ RTPHeader header,
+ size_t header_length,
+ size_t total_length)
+ : 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(); }
+ Timestamp log_time() const { return rtp.timestamp; }
+
+ LoggedRtpPacket rtp;
+};
+
+struct LoggedRtcpPacket {
+ LoggedRtcpPacket(Timestamp timestamp, const std::vector<uint8_t>& packet)
+ : timestamp(timestamp), raw_data(packet) {}
+ LoggedRtcpPacket(Timestamp timestamp, absl::string_view packet)
+ : timestamp(timestamp), raw_data(packet.size()) {
+ memcpy(raw_data.data(), packet.data(), packet.size());
+ }
+
+ LoggedRtcpPacket(const LoggedRtcpPacket& rhs) = default;
+
+ ~LoggedRtcpPacket() = default;
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp;
+ std::vector<uint8_t> raw_data;
+};
+
+struct LoggedRtcpPacketIncoming {
+ LoggedRtcpPacketIncoming(Timestamp timestamp,
+ const std::vector<uint8_t>& packet)
+ : rtcp(timestamp, packet) {}
+ LoggedRtcpPacketIncoming(Timestamp timestamp, absl::string_view packet)
+ : rtcp(timestamp, packet) {}
+
+ int64_t log_time_us() const { return rtcp.timestamp.us(); }
+ int64_t log_time_ms() const { return rtcp.timestamp.ms(); }
+ Timestamp log_time() const { return rtcp.timestamp; }
+
+ LoggedRtcpPacket rtcp;
+};
+
+struct LoggedRtcpPacketOutgoing {
+ LoggedRtcpPacketOutgoing(Timestamp timestamp,
+ const std::vector<uint8_t>& packet)
+ : rtcp(timestamp, packet) {}
+ LoggedRtcpPacketOutgoing(Timestamp timestamp, absl::string_view packet)
+ : rtcp(timestamp, packet) {}
+
+ int64_t log_time_us() const { return rtcp.timestamp.us(); }
+ int64_t log_time_ms() const { return rtcp.timestamp.ms(); }
+ Timestamp log_time() const { return rtcp.timestamp; }
+
+ LoggedRtcpPacket rtcp;
+};
+
+struct LoggedRtcpPacketReceiverReport {
+ LoggedRtcpPacketReceiverReport() = default;
+ LoggedRtcpPacketReceiverReport(Timestamp timestamp,
+ const rtcp::ReceiverReport& rr)
+ : timestamp(timestamp), rr(rr) {}
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtcp::ReceiverReport rr;
+};
+
+struct LoggedRtcpPacketSenderReport {
+ LoggedRtcpPacketSenderReport() = default;
+ LoggedRtcpPacketSenderReport(Timestamp timestamp,
+ const rtcp::SenderReport& sr)
+ : timestamp(timestamp), sr(sr) {}
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtcp::ExtendedReports xr;
+};
+
+struct LoggedRtcpPacketRemb {
+ LoggedRtcpPacketRemb() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtcp::Remb remb;
+};
+
+struct LoggedRtcpPacketNack {
+ LoggedRtcpPacketNack() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtcp::Pli pli;
+};
+
+struct LoggedRtcpPacketTransportFeedback {
+ LoggedRtcpPacketTransportFeedback()
+ : transport_feedback(/*include_timestamps=*/true) {}
+ LoggedRtcpPacketTransportFeedback(
+ Timestamp timestamp,
+ const rtcp::TransportFeedback& 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtcp::TransportFeedback transport_feedback;
+};
+
+struct LoggedRtcpPacketLossNotification {
+ LoggedRtcpPacketLossNotification() = default;
+ LoggedRtcpPacketLossNotification(
+ Timestamp timestamp,
+ const rtcp::LossNotification& 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtcp::Bye bye;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_LOGGED_RTP_RTCP_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.cc
new file mode 100644
index 0000000000..25941eb16b
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+constexpr RtcEvent::Type RtcEventAlrState::kType;
+constexpr RtcEventDefinition<RtcEventAlrState, LoggedAlrStateEvent, bool>
+ RtcEventAlrState::definition_;
+
+RtcEventAlrState::RtcEventAlrState(bool in_alr) : in_alr_(in_alr) {}
+
+RtcEventAlrState::RtcEventAlrState(const RtcEventAlrState& other)
+ : RtcEvent(other.timestamp_us_), in_alr_(other.in_alr_) {}
+
+RtcEventAlrState::~RtcEventAlrState() = default;
+
+std::unique_ptr<RtcEventAlrState> RtcEventAlrState::Copy() const {
+ return absl::WrapUnique<RtcEventAlrState>(new RtcEventAlrState(*this));
+}
+
+RtcEventLogParseStatus RtcEventAlrState::Parse(
+ absl::string_view s,
+ bool batched,
+ std::vector<LoggedAlrStateEvent>& output) {
+ return RtcEventAlrState::definition_.ParseBatch(s, batched, output);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.h
new file mode 100644
index 0000000000..9f595ecd90
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_alr_state.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ALR_STATE_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ALR_STATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_definition.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+
+namespace webrtc {
+
+struct LoggedAlrStateEvent {
+ LoggedAlrStateEvent() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ bool in_alr;
+};
+
+class RtcEventAlrState final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::AlrStateEvent;
+
+ explicit RtcEventAlrState(bool in_alr);
+ ~RtcEventAlrState() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventAlrState> Copy() const;
+
+ bool in_alr() const { return in_alr_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ return RtcEventAlrState::definition_.EncodeBatch(batch);
+ }
+
+ static RtcEventLogParseStatus Parse(absl::string_view s,
+ bool batched,
+ std::vector<LoggedAlrStateEvent>& output);
+
+ private:
+ RtcEventAlrState(const RtcEventAlrState& other);
+
+ const bool in_alr_;
+
+ static constexpr RtcEventDefinition<RtcEventAlrState,
+ LoggedAlrStateEvent,
+ bool>
+ definition_{{"AlrState", RtcEventAlrState::kType},
+ {&RtcEventAlrState::in_alr_,
+ &LoggedAlrStateEvent::in_alr,
+ {"in_alr", /*id=*/1, FieldType::kFixed8, /*width=*/1}}};
+};
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ALR_STATE_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc
new file mode 100644
index 0000000000..5f2d55c357
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RtcEventAudioNetworkAdaptation::RtcEventAudioNetworkAdaptation(
+ std::unique_ptr<AudioEncoderRuntimeConfig> config)
+ : config_(std::move(config)) {
+ RTC_DCHECK(config_);
+}
+
+RtcEventAudioNetworkAdaptation::RtcEventAudioNetworkAdaptation(
+ const RtcEventAudioNetworkAdaptation& other)
+ : RtcEvent(other.timestamp_us_),
+ config_(std::make_unique<AudioEncoderRuntimeConfig>(*other.config_)) {}
+
+RtcEventAudioNetworkAdaptation::~RtcEventAudioNetworkAdaptation() = default;
+
+std::unique_ptr<RtcEventAudioNetworkAdaptation>
+RtcEventAudioNetworkAdaptation::Copy() const {
+ return absl::WrapUnique(new RtcEventAudioNetworkAdaptation(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h
new file mode 100644
index 0000000000..d4cae3abfa
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_NETWORK_ADAPTATION_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_NETWORK_ADAPTATION_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
+
+namespace webrtc {
+
+struct LoggedAudioNetworkAdaptationEvent {
+ LoggedAudioNetworkAdaptationEvent() = default;
+ LoggedAudioNetworkAdaptationEvent(Timestamp timestamp,
+ const AudioEncoderRuntimeConfig& config)
+ : timestamp(timestamp), config(config) {}
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ AudioEncoderRuntimeConfig config;
+};
+
+struct AudioEncoderRuntimeConfig;
+
+class RtcEventAudioNetworkAdaptation final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::AudioNetworkAdaptation;
+
+ explicit RtcEventAudioNetworkAdaptation(
+ std::unique_ptr<AudioEncoderRuntimeConfig> config);
+ ~RtcEventAudioNetworkAdaptation() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventAudioNetworkAdaptation> Copy() const;
+
+ const AudioEncoderRuntimeConfig& config() const { return *config_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedAudioNetworkAdaptationEvent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventAudioNetworkAdaptation(const RtcEventAudioNetworkAdaptation& other);
+
+ const std::unique_ptr<const AudioEncoderRuntimeConfig> config_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_NETWORK_ADAPTATION_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.cc
new file mode 100644
index 0000000000..21a3f9266c
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+constexpr RtcEventDefinition<RtcEventAudioPlayout,
+ LoggedAudioPlayoutEvent,
+ uint32_t>
+ RtcEventAudioPlayout::definition_;
+
+RtcEventAudioPlayout::RtcEventAudioPlayout(uint32_t ssrc) : ssrc_(ssrc) {}
+
+RtcEventAudioPlayout::RtcEventAudioPlayout(const RtcEventAudioPlayout& other)
+ : RtcEvent(other.timestamp_us_), ssrc_(other.ssrc_) {}
+
+std::unique_ptr<RtcEventAudioPlayout> RtcEventAudioPlayout::Copy() const {
+ return absl::WrapUnique<RtcEventAudioPlayout>(
+ new RtcEventAudioPlayout(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.h
new file mode 100644
index 0000000000..196c3ca247
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_playout.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_PLAYOUT_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_PLAYOUT_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_definition.h"
+
+namespace webrtc {
+
+struct LoggedAudioPlayoutEvent {
+ LoggedAudioPlayoutEvent() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ uint32_t ssrc;
+};
+
+class RtcEventAudioPlayout final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::AudioPlayout;
+
+ explicit RtcEventAudioPlayout(uint32_t ssrc);
+ ~RtcEventAudioPlayout() override = default;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventAudioPlayout> Copy() const;
+
+ uint32_t ssrc() const { return ssrc_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ return RtcEventAudioPlayout::definition_.EncodeBatch(batch);
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::map<uint32_t, std::vector<LoggedAudioPlayoutEvent>>& output) {
+ std::vector<LoggedAudioPlayoutEvent> temp_output;
+ auto status = RtcEventAudioPlayout::definition_.ParseBatch(
+ encoded_bytes, batched, temp_output);
+ for (const LoggedAudioPlayoutEvent& event : temp_output) {
+ output[event.ssrc].push_back(event);
+ }
+ return status;
+ }
+
+ private:
+ RtcEventAudioPlayout(const RtcEventAudioPlayout& other);
+
+ const uint32_t ssrc_;
+
+ static constexpr RtcEventDefinition<RtcEventAudioPlayout,
+ LoggedAudioPlayoutEvent,
+ uint32_t>
+ definition_{{"AudioPlayout", RtcEventAudioPlayout::kType},
+ {&RtcEventAudioPlayout::ssrc_,
+ &LoggedAudioPlayoutEvent::ssrc,
+ {"ssrc", /*id=*/1, FieldType::kFixed32, /*width=*/32}}};
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_PLAYOUT_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc
new file mode 100644
index 0000000000..87caaff098
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "logging/rtc_event_log/rtc_stream_config.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RtcEventAudioReceiveStreamConfig::RtcEventAudioReceiveStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config)
+ : config_(std::move(config)) {
+ RTC_DCHECK(config_);
+}
+
+RtcEventAudioReceiveStreamConfig::RtcEventAudioReceiveStreamConfig(
+ const RtcEventAudioReceiveStreamConfig& other)
+ : RtcEvent(other.timestamp_us_),
+ config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
+
+RtcEventAudioReceiveStreamConfig::~RtcEventAudioReceiveStreamConfig() = default;
+
+std::unique_ptr<RtcEventAudioReceiveStreamConfig>
+RtcEventAudioReceiveStreamConfig::Copy() const {
+ return absl::WrapUnique<RtcEventAudioReceiveStreamConfig>(
+ new RtcEventAudioReceiveStreamConfig(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h
new file mode 100644
index 0000000000..9863e235af
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_RECEIVE_STREAM_CONFIG_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_RECEIVE_STREAM_CONFIG_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/rtc_stream_config.h"
+
+namespace webrtc {
+
+struct LoggedAudioRecvConfig {
+ LoggedAudioRecvConfig() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtclog::StreamConfig config;
+};
+
+class RtcEventAudioReceiveStreamConfig final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::AudioReceiveStreamConfig;
+
+ explicit RtcEventAudioReceiveStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config);
+ ~RtcEventAudioReceiveStreamConfig() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return true; }
+
+ std::unique_ptr<RtcEventAudioReceiveStreamConfig> Copy() const;
+
+ const rtclog::StreamConfig& config() const { return *config_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedAudioRecvConfig>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventAudioReceiveStreamConfig(
+ const RtcEventAudioReceiveStreamConfig& other);
+
+ const std::unique_ptr<const rtclog::StreamConfig> config_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_RECEIVE_STREAM_CONFIG_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc
new file mode 100644
index 0000000000..681ae11e63
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "logging/rtc_event_log/rtc_stream_config.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RtcEventAudioSendStreamConfig::RtcEventAudioSendStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config)
+ : config_(std::move(config)) {
+ RTC_DCHECK(config_);
+}
+
+RtcEventAudioSendStreamConfig::RtcEventAudioSendStreamConfig(
+ const RtcEventAudioSendStreamConfig& other)
+ : RtcEvent(other.timestamp_us_),
+ config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
+
+RtcEventAudioSendStreamConfig::~RtcEventAudioSendStreamConfig() = default;
+
+std::unique_ptr<RtcEventAudioSendStreamConfig>
+RtcEventAudioSendStreamConfig::Copy() const {
+ return absl::WrapUnique<RtcEventAudioSendStreamConfig>(
+ new RtcEventAudioSendStreamConfig(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h
new file mode 100644
index 0000000000..550723bcf0
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_SEND_STREAM_CONFIG_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_SEND_STREAM_CONFIG_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/rtc_stream_config.h"
+
+namespace webrtc {
+
+struct LoggedAudioSendConfig {
+ LoggedAudioSendConfig() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtclog::StreamConfig config;
+};
+
+class RtcEventAudioSendStreamConfig final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::AudioSendStreamConfig;
+
+ explicit RtcEventAudioSendStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config);
+ ~RtcEventAudioSendStreamConfig() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return true; }
+
+ std::unique_ptr<RtcEventAudioSendStreamConfig> Copy() const;
+
+ const rtclog::StreamConfig& config() const { return *config_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedAudioSendConfig>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventAudioSendStreamConfig(const RtcEventAudioSendStreamConfig& other);
+
+ const std::unique_ptr<const rtclog::StreamConfig> config_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_SEND_STREAM_CONFIG_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.cc
new file mode 100644
index 0000000000..49b9effa9e
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_begin_log.h"
+
+#include "absl/strings/string_view.h"
+
+namespace webrtc {
+constexpr RtcEvent::Type RtcEventBeginLog::kType;
+constexpr EventParameters RtcEventBeginLog::event_params_;
+constexpr FieldParameters RtcEventBeginLog::utc_start_time_params_;
+
+RtcEventBeginLog::RtcEventBeginLog(Timestamp timestamp,
+ Timestamp utc_start_time)
+ : RtcEvent(timestamp.us()), utc_start_time_ms_(utc_start_time.ms()) {}
+
+RtcEventBeginLog::RtcEventBeginLog(const RtcEventBeginLog& other)
+ : RtcEvent(other.timestamp_us_) {}
+
+RtcEventBeginLog::~RtcEventBeginLog() = default;
+
+std::string RtcEventBeginLog::Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ EventEncoder encoder(event_params_, batch);
+
+ encoder.EncodeField(
+ utc_start_time_params_,
+ ExtractRtcEventMember(batch, &RtcEventBeginLog::utc_start_time_ms_));
+
+ return encoder.AsString();
+}
+
+RtcEventLogParseStatus RtcEventBeginLog::Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedStartEvent>& output) {
+ EventParser parser;
+ auto status = parser.Initialize(encoded_bytes, batched);
+ if (!status.ok())
+ return status;
+
+ rtc::ArrayView<LoggedStartEvent> output_batch =
+ ExtendLoggedBatch(output, parser.NumEventsInBatch());
+
+ constexpr FieldParameters timestamp_params{
+ "timestamp_ms", FieldParameters::kTimestampField, FieldType::kVarInt, 64};
+ RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> result =
+ parser.ParseNumericField(timestamp_params);
+ if (!result.ok())
+ return result.status();
+ status = PopulateRtcEventTimestamp(
+ result.value(), &LoggedStartEvent::timestamp, output_batch);
+ if (!status.ok())
+ return status;
+
+ result = parser.ParseNumericField(utc_start_time_params_);
+ if (!result.ok())
+ return result.status();
+ status = PopulateRtcEventTimestamp(
+ result.value(), &LoggedStartEvent::utc_start_time, output_batch);
+ if (!status.ok())
+ return status;
+
+ return RtcEventLogParseStatus::Success();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.h
new file mode 100644
index 0000000000..f3b74c117e
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_begin_log.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BEGIN_LOG_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BEGIN_LOG_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+
+namespace webrtc {
+
+struct LoggedStartEvent {
+ LoggedStartEvent() = default;
+
+ explicit LoggedStartEvent(Timestamp timestamp)
+ : LoggedStartEvent(timestamp, timestamp) {}
+
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp utc_time() const { return utc_start_time; }
+
+ Timestamp timestamp = Timestamp::PlusInfinity();
+ Timestamp utc_start_time = Timestamp::PlusInfinity();
+};
+
+class RtcEventBeginLog final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::BeginV3Log;
+
+ RtcEventBeginLog(Timestamp timestamp, Timestamp utc_start_time);
+ ~RtcEventBeginLog() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch);
+
+ static RtcEventLogParseStatus Parse(absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedStartEvent>& output);
+
+ private:
+ RtcEventBeginLog(const RtcEventBeginLog& other);
+
+ int64_t utc_start_time_ms_;
+
+ static constexpr EventParameters event_params_{"BeginLog",
+ RtcEventBeginLog::kType};
+ static constexpr FieldParameters utc_start_time_params_{
+ "utc_start_time_ms", /*id=*/1, FieldType::kVarInt, /*width=*/64};
+};
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BEGIN_LOG_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc
new file mode 100644
index 0000000000..0e98b2ff11
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
+
+#include "absl/memory/memory.h"
+#include "api/network_state_predictor.h"
+
+namespace webrtc {
+
+constexpr RtcEventDefinition<RtcEventBweUpdateDelayBased,
+ LoggedBweDelayBasedUpdate,
+ int32_t,
+ BandwidthUsage>
+ RtcEventBweUpdateDelayBased::definition_;
+
+RtcEventBweUpdateDelayBased::RtcEventBweUpdateDelayBased(
+ int32_t bitrate_bps,
+ BandwidthUsage detector_state)
+ : bitrate_bps_(bitrate_bps), detector_state_(detector_state) {}
+
+RtcEventBweUpdateDelayBased::RtcEventBweUpdateDelayBased(
+ const RtcEventBweUpdateDelayBased& other)
+ : RtcEvent(other.timestamp_us_),
+ bitrate_bps_(other.bitrate_bps_),
+ detector_state_(other.detector_state_) {}
+
+RtcEventBweUpdateDelayBased::~RtcEventBweUpdateDelayBased() = default;
+
+std::unique_ptr<RtcEventBweUpdateDelayBased> RtcEventBweUpdateDelayBased::Copy()
+ const {
+ return absl::WrapUnique<RtcEventBweUpdateDelayBased>(
+ new RtcEventBweUpdateDelayBased(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h
new file mode 100644
index 0000000000..796f119388
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_DELAY_BASED_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_DELAY_BASED_H_
+
+#include <stdint.h>
+
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/network_state_predictor.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_definition.h"
+
+namespace webrtc {
+
+// Separate the event log encoding from the enum values.
+// As long as the enum values are the same as the encodings,
+// the two conversion functions can be compiled to (roughly)
+// a range check each.
+template <>
+class RtcEventLogEnum<BandwidthUsage> {
+ static constexpr uint64_t kBwNormal = 0;
+ static constexpr uint64_t kBwUnderusing = 1;
+ static constexpr uint64_t kBwOverusing = 2;
+
+ public:
+ static uint64_t Encode(BandwidthUsage x) {
+ switch (x) {
+ case BandwidthUsage::kBwNormal:
+ return kBwNormal;
+ case BandwidthUsage::kBwUnderusing:
+ return kBwUnderusing;
+ case BandwidthUsage::kBwOverusing:
+ return kBwOverusing;
+ case BandwidthUsage::kLast:
+ RTC_DCHECK_NOTREACHED();
+ }
+ RTC_DCHECK_NOTREACHED();
+ return std::numeric_limits<uint64_t>::max();
+ }
+ static RtcEventLogParseStatusOr<BandwidthUsage> Decode(uint64_t x) {
+ switch (x) {
+ case kBwNormal:
+ return BandwidthUsage::kBwNormal;
+ case kBwUnderusing:
+ return BandwidthUsage::kBwUnderusing;
+ case kBwOverusing:
+ return BandwidthUsage::kBwOverusing;
+ }
+ return RtcEventLogParseStatus::Error("Failed to decode BandwidthUsage enum",
+ __FILE__, __LINE__);
+ }
+};
+
+struct LoggedBweDelayBasedUpdate {
+ LoggedBweDelayBasedUpdate() = default;
+ LoggedBweDelayBasedUpdate(Timestamp timestamp,
+ int32_t bitrate_bps,
+ BandwidthUsage detector_state)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int32_t bitrate_bps;
+ BandwidthUsage detector_state;
+};
+
+class RtcEventBweUpdateDelayBased final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::BweUpdateDelayBased;
+
+ RtcEventBweUpdateDelayBased(int32_t bitrate_bps,
+ BandwidthUsage detector_state);
+ ~RtcEventBweUpdateDelayBased() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventBweUpdateDelayBased> Copy() const;
+
+ int32_t bitrate_bps() const { return bitrate_bps_; }
+ BandwidthUsage detector_state() const { return detector_state_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ return RtcEventBweUpdateDelayBased::definition_.EncodeBatch(batch);
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedBweDelayBasedUpdate>& output) {
+ return RtcEventBweUpdateDelayBased::definition_.ParseBatch(encoded_bytes,
+ batched, output);
+ }
+
+ private:
+ RtcEventBweUpdateDelayBased(const RtcEventBweUpdateDelayBased& other);
+
+ const int32_t bitrate_bps_;
+ const BandwidthUsage detector_state_;
+
+ static constexpr RtcEventDefinition<RtcEventBweUpdateDelayBased,
+ LoggedBweDelayBasedUpdate,
+ int32_t,
+ BandwidthUsage>
+ definition_{
+ {"BweDelayBased", RtcEventBweUpdateDelayBased::kType},
+ {&RtcEventBweUpdateDelayBased::bitrate_bps_,
+ &LoggedBweDelayBasedUpdate::bitrate_bps,
+ {"bitrate_bps", /*id=*/1, FieldType::kVarInt, /*width=*/32}},
+ {&RtcEventBweUpdateDelayBased::detector_state_,
+ &LoggedBweDelayBasedUpdate::detector_state,
+ {"detector_state", /*id=*/2, FieldType::kVarInt, /*width=*/64}}};
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_DELAY_BASED_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc
new file mode 100644
index 0000000000..44524ab033
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventBweUpdateLossBased::RtcEventBweUpdateLossBased(int32_t bitrate_bps,
+ uint8_t fraction_loss,
+ int32_t total_packets)
+ : bitrate_bps_(bitrate_bps),
+ fraction_loss_(fraction_loss),
+ total_packets_(total_packets) {}
+
+RtcEventBweUpdateLossBased::RtcEventBweUpdateLossBased(
+ const RtcEventBweUpdateLossBased& other)
+ : RtcEvent(other.timestamp_us_),
+ bitrate_bps_(other.bitrate_bps_),
+ fraction_loss_(other.fraction_loss_),
+ total_packets_(other.total_packets_) {}
+
+RtcEventBweUpdateLossBased::~RtcEventBweUpdateLossBased() = default;
+
+std::unique_ptr<RtcEventBweUpdateLossBased> RtcEventBweUpdateLossBased::Copy()
+ const {
+ return absl::WrapUnique<RtcEventBweUpdateLossBased>(
+ new RtcEventBweUpdateLossBased(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h
new file mode 100644
index 0000000000..fd41b316e0
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_LOSS_BASED_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_LOSS_BASED_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedBweLossBasedUpdate {
+ LoggedBweLossBasedUpdate() = default;
+ LoggedBweLossBasedUpdate(Timestamp timestamp,
+ int32_t bitrate_bps,
+ uint8_t fraction_lost,
+ int32_t expected_packets)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int32_t bitrate_bps;
+ uint8_t fraction_lost;
+ int32_t expected_packets;
+};
+
+class RtcEventBweUpdateLossBased final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::BweUpdateLossBased;
+
+ RtcEventBweUpdateLossBased(int32_t bitrate_bps_,
+ uint8_t fraction_loss_,
+ int32_t total_packets_);
+ ~RtcEventBweUpdateLossBased() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventBweUpdateLossBased> Copy() const;
+
+ int32_t bitrate_bps() const { return bitrate_bps_; }
+ uint8_t fraction_loss() const { return fraction_loss_; }
+ int32_t total_packets() const { return total_packets_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedBweLossBasedUpdate>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventBweUpdateLossBased(const RtcEventBweUpdateLossBased& other);
+
+ const int32_t bitrate_bps_;
+ const uint8_t fraction_loss_;
+ const int32_t total_packets_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_LOSS_BASED_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_definition.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_definition.h
new file mode 100644
index 0000000000..8688c5fc7b
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_definition.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+template <typename EventType, typename LoggedType, typename T>
+struct RtcEventFieldDefinition {
+ const T EventType::*event_member;
+ T LoggedType::*logged_member;
+ FieldParameters params;
+};
+
+// Base case
+template <typename EventType, typename LoggedType, typename... Ts>
+class RtcEventDefinitionImpl {
+ public:
+ void EncodeImpl(EventEncoder&, rtc::ArrayView<const RtcEvent*>) const {}
+ RtcEventLogParseStatus ParseImpl(EventParser&,
+ rtc::ArrayView<LoggedType>) const {
+ return RtcEventLogParseStatus::Success();
+ }
+};
+
+// Recursive case
+template <typename EventType, typename LoggedType, typename T, typename... Ts>
+class RtcEventDefinitionImpl<EventType, LoggedType, T, Ts...> {
+ public:
+ constexpr RtcEventDefinitionImpl(
+ RtcEventFieldDefinition<EventType, LoggedType, T> field,
+ RtcEventFieldDefinition<EventType, LoggedType, Ts>... rest)
+ : field_(field), rest_(rest...) {}
+
+ void EncodeImpl(EventEncoder& encoder,
+ rtc::ArrayView<const RtcEvent*> batch) const {
+ auto values = ExtractRtcEventMember(batch, field_.event_member);
+ encoder.EncodeField(field_.params, values);
+ rest_.EncodeImpl(encoder, batch);
+ }
+
+ RtcEventLogParseStatus ParseImpl(
+ EventParser& parser,
+ rtc::ArrayView<LoggedType> output_batch) const {
+ RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> result =
+ parser.ParseNumericField(field_.params);
+ if (!result.ok())
+ return result.status();
+ auto status = PopulateRtcEventMember(result.value(), field_.logged_member,
+ output_batch);
+ if (!status.ok())
+ return status;
+
+ return rest_.ParseImpl(parser, output_batch);
+ }
+
+ private:
+ RtcEventFieldDefinition<EventType, LoggedType, T> field_;
+ RtcEventDefinitionImpl<EventType, LoggedType, Ts...> rest_;
+};
+
+// The RtcEventDefinition sets up a mapping between the fields
+// in an RtcEvent and the corresponding fields in the parsed struct.
+// For example, an RtcFoo class containing two fields; `uint32_t bar`
+// and `bool baz` (a log timestamp is always implicitly added)
+// might have a definition
+// RtcEventDefinition<RtcFoo, LoggedFoo, uint32_t, bool>(
+// {"foo", RtcFoo::Type},
+// {&RtcFoo::bar_, &LoggedFoo::bar, {"bar", 1, FieldType::kVarInt, 32}},
+// {&RtcFoo::baz_, &LoggedFoo::baz, {"baz", 2, FieldType::kFixed8, 1}},
+// );
+// In addition to defining string names to aid debugging,
+// this specifies that
+// * RtcFoo::Type uniquely identifies an RtcFoo in the encoded stream
+// * The `bar` field has ID 1, is encoded as a VarInt
+// (when not delta compressed), and wraps around after 32 bits.
+// * The `baz` field has ID 2, is encoded as an 8-bit field
+// (when not delta compressed), and wraps around after 1 bit.
+// Note that the numerical field and event IDs can't be changed since
+// that would break compatibility with old logs.
+// In most cases (including all cases where wrap around isn't
+// expected), the wrap around should be equal to the bitwidth of
+// the field.
+template <typename EventType, typename LoggedType, typename... Ts>
+class RtcEventDefinition {
+ public:
+ constexpr RtcEventDefinition(
+ EventParameters params,
+ RtcEventFieldDefinition<EventType, LoggedType, Ts>... fields)
+ : params_(params), fields_(fields...) {}
+
+ std::string EncodeBatch(rtc::ArrayView<const RtcEvent*> batch) const {
+ EventEncoder encoder(params_, batch);
+ fields_.EncodeImpl(encoder, batch);
+ return encoder.AsString();
+ }
+
+ RtcEventLogParseStatus ParseBatch(absl::string_view s,
+ bool batched,
+ std::vector<LoggedType>& output) const {
+ EventParser parser;
+ auto status = parser.Initialize(s, batched);
+ if (!status.ok())
+ return status;
+
+ rtc::ArrayView<LoggedType> output_batch =
+ ExtendLoggedBatch(output, parser.NumEventsInBatch());
+
+ constexpr FieldParameters timestamp_params{"timestamp_ms",
+ FieldParameters::kTimestampField,
+ FieldType::kVarInt, 64};
+ RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> result =
+ parser.ParseNumericField(timestamp_params);
+ if (!result.ok())
+ return result.status();
+ status = PopulateRtcEventTimestamp(result.value(), &LoggedType::timestamp,
+ output_batch);
+ if (!status.ok())
+ return status;
+
+ return fields_.ParseImpl(parser, output_batch);
+ }
+
+ private:
+ EventParameters params_;
+ RtcEventDefinitionImpl<EventType, LoggedType, Ts...> fields_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DEFINITION_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.cc
new file mode 100644
index 0000000000..f00342df72
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventDtlsTransportState::RtcEventDtlsTransportState(DtlsTransportState state)
+ : dtls_transport_state_(state) {}
+
+RtcEventDtlsTransportState::RtcEventDtlsTransportState(
+ const RtcEventDtlsTransportState& other)
+ : RtcEvent(other.timestamp_us_),
+ dtls_transport_state_(other.dtls_transport_state_) {}
+
+RtcEventDtlsTransportState::~RtcEventDtlsTransportState() = default;
+
+std::unique_ptr<RtcEventDtlsTransportState> RtcEventDtlsTransportState::Copy()
+ const {
+ return absl::WrapUnique<RtcEventDtlsTransportState>(
+ new RtcEventDtlsTransportState(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
new file mode 100644
index 0000000000..b9af213256
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_transport_state.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_TRANSPORT_STATE_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_TRANSPORT_STATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/dtls_transport_interface.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedDtlsTransportState {
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ DtlsTransportState dtls_transport_state;
+};
+
+class RtcEventDtlsTransportState : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::DtlsTransportState;
+
+ explicit RtcEventDtlsTransportState(DtlsTransportState state);
+ ~RtcEventDtlsTransportState() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventDtlsTransportState> Copy() const;
+
+ DtlsTransportState dtls_transport_state() const {
+ return dtls_transport_state_;
+ }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedDtlsTransportState>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventDtlsTransportState(const RtcEventDtlsTransportState& other);
+
+ const DtlsTransportState dtls_transport_state_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_TRANSPORT_STATE_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.cc
new file mode 100644
index 0000000000..d4cb093ce6
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventDtlsWritableState::RtcEventDtlsWritableState(bool writable)
+ : writable_(writable) {}
+
+RtcEventDtlsWritableState::RtcEventDtlsWritableState(
+ const RtcEventDtlsWritableState& other)
+ : RtcEvent(other.timestamp_us_), writable_(other.writable_) {}
+
+RtcEventDtlsWritableState::~RtcEventDtlsWritableState() = default;
+
+std::unique_ptr<RtcEventDtlsWritableState> RtcEventDtlsWritableState::Copy()
+ const {
+ return absl::WrapUnique<RtcEventDtlsWritableState>(
+ new RtcEventDtlsWritableState(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h
new file mode 100644
index 0000000000..c820f184d7
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_dtls_writable_state.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_WRITABLE_STATE_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_WRITABLE_STATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedDtlsWritableState {
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ bool writable;
+};
+
+class RtcEventDtlsWritableState : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::DtlsWritableState;
+
+ explicit RtcEventDtlsWritableState(bool writable);
+ ~RtcEventDtlsWritableState() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventDtlsWritableState> Copy() const;
+
+ bool writable() const { return writable_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedDtlsWritableState>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventDtlsWritableState(const RtcEventDtlsWritableState& other);
+
+ const bool writable_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_DTLS_WRITABLE_STATE_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.cc
new file mode 100644
index 0000000000..52abf9e842
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.cc
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_end_log.h"
+
+#include "absl/strings/string_view.h"
+
+namespace webrtc {
+constexpr RtcEvent::Type RtcEventEndLog::kType;
+constexpr EventParameters RtcEventEndLog::event_params_;
+
+RtcEventEndLog::RtcEventEndLog(Timestamp timestamp)
+ : RtcEvent(timestamp.us()) {}
+
+RtcEventEndLog::RtcEventEndLog(const RtcEventEndLog& other)
+ : RtcEvent(other.timestamp_us_) {}
+
+RtcEventEndLog::~RtcEventEndLog() = default;
+
+std::string RtcEventEndLog::Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ EventEncoder encoder(event_params_, batch);
+ return encoder.AsString();
+}
+
+RtcEventLogParseStatus RtcEventEndLog::Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedStopEvent>& output) {
+ EventParser parser;
+ auto status = parser.Initialize(encoded_bytes, batched);
+ if (!status.ok())
+ return status;
+
+ rtc::ArrayView<LoggedStopEvent> output_batch =
+ ExtendLoggedBatch(output, parser.NumEventsInBatch());
+
+ constexpr FieldParameters timestamp_params{
+ "timestamp_ms", FieldParameters::kTimestampField, FieldType::kVarInt, 64};
+ RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> result =
+ parser.ParseNumericField(timestamp_params);
+ if (!result.ok())
+ return result.status();
+ status = PopulateRtcEventTimestamp(result.value(),
+ &LoggedStopEvent::timestamp, output_batch);
+ if (!status.ok())
+ return status;
+
+ return RtcEventLogParseStatus::Success();
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.h
new file mode 100644
index 0000000000..79648bdb8d
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_end_log.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_END_LOG_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_END_LOG_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+
+namespace webrtc {
+
+struct LoggedStopEvent {
+ LoggedStopEvent() = default;
+
+ explicit LoggedStopEvent(Timestamp timestamp) : timestamp(timestamp) {}
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::PlusInfinity();
+};
+
+class RtcEventEndLog final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::EndV3Log;
+
+ explicit RtcEventEndLog(Timestamp timestamp);
+ ~RtcEventEndLog() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch);
+
+ static RtcEventLogParseStatus Parse(absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedStopEvent>& output);
+
+ private:
+ RtcEventEndLog(const RtcEventEndLog& other);
+
+ static constexpr EventParameters event_params_{"EndLog",
+ RtcEventEndLog::kType};
+};
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_END_LOG_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.cc
new file mode 100644
index 0000000000..68188ce856
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.cc
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <utility>
+
+#include "logging/rtc_event_log/encoder/bit_writer.h"
+#include "logging/rtc_event_log/encoder/var_int.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/logging.h"
+
+using webrtc_event_logging::UnsignedDelta;
+
+namespace {
+
+std::string SerializeLittleEndian(uint64_t value, uint8_t bytes) {
+ RTC_DCHECK_LE(bytes, sizeof(uint64_t));
+ RTC_DCHECK_GE(bytes, 1);
+ if (bytes < sizeof(uint64_t)) {
+ // Note that shifting a 64-bit value by 64 (or more) bits is undefined.
+ RTC_DCHECK_EQ(value >> (8 * bytes), 0);
+ }
+ std::string output(bytes, 0);
+ // Getting a non-const pointer to the representation. See e.g.
+ // https://en.cppreference.com/w/cpp/string/basic_string:
+ // "The elements of a basic_string are stored contiguously,
+ // that is, [...] a pointer to s[0] can be passed to functions
+ // that expect a pointer to the first element of a null-terminated
+ // CharT[] array."
+ uint8_t* p = reinterpret_cast<uint8_t*>(&output[0]);
+#ifdef WEBRTC_ARCH_LITTLE_ENDIAN
+ memcpy(p, &value, bytes);
+#else
+ while (bytes > 0) {
+ *p = static_cast<uint8_t>(value & 0xFF);
+ value >>= 8;
+ ++p;
+ --bytes;
+ }
+#endif // WEBRTC_ARCH_LITTLE_ENDIAN
+ return output;
+}
+
+} // namespace
+
+namespace webrtc {
+
+std::string EncodeOptionalValuePositions(std::vector<bool> positions) {
+ BitWriter writer((positions.size() + 7) / 8);
+ for (bool position : positions) {
+ writer.WriteBits(position ? 1u : 0u, 1);
+ }
+ return writer.GetString();
+}
+
+std::string EncodeSingleValue(uint64_t value, FieldType field_type) {
+ switch (field_type) {
+ case FieldType::kFixed8:
+ return SerializeLittleEndian(value, /*bytes=*/1);
+ case FieldType::kFixed32:
+ return SerializeLittleEndian(value, /*bytes=*/4);
+ case FieldType::kFixed64:
+ return SerializeLittleEndian(value, /*bytes=*/8);
+ case FieldType::kVarInt:
+ return EncodeVarInt(value);
+ case FieldType::kString:
+ RTC_DCHECK_NOTREACHED();
+ return std::string();
+ }
+ RTC_DCHECK_NOTREACHED();
+ return std::string();
+}
+
+absl::optional<FieldType> ConvertFieldType(uint64_t value) {
+ switch (value) {
+ case static_cast<uint64_t>(FieldType::kFixed8):
+ return FieldType::kFixed8;
+ case static_cast<uint64_t>(FieldType::kFixed32):
+ return FieldType::kFixed32;
+ case static_cast<uint64_t>(FieldType::kFixed64):
+ return FieldType::kFixed64;
+ case static_cast<uint64_t>(FieldType::kVarInt):
+ return FieldType::kVarInt;
+ case static_cast<uint64_t>(FieldType::kString):
+ return FieldType::kString;
+ default:
+ return absl::nullopt;
+ }
+}
+
+std::string EncodeDeltasV3(FixedLengthEncodingParametersV3 params,
+ uint64_t base,
+ rtc::ArrayView<const uint64_t> values) {
+ size_t outputbound = (values.size() * params.delta_bit_width() + 7) / 8;
+ BitWriter writer(outputbound);
+
+ uint64_t previous = base;
+ for (uint64_t value : values) {
+ if (params.signed_deltas()) {
+ uint64_t positive_delta =
+ UnsignedDelta(previous, value, params.value_mask());
+ uint64_t negative_delta =
+ UnsignedDelta(value, previous, params.value_mask());
+ uint64_t delta;
+ if (positive_delta <= negative_delta) {
+ delta = positive_delta;
+ } else {
+ // Compute the two's complement representation of a negative
+ // delta, in a field width params_.delta_mask().
+ RTC_DCHECK_GE(params.delta_mask(), negative_delta);
+ RTC_DCHECK_LT(params.delta_mask() - negative_delta,
+ params.delta_mask());
+ delta = params.delta_mask() - negative_delta + 1;
+ RTC_DCHECK_LE(delta, params.delta_mask());
+ }
+ writer.WriteBits(delta, params.delta_bit_width());
+ } else {
+ uint64_t delta = UnsignedDelta(previous, value, params.value_mask());
+ writer.WriteBits(delta, params.delta_bit_width());
+ }
+ previous = value;
+ }
+
+ return writer.GetString();
+}
+
+EventEncoder::EventEncoder(EventParameters params,
+ rtc::ArrayView<const RtcEvent*> batch) {
+ batch_size_ = batch.size();
+ if (!batch.empty()) {
+ // Encode event type.
+ uint32_t batched = batch.size() > 1 ? 1 : 0;
+ event_tag_ = (static_cast<uint32_t>(params.id) << 1) + batched;
+
+ // Event tag and number of encoded bytes will be filled in when the
+ // encoding is finalized in AsString().
+
+ // Encode number of events in batch
+ if (batched) {
+ encoded_fields_.push_back(EncodeVarInt(batch.size()));
+ }
+
+ // Encode timestamp
+ std::vector<uint64_t> timestamps;
+ timestamps.reserve(batch.size());
+ for (const RtcEvent* event : batch) {
+ timestamps.push_back(EncodeAsUnsigned(event->timestamp_ms()));
+ }
+ constexpr FieldParameters timestamp_params{"timestamp_ms",
+ FieldParameters::kTimestampField,
+ FieldType::kVarInt, 64};
+ EncodeField(timestamp_params, timestamps);
+ }
+}
+
+void EventEncoder::EncodeField(const FieldParameters& params,
+ const ValuesWithPositions& values) {
+ return EncodeField(params, values.values, &values.position_mask);
+}
+
+void EventEncoder::EncodeField(const FieldParameters& params,
+ const std::vector<uint64_t>& values,
+ const std::vector<bool>* positions) {
+ if (positions) {
+ RTC_DCHECK_EQ(positions->size(), batch_size_);
+ RTC_DCHECK_LE(values.size(), batch_size_);
+ } else {
+ RTC_DCHECK_EQ(values.size(), batch_size_);
+ }
+
+ if (values.size() == 0) {
+ // If all values for a particular field is empty/nullopt,
+ // then we completely skip the field even if the the batch is non-empty.
+ return;
+ }
+
+ // We know that each event starts with the varint encoded timestamp,
+ // so we omit that field tag (field id + field type). In all other
+ // cases, we write the field tag.
+ if (params.field_id != FieldParameters::kTimestampField) {
+ RTC_DCHECK_LE(params.field_id, std::numeric_limits<uint64_t>::max() >> 3);
+ uint64_t field_tag = params.field_id << 3;
+ field_tag += static_cast<uint64_t>(params.field_type);
+ encoded_fields_.push_back(EncodeVarInt(field_tag));
+ }
+
+ RTC_CHECK_GE(values.size(), 1);
+ if (batch_size_ == 1) {
+ encoded_fields_.push_back(EncodeSingleValue(values[0], params.field_type));
+ return;
+ }
+
+ const bool values_optional = values.size() != batch_size_;
+
+ // Compute delta parameters
+ rtc::ArrayView<const uint64_t> all_values(values);
+ uint64_t base = values[0];
+ rtc::ArrayView<const uint64_t> remaining_values(all_values.subview(1));
+
+ FixedLengthEncodingParametersV3 delta_params =
+ FixedLengthEncodingParametersV3::CalculateParameters(
+ base, remaining_values, params.value_width, values_optional);
+
+ encoded_fields_.push_back(EncodeVarInt(delta_params.DeltaHeaderAsInt()));
+
+ if (values_optional) {
+ RTC_CHECK(positions);
+ encoded_fields_.push_back(EncodeOptionalValuePositions(*positions));
+ }
+ // Base element, encoded as uint8, uint32, uint64 or varint
+ encoded_fields_.push_back(EncodeSingleValue(base, params.field_type));
+
+ // If all (existing) values are equal to the base, then we can skip
+ // writing the all-zero deltas, and instead infer those from the delta
+ // header.
+ if (!delta_params.values_equal()) {
+ encoded_fields_.push_back(
+ EncodeDeltasV3(delta_params, base, remaining_values));
+ }
+}
+
+void EventEncoder::EncodeField(const FieldParameters& params,
+ const std::vector<absl::string_view>& values) {
+ RTC_DCHECK_EQ(values.size(), batch_size_);
+
+ if (values.size() == 0) {
+ // If all values for a particular field is empty/nullopt,
+ // then we completely skip the field even if the the batch is non-empty.
+ return;
+ }
+
+ // Write the field tag.
+ RTC_CHECK_NE(params.field_id, FieldParameters::kTimestampField);
+ RTC_DCHECK_LE(params.field_id, std::numeric_limits<uint64_t>::max() >> 3);
+ RTC_DCHECK_EQ(params.field_type, FieldType::kString);
+ uint64_t field_tag = params.field_id << 3;
+ field_tag += static_cast<uint64_t>(params.field_type);
+ encoded_fields_.push_back(EncodeVarInt(field_tag));
+
+ if (values.size() > 1) {
+ // If multiple values in the batch, write the encoding
+ // parameters. (Values >0 reserved for future use.)
+ uint64_t encoding_params = 0;
+ encoded_fields_.push_back(EncodeVarInt(encoding_params));
+ }
+
+ // Write the strings as (length, data) pairs.
+ for (absl::string_view s : values) {
+ encoded_fields_.push_back(EncodeVarInt(s.size()));
+ encoded_fields_.push_back(std::string(s));
+ }
+}
+
+std::string EventEncoder::AsString() {
+ std::string encoded_event;
+
+ if (batch_size_ == 0) {
+ RTC_DCHECK_EQ(encoded_fields_.size(), 0);
+ return encoded_event;
+ }
+
+ // Compute size of encoded fields.
+ size_t total_fields_size = 0;
+ for (const std::string& s : encoded_fields_) {
+ total_fields_size += s.size();
+ }
+
+ constexpr size_t kExpectedMaxEventTagBytes = 4;
+ constexpr size_t kExpectedMaxSizeEncodingBytes = 4;
+ encoded_event.reserve(kExpectedMaxEventTagBytes +
+ kExpectedMaxSizeEncodingBytes + total_fields_size);
+
+ // Encode event tag (event id and whether batch or single event).
+ encoded_event.append(EncodeVarInt(event_tag_));
+
+ // Encode size of the remaining fields.
+ encoded_event.append(EncodeVarInt(total_fields_size));
+
+ // Append encoded fields.
+ for (const std::string& s : encoded_fields_) {
+ encoded_event.append(s);
+ }
+
+ return encoded_event;
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.h
new file mode 100644
index 0000000000..33b77b80f5
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
+#include "logging/rtc_event_log/events/fixed_length_encoding_parameters_v3.h"
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc {
+
+// To maintain backwards compatibility with past (or future) logs,
+// the constants in this enum must not be changed.
+// New field types with numerical IDs 5-7 can be added, but old
+// parsers will fail to parse events containing the new fields.
+enum class FieldType : uint8_t {
+ kFixed8 = 0,
+ kFixed32 = 1,
+ kFixed64 = 2,
+ kVarInt = 3,
+ kString = 4,
+};
+
+// EventParameters map an event name to a numerical ID.
+struct EventParameters {
+ // The name is primarily used for debugging purposes.
+ const char* const name;
+ //
+ const RtcEvent::Type id;
+};
+
+// FieldParameters define the encoding for a field.
+struct FieldParameters {
+ // The name is primarily used for debugging purposes.
+ const char* const name;
+ // Numerical ID for the field. Must be strictly greater than 0,
+ // and unique within each event type.
+ const uint64_t field_id;
+ // Encoding type for the base (i.e. non-delta) field in a batch.
+ const FieldType field_type;
+ // Number of bits after which wrap-around occurs. In most cases,
+ // this should be the number of bits in the field data type, i.e.
+ // 8 for an uint8_t, 32 for a int32_t and so on. However, `value_width`
+ // can be used to achieve a more efficient encoding if it is known
+ // that the field uses a smaller number of bits. For example, a
+ // 15-bit counter could set `value_width` to 15 even if the data is
+ // actually stored in a uint32_t.
+ const uint64_t value_width;
+ // Field ID 0 is reserved for timestamps.
+ static constexpr uint64_t kTimestampField = 0;
+};
+
+// The EventEncoder is used to encode a batch of events.
+class EventEncoder {
+ public:
+ EventEncoder(EventParameters params, rtc::ArrayView<const RtcEvent*> batch);
+
+ void EncodeField(const FieldParameters& params,
+ const std::vector<uint64_t>& values,
+ const std::vector<bool>* positions = nullptr);
+
+ void EncodeField(const FieldParameters& params,
+ const ValuesWithPositions& values);
+
+ void EncodeField(const FieldParameters& params,
+ const std::vector<absl::string_view>& values);
+
+ std::string AsString();
+
+ private:
+ size_t batch_size_;
+ uint32_t event_tag_;
+ std::vector<std::string> encoded_fields_;
+};
+
+std::string EncodeSingleValue(uint64_t value, FieldType field_type);
+std::string EncodeDeltasV3(FixedLengthEncodingParametersV3 params,
+ uint64_t base,
+ rtc::ArrayView<const uint64_t> values);
+
+// Given a batch of RtcEvents and a member pointer, extract that
+// member from each event in the batch. Signed integer members are
+// encoded as unsigned, and the bitsize increased so the result can
+// represented as a std::vector<uint64_t>.
+// This is intended to be used in conjuction with
+// EventEncoder::EncodeField to encode a batch of events as follows:
+// auto values = ExtractRtcEventMember(batch, RtcEventFoo::timestamp_ms);
+// encoder.EncodeField(timestamp_params, values)
+template <typename T,
+ typename E,
+ std::enable_if_t<std::is_integral<T>::value, bool> = true>
+std::vector<uint64_t> ExtractRtcEventMember(
+ rtc::ArrayView<const RtcEvent*> batch,
+ const T E::*member) {
+ std::vector<uint64_t> values;
+ values.reserve(batch.size());
+ for (const RtcEvent* event : batch) {
+ RTC_CHECK_EQ(event->GetType(), E::kType);
+ T value = static_cast<const E*>(event)->*member;
+ values.push_back(EncodeAsUnsigned(value));
+ }
+ return values;
+}
+
+// Extract an optional field from a batch of RtcEvents.
+// The function returns a vector of positions in addition to the vector of
+// values. The vector `positions` has the same length as the batch where
+// `positions[i] == true` iff the batch[i]->member has a value.
+// The values vector only contains the values that exists, so it
+// may be shorter than the batch.
+template <typename T,
+ typename E,
+ std::enable_if_t<std::is_integral<T>::value, bool> = true>
+ValuesWithPositions ExtractRtcEventMember(rtc::ArrayView<const RtcEvent*> batch,
+ const absl::optional<T> E::*member) {
+ ValuesWithPositions result;
+ result.position_mask.reserve(batch.size());
+ result.values.reserve(batch.size());
+ for (const RtcEvent* event : batch) {
+ RTC_CHECK_EQ(event->GetType(), E::kType);
+ absl::optional<T> field = static_cast<const E*>(event)->*member;
+ result.position_mask.push_back(field.has_value());
+ if (field.has_value()) {
+ result.values.push_back(EncodeAsUnsigned(field.value()));
+ }
+ }
+ return result;
+}
+
+// Extract an enum field from a batch of RtcEvents.
+// Requires specializing RtcEventLogEnum<T> for the enum type T.
+template <typename T,
+ typename E,
+ std::enable_if_t<std::is_enum<T>::value, bool> = true>
+std::vector<uint64_t> ExtractRtcEventMember(
+ rtc::ArrayView<const RtcEvent*> batch,
+ const T E::*member) {
+ std::vector<uint64_t> values;
+ values.reserve(batch.size());
+ for (const RtcEvent* event : batch) {
+ RTC_CHECK_EQ(event->GetType(), E::kType);
+ T value = static_cast<const E*>(event)->*member;
+ values.push_back(RtcEventLogEnum<T>::Encode(value));
+ }
+ return values;
+}
+
+// Extract a string field from a batch of RtcEvents.
+template <typename E>
+std::vector<absl::string_view> ExtractRtcEventMember(
+ rtc::ArrayView<const RtcEvent*> batch,
+ const std::string E::*member) {
+ std::vector<absl::string_view> values;
+ values.reserve(batch.size());
+ for (const RtcEvent* event : batch) {
+ RTC_CHECK_EQ(event->GetType(), E::kType);
+ absl::string_view str = static_cast<const E*>(event)->*member;
+ values.push_back(str);
+ }
+ return values;
+}
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc
new file mode 100644
index 0000000000..a9b0c08307
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.cc
@@ -0,0 +1,398 @@
+
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "logging/rtc_event_log/encoder/var_int.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+#include "rtc_base/bitstream_reader.h"
+#include "rtc_base/checks.h"
+
+namespace {
+absl::optional<webrtc::FieldType> ConvertFieldType(uint64_t value) {
+ switch (value) {
+ case static_cast<uint64_t>(webrtc::FieldType::kFixed8):
+ return webrtc::FieldType::kFixed8;
+ case static_cast<uint64_t>(webrtc::FieldType::kFixed32):
+ return webrtc::FieldType::kFixed32;
+ case static_cast<uint64_t>(webrtc::FieldType::kFixed64):
+ return webrtc::FieldType::kFixed64;
+ case static_cast<uint64_t>(webrtc::FieldType::kVarInt):
+ return webrtc::FieldType::kVarInt;
+ case static_cast<uint64_t>(webrtc::FieldType::kString):
+ return webrtc::FieldType::kString;
+ default:
+ return absl::nullopt;
+ }
+}
+} // namespace
+
+namespace webrtc {
+
+uint64_t EventParser::ReadLittleEndian(uint8_t bytes) {
+ RTC_DCHECK_LE(bytes, sizeof(uint64_t));
+ RTC_DCHECK_GE(bytes, 1);
+
+ uint64_t value = 0;
+
+ if (bytes > pending_data_.length()) {
+ SetError();
+ return value;
+ }
+
+ const uint8_t* p = reinterpret_cast<const uint8_t*>(pending_data_.data());
+ unsigned int shift = 0;
+ uint8_t remaining = bytes;
+ while (remaining > 0) {
+ value += (static_cast<uint64_t>(*p) << shift);
+ shift += 8;
+ ++p;
+ --remaining;
+ }
+
+ pending_data_ = pending_data_.substr(bytes);
+ return value;
+}
+
+uint64_t EventParser::ReadVarInt() {
+ uint64_t output = 0;
+ bool success;
+ std::tie(success, pending_data_) = DecodeVarInt(pending_data_, &output);
+ if (!success) {
+ SetError();
+ }
+ return output;
+}
+
+uint64_t EventParser::ReadOptionalValuePositions() {
+ RTC_DCHECK(positions_.empty());
+ size_t bits_to_read = NumEventsInBatch();
+ positions_.reserve(bits_to_read);
+ if (pending_data_.size() * 8 < bits_to_read) {
+ SetError();
+ return 0;
+ }
+
+ BitstreamReader reader(pending_data_);
+ for (size_t i = 0; i < bits_to_read; i++) {
+ positions_.push_back(reader.ReadBit());
+ }
+ if (!reader.Ok()) {
+ SetError();
+ return 0;
+ }
+
+ size_t num_existing_values =
+ std::count(positions_.begin(), positions_.end(), 1);
+ pending_data_ = pending_data_.substr((bits_to_read + 7) / 8);
+ return num_existing_values;
+}
+
+uint64_t EventParser::ReadSingleValue(FieldType field_type) {
+ switch (field_type) {
+ case FieldType::kFixed8:
+ return ReadLittleEndian(/*bytes=*/1);
+ case FieldType::kFixed32:
+ return ReadLittleEndian(/*bytes=*/4);
+ case FieldType::kFixed64:
+ return ReadLittleEndian(/*bytes=*/8);
+ case FieldType::kVarInt:
+ return ReadVarInt();
+ case FieldType::kString:
+ RTC_DCHECK_NOTREACHED();
+ SetError();
+ return 0;
+ }
+ RTC_DCHECK_NOTREACHED();
+ SetError();
+ return 0;
+}
+
+void EventParser::ReadDeltasAndPopulateValues(
+ FixedLengthEncodingParametersV3 params,
+ uint64_t num_deltas,
+ uint64_t base) {
+ RTC_DCHECK(values_.empty());
+ values_.reserve(num_deltas + 1);
+ values_.push_back(base);
+
+ if (pending_data_.size() * 8 < num_deltas * params.delta_bit_width()) {
+ SetError();
+ return;
+ }
+
+ BitstreamReader reader(pending_data_);
+ const uint64_t top_bit = static_cast<uint64_t>(1)
+ << (params.delta_bit_width() - 1);
+
+ uint64_t value = base;
+ for (uint64_t i = 0; i < num_deltas; ++i) {
+ uint64_t delta = reader.ReadBits(params.delta_bit_width());
+ RTC_DCHECK_LE(value, webrtc_event_logging::MaxUnsignedValueOfBitWidth(
+ params.value_bit_width()));
+ RTC_DCHECK_LE(delta, webrtc_event_logging::MaxUnsignedValueOfBitWidth(
+ params.delta_bit_width()));
+ bool negative_delta = params.signed_deltas() && ((delta & top_bit) != 0);
+ if (negative_delta) {
+ uint64_t delta_abs = (~delta & params.delta_mask()) + 1;
+ value = (value - delta_abs) & params.value_mask();
+ } else {
+ value = (value + delta) & params.value_mask();
+ }
+ values_.push_back(value);
+ }
+
+ if (!reader.Ok()) {
+ SetError();
+ return;
+ }
+
+ pending_data_ =
+ pending_data_.substr((num_deltas * params.delta_bit_width() + 7) / 8);
+}
+
+RtcEventLogParseStatus EventParser::Initialize(absl::string_view s,
+ bool batched) {
+ pending_data_ = s;
+ num_events_ = 1;
+
+ if (batched) {
+ num_events_ = ReadVarInt();
+ if (!Ok()) {
+ return RtcEventLogParseStatus::Error(
+ "Failed to read number of events in batch.", __FILE__, __LINE__);
+ }
+ }
+ return RtcEventLogParseStatus::Success();
+}
+
+RtcEventLogParseStatus EventParser::ParseNumericFieldInternal(
+ uint64_t value_bit_width,
+ FieldType field_type) {
+ RTC_DCHECK(values_.empty());
+ RTC_DCHECK(positions_.empty());
+
+ if (num_events_ == 1) {
+ // Just a single value in the batch.
+ uint64_t base = ReadSingleValue(field_type);
+ if (!Ok()) {
+ return RtcEventLogParseStatus::Error("Failed to read value", __FILE__,
+ __LINE__);
+ }
+ positions_.push_back(true);
+ values_.push_back(base);
+ } else {
+ // Delta compressed batch.
+ // Read delta header.
+ uint64_t header_value = ReadVarInt();
+ if (!Ok())
+ return RtcEventLogParseStatus::Error("Failed to read delta header",
+ __FILE__, __LINE__);
+ // NB: value_bit_width may be incorrect for the field, if this isn't the
+ // field we are looking for.
+ absl::optional<FixedLengthEncodingParametersV3> delta_header =
+ FixedLengthEncodingParametersV3::ParseDeltaHeader(header_value,
+ value_bit_width);
+ if (!delta_header.has_value()) {
+ return RtcEventLogParseStatus::Error("Failed to parse delta header",
+ __FILE__, __LINE__);
+ }
+
+ uint64_t num_existing_deltas = NumEventsInBatch() - 1;
+ if (delta_header->values_optional()) {
+ size_t num_nonempty_values = ReadOptionalValuePositions();
+ if (!Ok()) {
+ return RtcEventLogParseStatus::Error(
+ "Failed to read positions of optional values", __FILE__, __LINE__);
+ }
+ if (num_nonempty_values < 1 || NumEventsInBatch() < num_nonempty_values) {
+ return RtcEventLogParseStatus::Error(
+ "Expected at least one non_empty value", __FILE__, __LINE__);
+ }
+ num_existing_deltas = num_nonempty_values - 1;
+ } else {
+ // All elements in the batch have values.
+ positions_.assign(NumEventsInBatch(), 1u);
+ }
+
+ // Read base.
+ uint64_t base = ReadSingleValue(field_type);
+ if (!Ok()) {
+ return RtcEventLogParseStatus::Error("Failed to read value", __FILE__,
+ __LINE__);
+ }
+
+ if (delta_header->values_equal()) {
+ // Duplicate the base value num_existing_deltas times.
+ values_.assign(num_existing_deltas + 1, base);
+ } else {
+ // Read deltas; ceil(num_existing_deltas*delta_width/8) bits
+ ReadDeltasAndPopulateValues(delta_header.value(), num_existing_deltas,
+ base);
+ if (!Ok()) {
+ return RtcEventLogParseStatus::Error("Failed to decode deltas",
+ __FILE__, __LINE__);
+ }
+ }
+ }
+ return RtcEventLogParseStatus::Success();
+}
+
+RtcEventLogParseStatus EventParser::ParseStringFieldInternal() {
+ RTC_DCHECK(strings_.empty());
+ if (num_events_ > 1) {
+ // String encoding params reserved for future use.
+ uint64_t encoding_params = ReadVarInt();
+ if (!Ok()) {
+ return RtcEventLogParseStatus::Error("Failed to read string encoding",
+ __FILE__, __LINE__);
+ }
+ if (encoding_params != 0) {
+ return RtcEventLogParseStatus::Error(
+ "Unrecognized string encoding parameters", __FILE__, __LINE__);
+ }
+ }
+ strings_.reserve(num_events_);
+ for (uint64_t i = 0; i < num_events_; ++i) {
+ // Just a single value in the batch.
+ uint64_t size = ReadVarInt();
+ if (!Ok()) {
+ return RtcEventLogParseStatus::Error("Failed to read string size",
+ __FILE__, __LINE__);
+ }
+ if (size > pending_data_.size()) {
+ return RtcEventLogParseStatus::Error("String size exceeds remaining data",
+ __FILE__, __LINE__);
+ }
+ strings_.push_back(pending_data_.substr(0, size));
+ pending_data_ = pending_data_.substr(size);
+ }
+ return RtcEventLogParseStatus::Success();
+}
+
+RtcEventLogParseStatus EventParser::ParseField(const FieldParameters& params) {
+ // Verify that the event parses fields in increasing order.
+ if (params.field_id == FieldParameters::kTimestampField) {
+ RTC_DCHECK_EQ(last_field_id_, FieldParameters::kTimestampField);
+ } else {
+ RTC_DCHECK_GT(params.field_id, last_field_id_);
+ }
+ last_field_id_ = params.field_id;
+
+ // Initialization for positional fields that don't encode field ID and type.
+ uint64_t field_id = params.field_id;
+ FieldType field_type = params.field_type;
+
+ // Fields are encoded in increasing field_id order.
+ // Skip unknown fields with field_id < params.field_id until we either
+ // find params.field_id or a field with higher id, in which case we know that
+ // params.field_id doesn't exist.
+ while (!pending_data_.empty()) {
+ absl::string_view field_start = pending_data_;
+ ClearTemporaries();
+
+ // Read tag for non-positional fields.
+ if (params.field_id != FieldParameters::kTimestampField) {
+ uint64_t field_tag = ReadVarInt();
+ if (!Ok())
+ return RtcEventLogParseStatus::Error("Failed to read field tag",
+ __FILE__, __LINE__);
+ // Split tag into field ID and field type.
+ field_id = field_tag >> 3;
+ absl::optional<FieldType> conversion = ConvertFieldType(field_tag & 7u);
+ if (!conversion.has_value())
+ return RtcEventLogParseStatus::Error("Failed to parse field type",
+ __FILE__, __LINE__);
+ field_type = conversion.value();
+ }
+
+ if (field_id > params.field_id) {
+ // We've passed all fields with ids less than or equal to what we are
+ // looking for. Reset pending_data_ to first field with id higher than
+ // params.field_id, since we didn't find the field we were looking for.
+ pending_data_ = field_start;
+ return RtcEventLogParseStatus::Success();
+ }
+
+ if (field_type == FieldType::kString) {
+ auto status = ParseStringFieldInternal();
+ if (!status.ok()) {
+ return status;
+ }
+ } else {
+ auto status = ParseNumericFieldInternal(params.value_width, field_type);
+ if (!status.ok()) {
+ return status;
+ }
+ }
+
+ if (field_id == params.field_id) {
+ // The field we're looking for has been found and values populated.
+ return RtcEventLogParseStatus::Success();
+ }
+ }
+
+ // Field not found because the event ended.
+ ClearTemporaries();
+ return RtcEventLogParseStatus::Success();
+}
+
+RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>>
+EventParser::ParseStringField(const FieldParameters& params,
+ bool required_field) {
+ using StatusOr = RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>>;
+ RTC_DCHECK_EQ(params.field_type, FieldType::kString);
+ auto status = ParseField(params);
+ if (!status.ok())
+ return StatusOr(status);
+ rtc::ArrayView<absl::string_view> strings = GetStrings();
+ if (required_field && strings.size() != NumEventsInBatch()) {
+ return StatusOr::Error("Required string field not found", __FILE__,
+ __LINE__);
+ }
+ return StatusOr(strings);
+}
+
+RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>>
+EventParser::ParseNumericField(const FieldParameters& params,
+ bool required_field) {
+ using StatusOr = RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>>;
+ RTC_DCHECK_NE(params.field_type, FieldType::kString);
+ auto status = ParseField(params);
+ if (!status.ok())
+ return StatusOr(status);
+ rtc::ArrayView<uint64_t> values = GetValues();
+ if (required_field && values.size() != NumEventsInBatch()) {
+ return StatusOr::Error("Required numerical field not found", __FILE__,
+ __LINE__);
+ }
+ return StatusOr(values);
+}
+
+RtcEventLogParseStatusOr<EventParser::ValueAndPostionView>
+EventParser::ParseOptionalNumericField(const FieldParameters& params,
+ bool required_field) {
+ using StatusOr = RtcEventLogParseStatusOr<ValueAndPostionView>;
+ RTC_DCHECK_NE(params.field_type, FieldType::kString);
+ auto status = ParseField(params);
+ if (!status.ok())
+ return StatusOr(status);
+ ValueAndPostionView view{GetValues(), GetPositions()};
+ if (required_field && view.positions.size() != NumEventsInBatch()) {
+ return StatusOr::Error("Required numerical field not found", __FILE__,
+ __LINE__);
+ }
+ return StatusOr(view);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h
new file mode 100644
index 0000000000..fc87faf611
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_parser.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_PARSER_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_PARSER_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+
+// TODO(terelius): Compared to a generic 'Status' class, this
+// class allows us additional information about the context
+// in which the error occurred. This is currently limited to
+// the source location (file and line), but we plan on adding
+// information about the event and field name being parsed.
+// If/when we start using absl::Status in WebRTC, consider
+// whether payloads would be an appropriate alternative.
+class RtcEventLogParseStatus {
+ template <typename T>
+ friend class RtcEventLogParseStatusOr;
+
+ public:
+ static RtcEventLogParseStatus Success() { return RtcEventLogParseStatus(); }
+ static RtcEventLogParseStatus Error(absl::string_view error,
+ absl::string_view file,
+ int line) {
+ return RtcEventLogParseStatus(error, file, line);
+ }
+
+ bool ok() const { return error_.empty(); }
+ ABSL_DEPRECATED("Use ok() instead") explicit operator bool() const {
+ return ok();
+ }
+
+ std::string message() const { return error_; }
+
+ private:
+ RtcEventLogParseStatus() : error_() {}
+ RtcEventLogParseStatus(absl::string_view error,
+ absl::string_view file,
+ int line)
+ : error_(std::string(error) + " (" + std::string(file) + ": " +
+ std::to_string(line) + ")") {}
+
+ std::string error_;
+};
+
+template <typename T>
+class RtcEventLogParseStatusOr {
+ public:
+ RtcEventLogParseStatusOr(RtcEventLogParseStatus status) // NOLINT
+ : status_(status), value_() {}
+ RtcEventLogParseStatusOr(const T& value) // NOLINT
+ : status_(), value_(value) {}
+
+ bool ok() const { return status_.ok(); }
+
+ std::string message() const { return status_.message(); }
+
+ RtcEventLogParseStatus status() const { return status_; }
+
+ const T& value() const {
+ RTC_DCHECK(ok());
+ return value_;
+ }
+
+ T& value() {
+ RTC_DCHECK(ok());
+ return value_;
+ }
+
+ static RtcEventLogParseStatusOr Error(absl::string_view error,
+ absl::string_view file,
+ int line) {
+ return RtcEventLogParseStatusOr(error, file, line);
+ }
+
+ private:
+ RtcEventLogParseStatusOr() : status_() {}
+ RtcEventLogParseStatusOr(absl::string_view error,
+ absl::string_view file,
+ int line)
+ : status_(error, file, line), value_() {}
+
+ RtcEventLogParseStatus status_;
+ T value_;
+};
+
+namespace webrtc {
+
+class EventParser {
+ public:
+ struct ValueAndPostionView {
+ rtc::ArrayView<uint64_t> values;
+ rtc::ArrayView<uint8_t> positions;
+ };
+
+ EventParser() = default;
+
+ // N.B: This method stores a abls::string_view into the string to be
+ // parsed. The caller is responsible for ensuring that the actual string
+ // remains unmodified and outlives the EventParser.
+ RtcEventLogParseStatus Initialize(absl::string_view s, bool batched);
+
+ // Attempts to parse the field specified by `params`, skipping past
+ // other fields that may occur before it. If 'required_field == true',
+ // then failing to find the field is an error, otherwise the functions
+ // return success, but with an empty view of values.
+ RtcEventLogParseStatusOr<rtc::ArrayView<absl::string_view>> ParseStringField(
+ const FieldParameters& params,
+ bool required_field = true);
+ RtcEventLogParseStatusOr<rtc::ArrayView<uint64_t>> ParseNumericField(
+ const FieldParameters& params,
+ bool required_field = true);
+ RtcEventLogParseStatusOr<ValueAndPostionView> ParseOptionalNumericField(
+ const FieldParameters& params,
+ bool required_field = true);
+
+ // Number of events in a batch.
+ uint64_t NumEventsInBatch() const { return num_events_; }
+
+ // Bytes remaining in `pending_data_`. Assuming there are no unknown
+ // fields, BytesRemaining() should return 0 when all known fields
+ // in the event have been parsed.
+ size_t RemainingBytes() const { return pending_data_.size(); }
+
+ private:
+ uint64_t ReadLittleEndian(uint8_t bytes);
+ uint64_t ReadVarInt();
+ uint64_t ReadSingleValue(FieldType field_type);
+ uint64_t ReadOptionalValuePositions();
+ void ReadDeltasAndPopulateValues(FixedLengthEncodingParametersV3 params,
+ uint64_t num_deltas,
+ uint64_t base);
+ RtcEventLogParseStatus ParseNumericFieldInternal(uint64_t value_bit_width,
+ FieldType field_type);
+ RtcEventLogParseStatus ParseStringFieldInternal();
+
+ // Attempts to parse the field specified by `params`, skipping past
+ // other fields that may occur before it. Returns
+ // RtcEventLogParseStatus::Success() and populates `values_` (and
+ // `positions_`) if the field is found. Returns
+ // RtcEventLogParseStatus::Success() and clears `values_` (and `positions_`)
+ // if the field doesn't exist. Returns a RtcEventLogParseStatus::Error() if
+ // the log is incomplete, malformed or otherwise can't be parsed.
+ RtcEventLogParseStatus ParseField(const FieldParameters& params);
+
+ void SetError() { error_ = true; }
+ bool Ok() const { return !error_; }
+
+ rtc::ArrayView<uint64_t> GetValues() { return values_; }
+ rtc::ArrayView<uint8_t> GetPositions() { return positions_; }
+ rtc::ArrayView<absl::string_view> GetStrings() { return strings_; }
+
+ void ClearTemporaries() {
+ positions_.clear();
+ values_.clear();
+ strings_.clear();
+ }
+
+ // Tracks whether an error has occurred in one of the helper
+ // functions above.
+ bool error_ = false;
+
+ // Temporary storage for result.
+ std::vector<uint8_t> positions_;
+ std::vector<uint64_t> values_;
+ std::vector<absl::string_view> strings_;
+
+ // String to be consumed.
+ absl::string_view pending_data_;
+ uint64_t num_events_ = 1;
+ uint64_t last_field_id_ = FieldParameters::kTimestampField;
+};
+
+// Inverse of the ExtractRtcEventMember function used when parsing
+// a log. Uses a vector of values to populate a specific field in a
+// vector of structs.
+template <typename T,
+ typename E,
+ std::enable_if_t<std::is_integral<T>::value, bool> = true>
+ABSL_MUST_USE_RESULT RtcEventLogParseStatus
+PopulateRtcEventMember(const rtc::ArrayView<uint64_t> values,
+ T E::*member,
+ rtc::ArrayView<E> output) {
+ size_t batch_size = values.size();
+ RTC_CHECK_EQ(output.size(), batch_size);
+ for (size_t i = 0; i < batch_size; ++i) {
+ output[i].*member = DecodeFromUnsignedToType<T>(values[i]);
+ }
+ return RtcEventLogParseStatus::Success();
+}
+
+// Same as above, but for optional fields.
+template <typename T,
+ typename E,
+ std::enable_if_t<std::is_integral<T>::value, bool> = true>
+ABSL_MUST_USE_RESULT RtcEventLogParseStatus
+PopulateRtcEventMember(const rtc::ArrayView<uint8_t> positions,
+ const rtc::ArrayView<uint64_t> values,
+ absl::optional<T> E::*member,
+ rtc::ArrayView<E> output) {
+ size_t batch_size = positions.size();
+ RTC_CHECK_EQ(output.size(), batch_size);
+ RTC_CHECK_LE(values.size(), batch_size);
+ auto value_it = values.begin();
+ for (size_t i = 0; i < batch_size; ++i) {
+ if (positions[i]) {
+ RTC_CHECK(value_it != values.end());
+ output[i].*member = DecodeFromUnsignedToType<T>(value_it);
+ ++value_it;
+ } else {
+ output[i].*member = absl::nullopt;
+ }
+ }
+ RTC_CHECK(value_it == values.end());
+ return RtcEventLogParseStatus::Success();
+}
+
+// Same as above, but for enum fields.
+template <typename T,
+ typename E,
+ std::enable_if_t<std::is_enum<T>::value, bool> = true>
+ABSL_MUST_USE_RESULT RtcEventLogParseStatus
+PopulateRtcEventMember(const rtc::ArrayView<uint64_t> values,
+ T E::*member,
+ rtc::ArrayView<E> output) {
+ size_t batch_size = values.size();
+ RTC_CHECK_EQ(output.size(), batch_size);
+ for (size_t i = 0; i < batch_size; ++i) {
+ auto result = RtcEventLogEnum<T>::Decode(values[i]);
+ if (!result.ok()) {
+ return result.status();
+ }
+ output[i].*member = result.value();
+ }
+ return RtcEventLogParseStatus::Success();
+}
+
+// Same as above, but for string fields.
+template <typename E>
+ABSL_MUST_USE_RESULT RtcEventLogParseStatus
+PopulateRtcEventMember(const rtc::ArrayView<absl::string_view> values,
+ std::string E::*member,
+ rtc::ArrayView<E> output) {
+ size_t batch_size = values.size();
+ RTC_CHECK_EQ(output.size(), batch_size);
+ for (size_t i = 0; i < batch_size; ++i) {
+ output[i].*member = values[i];
+ }
+ return RtcEventLogParseStatus::Success();
+}
+
+// Same as above, but for Timestamp fields.
+// N.B. Assumes that the encoded value uses millisecond precision.
+template <typename E>
+ABSL_MUST_USE_RESULT RtcEventLogParseStatus
+PopulateRtcEventTimestamp(const rtc::ArrayView<uint64_t>& values,
+ Timestamp E::*timestamp,
+ rtc::ArrayView<E> output) {
+ size_t batch_size = values.size();
+ RTC_CHECK_EQ(batch_size, output.size());
+ for (size_t i = 0; i < batch_size; ++i) {
+ output[i].*timestamp =
+ Timestamp::Millis(DecodeFromUnsignedToType<int64_t>(values[i]));
+ }
+ return RtcEventLogParseStatus::Success();
+}
+
+template <typename E>
+rtc::ArrayView<E> ExtendLoggedBatch(std::vector<E>& output,
+ size_t new_elements) {
+ size_t old_size = output.size();
+ output.insert(output.end(), old_size + new_elements, E());
+ rtc::ArrayView<E> output_batch = output;
+ output_batch.subview(old_size);
+ RTC_DCHECK_EQ(output_batch.size(), new_elements);
+ return output_batch;
+}
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_ENCODING_PARSER_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc
new file mode 100644
index 0000000000..18beda1417
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_encoding_unittest.cc
@@ -0,0 +1,886 @@
+/* Copyright (c) 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "logging/rtc_event_log/events/rtc_event_field_encoding.h"
+
+#include <limits>
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "logging/rtc_event_log/encoder/var_int.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+constexpr int32_t kInt32Max = std::numeric_limits<int32_t>::max();
+constexpr int32_t kInt32Min = std::numeric_limits<int32_t>::min();
+constexpr uint32_t kUint32Max = std::numeric_limits<uint32_t>::max();
+constexpr int64_t kInt64Max = std::numeric_limits<int64_t>::max();
+constexpr int64_t kInt64Min = std::numeric_limits<int64_t>::min();
+constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
+
+template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
+size_t ExpectedVarIntSize(T value) {
+ size_t bytes = 0;
+ uint64_t x = EncodeAsUnsigned(value);
+ do {
+ ++bytes;
+ x = x >> 7;
+ } while (x > 0);
+ return bytes;
+}
+
+template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
+size_t ExpectedBaseValueSize(const FieldParameters& params, T value) {
+ switch (params.field_type) {
+ case FieldType::kFixed8:
+ return 1;
+ case FieldType::kFixed32:
+ return 4;
+ case FieldType::kFixed64:
+ return 8;
+ case FieldType::kVarInt:
+ return ExpectedVarIntSize(value);
+ default:
+ break;
+ }
+ RTC_DCHECK_NOTREACHED();
+ return 0;
+}
+
+template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
+size_t ExpectedEncodingSize(const FieldParameters& params,
+ const std::vector<T>& v,
+ size_t expected_bits_per_delta) {
+ if (v.size() == 0)
+ return 0;
+
+ uint64_t numeric_field_type = static_cast<uint64_t>(params.field_type);
+ RTC_DCHECK_LT(numeric_field_type, 1u << 3);
+ size_t tag_size =
+ ExpectedVarIntSize((params.field_id << 3) + numeric_field_type);
+ T base = v[0];
+ size_t base_size = ExpectedBaseValueSize(params, base);
+ if (v.size() == 1)
+ return tag_size + base_size;
+
+ size_t delta_header_size = 1;
+ // Check if there is an element *not* equal to base.
+ if (std::all_of(v.begin(), v.end(), [base](T x) { return x == base; })) {
+ return tag_size + base_size + delta_header_size;
+ }
+
+ size_t delta_size = ((v.size() - 1) * expected_bits_per_delta + 7) / 8;
+ return tag_size + base_size + delta_header_size + delta_size;
+}
+
+template <typename T, std::enable_if_t<std::is_integral<T>::value, bool> = true>
+size_t ExpectedEncodingSize(const FieldParameters& params,
+ const std::vector<absl::optional<T>>& v,
+ size_t expected_bits_per_delta) {
+ size_t num_existing_values =
+ v.size() - std::count(v.begin(), v.end(), absl::nullopt);
+ auto first_existing_value = std::find_if(
+ v.begin(), v.end(), [](absl::optional<T> x) { return x.has_value(); });
+ if (num_existing_values == 0)
+ return 0;
+
+ uint64_t numeric_field_type = static_cast<uint64_t>(params.field_type);
+ RTC_DCHECK_LT(numeric_field_type, 1u << 3);
+ size_t tag_size =
+ ExpectedVarIntSize((params.field_id << 3) + numeric_field_type);
+ T base = first_existing_value->value();
+ size_t base_size = ExpectedBaseValueSize(params, base);
+ if (num_existing_values == 1 && v.size() == 1)
+ return tag_size + base_size;
+
+ size_t delta_header_size = (num_existing_values == v.size() ? 1 : 2);
+ size_t positions_size =
+ (num_existing_values == v.size() ? 0 : (v.size() + 7) / 8);
+ // Check if there is an element *not* equal to base.
+ if (std::all_of(v.begin(), v.end(),
+ [base](absl::optional<T> x) { return x == base; })) {
+ return tag_size + base_size + delta_header_size + positions_size;
+ }
+
+ size_t delta_size =
+ ((num_existing_values - 1) * expected_bits_per_delta + 7) / 8;
+ return tag_size + base_size + delta_header_size + positions_size + delta_size;
+}
+
+size_t ExpectedStringEncodingSize(const FieldParameters& params,
+ const std::vector<std::string>& values) {
+ EXPECT_EQ(params.field_type, FieldType::kString);
+ uint64_t numeric_field_type = static_cast<uint64_t>(params.field_type);
+ RTC_DCHECK_LT(numeric_field_type, 1u << 3);
+ size_t tag_size =
+ ExpectedVarIntSize((params.field_id << 3) + numeric_field_type);
+
+ size_t expected_size = tag_size;
+ if (values.size() > 1) {
+ // VarInt encoding header reserved for future use. Currently always 0.
+ expected_size += 1;
+ }
+ for (const auto& s : values) {
+ expected_size += ExpectedVarIntSize(s.size());
+ expected_size += s.size();
+ }
+ return expected_size;
+}
+
+} // namespace
+
+class RtcTestEvent final : public RtcEvent {
+ public:
+ RtcTestEvent(bool b,
+ int32_t signed32,
+ uint32_t unsigned32,
+ int64_t signed64,
+ uint64_t unsigned64)
+ : b_(b),
+ signed32_(signed32),
+ unsigned32_(unsigned32),
+ signed64_(signed64),
+ unsigned64_(unsigned64) {}
+ RtcTestEvent(bool b,
+ int32_t signed32,
+ uint32_t unsigned32,
+ int64_t signed64,
+ uint64_t unsigned64,
+ absl::optional<int32_t> optional_signed32,
+ absl::optional<int64_t> optional_signed64,
+ uint32_t wrapping21,
+ absl::string_view string)
+ : b_(b),
+ signed32_(signed32),
+ unsigned32_(unsigned32),
+ signed64_(signed64),
+ unsigned64_(unsigned64),
+ optional_signed32_(optional_signed32),
+ optional_signed64_(optional_signed64),
+ wrapping21_(wrapping21),
+ string_(string) {}
+ ~RtcTestEvent() override = default;
+
+ Type GetType() const override { return static_cast<Type>(4711); }
+ bool IsConfigEvent() const override { return false; }
+
+ static constexpr EventParameters event_params{
+ "TestEvent", static_cast<RtcEvent::Type>(4711)};
+ static constexpr FieldParameters timestamp_params{
+ "timestamp_ms", FieldParameters::kTimestampField, FieldType::kVarInt, 64};
+ static constexpr FieldParameters bool_params{"b", 2, FieldType::kFixed8, 1};
+ static constexpr FieldParameters signed32_params{"signed32", 3,
+ FieldType::kVarInt, 32};
+ static constexpr FieldParameters unsigned32_params{"unsigned32", 4,
+ FieldType::kFixed32, 32};
+ static constexpr FieldParameters signed64_params{"signed64", 5,
+ FieldType::kFixed64, 64};
+ static constexpr FieldParameters unsigned64_params{"unsigned64", 6,
+ FieldType::kVarInt, 64};
+ static constexpr FieldParameters optional32_params{"optional_signed32", 7,
+ FieldType::kFixed32, 32};
+ static constexpr FieldParameters optional64_params{"optional_signed64", 8,
+ FieldType::kVarInt, 64};
+ static constexpr FieldParameters wrapping21_params{"wrapping21", 9,
+ FieldType::kFixed32, 21};
+ static constexpr FieldParameters string_params{
+ "string", 10, FieldType::kString, /*value_width = */ 0};
+
+ static constexpr Type kType = static_cast<RtcEvent::Type>(4711);
+
+ const bool b_;
+ const int32_t signed32_;
+ const uint32_t unsigned32_;
+ const int64_t signed64_;
+ const uint64_t unsigned64_;
+ const absl::optional<int32_t> optional_signed32_ = absl::nullopt;
+ const absl::optional<int64_t> optional_signed64_ = absl::nullopt;
+ const uint32_t wrapping21_ = 0;
+ const std::string string_;
+};
+
+constexpr EventParameters RtcTestEvent::event_params;
+constexpr FieldParameters RtcTestEvent::timestamp_params;
+constexpr FieldParameters RtcTestEvent::bool_params;
+constexpr FieldParameters RtcTestEvent::signed32_params;
+constexpr FieldParameters RtcTestEvent::unsigned32_params;
+constexpr FieldParameters RtcTestEvent::signed64_params;
+constexpr FieldParameters RtcTestEvent::unsigned64_params;
+
+constexpr FieldParameters RtcTestEvent::optional32_params;
+constexpr FieldParameters RtcTestEvent::optional64_params;
+constexpr FieldParameters RtcTestEvent::wrapping21_params;
+constexpr FieldParameters RtcTestEvent::string_params;
+
+constexpr RtcEvent::Type RtcTestEvent::kType;
+
+class RtcEventFieldTest : public ::testing::Test {
+ protected:
+ void SetUp() override {}
+
+ void CreateFullEvents(
+ const std::vector<bool>& bool_values,
+ const std::vector<int32_t>& signed32_values,
+ const std::vector<uint32_t>& unsigned32_values,
+ const std::vector<int64_t>& signed64_values,
+ const std::vector<uint64_t>& unsigned64_values,
+ const std::vector<absl::optional<int32_t>>& optional32_values,
+ const std::vector<absl::optional<int64_t>>& optional64_values,
+ const std::vector<uint32_t>& wrapping21_values,
+ const std::vector<std::string>& string_values) {
+ size_t size = bool_values.size();
+ RTC_CHECK_EQ(signed32_values.size(), size);
+ RTC_CHECK_EQ(unsigned32_values.size(), size);
+ RTC_CHECK_EQ(signed64_values.size(), size);
+ RTC_CHECK_EQ(unsigned64_values.size(), size);
+ RTC_CHECK_EQ(optional32_values.size(), size);
+ RTC_CHECK_EQ(optional64_values.size(), size);
+ RTC_CHECK_EQ(wrapping21_values.size(), size);
+ RTC_CHECK_EQ(string_values.size(), size);
+
+ for (size_t i = 0; i < size; i++) {
+ batch_.push_back(new RtcTestEvent(
+ bool_values[i], signed32_values[i], unsigned32_values[i],
+ signed64_values[i], unsigned64_values[i], optional32_values[i],
+ optional64_values[i], wrapping21_values[i], string_values[i]));
+ }
+ }
+
+ void PrintBytes(absl::string_view s) {
+ for (auto c : s) {
+ fprintf(stderr, "%d ", static_cast<uint8_t>(c));
+ }
+ fprintf(stderr, "\n");
+ }
+
+ void ParseEventHeader(absl::string_view encoded_event) {
+ uint64_t event_tag;
+ bool success;
+ std::tie(success, encoded_event) = DecodeVarInt(encoded_event, &event_tag);
+ ASSERT_TRUE(success);
+ uint64_t event_id = event_tag >> 1;
+ ASSERT_EQ(event_id, static_cast<uint64_t>(RtcTestEvent::event_params.id));
+ bool batched = event_tag & 1u;
+ ASSERT_EQ(batched, batch_.size() > 1u);
+
+ uint64_t size;
+ std::tie(success, encoded_event) = DecodeVarInt(encoded_event, &size);
+ ASSERT_EQ(encoded_event.size(), size);
+
+ ASSERT_TRUE(parser_.Initialize(encoded_event, batched).ok());
+ }
+
+ void ParseAndVerifyTimestamps() {
+ auto result = parser_.ParseNumericField(RtcTestEvent::timestamp_params);
+ ASSERT_TRUE(result.ok()) << result.message().c_str();
+ ASSERT_EQ(result.value().size(), batch_.size());
+ for (size_t i = 0; i < batch_.size(); i++) {
+ EXPECT_EQ(result.value()[i],
+ static_cast<uint64_t>(batch_[i]->timestamp_ms()));
+ }
+ }
+
+ void ParseAndVerifyStringField(
+ const FieldParameters& params,
+ const std::vector<std::string>& expected_values,
+ size_t expected_skipped_bytes = 0) {
+ size_t expected_size = ExpectedStringEncodingSize(params, expected_values) +
+ expected_skipped_bytes;
+ size_t size_before = parser_.RemainingBytes();
+ auto result = parser_.ParseStringField(params);
+ ASSERT_TRUE(result.ok()) << result.message().c_str();
+ ASSERT_EQ(result.value().size(), expected_values.size());
+ for (size_t i = 0; i < expected_values.size(); i++) {
+ EXPECT_EQ(result.value()[i], expected_values[i]);
+ }
+ size_t size_after = parser_.RemainingBytes();
+ EXPECT_EQ(size_before - size_after, expected_size)
+ << " for field " << params.name;
+ }
+
+ template <typename T>
+ void ParseAndVerifyField(const FieldParameters& params,
+ const std::vector<T>& expected_values,
+ size_t expected_bits_per_delta,
+ size_t expected_skipped_bytes = 0) {
+ size_t expected_size =
+ ExpectedEncodingSize(params, expected_values, expected_bits_per_delta) +
+ expected_skipped_bytes;
+ size_t size_before = parser_.RemainingBytes();
+ auto result = parser_.ParseNumericField(params);
+ ASSERT_TRUE(result.ok()) << result.message().c_str();
+ ASSERT_EQ(result.value().size(), expected_values.size());
+ for (size_t i = 0; i < expected_values.size(); i++) {
+ EXPECT_EQ(DecodeFromUnsignedToType<T>(result.value()[i]),
+ expected_values[i]);
+ }
+ size_t size_after = parser_.RemainingBytes();
+ EXPECT_EQ(size_before - size_after, expected_size)
+ << " for field " << params.name;
+ }
+
+ template <typename T>
+ void ParseAndVerifyOptionalField(
+ const FieldParameters& params,
+ const std::vector<absl::optional<T>>& expected_values,
+ size_t expected_bits_per_delta,
+ size_t expected_skipped_bytes = 0) {
+ size_t expected_size =
+ ExpectedEncodingSize(params, expected_values, expected_bits_per_delta) +
+ expected_skipped_bytes;
+ size_t size_before = parser_.RemainingBytes();
+ auto result = parser_.ParseOptionalNumericField(params);
+ ASSERT_TRUE(result.ok()) << result.message().c_str();
+ rtc::ArrayView<uint64_t> values = result.value().values;
+ rtc::ArrayView<uint8_t> positions = result.value().positions;
+ ASSERT_EQ(positions.size(), expected_values.size());
+ auto value_it = values.begin();
+ for (size_t i = 0; i < expected_values.size(); i++) {
+ if (positions[i]) {
+ ASSERT_NE(value_it, values.end());
+ ASSERT_TRUE(expected_values[i].has_value());
+ EXPECT_EQ(DecodeFromUnsignedToType<T>(*value_it),
+ expected_values[i].value());
+ ++value_it;
+ } else {
+ EXPECT_EQ(absl::nullopt, expected_values[i]);
+ }
+ }
+ EXPECT_EQ(value_it, values.end());
+ size_t size_after = parser_.RemainingBytes();
+ EXPECT_EQ(size_before - size_after, expected_size);
+ }
+
+ void ParseAndVerifyMissingField(const FieldParameters& params) {
+ auto result = parser_.ParseNumericField(params, /*required_field=*/false);
+ ASSERT_TRUE(result.ok()) << result.message().c_str();
+ EXPECT_EQ(result.value().size(), 0u);
+ }
+
+ void ParseAndVerifyMissingOptionalField(const FieldParameters& params) {
+ auto result =
+ parser_.ParseOptionalNumericField(params, /*required_field=*/false);
+ ASSERT_TRUE(result.ok()) << result.message().c_str();
+ rtc::ArrayView<uint64_t> values = result.value().values;
+ rtc::ArrayView<uint8_t> positions = result.value().positions;
+ EXPECT_EQ(positions.size(), 0u);
+ EXPECT_EQ(values.size(), 0u);
+ }
+
+ void TearDown() override {
+ for (const RtcEvent* event : batch_) {
+ delete event;
+ }
+ }
+
+ std::vector<const RtcEvent*> batch_;
+ EventParser parser_;
+};
+
+TEST_F(RtcEventFieldTest, EmptyList) {
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(RtcTestEvent::bool_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::b_));
+ std::string s = encoder.AsString();
+ EXPECT_TRUE(s.empty());
+}
+
+TEST_F(RtcEventFieldTest, Singleton) {
+ std::vector<bool> bool_values = {true};
+ std::vector<int32_t> signed32_values = {-2};
+ std::vector<uint32_t> unsigned32_values = {123456789};
+ std::vector<int64_t> signed64_values = {-9876543210};
+ std::vector<uint64_t> unsigned64_values = {9876543210};
+ std::vector<absl::optional<int32_t>> optional32_values = {kInt32Min};
+ std::vector<absl::optional<int64_t>> optional64_values = {kInt64Max};
+ std::vector<uint32_t> wrapping21_values = {(1 << 21) - 1};
+ std::vector<std::string> string_values = {"foo"};
+
+ CreateFullEvents(bool_values, signed32_values, unsigned32_values,
+ signed64_values, unsigned64_values, optional32_values,
+ optional64_values, wrapping21_values, string_values);
+
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(RtcTestEvent::bool_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::b_));
+ encoder.EncodeField(RtcTestEvent::signed32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned32_));
+ encoder.EncodeField(RtcTestEvent::signed64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned64_));
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::optional64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::wrapping21_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::wrapping21_));
+ encoder.EncodeField(RtcTestEvent::string_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::string_));
+ std::string s = encoder.AsString();
+
+ // Optional debug printing
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyField(RtcTestEvent::bool_params, bool_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::signed32_params, signed32_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::unsigned32_params, unsigned32_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::signed64_params, signed64_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::unsigned64_params, unsigned64_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional32_params,
+ optional32_values, /*no deltas*/ 0);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional64_params,
+ optional64_values, /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::wrapping21_params, wrapping21_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyStringField(RtcTestEvent::string_params, string_values);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+TEST_F(RtcEventFieldTest, EqualElements) {
+ std::vector<bool> bool_values = {true, true, true, true};
+ std::vector<int32_t> signed32_values = {-2, -2, -2, -2};
+ std::vector<uint32_t> unsigned32_values = {123456789, 123456789, 123456789,
+ 123456789};
+ std::vector<int64_t> signed64_values = {-9876543210, -9876543210, -9876543210,
+ -9876543210};
+ std::vector<uint64_t> unsigned64_values = {9876543210, 9876543210, 9876543210,
+ 9876543210};
+ std::vector<absl::optional<int32_t>> optional32_values = {
+ kInt32Min, kInt32Min, kInt32Min, kInt32Min};
+ std::vector<absl::optional<int64_t>> optional64_values = {
+ kInt64Max, kInt64Max, kInt64Max, kInt64Max};
+ std::vector<uint32_t> wrapping21_values = {(1 << 21) - 1, (1 << 21) - 1,
+ (1 << 21) - 1, (1 << 21) - 1};
+ std::vector<std::string> string_values = {"foo", "foo", "foo", "foo"};
+
+ CreateFullEvents(bool_values, signed32_values, unsigned32_values,
+ signed64_values, unsigned64_values, optional32_values,
+ optional64_values, wrapping21_values, string_values);
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(RtcTestEvent::bool_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::b_));
+ encoder.EncodeField(RtcTestEvent::signed32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned32_));
+ encoder.EncodeField(RtcTestEvent::signed64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned64_));
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::optional64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::wrapping21_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::wrapping21_));
+ encoder.EncodeField(RtcTestEvent::string_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::string_));
+ std::string s = encoder.AsString();
+
+ // Optional debug printing
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyField(RtcTestEvent::bool_params, bool_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::signed32_params, signed32_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::unsigned32_params, unsigned32_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::signed64_params, signed64_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::unsigned64_params, unsigned64_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional32_params,
+ optional32_values, /*no deltas*/ 0);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional64_params,
+ optional64_values, /*no deltas*/ 0);
+ ParseAndVerifyField(RtcTestEvent::wrapping21_params, wrapping21_values,
+ /*no deltas*/ 0);
+ ParseAndVerifyStringField(RtcTestEvent::string_params, string_values);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+TEST_F(RtcEventFieldTest, Increasing) {
+ std::vector<bool> bool_values = {false, true, false, true};
+ std::vector<int32_t> signed32_values = {-2, -1, 0, 1};
+ std::vector<uint32_t> unsigned32_values = {kUint32Max - 1, kUint32Max, 0, 1};
+ std::vector<int64_t> signed64_values = {kInt64Max - 1, kInt64Max, kInt64Min,
+ kInt64Min + 1};
+ std::vector<uint64_t> unsigned64_values = {kUint64Max - 1, kUint64Max, 0, 1};
+ std::vector<absl::optional<int32_t>> optional32_values = {
+ kInt32Max - 1, kInt32Max, kInt32Min, kInt32Min + 1};
+ std::vector<absl::optional<int64_t>> optional64_values = {
+ kInt64Max - 1, kInt64Max, kInt64Min, kInt64Min + 1};
+ std::vector<uint32_t> wrapping21_values = {(1 << 21) - 2, (1 << 21) - 1, 0,
+ 1};
+ std::vector<std::string> string_values = {
+ "", "a", "bc", "def"}; // No special compression of strings.
+
+ CreateFullEvents(bool_values, signed32_values, unsigned32_values,
+ signed64_values, unsigned64_values, optional32_values,
+ optional64_values, wrapping21_values, string_values);
+
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(RtcTestEvent::bool_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::b_));
+ encoder.EncodeField(RtcTestEvent::signed32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned32_));
+ encoder.EncodeField(RtcTestEvent::signed64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned64_));
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::optional64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::wrapping21_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::wrapping21_));
+ encoder.EncodeField(RtcTestEvent::string_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::string_));
+ std::string s = encoder.AsString();
+
+ // Optional debug printing
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyField(RtcTestEvent::bool_params, bool_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::signed32_params, signed32_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::unsigned32_params, unsigned32_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::signed64_params, signed64_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::unsigned64_params, unsigned64_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional32_params,
+ optional32_values, /*delta bits*/ 1);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional64_params,
+ optional64_values, /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::wrapping21_params, wrapping21_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyStringField(RtcTestEvent::string_params, string_values);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+TEST_F(RtcEventFieldTest, Decreasing) {
+ std::vector<bool> bool_values = {true, false, true, false};
+ std::vector<int32_t> signed32_values = {2, 1, 0, -1};
+ std::vector<uint32_t> unsigned32_values = {1, 0, kUint32Max, kUint32Max - 1};
+ std::vector<int64_t> signed64_values = {kInt64Min + 1, kInt64Min, kInt64Max,
+ kInt64Max - 1};
+ std::vector<uint64_t> unsigned64_values = {1, 0, kUint64Max, kUint64Max - 1};
+ std::vector<absl::optional<int32_t>> optional32_values = {
+ kInt32Min + 1, kInt32Min, kInt32Max, kInt32Max - 1};
+ std::vector<absl::optional<int64_t>> optional64_values = {
+ kInt64Min + 1, kInt64Min, kInt64Max, kInt64Max - 1};
+ std::vector<uint32_t> wrapping21_values = {1, 0, (1 << 21) - 1,
+ (1 << 21) - 2};
+ std::vector<std::string> string_values = {
+ "def", "bc", "a", ""}; // No special compression of strings.
+
+ CreateFullEvents(bool_values, signed32_values, unsigned32_values,
+ signed64_values, unsigned64_values, optional32_values,
+ optional64_values, wrapping21_values, string_values);
+
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(RtcTestEvent::bool_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::b_));
+ encoder.EncodeField(RtcTestEvent::signed32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned32_));
+ encoder.EncodeField(RtcTestEvent::signed64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned64_));
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::optional64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::wrapping21_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::wrapping21_));
+ encoder.EncodeField(RtcTestEvent::string_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::string_));
+ std::string s = encoder.AsString();
+
+ // Optional debug printing
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyField(RtcTestEvent::bool_params, bool_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::signed32_params, signed32_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::unsigned32_params, unsigned32_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::signed64_params, signed64_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::unsigned64_params, unsigned64_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional32_params,
+ optional32_values, /*delta bits*/ 1);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional64_params,
+ optional64_values, /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::wrapping21_params, wrapping21_values,
+ /*delta bits*/ 1);
+ ParseAndVerifyStringField(RtcTestEvent::string_params, string_values);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+TEST_F(RtcEventFieldTest, SkipsDeprecatedFields) {
+ // Expect parser to skip fields it doesn't recognize, but find subsequent
+ // fields.
+ std::vector<bool> bool_values = {true, false};
+ std::vector<int32_t> signed32_values = {kInt32Min / 2, kInt32Max / 2};
+ std::vector<uint32_t> unsigned32_values = {0, kUint32Max / 2};
+ std::vector<int64_t> signed64_values = {kInt64Min / 2, kInt64Max / 2};
+ std::vector<uint64_t> unsigned64_values = {0, kUint64Max / 2};
+ std::vector<absl::optional<int32_t>> optional32_values = {kInt32Max / 2,
+ kInt32Min / 2};
+ std::vector<absl::optional<int64_t>> optional64_values = {kInt64Min / 2,
+ kInt64Max / 2};
+ std::vector<uint32_t> wrapping21_values = {0, 1 << 20};
+ std::vector<std::string> string_values = {"foo", "bar"};
+
+ size_t signed32_encoding_size =
+ /*tag*/ 1 + /* varint base*/ 5 + /* delta_header*/ 1 + /*deltas*/ 4;
+ size_t signed64_encoding_size =
+ /*tag*/ 1 + /* fixed64 base*/ 8 + /* delta_header*/ 1 + /*deltas*/ 8;
+ size_t optional32_encoding_size =
+ /*tag*/ 1 + /* fixed32 base*/ 4 + /* delta_header*/ 1 + /*deltas*/ 4;
+
+ CreateFullEvents(bool_values, signed32_values, unsigned32_values,
+ signed64_values, unsigned64_values, optional32_values,
+ optional64_values, wrapping21_values, string_values);
+
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(RtcTestEvent::bool_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::b_));
+ encoder.EncodeField(RtcTestEvent::signed32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned32_));
+ encoder.EncodeField(RtcTestEvent::signed64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::unsigned64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::unsigned64_));
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::optional64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::wrapping21_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::wrapping21_));
+ encoder.EncodeField(RtcTestEvent::string_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::string_));
+ std::string s = encoder.AsString();
+
+ // Optional debug printing
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyField(RtcTestEvent::bool_params, bool_values,
+ /*delta_bits=*/1);
+ // Skips parsing the `signed32_values`. The following unsigned fields should
+ // still be found.
+ ParseAndVerifyField(RtcTestEvent::unsigned32_params, unsigned32_values,
+ /*delta_bits=*/31,
+ /*expected_skipped_bytes=*/signed32_encoding_size);
+ // Skips parsing the `signed64_values`. The following unsigned fields should
+ // still be found.
+ ParseAndVerifyField(RtcTestEvent::unsigned64_params, unsigned64_values,
+ /*delta_bits=*/63, signed64_encoding_size);
+ // Skips parsing the `optional32_values`. The following unsigned fields should
+ // still be found.
+ ParseAndVerifyOptionalField(RtcTestEvent::optional64_params,
+ optional64_values,
+ /*delta_bits=*/63, optional32_encoding_size);
+ ParseAndVerifyField(RtcTestEvent::wrapping21_params, wrapping21_values,
+ /*delta_bits=*/20);
+ ParseAndVerifyStringField(RtcTestEvent::string_params, string_values);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+TEST_F(RtcEventFieldTest, SkipsMissingFields) {
+ // Expect parsing of missing field to succeed but return an empty list.
+
+ std::vector<bool> bool_values = {true, false};
+ std::vector<int32_t> signed32_values = {kInt32Min / 2, kInt32Max / 2};
+ std::vector<uint32_t> unsigned32_values = {0, kUint32Max / 2};
+ std::vector<int64_t> signed64_values = {kInt64Min / 2, kInt64Max / 2};
+ std::vector<uint64_t> unsigned64_values = {0, kUint64Max / 2};
+ std::vector<absl::optional<int32_t>> optional32_values = {kInt32Max / 2,
+ kInt32Min / 2};
+ std::vector<absl::optional<int64_t>> optional64_values = {kInt64Min / 2,
+ kInt64Max / 2};
+ std::vector<uint32_t> wrapping21_values = {0, 1 << 20};
+ std::vector<std::string> string_values = {"foo", "foo"};
+
+ CreateFullEvents(bool_values, signed32_values, unsigned32_values,
+ signed64_values, unsigned64_values, optional32_values,
+ optional64_values, wrapping21_values, string_values);
+
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ // Skip encoding the `bool_values`.
+ encoder.EncodeField(RtcTestEvent::signed32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed32_));
+ // Skip encoding the `unsigned32_values`.
+ encoder.EncodeField(RtcTestEvent::signed64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::signed64_));
+ // Skip encoding the `unsigned64_values`.
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ // Skip encoding the `optional64_values`.
+ encoder.EncodeField(
+ RtcTestEvent::wrapping21_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::wrapping21_));
+ encoder.EncodeField(RtcTestEvent::string_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::string_));
+ std::string s = encoder.AsString();
+
+ // Optional debug printing
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyMissingField(RtcTestEvent::bool_params);
+ ParseAndVerifyField(RtcTestEvent::signed32_params, signed32_values,
+ /*delta_bits=*/31);
+ ParseAndVerifyMissingField(RtcTestEvent::unsigned32_params);
+ ParseAndVerifyField(RtcTestEvent::signed64_params, signed64_values,
+ /*delta_bits=*/63);
+ ParseAndVerifyMissingField(RtcTestEvent::unsigned64_params);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional32_params,
+ optional32_values, /*delta_bits=*/31);
+ ParseAndVerifyMissingOptionalField(RtcTestEvent::optional64_params);
+ ParseAndVerifyField(RtcTestEvent::wrapping21_params, wrapping21_values,
+ /*delta_bits=*/20);
+ ParseAndVerifyStringField(RtcTestEvent::string_params, string_values);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+TEST_F(RtcEventFieldTest, OptionalFields) {
+ std::vector<absl::optional<int32_t>> optional32_values = {
+ 2, absl::nullopt, 4, absl::nullopt, 6, absl::nullopt};
+ std::vector<absl::optional<int64_t>> optional64_values = {
+ absl::nullopt, 1024, absl::nullopt, 1025, absl::nullopt, 1026};
+ std::vector<uint32_t> wrapping21_values = {(1 << 21) - 3, 0, 2, 5, 5, 6};
+
+ for (size_t i = 0; i < optional32_values.size(); i++) {
+ batch_.push_back(new RtcTestEvent(0, 0, 0, 0, 0, optional32_values[i],
+ optional64_values[i],
+ wrapping21_values[i], ""));
+ }
+
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::optional64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed64_));
+ encoder.EncodeField(
+ RtcTestEvent::wrapping21_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::wrapping21_));
+ std::string s = encoder.AsString();
+
+ // Optional debug output
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyOptionalField(RtcTestEvent::optional32_params,
+ optional32_values, /*delta bits*/ 2);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional64_params,
+ optional64_values, /*delta bits*/ 1);
+ ParseAndVerifyField(RtcTestEvent::wrapping21_params, wrapping21_values,
+ /*delta bits*/ 2);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+TEST_F(RtcEventFieldTest, AllNulloptTreatedAsMissing) {
+ std::vector<absl::optional<int32_t>> optional32_values = {
+ absl::nullopt, absl::nullopt, absl::nullopt,
+ absl::nullopt, absl::nullopt, absl::nullopt};
+ std::vector<absl::optional<int64_t>> optional64_values = {
+ absl::nullopt, 1024, absl::nullopt, 1025, absl::nullopt, 1026};
+
+ for (size_t i = 0; i < optional32_values.size(); i++) {
+ batch_.push_back(new RtcTestEvent(0, 0, 0, 0, 0, optional32_values[i],
+ optional64_values[i], 0, ""));
+ }
+
+ EventEncoder encoder(RtcTestEvent::event_params, batch_);
+ encoder.EncodeField(
+ RtcTestEvent::optional32_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed32_));
+ encoder.EncodeField(
+ RtcTestEvent::optional64_params,
+ ExtractRtcEventMember(batch_, &RtcTestEvent::optional_signed64_));
+ std::string s = encoder.AsString();
+
+ // Optional debug output
+ // PrintBytes(s);
+
+ ParseEventHeader(s);
+ ParseAndVerifyTimestamps();
+ ParseAndVerifyMissingOptionalField(RtcTestEvent::optional32_params);
+ ParseAndVerifyOptionalField(RtcTestEvent::optional64_params,
+ optional64_values, /*delta_bits=*/1);
+ EXPECT_EQ(parser_.RemainingBytes(), 0u);
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.cc
new file mode 100644
index 0000000000..99f0b3697c
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+
+#include <algorithm>
+#include <limits>
+
+#include "rtc_base/checks.h"
+
+namespace webrtc_event_logging {
+
+// The bitwidth required to encode values in the range
+// [0, `max_pos_magnitude`] using an unsigned representation.
+uint8_t UnsignedBitWidth(uint64_t max_magnitude) {
+ uint8_t required_bits = 1;
+ while (max_magnitude >>= 1) {
+ ++required_bits;
+ }
+ return required_bits;
+}
+
+// The bitwidth required to encode signed values in the range
+// [-`max_neg_magnitude`, `max_pos_magnitude`] using a signed
+// 2-complement representation.
+uint8_t SignedBitWidth(uint64_t max_pos_magnitude, uint64_t max_neg_magnitude) {
+ const uint8_t bitwidth_positive =
+ max_pos_magnitude > 0 ? UnsignedBitWidth(max_pos_magnitude) : 0;
+ const uint8_t bitwidth_negative =
+ (max_neg_magnitude > 1) ? UnsignedBitWidth(max_neg_magnitude - 1) : 0;
+ return 1 + std::max(bitwidth_positive, bitwidth_negative);
+}
+
+// Return the maximum integer of a given bit width.
+uint64_t MaxUnsignedValueOfBitWidth(uint64_t bit_width) {
+ RTC_DCHECK_GE(bit_width, 1);
+ RTC_DCHECK_LE(bit_width, 64);
+ return (bit_width == 64) ? std::numeric_limits<uint64_t>::max()
+ : ((static_cast<uint64_t>(1) << bit_width) - 1);
+}
+
+// Computes the delta between `previous` and `current`, under the assumption
+// that `bit_mask` is the largest value before wrap-around occurs. The bitmask
+// must be of the form 2^x-1. (We use the wrap-around to more efficiently
+// compress counters that wrap around at different bit widths than the
+// backing C++ data type.)
+uint64_t UnsignedDelta(uint64_t previous, uint64_t current, uint64_t bit_mask) {
+ RTC_DCHECK_LE(previous, bit_mask);
+ RTC_DCHECK_LE(current, bit_mask);
+ return (current - previous) & bit_mask;
+}
+
+} // namespace webrtc_event_logging
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.h
new file mode 100644
index 0000000000..eb9d67f1c2
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_EXTRACTION_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_EXTRACTION_H_
+
+#include <string>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
+#include "rtc_base/logging.h"
+
+namespace webrtc_event_logging {
+uint8_t UnsignedBitWidth(uint64_t max_magnitude);
+uint8_t SignedBitWidth(uint64_t max_pos_magnitude, uint64_t max_neg_magnitude);
+uint64_t MaxUnsignedValueOfBitWidth(uint64_t bit_width);
+uint64_t UnsignedDelta(uint64_t previous, uint64_t current, uint64_t bit_mask);
+} // namespace webrtc_event_logging
+
+namespace webrtc {
+template <typename T, std::enable_if_t<std::is_signed<T>::value, bool> = true>
+uint64_t EncodeAsUnsigned(T value) {
+ return webrtc_event_logging::ToUnsigned(value);
+}
+
+template <typename T, std::enable_if_t<std::is_unsigned<T>::value, bool> = true>
+uint64_t EncodeAsUnsigned(T value) {
+ return static_cast<uint64_t>(value);
+}
+
+template <typename T, std::enable_if_t<std::is_signed<T>::value, bool> = true>
+T DecodeFromUnsignedToType(uint64_t value) {
+ T signed_value = 0;
+ bool success = webrtc_event_logging::ToSigned<T>(value, &signed_value);
+ if (!success) {
+ RTC_LOG(LS_ERROR) << "Failed to convert " << value << "to signed type.";
+ // TODO(terelius): Propagate error?
+ }
+ return signed_value;
+}
+
+template <typename T, std::enable_if_t<std::is_unsigned<T>::value, bool> = true>
+T DecodeFromUnsignedToType(uint64_t value) {
+ // TODO(terelius): Check range?
+ return static_cast<T>(value);
+}
+
+// RtcEventLogEnum<T> defines a mapping between an enum T
+// and the event log encodings. To log a new enum type T,
+// specialize RtcEventLogEnum<T> and add static methods
+// static uint64_t Encode(T x) {}
+// static RtcEventLogParseStatusOr<T> Decode(uint64_t x) {}
+template <typename T>
+class RtcEventLogEnum {
+ static_assert(sizeof(T) != sizeof(T),
+ "Missing specialisation of RtcEventLogEnum for type");
+};
+
+// Represents a vector<optional<uint64_t>> optional_values
+// as a bit-vector `position_mask` which identifies the positions
+// of existing values, and a (potentially shorter)
+// `vector<uint64_t> values` containing the actual values.
+// The bit vector is constructed such that position_mask[i]
+// is true iff optional_values[i] has a value, and `values.size()`
+// is equal to the number of set bits in `position_mask`.
+struct ValuesWithPositions {
+ std::vector<bool> position_mask;
+ std::vector<uint64_t> values;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FIELD_EXTRACTION_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction_unittest.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction_unittest.cc
new file mode 100644
index 0000000000..f9fb993af0
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_field_extraction_unittest.cc
@@ -0,0 +1,97 @@
+/* Copyright (c) 2021 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_field_extraction.h"
+
+#include "rtc_base/random.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(UnsignedBitWidthTest, SmallValues) {
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(0), 1u);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(1), 1u);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(2), 2u);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(3), 2u);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(4), 3u);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(5), 3u);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(6), 3u);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(7), 3u);
+}
+
+TEST(UnsignedBitWidthTest, PowersOfTwo) {
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(0), 1u);
+
+ for (unsigned i = 0; i < 64; i++) {
+ uint64_t x = 1;
+ x = x << i;
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(x), i + 1);
+ }
+}
+
+TEST(UnsignedBitWidthTest, PowersOfTwoMinusOne) {
+ for (unsigned i = 1; i < 64; i++) {
+ uint64_t x = 1;
+ x = (x << i) - 1;
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(x), i);
+ }
+
+ uint64_t x = ~static_cast<uint64_t>(0);
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(x), 64u);
+}
+
+TEST(UnsignedBitWidthTest, RandomInputs) {
+ Random rand(12345);
+
+ for (unsigned i = 0; i < 64; i++) {
+ uint64_t x = 1;
+ x = x << i;
+ uint64_t high = rand.Rand<uint32_t>();
+ uint64_t low = rand.Rand<uint32_t>();
+ x += ((high << 32) + low) % x;
+ EXPECT_EQ(webrtc_event_logging::UnsignedBitWidth(x), i + 1);
+ }
+}
+
+TEST(SignedBitWidthTest, SignedBitWidth) {
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(0, 1), 1u);
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(1, 0), 2u);
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(1, 2), 2u);
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(1, 128), 8u);
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(127, 1), 8u);
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(127, 128), 8u);
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(1, 129), 9u);
+ EXPECT_EQ(webrtc_event_logging::SignedBitWidth(128, 1), 9u);
+}
+
+TEST(MaxUnsignedValueOfBitWidthTest, MaxUnsignedValueOfBitWidth) {
+ EXPECT_EQ(webrtc_event_logging::MaxUnsignedValueOfBitWidth(1), 0x01u);
+ EXPECT_EQ(webrtc_event_logging::MaxUnsignedValueOfBitWidth(6), 0x3Fu);
+ EXPECT_EQ(webrtc_event_logging::MaxUnsignedValueOfBitWidth(8), 0xFFu);
+ EXPECT_EQ(webrtc_event_logging::MaxUnsignedValueOfBitWidth(32), 0xFFFFFFFFu);
+}
+
+TEST(EncodeAsUnsignedTest, NegativeValues) {
+ // Negative values are converted as if cast to unsigned type of
+ // the same bitsize using 2-complement representation.
+ int16_t x = -1;
+ EXPECT_EQ(EncodeAsUnsigned(x), static_cast<uint64_t>(0xFFFF));
+ int64_t y = -1;
+ EXPECT_EQ(EncodeAsUnsigned(y), static_cast<uint64_t>(0xFFFFFFFFFFFFFFFFull));
+}
+
+TEST(EncodeAsUnsignedTest, PositiveValues) {
+ // Postive values are unchanged.
+ int16_t x = 42;
+ EXPECT_EQ(EncodeAsUnsigned(x), static_cast<uint64_t>(42));
+ int64_t y = 42;
+ EXPECT_EQ(EncodeAsUnsigned(y), static_cast<uint64_t>(42));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.cc
new file mode 100644
index 0000000000..cde412e6c4
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_frame_decoded.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventFrameDecoded::RtcEventFrameDecoded(int64_t render_time_ms,
+ uint32_t ssrc,
+ int width,
+ int height,
+ VideoCodecType codec,
+ uint8_t qp)
+ : render_time_ms_(render_time_ms),
+ ssrc_(ssrc),
+ width_(width),
+ height_(height),
+ codec_(codec),
+ qp_(qp) {}
+
+RtcEventFrameDecoded::RtcEventFrameDecoded(const RtcEventFrameDecoded& other)
+ : RtcEvent(other.timestamp_us_),
+ render_time_ms_(other.render_time_ms_),
+ ssrc_(other.ssrc_),
+ width_(other.width_),
+ height_(other.height_),
+ codec_(other.codec_),
+ qp_(other.qp_) {}
+
+std::unique_ptr<RtcEventFrameDecoded> RtcEventFrameDecoded::Copy() const {
+ return absl::WrapUnique<RtcEventFrameDecoded>(
+ new RtcEventFrameDecoded(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.h
new file mode 100644
index 0000000000..91190faea9
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_frame_decoded.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FRAME_DECODED_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FRAME_DECODED_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "api/video/video_codec_type.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedFrameDecoded {
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int64_t render_time_ms;
+ uint32_t ssrc;
+ int width;
+ int height;
+ VideoCodecType codec;
+ uint8_t qp;
+};
+
+class RtcEventFrameDecoded final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::FrameDecoded;
+
+ RtcEventFrameDecoded(int64_t render_time_ms,
+ uint32_t ssrc,
+ int width,
+ int height,
+ VideoCodecType codec,
+ uint8_t qp);
+ ~RtcEventFrameDecoded() override = default;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventFrameDecoded> Copy() const;
+
+ int64_t render_time_ms() const { return render_time_ms_; }
+ uint32_t ssrc() const { return ssrc_; }
+ int width() const { return width_; }
+ int height() const { return height_; }
+ VideoCodecType codec() const { return codec_; }
+ uint8_t qp() const { return qp_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::map<uint32_t, std::vector<LoggedFrameDecoded>>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventFrameDecoded(const RtcEventFrameDecoded& other);
+
+ const int64_t render_time_ms_;
+ const uint32_t ssrc_;
+ const int width_;
+ const int height_;
+ const VideoCodecType codec_;
+ const uint8_t qp_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_FRAME_DECODED_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc
new file mode 100644
index 0000000000..ba18d50ab6
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
+
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "rtc_base/time_utils.h"
+
+namespace webrtc {
+
+std::vector<std::unique_ptr<RtcEventGenericAckReceived>>
+RtcEventGenericAckReceived::CreateLogs(
+ int64_t packet_number,
+ const std::vector<AckedPacket>& acked_packets) {
+ std::vector<std::unique_ptr<RtcEventGenericAckReceived>> result;
+ int64_t time_us = rtc::TimeMicros();
+ result.reserve(acked_packets.size());
+ for (const AckedPacket& packet : acked_packets) {
+ result.emplace_back(new RtcEventGenericAckReceived(
+ time_us, packet_number, packet.packet_number,
+ packet.receive_acked_packet_time_ms));
+ }
+ return result;
+}
+
+RtcEventGenericAckReceived::RtcEventGenericAckReceived(
+ int64_t timestamp_us,
+ int64_t packet_number,
+ int64_t acked_packet_number,
+ absl::optional<int64_t> receive_acked_packet_time_ms)
+ : RtcEvent(timestamp_us),
+ packet_number_(packet_number),
+ acked_packet_number_(acked_packet_number),
+ receive_acked_packet_time_ms_(receive_acked_packet_time_ms) {}
+
+std::unique_ptr<RtcEventGenericAckReceived> RtcEventGenericAckReceived::Copy()
+ const {
+ return absl::WrapUnique(new RtcEventGenericAckReceived(*this));
+}
+
+RtcEventGenericAckReceived::RtcEventGenericAckReceived(
+ const RtcEventGenericAckReceived& packet) = default;
+
+RtcEventGenericAckReceived::~RtcEventGenericAckReceived() = default;
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
new file mode 100644
index 0000000000..57fd7cd9a6
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_ack_received.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_ACK_RECEIVED_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_ACK_RECEIVED_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedGenericAckReceived {
+ LoggedGenericAckReceived() = default;
+ LoggedGenericAckReceived(Timestamp timestamp,
+ int64_t packet_number,
+ int64_t acked_packet_number,
+ absl::optional<int64_t> receive_acked_packet_time_ms)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int64_t packet_number;
+ int64_t acked_packet_number;
+ absl::optional<int64_t> receive_acked_packet_time_ms;
+};
+
+struct AckedPacket {
+ // The packet number that was acked.
+ int64_t packet_number;
+
+ // The time where the packet was received. Not every ACK will
+ // include the receive timestamp.
+ absl::optional<int64_t> receive_acked_packet_time_ms;
+};
+
+class RtcEventGenericAckReceived final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::GenericAckReceived;
+
+ // For a collection of acked packets, it creates a vector of logs to log with
+ // the same timestamp.
+ static std::vector<std::unique_ptr<RtcEventGenericAckReceived>> CreateLogs(
+ int64_t packet_number,
+ const std::vector<AckedPacket>& acked_packets);
+
+ ~RtcEventGenericAckReceived() override;
+
+ std::unique_ptr<RtcEventGenericAckReceived> Copy() const;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ // An identifier of the packet which contained an ack.
+ int64_t packet_number() const { return packet_number_; }
+
+ // An identifier of the acked packet.
+ int64_t acked_packet_number() const { return acked_packet_number_; }
+
+ // Timestamp when the `acked_packet_number` was received by the remote side.
+ absl::optional<int64_t> receive_acked_packet_time_ms() const {
+ return receive_acked_packet_time_ms_;
+ }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedGenericAckReceived>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventGenericAckReceived(const RtcEventGenericAckReceived& packet);
+
+ // When the ack is received, `packet_number` identifies the packet which
+ // contained an ack for `acked_packet_number`, and contains the
+ // `receive_acked_packet_time_ms` on which the `acked_packet_number` was
+ // received on the remote side. The `receive_acked_packet_time_ms` may be
+ // null.
+ RtcEventGenericAckReceived(
+ int64_t timestamp_us,
+ int64_t packet_number,
+ int64_t acked_packet_number,
+ absl::optional<int64_t> receive_acked_packet_time_ms);
+
+ const int64_t packet_number_;
+ const int64_t acked_packet_number_;
+ const absl::optional<int64_t> receive_acked_packet_time_ms_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_ACK_RECEIVED_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.cc
new file mode 100644
index 0000000000..0bdc4dd505
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventGenericPacketReceived::RtcEventGenericPacketReceived(
+ int64_t packet_number,
+ size_t packet_length)
+ : packet_number_(packet_number), packet_length_(packet_length) {}
+
+RtcEventGenericPacketReceived::RtcEventGenericPacketReceived(
+ const RtcEventGenericPacketReceived& packet) = default;
+
+RtcEventGenericPacketReceived::~RtcEventGenericPacketReceived() = default;
+
+std::unique_ptr<RtcEventGenericPacketReceived>
+RtcEventGenericPacketReceived::Copy() const {
+ return absl::WrapUnique(new RtcEventGenericPacketReceived(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.h
new file mode 100644
index 0000000000..a6006ca4d4
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_received.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_RECEIVED_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_RECEIVED_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedGenericPacketReceived {
+ LoggedGenericPacketReceived() = default;
+ LoggedGenericPacketReceived(Timestamp timestamp,
+ int64_t packet_number,
+ int packet_length)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int64_t packet_number;
+ int packet_length;
+};
+
+class RtcEventGenericPacketReceived final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::GenericPacketReceived;
+
+ RtcEventGenericPacketReceived(int64_t packet_number, size_t packet_length);
+ ~RtcEventGenericPacketReceived() override;
+
+ std::unique_ptr<RtcEventGenericPacketReceived> Copy() const;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ // An identifier of the packet.
+ int64_t packet_number() const { return packet_number_; }
+
+ // Total packet length, including all packetization overheads, but not
+ // including ICE/TURN/IP overheads.
+ size_t packet_length() const { return packet_length_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedGenericPacketReceived>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventGenericPacketReceived(const RtcEventGenericPacketReceived& packet);
+
+ const int64_t packet_number_;
+ const size_t packet_length_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_RECEIVED_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.cc
new file mode 100644
index 0000000000..e8335624b1
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventGenericPacketSent::RtcEventGenericPacketSent(int64_t packet_number,
+ size_t overhead_length,
+ size_t payload_length,
+ size_t padding_length)
+ : packet_number_(packet_number),
+ overhead_length_(overhead_length),
+ payload_length_(payload_length),
+ padding_length_(padding_length) {}
+
+RtcEventGenericPacketSent::RtcEventGenericPacketSent(
+ const RtcEventGenericPacketSent& packet) = default;
+
+RtcEventGenericPacketSent::~RtcEventGenericPacketSent() = default;
+
+std::unique_ptr<RtcEventGenericPacketSent> RtcEventGenericPacketSent::Copy()
+ const {
+ return absl::WrapUnique(new RtcEventGenericPacketSent(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h
new file mode 100644
index 0000000000..903950a398
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_generic_packet_sent.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_SENT_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_SENT_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedGenericPacketSent {
+ LoggedGenericPacketSent() = default;
+ LoggedGenericPacketSent(Timestamp timestamp,
+ int64_t packet_number,
+ size_t overhead_length,
+ size_t payload_length,
+ size_t padding_length)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ size_t packet_length() const {
+ return payload_length + padding_length + overhead_length;
+ }
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int64_t packet_number;
+ size_t overhead_length;
+ size_t payload_length;
+ size_t padding_length;
+};
+
+class RtcEventGenericPacketSent final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::GenericPacketSent;
+
+ RtcEventGenericPacketSent(int64_t packet_number,
+ size_t overhead_length,
+ size_t payload_length,
+ size_t padding_length);
+ ~RtcEventGenericPacketSent() override;
+
+ std::unique_ptr<RtcEventGenericPacketSent> Copy() const;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ // An identifier of the packet.
+ int64_t packet_number() const { return packet_number_; }
+
+ // Total packet length, including all packetization overheads, but not
+ // including ICE/TURN/IP overheads.
+ size_t packet_length() const {
+ return overhead_length_ + payload_length_ + padding_length_;
+ }
+
+ // The number of bytes in overhead, including framing overheads, acks if
+ // present, etc.
+ size_t overhead_length() const { return overhead_length_; }
+
+ // Length of payload sent (size of raw audio/video/data), without
+ // packetization overheads. This may still include serialization overheads.
+ size_t payload_length() const { return payload_length_; }
+
+ size_t padding_length() const { return padding_length_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedGenericPacketSent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventGenericPacketSent(const RtcEventGenericPacketSent& packet);
+
+ const int64_t packet_number_;
+ const size_t overhead_length_;
+ const size_t payload_length_;
+ const size_t padding_length_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_SENT_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc
new file mode 100644
index 0000000000..2b4b5ba762
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventIceCandidatePair::RtcEventIceCandidatePair(
+ IceCandidatePairEventType type,
+ uint32_t candidate_pair_id,
+ uint32_t transaction_id)
+ : type_(type),
+ candidate_pair_id_(candidate_pair_id),
+ transaction_id_(transaction_id) {}
+
+RtcEventIceCandidatePair::RtcEventIceCandidatePair(
+ const RtcEventIceCandidatePair& other)
+ : RtcEvent(other.timestamp_us_),
+ type_(other.type_),
+ candidate_pair_id_(other.candidate_pair_id_),
+ transaction_id_(other.transaction_id_) {}
+
+RtcEventIceCandidatePair::~RtcEventIceCandidatePair() = default;
+
+std::unique_ptr<RtcEventIceCandidatePair> RtcEventIceCandidatePair::Copy()
+ const {
+ return absl::WrapUnique<RtcEventIceCandidatePair>(
+ new RtcEventIceCandidatePair(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h
new file mode 100644
index 0000000000..bdacf15a59
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+enum class IceCandidatePairEventType {
+ kCheckSent,
+ kCheckReceived,
+ kCheckResponseSent,
+ kCheckResponseReceived,
+ kNumValues,
+};
+
+struct LoggedIceCandidatePairEvent {
+ LoggedIceCandidatePairEvent() = default;
+ LoggedIceCandidatePairEvent(Timestamp timestamp,
+ IceCandidatePairEventType type,
+ uint32_t candidate_pair_id,
+ uint32_t transaction_id)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ IceCandidatePairEventType type;
+ uint32_t candidate_pair_id;
+ uint32_t transaction_id;
+};
+
+class RtcEventIceCandidatePair final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::IceCandidatePairEvent;
+
+ RtcEventIceCandidatePair(IceCandidatePairEventType type,
+ uint32_t candidate_pair_id,
+ uint32_t transaction_id);
+
+ ~RtcEventIceCandidatePair() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventIceCandidatePair> Copy() const;
+
+ IceCandidatePairEventType type() const { return type_; }
+ uint32_t candidate_pair_id() const { return candidate_pair_id_; }
+ uint32_t transaction_id() const { return transaction_id_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedIceCandidatePairEvent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventIceCandidatePair(const RtcEventIceCandidatePair& other);
+
+ const IceCandidatePairEventType type_;
+ const uint32_t candidate_pair_id_;
+ const uint32_t transaction_id_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc
new file mode 100644
index 0000000000..eb458c4640
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+IceCandidatePairDescription::IceCandidatePairDescription() {
+ local_candidate_type = IceCandidateType::kUnknown;
+ local_relay_protocol = IceCandidatePairProtocol::kUnknown;
+ local_network_type = IceCandidateNetworkType::kUnknown;
+ local_address_family = IceCandidatePairAddressFamily::kUnknown;
+ remote_candidate_type = IceCandidateType::kUnknown;
+ remote_address_family = IceCandidatePairAddressFamily::kUnknown;
+ candidate_pair_protocol = IceCandidatePairProtocol::kUnknown;
+}
+
+IceCandidatePairDescription::IceCandidatePairDescription(
+ const IceCandidatePairDescription& other) {
+ local_candidate_type = other.local_candidate_type;
+ local_relay_protocol = other.local_relay_protocol;
+ local_network_type = other.local_network_type;
+ local_address_family = other.local_address_family;
+ remote_candidate_type = other.remote_candidate_type;
+ remote_address_family = other.remote_address_family;
+ candidate_pair_protocol = other.candidate_pair_protocol;
+}
+
+IceCandidatePairDescription::~IceCandidatePairDescription() {}
+
+RtcEventIceCandidatePairConfig::RtcEventIceCandidatePairConfig(
+ IceCandidatePairConfigType type,
+ uint32_t candidate_pair_id,
+ const IceCandidatePairDescription& candidate_pair_desc)
+ : type_(type),
+ candidate_pair_id_(candidate_pair_id),
+ candidate_pair_desc_(candidate_pair_desc) {}
+
+RtcEventIceCandidatePairConfig::RtcEventIceCandidatePairConfig(
+ const RtcEventIceCandidatePairConfig& other)
+ : RtcEvent(other.timestamp_us_),
+ type_(other.type_),
+ candidate_pair_id_(other.candidate_pair_id_),
+ candidate_pair_desc_(other.candidate_pair_desc_) {}
+
+RtcEventIceCandidatePairConfig::~RtcEventIceCandidatePairConfig() = default;
+
+std::unique_ptr<RtcEventIceCandidatePairConfig>
+RtcEventIceCandidatePairConfig::Copy() const {
+ return absl::WrapUnique<RtcEventIceCandidatePairConfig>(
+ new RtcEventIceCandidatePairConfig(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h
new file mode 100644
index 0000000000..e72d999cff
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+enum class IceCandidatePairConfigType {
+ kAdded,
+ kUpdated,
+ kDestroyed,
+ kSelected,
+ kNumValues,
+};
+
+// TODO(qingsi): Change the names of candidate types to "host", "srflx", "prflx"
+// and "relay" after the naming is spec-compliant in the signaling part
+enum class IceCandidateType {
+ kUnknown,
+ kLocal,
+ kStun,
+ kPrflx,
+ kRelay,
+ kNumValues,
+};
+
+enum class IceCandidatePairProtocol {
+ kUnknown,
+ kUdp,
+ kTcp,
+ kSsltcp,
+ kTls,
+ kNumValues,
+};
+
+enum class IceCandidatePairAddressFamily {
+ kUnknown,
+ kIpv4,
+ kIpv6,
+ kNumValues,
+};
+
+enum class IceCandidateNetworkType {
+ kUnknown,
+ kEthernet,
+ kLoopback,
+ kWifi,
+ kVpn,
+ kCellular,
+ kNumValues,
+};
+
+struct LoggedIceCandidatePairConfig {
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ IceCandidatePairConfigType type;
+ uint32_t candidate_pair_id;
+ IceCandidateType local_candidate_type;
+ IceCandidatePairProtocol local_relay_protocol;
+ IceCandidateNetworkType local_network_type;
+ IceCandidatePairAddressFamily local_address_family;
+ IceCandidateType remote_candidate_type;
+ IceCandidatePairAddressFamily remote_address_family;
+ IceCandidatePairProtocol candidate_pair_protocol;
+};
+
+class IceCandidatePairDescription {
+ public:
+ IceCandidatePairDescription();
+ explicit IceCandidatePairDescription(
+ const IceCandidatePairDescription& other);
+
+ ~IceCandidatePairDescription();
+
+ IceCandidateType local_candidate_type;
+ IceCandidatePairProtocol local_relay_protocol;
+ IceCandidateNetworkType local_network_type;
+ IceCandidatePairAddressFamily local_address_family;
+ IceCandidateType remote_candidate_type;
+ IceCandidatePairAddressFamily remote_address_family;
+ IceCandidatePairProtocol candidate_pair_protocol;
+};
+
+class RtcEventIceCandidatePairConfig final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::IceCandidatePairConfig;
+
+ RtcEventIceCandidatePairConfig(
+ IceCandidatePairConfigType type,
+ uint32_t candidate_pair_id,
+ const IceCandidatePairDescription& candidate_pair_desc);
+
+ ~RtcEventIceCandidatePairConfig() override;
+
+ Type GetType() const override { return kType; }
+ // N.B. An ICE config event is not considered an RtcEventLog config event.
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventIceCandidatePairConfig> Copy() const;
+
+ IceCandidatePairConfigType type() const { return type_; }
+ uint32_t candidate_pair_id() const { return candidate_pair_id_; }
+ const IceCandidatePairDescription& candidate_pair_desc() const {
+ return candidate_pair_desc_;
+ }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedIceCandidatePairConfig>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventIceCandidatePairConfig(const RtcEventIceCandidatePairConfig& other);
+
+ const IceCandidatePairConfigType type_;
+ const uint32_t candidate_pair_id_;
+ const IceCandidatePairDescription candidate_pair_desc_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.cc
new file mode 100644
index 0000000000..7b958c181b
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.cc
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h"
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_definition.h"
+
+namespace webrtc {
+
+RtcEventNetEqSetMinimumDelay::RtcEventNetEqSetMinimumDelay(uint32_t remote_ssrc,
+ int delay_ms)
+ : remote_ssrc_(remote_ssrc), minimum_delay_ms_(delay_ms) {}
+RtcEventNetEqSetMinimumDelay::~RtcEventNetEqSetMinimumDelay() {}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h
new file mode 100644
index 0000000000..2e49adb36e
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_neteq_set_minimum_delay.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_NETEQ_SET_MINIMUM_DELAY_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_NETEQ_SET_MINIMUM_DELAY_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_definition.h"
+
+namespace webrtc {
+
+struct LoggedNetEqSetMinimumDelayEvent {
+ LoggedNetEqSetMinimumDelayEvent() = default;
+ LoggedNetEqSetMinimumDelayEvent(Timestamp timestamp,
+ uint32_t remote_ssrc,
+ int minimum_delay_ms)
+ : timestamp(timestamp),
+ remote_ssrc(remote_ssrc),
+ minimum_delay_ms(minimum_delay_ms) {}
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ uint32_t remote_ssrc;
+ int minimum_delay_ms;
+};
+
+class RtcEventNetEqSetMinimumDelay final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::NetEqSetMinimumDelay;
+
+ explicit RtcEventNetEqSetMinimumDelay(uint32_t remote_ssrc, int delay_ms);
+ ~RtcEventNetEqSetMinimumDelay() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+ uint32_t remote_ssrc() const { return remote_ssrc_; }
+ int minimum_delay_ms() const { return minimum_delay_ms_; }
+
+ std::unique_ptr<RtcEventNetEqSetMinimumDelay> Copy() const {
+ return absl::WrapUnique<RtcEventNetEqSetMinimumDelay>(
+ new RtcEventNetEqSetMinimumDelay(*this));
+ }
+
+ private:
+ uint32_t remote_ssrc_;
+ int minimum_delay_ms_;
+};
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_NETEQ_SET_MINIMUM_DELAY_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc
new file mode 100644
index 0000000000..c3d9e59b47
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventProbeClusterCreated::RtcEventProbeClusterCreated(int32_t id,
+ int32_t bitrate_bps,
+ uint32_t min_probes,
+ uint32_t min_bytes)
+ : id_(id),
+ bitrate_bps_(bitrate_bps),
+ min_probes_(min_probes),
+ min_bytes_(min_bytes) {}
+
+RtcEventProbeClusterCreated::RtcEventProbeClusterCreated(
+ const RtcEventProbeClusterCreated& other)
+ : RtcEvent(other.timestamp_us_),
+ id_(other.id_),
+ bitrate_bps_(other.bitrate_bps_),
+ min_probes_(other.min_probes_),
+ min_bytes_(other.min_bytes_) {}
+
+std::unique_ptr<RtcEventProbeClusterCreated> RtcEventProbeClusterCreated::Copy()
+ const {
+ return absl::WrapUnique<RtcEventProbeClusterCreated>(
+ new RtcEventProbeClusterCreated(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h
new file mode 100644
index 0000000000..ae6810c39d
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_CLUSTER_CREATED_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_CLUSTER_CREATED_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedBweProbeClusterCreatedEvent {
+ LoggedBweProbeClusterCreatedEvent() = default;
+ LoggedBweProbeClusterCreatedEvent(Timestamp timestamp,
+ int32_t id,
+ int32_t bitrate_bps,
+ uint32_t min_packets,
+ uint32_t min_bytes)
+ : 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int32_t id;
+ int32_t bitrate_bps;
+ uint32_t min_packets;
+ uint32_t min_bytes;
+};
+
+class RtcEventProbeClusterCreated final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::ProbeClusterCreated;
+
+ RtcEventProbeClusterCreated(int32_t id,
+ int32_t bitrate_bps,
+ uint32_t min_probes,
+ uint32_t min_bytes);
+ ~RtcEventProbeClusterCreated() override = default;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventProbeClusterCreated> Copy() const;
+
+ int32_t id() const { return id_; }
+ int32_t bitrate_bps() const { return bitrate_bps_; }
+ uint32_t min_probes() const { return min_probes_; }
+ uint32_t min_bytes() const { return min_bytes_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedBweProbeClusterCreatedEvent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventProbeClusterCreated(const RtcEventProbeClusterCreated& other);
+
+ const int32_t id_;
+ const int32_t bitrate_bps_;
+ const uint32_t min_probes_;
+ const uint32_t min_bytes_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_CLUSTER_CREATED_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc
new file mode 100644
index 0000000000..a79b0c173d
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventProbeResultFailure::RtcEventProbeResultFailure(
+ int32_t id,
+ ProbeFailureReason failure_reason)
+ : id_(id), failure_reason_(failure_reason) {}
+
+RtcEventProbeResultFailure::RtcEventProbeResultFailure(
+ const RtcEventProbeResultFailure& other)
+ : RtcEvent(other.timestamp_us_),
+ id_(other.id_),
+ failure_reason_(other.failure_reason_) {}
+
+std::unique_ptr<RtcEventProbeResultFailure> RtcEventProbeResultFailure::Copy()
+ const {
+ return absl::WrapUnique<RtcEventProbeResultFailure>(
+ new RtcEventProbeResultFailure(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.h
new file mode 100644
index 0000000000..1aa6e75cb7
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_failure.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_FAILURE_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_FAILURE_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+enum class ProbeFailureReason {
+ kInvalidSendReceiveInterval = 0,
+ kInvalidSendReceiveRatio,
+ kTimeout,
+ kLast
+};
+
+struct LoggedBweProbeFailureEvent {
+ LoggedBweProbeFailureEvent() = default;
+ LoggedBweProbeFailureEvent(Timestamp timestamp,
+ int32_t id,
+ ProbeFailureReason 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int32_t id;
+ ProbeFailureReason failure_reason;
+};
+
+class RtcEventProbeResultFailure final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::ProbeResultFailure;
+
+ RtcEventProbeResultFailure(int32_t id, ProbeFailureReason failure_reason);
+ ~RtcEventProbeResultFailure() override = default;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventProbeResultFailure> Copy() const;
+
+ int32_t id() const { return id_; }
+ ProbeFailureReason failure_reason() const { return failure_reason_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedBweProbeFailureEvent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventProbeResultFailure(const RtcEventProbeResultFailure& other);
+
+ const int32_t id_;
+ const ProbeFailureReason failure_reason_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_FAILURE_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.cc
new file mode 100644
index 0000000000..e7bc7c25da
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.cc
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventProbeResultSuccess::RtcEventProbeResultSuccess(int32_t id,
+ int32_t bitrate_bps)
+ : id_(id), bitrate_bps_(bitrate_bps) {}
+
+RtcEventProbeResultSuccess::RtcEventProbeResultSuccess(
+ const RtcEventProbeResultSuccess& other)
+ : RtcEvent(other.timestamp_us_),
+ id_(other.id_),
+ bitrate_bps_(other.bitrate_bps_) {}
+
+std::unique_ptr<RtcEventProbeResultSuccess> RtcEventProbeResultSuccess::Copy()
+ const {
+ return absl::WrapUnique<RtcEventProbeResultSuccess>(
+ new RtcEventProbeResultSuccess(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.h
new file mode 100644
index 0000000000..49d1abec5a
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_probe_result_success.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_SUCCESS_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_SUCCESS_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedBweProbeSuccessEvent {
+ LoggedBweProbeSuccessEvent() = default;
+ LoggedBweProbeSuccessEvent(Timestamp timestamp,
+ int32_t id,
+ int32_t 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ int32_t id;
+ int32_t bitrate_bps;
+};
+
+class RtcEventProbeResultSuccess final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::ProbeResultSuccess;
+
+ RtcEventProbeResultSuccess(int32_t id, int32_t bitrate_bps);
+ ~RtcEventProbeResultSuccess() override = default;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventProbeResultSuccess> Copy() const;
+
+ int32_t id() const { return id_; }
+ int32_t bitrate_bps() const { return bitrate_bps_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedBweProbeSuccessEvent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventProbeResultSuccess(const RtcEventProbeResultSuccess& other);
+
+ const int32_t id_;
+ const int32_t bitrate_bps_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_SUCCESS_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_remote_estimate.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_remote_estimate.h
new file mode 100644
index 0000000000..4a39ecc597
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_remote_estimate.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/data_rate.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedRemoteEstimateEvent {
+ LoggedRemoteEstimateEvent() = default;
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ absl::optional<DataRate> link_capacity_lower;
+ absl::optional<DataRate> link_capacity_upper;
+};
+
+class RtcEventRemoteEstimate final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::RemoteEstimateEvent;
+
+ RtcEventRemoteEstimate(DataRate link_capacity_lower,
+ DataRate link_capacity_upper)
+ : link_capacity_lower_(link_capacity_lower),
+ link_capacity_upper_(link_capacity_upper) {}
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedRemoteEstimateEvent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ const DataRate link_capacity_lower_;
+ const DataRate link_capacity_upper_;
+};
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_REMOTE_ESTIMATE_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.cc
new file mode 100644
index 0000000000..71bd78b346
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.cc
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_route_change.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventRouteChange::RtcEventRouteChange(bool connected, uint32_t overhead)
+ : connected_(connected), overhead_(overhead) {}
+
+RtcEventRouteChange::RtcEventRouteChange(const RtcEventRouteChange& other)
+ : RtcEvent(other.timestamp_us_),
+ connected_(other.connected_),
+ overhead_(other.overhead_) {}
+
+RtcEventRouteChange::~RtcEventRouteChange() = default;
+
+std::unique_ptr<RtcEventRouteChange> RtcEventRouteChange::Copy() const {
+ return absl::WrapUnique<RtcEventRouteChange>(new RtcEventRouteChange(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.h
new file mode 100644
index 0000000000..bc1461d7bb
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_route_change.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ROUTE_CHANGE_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ROUTE_CHANGE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+
+namespace webrtc {
+
+struct LoggedRouteChangeEvent {
+ LoggedRouteChangeEvent() = default;
+ LoggedRouteChangeEvent(Timestamp timestamp, bool connected, uint32_t overhead)
+ : timestamp(timestamp), connected(connected), overhead(overhead) {}
+
+ int64_t log_time_us() const { return timestamp.us(); }
+ int64_t log_time_ms() const { return timestamp.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ bool connected;
+ uint32_t overhead;
+};
+
+class RtcEventRouteChange final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::RouteChangeEvent;
+
+ RtcEventRouteChange(bool connected, uint32_t overhead);
+ ~RtcEventRouteChange() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventRouteChange> Copy() const;
+
+ bool connected() const { return connected_; }
+ uint32_t overhead() const { return overhead_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedRouteChangeEvent>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventRouteChange(const RtcEventRouteChange& other);
+
+ const bool connected_;
+ const uint32_t overhead_;
+};
+
+} // namespace webrtc
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ROUTE_CHANGE_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc
new file mode 100644
index 0000000000..0ea700a024
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventRtcpPacketIncoming::RtcEventRtcpPacketIncoming(
+ rtc::ArrayView<const uint8_t> packet)
+ : packet_(packet.data(), packet.size()) {}
+
+RtcEventRtcpPacketIncoming::RtcEventRtcpPacketIncoming(
+ const RtcEventRtcpPacketIncoming& other)
+ : RtcEvent(other.timestamp_us_),
+ packet_(other.packet_.data(), other.packet_.size()) {}
+
+RtcEventRtcpPacketIncoming::~RtcEventRtcpPacketIncoming() = default;
+
+std::unique_ptr<RtcEventRtcpPacketIncoming> RtcEventRtcpPacketIncoming::Copy()
+ const {
+ return absl::WrapUnique<RtcEventRtcpPacketIncoming>(
+ new RtcEventRtcpPacketIncoming(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h
new file mode 100644
index 0000000000..84fe398e08
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_INCOMING_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_INCOMING_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "rtc_base/buffer.h"
+
+namespace webrtc {
+
+class RtcEventRtcpPacketIncoming final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::RtcpPacketIncoming;
+
+ explicit RtcEventRtcpPacketIncoming(rtc::ArrayView<const uint8_t> packet);
+ ~RtcEventRtcpPacketIncoming() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventRtcpPacketIncoming> Copy() const;
+
+ const rtc::Buffer& packet() const { return packet_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedRtcpPacketIncoming>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventRtcpPacketIncoming(const RtcEventRtcpPacketIncoming& other);
+
+ rtc::Buffer packet_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_INCOMING_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc
new file mode 100644
index 0000000000..b6a41ac034
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventRtcpPacketOutgoing::RtcEventRtcpPacketOutgoing(
+ rtc::ArrayView<const uint8_t> packet)
+ : packet_(packet.data(), packet.size()) {}
+
+RtcEventRtcpPacketOutgoing::RtcEventRtcpPacketOutgoing(
+ const RtcEventRtcpPacketOutgoing& other)
+ : RtcEvent(other.timestamp_us_),
+ packet_(other.packet_.data(), other.packet_.size()) {}
+
+RtcEventRtcpPacketOutgoing::~RtcEventRtcpPacketOutgoing() = default;
+
+std::unique_ptr<RtcEventRtcpPacketOutgoing> RtcEventRtcpPacketOutgoing::Copy()
+ const {
+ return absl::WrapUnique<RtcEventRtcpPacketOutgoing>(
+ new RtcEventRtcpPacketOutgoing(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h
new file mode 100644
index 0000000000..687bd319b4
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_OUTGOING_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_OUTGOING_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "rtc_base/buffer.h"
+
+namespace webrtc {
+
+class RtcEventRtcpPacketOutgoing final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::RtcpPacketOutgoing;
+
+ explicit RtcEventRtcpPacketOutgoing(rtc::ArrayView<const uint8_t> packet);
+ ~RtcEventRtcpPacketOutgoing() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventRtcpPacketOutgoing> Copy() const;
+
+ const rtc::Buffer& packet() const { return packet_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedRtcpPacketOutgoing>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing& other);
+
+ rtc::Buffer packet_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_OUTGOING_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc
new file mode 100644
index 0000000000..4cf33a238f
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
+
+#include "absl/memory/memory.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RtcEventRtpPacketIncoming::RtcEventRtpPacketIncoming(
+ const RtpPacketReceived& packet)
+ : packet_(packet) {}
+
+RtcEventRtpPacketIncoming::RtcEventRtpPacketIncoming(
+ const RtcEventRtpPacketIncoming& other)
+ : RtcEvent(other.timestamp_us_), packet_(other.packet_) {}
+
+RtcEventRtpPacketIncoming::~RtcEventRtpPacketIncoming() = default;
+
+std::unique_ptr<RtcEventRtpPacketIncoming> RtcEventRtpPacketIncoming::Copy()
+ const {
+ return absl::WrapUnique<RtcEventRtpPacketIncoming>(
+ new RtcEventRtpPacketIncoming(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h
new file mode 100644
index 0000000000..926ddddff5
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_INCOMING_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_INCOMING_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "modules/rtp_rtcp/source/rtp_packet.h"
+
+namespace webrtc {
+
+class RtpPacketReceived;
+
+class RtcEventRtpPacketIncoming final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::RtpPacketIncoming;
+
+ explicit RtcEventRtpPacketIncoming(const RtpPacketReceived& packet);
+ ~RtcEventRtpPacketIncoming() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventRtpPacketIncoming> Copy() const;
+
+ size_t packet_length() const { return packet_.size(); }
+
+ rtc::ArrayView<const uint8_t> RawHeader() const {
+ return rtc::MakeArrayView(packet_.data(), header_length());
+ }
+ uint32_t Ssrc() const { return packet_.Ssrc(); }
+ uint32_t Timestamp() const { return packet_.Timestamp(); }
+ uint16_t SequenceNumber() const { return packet_.SequenceNumber(); }
+ uint8_t PayloadType() const { return packet_.PayloadType(); }
+ bool Marker() const { return packet_.Marker(); }
+ template <typename ExtensionTrait, typename... Args>
+ bool GetExtension(Args&&... args) const {
+ return packet_.GetExtension<ExtensionTrait>(std::forward<Args>(args)...);
+ }
+ template <typename ExtensionTrait>
+ bool HasExtension() const {
+ return packet_.HasExtension<ExtensionTrait>();
+ }
+
+ size_t payload_length() const { return packet_.payload_size(); }
+ size_t header_length() const { return packet_.headers_size(); }
+ size_t padding_length() const { return packet_.padding_size(); }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::map<uint32_t, std::vector<LoggedRtpPacketIncoming>>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventRtpPacketIncoming(const RtcEventRtpPacketIncoming& other);
+
+ const RtpPacket packet_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_INCOMING_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc
new file mode 100644
index 0000000000..a6a4d99702
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
+
+#include "absl/memory/memory.h"
+#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RtcEventRtpPacketOutgoing::RtcEventRtpPacketOutgoing(
+ const RtpPacketToSend& packet,
+ int probe_cluster_id)
+ : packet_(packet), probe_cluster_id_(probe_cluster_id) {}
+
+RtcEventRtpPacketOutgoing::RtcEventRtpPacketOutgoing(
+ const RtcEventRtpPacketOutgoing& other)
+ : RtcEvent(other.timestamp_us_),
+ packet_(other.packet_),
+ probe_cluster_id_(other.probe_cluster_id_) {}
+
+RtcEventRtpPacketOutgoing::~RtcEventRtpPacketOutgoing() = default;
+
+std::unique_ptr<RtcEventRtpPacketOutgoing> RtcEventRtpPacketOutgoing::Copy()
+ const {
+ return absl::WrapUnique<RtcEventRtpPacketOutgoing>(
+ new RtcEventRtpPacketOutgoing(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h
new file mode 100644
index 0000000000..c7b7a09718
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_OUTGOING_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_OUTGOING_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "logging/rtc_event_log/events/logged_rtp_rtcp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "modules/rtp_rtcp/source/rtp_packet.h"
+
+namespace webrtc {
+
+class RtpPacketToSend;
+
+class RtcEventRtpPacketOutgoing final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::RtpPacketOutgoing;
+
+ RtcEventRtpPacketOutgoing(const RtpPacketToSend& packet,
+ int probe_cluster_id);
+ ~RtcEventRtpPacketOutgoing() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return false; }
+
+ std::unique_ptr<RtcEventRtpPacketOutgoing> Copy() const;
+
+ size_t packet_length() const { return packet_.size(); }
+
+ rtc::ArrayView<const uint8_t> RawHeader() const {
+ return rtc::MakeArrayView(packet_.data(), header_length());
+ }
+ uint32_t Ssrc() const { return packet_.Ssrc(); }
+ uint32_t Timestamp() const { return packet_.Timestamp(); }
+ uint16_t SequenceNumber() const { return packet_.SequenceNumber(); }
+ uint8_t PayloadType() const { return packet_.PayloadType(); }
+ bool Marker() const { return packet_.Marker(); }
+ template <typename ExtensionTrait, typename... Args>
+ bool GetExtension(Args&&... args) const {
+ return packet_.GetExtension<ExtensionTrait>(std::forward<Args>(args)...);
+ }
+ template <typename ExtensionTrait>
+ bool HasExtension() const {
+ return packet_.HasExtension<ExtensionTrait>();
+ }
+
+ size_t payload_length() const { return packet_.payload_size(); }
+ size_t header_length() const { return packet_.headers_size(); }
+ size_t padding_length() const { return packet_.padding_size(); }
+ int probe_cluster_id() const { return probe_cluster_id_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::map<uint32_t, std::vector<LoggedRtpPacketOutgoing>>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventRtpPacketOutgoing(const RtcEventRtpPacketOutgoing& other);
+
+ const RtpPacket packet_;
+ // TODO(eladalon): Delete `probe_cluster_id_` along with legacy encoding.
+ const int probe_cluster_id_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_OUTGOING_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc
new file mode 100644
index 0000000000..90ab8185a3
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+RtcEventVideoReceiveStreamConfig::RtcEventVideoReceiveStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config)
+ : config_(std::move(config)) {
+ RTC_DCHECK(config_);
+}
+
+RtcEventVideoReceiveStreamConfig::RtcEventVideoReceiveStreamConfig(
+ const RtcEventVideoReceiveStreamConfig& other)
+ : RtcEvent(other.timestamp_us_),
+ config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
+
+RtcEventVideoReceiveStreamConfig::~RtcEventVideoReceiveStreamConfig() = default;
+
+std::unique_ptr<RtcEventVideoReceiveStreamConfig>
+RtcEventVideoReceiveStreamConfig::Copy() const {
+ return absl::WrapUnique<RtcEventVideoReceiveStreamConfig>(
+ new RtcEventVideoReceiveStreamConfig(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h
new file mode 100644
index 0000000000..0be56c2065
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_RECEIVE_STREAM_CONFIG_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_RECEIVE_STREAM_CONFIG_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/rtc_stream_config.h"
+
+namespace webrtc {
+
+struct LoggedVideoRecvConfig {
+ LoggedVideoRecvConfig() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtclog::StreamConfig config;
+};
+
+class RtcEventVideoReceiveStreamConfig final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::VideoReceiveStreamConfig;
+
+ explicit RtcEventVideoReceiveStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config);
+ ~RtcEventVideoReceiveStreamConfig() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return true; }
+
+ std::unique_ptr<RtcEventVideoReceiveStreamConfig> Copy() const;
+
+ const rtclog::StreamConfig& config() const { return *config_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedVideoRecvConfig>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventVideoReceiveStreamConfig(
+ const RtcEventVideoReceiveStreamConfig& other);
+
+ const std::unique_ptr<const rtclog::StreamConfig> config_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_RECEIVE_STREAM_CONFIG_H_
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc
new file mode 100644
index 0000000000..c28a476d01
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
+
+#include <utility>
+
+#include "absl/memory/memory.h"
+
+namespace webrtc {
+
+RtcEventVideoSendStreamConfig::RtcEventVideoSendStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config)
+ : config_(std::move(config)) {}
+
+RtcEventVideoSendStreamConfig::RtcEventVideoSendStreamConfig(
+ const RtcEventVideoSendStreamConfig& other)
+ : RtcEvent(other.timestamp_us_),
+ config_(std::make_unique<rtclog::StreamConfig>(*other.config_)) {}
+
+RtcEventVideoSendStreamConfig::~RtcEventVideoSendStreamConfig() = default;
+
+std::unique_ptr<RtcEventVideoSendStreamConfig>
+RtcEventVideoSendStreamConfig::Copy() const {
+ return absl::WrapUnique<RtcEventVideoSendStreamConfig>(
+ new RtcEventVideoSendStreamConfig(*this));
+}
+
+} // namespace webrtc
diff --git a/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h
new file mode 100644
index 0000000000..f1717b19ea
--- /dev/null
+++ b/third_party/libwebrtc/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_SEND_STREAM_CONFIG_H_
+#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_SEND_STREAM_CONFIG_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "api/rtc_event_log/rtc_event.h"
+#include "api/units/timestamp.h"
+#include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h"
+#include "logging/rtc_event_log/rtc_stream_config.h"
+
+namespace webrtc {
+
+struct LoggedVideoSendConfig {
+ LoggedVideoSendConfig() = default;
+ 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.ms(); }
+ Timestamp log_time() const { return timestamp; }
+
+ Timestamp timestamp = Timestamp::MinusInfinity();
+ rtclog::StreamConfig config;
+};
+
+class RtcEventVideoSendStreamConfig final : public RtcEvent {
+ public:
+ static constexpr Type kType = Type::VideoSendStreamConfig;
+
+ explicit RtcEventVideoSendStreamConfig(
+ std::unique_ptr<rtclog::StreamConfig> config);
+ ~RtcEventVideoSendStreamConfig() override;
+
+ Type GetType() const override { return kType; }
+ bool IsConfigEvent() const override { return true; }
+
+ std::unique_ptr<RtcEventVideoSendStreamConfig> Copy() const;
+
+ const rtclog::StreamConfig& config() const { return *config_; }
+
+ static std::string Encode(rtc::ArrayView<const RtcEvent*> batch) {
+ // TODO(terelius): Implement
+ return "";
+ }
+
+ static RtcEventLogParseStatus Parse(
+ absl::string_view encoded_bytes,
+ bool batched,
+ std::vector<LoggedVideoSendConfig>& output) {
+ // TODO(terelius): Implement
+ return RtcEventLogParseStatus::Error("Not Implemented", __FILE__, __LINE__);
+ }
+
+ private:
+ RtcEventVideoSendStreamConfig(const RtcEventVideoSendStreamConfig& other);
+
+ const std::unique_ptr<const rtclog::StreamConfig> config_;
+};
+
+} // namespace webrtc
+
+#endif // LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_VIDEO_SEND_STREAM_CONFIG_H_