• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h"
12 
13 #include "absl/types/optional.h"
14 #include "api/array_view.h"
15 #include "logging/rtc_event_log/encoder/blob_encoding.h"
16 #include "logging/rtc_event_log/encoder/delta_encoding.h"
17 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_common.h"
18 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
19 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
20 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
21 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
22 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
23 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
24 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
25 #include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
26 #include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
27 #include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
28 #include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
29 #include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
30 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
31 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
32 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
33 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
34 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
35 #include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
36 #include "logging/rtc_event_log/events/rtc_event_route_change.h"
37 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
38 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
39 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
40 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
41 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
42 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
43 #include "logging/rtc_event_log/rtc_stream_config.h"
44 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
45 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
46 #include "modules/rtp_rtcp/include/rtp_cvo.h"
47 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
48 #include "modules/rtp_rtcp/source/rtcp_packet/app.h"
49 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
50 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
51 #include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
52 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
53 #include "modules/rtp_rtcp/source/rtcp_packet/psfb.h"
54 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
55 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
56 #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
57 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
58 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
59 #include "modules/rtp_rtcp/source/rtp_packet.h"
60 #include "rtc_base/checks.h"
61 #include "rtc_base/ignore_wundef.h"
62 #include "rtc_base/logging.h"
63 
64 // *.pb.h files are generated at build-time by the protobuf compiler.
65 RTC_PUSH_IGNORING_WUNDEF()
66 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
67 #include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h"
68 #else
69 #include "logging/rtc_event_log/rtc_event_log2.pb.h"
70 #endif
71 RTC_POP_IGNORING_WUNDEF()
72 
73 using webrtc_event_logging::ToUnsigned;
74 
75 namespace webrtc {
76 
77 namespace {
ConvertToProtoFormat(BandwidthUsage state)78 rtclog2::DelayBasedBweUpdates::DetectorState ConvertToProtoFormat(
79     BandwidthUsage state) {
80   switch (state) {
81     case BandwidthUsage::kBwNormal:
82       return rtclog2::DelayBasedBweUpdates::BWE_NORMAL;
83     case BandwidthUsage::kBwUnderusing:
84       return rtclog2::DelayBasedBweUpdates::BWE_UNDERUSING;
85     case BandwidthUsage::kBwOverusing:
86       return rtclog2::DelayBasedBweUpdates::BWE_OVERUSING;
87     case BandwidthUsage::kLast:
88       RTC_NOTREACHED();
89   }
90   RTC_NOTREACHED();
91   return rtclog2::DelayBasedBweUpdates::BWE_UNKNOWN_STATE;
92 }
93 
ConvertToProtoFormat(ProbeFailureReason failure_reason)94 rtclog2::BweProbeResultFailure::FailureReason ConvertToProtoFormat(
95     ProbeFailureReason failure_reason) {
96   switch (failure_reason) {
97     case ProbeFailureReason::kInvalidSendReceiveInterval:
98       return rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_INTERVAL;
99     case ProbeFailureReason::kInvalidSendReceiveRatio:
100       return rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_RATIO;
101     case ProbeFailureReason::kTimeout:
102       return rtclog2::BweProbeResultFailure::TIMEOUT;
103     case ProbeFailureReason::kLast:
104       RTC_NOTREACHED();
105   }
106   RTC_NOTREACHED();
107   return rtclog2::BweProbeResultFailure::UNKNOWN;
108 }
109 
110 // Returns true if there are recognized extensions that we should log
111 // and false if there are no extensions or all extensions are types we don't
112 // log. The protobuf representation of the header configs is written to
113 // |proto_config|.
ConvertToProtoFormat(const std::vector<RtpExtension> & extensions,rtclog2::RtpHeaderExtensionConfig * proto_config)114 bool ConvertToProtoFormat(const std::vector<RtpExtension>& extensions,
115                           rtclog2::RtpHeaderExtensionConfig* proto_config) {
116   size_t unknown_extensions = 0;
117   for (auto& extension : extensions) {
118     if (extension.uri == RtpExtension::kAudioLevelUri) {
119       proto_config->set_audio_level_id(extension.id);
120     } else if (extension.uri == RtpExtension::kTimestampOffsetUri) {
121       proto_config->set_transmission_time_offset_id(extension.id);
122     } else if (extension.uri == RtpExtension::kAbsSendTimeUri) {
123       proto_config->set_absolute_send_time_id(extension.id);
124     } else if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
125       proto_config->set_transport_sequence_number_id(extension.id);
126     } else if (extension.uri == RtpExtension::kVideoRotationUri) {
127       proto_config->set_video_rotation_id(extension.id);
128     } else {
129       ++unknown_extensions;
130     }
131   }
132   return unknown_extensions < extensions.size();
133 }
134 
ConvertToProtoFormat(webrtc::DtlsTransportState state)135 rtclog2::DtlsTransportStateEvent::DtlsTransportState ConvertToProtoFormat(
136     webrtc::DtlsTransportState state) {
137   switch (state) {
138     case webrtc::DtlsTransportState::kNew:
139       return rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_NEW;
140     case webrtc::DtlsTransportState::kConnecting:
141       return rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTING;
142     case webrtc::DtlsTransportState::kConnected:
143       return rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CONNECTED;
144     case webrtc::DtlsTransportState::kClosed:
145       return rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_CLOSED;
146     case webrtc::DtlsTransportState::kFailed:
147       return rtclog2::DtlsTransportStateEvent::DTLS_TRANSPORT_FAILED;
148     case webrtc::DtlsTransportState::kNumValues:
149       RTC_NOTREACHED();
150   }
151   RTC_NOTREACHED();
152   return rtclog2::DtlsTransportStateEvent::UNKNOWN_DTLS_TRANSPORT_STATE;
153 }
154 
155 rtclog2::IceCandidatePairConfig::IceCandidatePairConfigType
ConvertToProtoFormat(IceCandidatePairConfigType type)156 ConvertToProtoFormat(IceCandidatePairConfigType type) {
157   switch (type) {
158     case IceCandidatePairConfigType::kAdded:
159       return rtclog2::IceCandidatePairConfig::ADDED;
160     case IceCandidatePairConfigType::kUpdated:
161       return rtclog2::IceCandidatePairConfig::UPDATED;
162     case IceCandidatePairConfigType::kDestroyed:
163       return rtclog2::IceCandidatePairConfig::DESTROYED;
164     case IceCandidatePairConfigType::kSelected:
165       return rtclog2::IceCandidatePairConfig::SELECTED;
166     case IceCandidatePairConfigType::kNumValues:
167       RTC_NOTREACHED();
168   }
169   RTC_NOTREACHED();
170   return rtclog2::IceCandidatePairConfig::UNKNOWN_CONFIG_TYPE;
171 }
172 
ConvertToProtoFormat(IceCandidateType type)173 rtclog2::IceCandidatePairConfig::IceCandidateType ConvertToProtoFormat(
174     IceCandidateType type) {
175   switch (type) {
176     case IceCandidateType::kUnknown:
177       return rtclog2::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE;
178     case IceCandidateType::kLocal:
179       return rtclog2::IceCandidatePairConfig::LOCAL;
180     case IceCandidateType::kStun:
181       return rtclog2::IceCandidatePairConfig::STUN;
182     case IceCandidateType::kPrflx:
183       return rtclog2::IceCandidatePairConfig::PRFLX;
184     case IceCandidateType::kRelay:
185       return rtclog2::IceCandidatePairConfig::RELAY;
186     case IceCandidateType::kNumValues:
187       RTC_NOTREACHED();
188   }
189   RTC_NOTREACHED();
190   return rtclog2::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE;
191 }
192 
ConvertToProtoFormat(IceCandidatePairProtocol protocol)193 rtclog2::IceCandidatePairConfig::Protocol ConvertToProtoFormat(
194     IceCandidatePairProtocol protocol) {
195   switch (protocol) {
196     case IceCandidatePairProtocol::kUnknown:
197       return rtclog2::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
198     case IceCandidatePairProtocol::kUdp:
199       return rtclog2::IceCandidatePairConfig::UDP;
200     case IceCandidatePairProtocol::kTcp:
201       return rtclog2::IceCandidatePairConfig::TCP;
202     case IceCandidatePairProtocol::kSsltcp:
203       return rtclog2::IceCandidatePairConfig::SSLTCP;
204     case IceCandidatePairProtocol::kTls:
205       return rtclog2::IceCandidatePairConfig::TLS;
206     case IceCandidatePairProtocol::kNumValues:
207       RTC_NOTREACHED();
208   }
209   RTC_NOTREACHED();
210   return rtclog2::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
211 }
212 
ConvertToProtoFormat(IceCandidatePairAddressFamily address_family)213 rtclog2::IceCandidatePairConfig::AddressFamily ConvertToProtoFormat(
214     IceCandidatePairAddressFamily address_family) {
215   switch (address_family) {
216     case IceCandidatePairAddressFamily::kUnknown:
217       return rtclog2::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
218     case IceCandidatePairAddressFamily::kIpv4:
219       return rtclog2::IceCandidatePairConfig::IPV4;
220     case IceCandidatePairAddressFamily::kIpv6:
221       return rtclog2::IceCandidatePairConfig::IPV6;
222     case IceCandidatePairAddressFamily::kNumValues:
223       RTC_NOTREACHED();
224   }
225   RTC_NOTREACHED();
226   return rtclog2::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
227 }
228 
ConvertToProtoFormat(IceCandidateNetworkType network_type)229 rtclog2::IceCandidatePairConfig::NetworkType ConvertToProtoFormat(
230     IceCandidateNetworkType network_type) {
231   switch (network_type) {
232     case IceCandidateNetworkType::kUnknown:
233       return rtclog2::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
234     case IceCandidateNetworkType::kEthernet:
235       return rtclog2::IceCandidatePairConfig::ETHERNET;
236     case IceCandidateNetworkType::kLoopback:
237       return rtclog2::IceCandidatePairConfig::LOOPBACK;
238     case IceCandidateNetworkType::kWifi:
239       return rtclog2::IceCandidatePairConfig::WIFI;
240     case IceCandidateNetworkType::kVpn:
241       return rtclog2::IceCandidatePairConfig::VPN;
242     case IceCandidateNetworkType::kCellular:
243       return rtclog2::IceCandidatePairConfig::CELLULAR;
244     case IceCandidateNetworkType::kNumValues:
245       RTC_NOTREACHED();
246   }
247   RTC_NOTREACHED();
248   return rtclog2::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
249 }
250 
ConvertToProtoFormat(IceCandidatePairEventType type)251 rtclog2::IceCandidatePairEvent::IceCandidatePairEventType ConvertToProtoFormat(
252     IceCandidatePairEventType type) {
253   switch (type) {
254     case IceCandidatePairEventType::kCheckSent:
255       return rtclog2::IceCandidatePairEvent::CHECK_SENT;
256     case IceCandidatePairEventType::kCheckReceived:
257       return rtclog2::IceCandidatePairEvent::CHECK_RECEIVED;
258     case IceCandidatePairEventType::kCheckResponseSent:
259       return rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_SENT;
260     case IceCandidatePairEventType::kCheckResponseReceived:
261       return rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED;
262     case IceCandidatePairEventType::kNumValues:
263       RTC_NOTREACHED();
264   }
265   RTC_NOTREACHED();
266   return rtclog2::IceCandidatePairEvent::UNKNOWN_CHECK_TYPE;
267 }
268 
269 // Copies all RTCP blocks except APP, SDES and unknown from |packet| to
270 // |buffer|. |buffer| must have space for |IP_PACKET_SIZE| bytes. |packet| must
271 // be at most |IP_PACKET_SIZE| bytes long.
RemoveNonWhitelistedRtcpBlocks(const rtc::Buffer & packet,uint8_t * buffer)272 size_t RemoveNonWhitelistedRtcpBlocks(const rtc::Buffer& packet,
273                                       uint8_t* buffer) {
274   RTC_DCHECK(packet.size() <= IP_PACKET_SIZE);
275   RTC_DCHECK(buffer != nullptr);
276   rtcp::CommonHeader header;
277   const uint8_t* block_begin = packet.data();
278   const uint8_t* packet_end = packet.data() + packet.size();
279   size_t buffer_length = 0;
280   while (block_begin < packet_end) {
281     if (!header.Parse(block_begin, packet_end - block_begin)) {
282       break;  // Incorrect message header.
283     }
284     const uint8_t* next_block = header.NextPacket();
285     RTC_DCHECK_GT(next_block, block_begin);
286     RTC_DCHECK_LE(next_block, packet_end);
287     size_t block_size = next_block - block_begin;
288     switch (header.type()) {
289       case rtcp::Bye::kPacketType:
290       case rtcp::ExtendedJitterReport::kPacketType:
291       case rtcp::ExtendedReports::kPacketType:
292       case rtcp::Psfb::kPacketType:
293       case rtcp::ReceiverReport::kPacketType:
294       case rtcp::Rtpfb::kPacketType:
295       case rtcp::SenderReport::kPacketType:
296         // We log sender reports, receiver reports, bye messages
297         // inter-arrival jitter, third-party loss reports, payload-specific
298         // feedback and extended reports.
299         // TODO(terelius): As an optimization, don't copy anything if all blocks
300         // in the packet are whitelisted types.
301         memcpy(buffer + buffer_length, block_begin, block_size);
302         buffer_length += block_size;
303         break;
304       case rtcp::App::kPacketType:
305       case rtcp::Sdes::kPacketType:
306       default:
307         // We don't log sender descriptions, application defined messages
308         // or message blocks of unknown type.
309         break;
310     }
311 
312     block_begin += block_size;
313   }
314   return buffer_length;
315 }
316 
317 template <typename EventType, typename ProtoType>
EncodeRtcpPacket(rtc::ArrayView<const EventType * > batch,ProtoType * proto_batch)318 void EncodeRtcpPacket(rtc::ArrayView<const EventType*> batch,
319                       ProtoType* proto_batch) {
320   if (batch.empty()) {
321     return;
322   }
323 
324   // Base event
325   const EventType* const base_event = batch[0];
326   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
327   {
328     uint8_t buffer[IP_PACKET_SIZE];
329     size_t buffer_length =
330         RemoveNonWhitelistedRtcpBlocks(base_event->packet(), buffer);
331     proto_batch->set_raw_packet(buffer, buffer_length);
332   }
333 
334   if (batch.size() == 1) {
335     return;
336   }
337 
338   // Delta encoding
339   proto_batch->set_number_of_deltas(batch.size() - 1);
340   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
341   std::string encoded_deltas;
342 
343   // timestamp_ms
344   for (size_t i = 0; i < values.size(); ++i) {
345     const EventType* event = batch[i + 1];
346     values[i] = ToUnsigned(event->timestamp_ms());
347   }
348   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
349   if (!encoded_deltas.empty()) {
350     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
351   }
352 
353   // raw_packet
354   std::vector<std::string> scrubed_packets(batch.size() - 1);
355   for (size_t i = 0; i < scrubed_packets.size(); ++i) {
356     const EventType* event = batch[i + 1];
357     scrubed_packets[i].resize(event->packet().size());
358     static_assert(sizeof(std::string::value_type) == sizeof(uint8_t), "");
359     const size_t buffer_length = RemoveNonWhitelistedRtcpBlocks(
360         event->packet(), reinterpret_cast<uint8_t*>(&scrubed_packets[i][0]));
361     if (buffer_length < event->packet().size()) {
362       scrubed_packets[i].resize(buffer_length);
363     }
364   }
365   proto_batch->set_raw_packet_blobs(EncodeBlobs(scrubed_packets));
366 }
367 
368 template <typename EventType, typename ProtoType>
EncodeRtpPacket(const std::vector<const EventType * > & batch,ProtoType * proto_batch)369 void EncodeRtpPacket(const std::vector<const EventType*>& batch,
370                      ProtoType* proto_batch) {
371   if (batch.empty()) {
372     return;
373   }
374 
375   // Base event
376   const EventType* const base_event = batch[0];
377   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
378   proto_batch->set_marker(base_event->header().Marker());
379   // TODO(terelius): Is payload type needed?
380   proto_batch->set_payload_type(base_event->header().PayloadType());
381   proto_batch->set_sequence_number(base_event->header().SequenceNumber());
382   proto_batch->set_rtp_timestamp(base_event->header().Timestamp());
383   proto_batch->set_ssrc(base_event->header().Ssrc());
384   proto_batch->set_payload_size(base_event->payload_length());
385   proto_batch->set_header_size(base_event->header_length());
386   proto_batch->set_padding_size(base_event->padding_length());
387 
388   // Add header extensions (base event).
389   absl::optional<uint64_t> base_transport_sequence_number;
390   {
391     uint16_t seqnum;
392     if (base_event->header().template GetExtension<TransportSequenceNumber>(
393             &seqnum)) {
394       proto_batch->set_transport_sequence_number(seqnum);
395       base_transport_sequence_number = seqnum;
396     }
397   }
398 
399   absl::optional<uint64_t> unsigned_base_transmission_time_offset;
400   {
401     int32_t offset;
402     if (base_event->header().template GetExtension<TransmissionOffset>(
403             &offset)) {
404       proto_batch->set_transmission_time_offset(offset);
405       unsigned_base_transmission_time_offset = ToUnsigned(offset);
406     }
407   }
408 
409   absl::optional<uint64_t> base_absolute_send_time;
410   {
411     uint32_t sendtime;
412     if (base_event->header().template GetExtension<AbsoluteSendTime>(
413             &sendtime)) {
414       proto_batch->set_absolute_send_time(sendtime);
415       base_absolute_send_time = sendtime;
416     }
417   }
418 
419   absl::optional<uint64_t> base_video_rotation;
420   {
421     VideoRotation video_rotation;
422     if (base_event->header().template GetExtension<VideoOrientation>(
423             &video_rotation)) {
424       proto_batch->set_video_rotation(
425           ConvertVideoRotationToCVOByte(video_rotation));
426       base_video_rotation = ConvertVideoRotationToCVOByte(video_rotation);
427     }
428   }
429 
430   absl::optional<uint64_t> base_audio_level;
431   absl::optional<uint64_t> base_voice_activity;
432   {
433     bool voice_activity;
434     uint8_t audio_level;
435     if (base_event->header().template GetExtension<AudioLevel>(&voice_activity,
436                                                                &audio_level)) {
437       RTC_DCHECK_LE(audio_level, 0x7Fu);
438       base_audio_level = audio_level;
439       proto_batch->set_audio_level(audio_level);
440 
441       base_voice_activity = voice_activity;
442       proto_batch->set_voice_activity(voice_activity);
443     }
444   }
445 
446   if (batch.size() == 1) {
447     return;
448   }
449 
450   // Delta encoding
451   proto_batch->set_number_of_deltas(batch.size() - 1);
452   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
453   std::string encoded_deltas;
454 
455   // timestamp_ms (event)
456   for (size_t i = 0; i < values.size(); ++i) {
457     const EventType* event = batch[i + 1];
458     values[i] = ToUnsigned(event->timestamp_ms());
459   }
460   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
461   if (!encoded_deltas.empty()) {
462     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
463   }
464 
465   // marker (RTP base)
466   for (size_t i = 0; i < values.size(); ++i) {
467     const EventType* event = batch[i + 1];
468     values[i] = event->header().Marker();
469   }
470   encoded_deltas = EncodeDeltas(base_event->header().Marker(), values);
471   if (!encoded_deltas.empty()) {
472     proto_batch->set_marker_deltas(encoded_deltas);
473   }
474 
475   // payload_type (RTP base)
476   for (size_t i = 0; i < values.size(); ++i) {
477     const EventType* event = batch[i + 1];
478     values[i] = event->header().PayloadType();
479   }
480   encoded_deltas = EncodeDeltas(base_event->header().PayloadType(), values);
481   if (!encoded_deltas.empty()) {
482     proto_batch->set_payload_type_deltas(encoded_deltas);
483   }
484 
485   // sequence_number (RTP base)
486   for (size_t i = 0; i < values.size(); ++i) {
487     const EventType* event = batch[i + 1];
488     values[i] = event->header().SequenceNumber();
489   }
490   encoded_deltas = EncodeDeltas(base_event->header().SequenceNumber(), values);
491   if (!encoded_deltas.empty()) {
492     proto_batch->set_sequence_number_deltas(encoded_deltas);
493   }
494 
495   // rtp_timestamp (RTP base)
496   for (size_t i = 0; i < values.size(); ++i) {
497     const EventType* event = batch[i + 1];
498     values[i] = event->header().Timestamp();
499   }
500   encoded_deltas = EncodeDeltas(base_event->header().Timestamp(), values);
501   if (!encoded_deltas.empty()) {
502     proto_batch->set_rtp_timestamp_deltas(encoded_deltas);
503   }
504 
505   // ssrc (RTP base)
506   for (size_t i = 0; i < values.size(); ++i) {
507     const EventType* event = batch[i + 1];
508     values[i] = event->header().Ssrc();
509   }
510   encoded_deltas = EncodeDeltas(base_event->header().Ssrc(), values);
511   if (!encoded_deltas.empty()) {
512     proto_batch->set_ssrc_deltas(encoded_deltas);
513   }
514 
515   // payload_size (RTP base)
516   for (size_t i = 0; i < values.size(); ++i) {
517     const EventType* event = batch[i + 1];
518     values[i] = event->payload_length();
519   }
520   encoded_deltas = EncodeDeltas(base_event->payload_length(), values);
521   if (!encoded_deltas.empty()) {
522     proto_batch->set_payload_size_deltas(encoded_deltas);
523   }
524 
525   // header_size (RTP base)
526   for (size_t i = 0; i < values.size(); ++i) {
527     const EventType* event = batch[i + 1];
528     values[i] = event->header_length();
529   }
530   encoded_deltas = EncodeDeltas(base_event->header_length(), values);
531   if (!encoded_deltas.empty()) {
532     proto_batch->set_header_size_deltas(encoded_deltas);
533   }
534 
535   // padding_size (RTP base)
536   for (size_t i = 0; i < values.size(); ++i) {
537     const EventType* event = batch[i + 1];
538     values[i] = event->padding_length();
539   }
540   encoded_deltas = EncodeDeltas(base_event->padding_length(), values);
541   if (!encoded_deltas.empty()) {
542     proto_batch->set_padding_size_deltas(encoded_deltas);
543   }
544 
545   // transport_sequence_number (RTP extension)
546   for (size_t i = 0; i < values.size(); ++i) {
547     const EventType* event = batch[i + 1];
548     uint16_t seqnum;
549     if (event->header().template GetExtension<TransportSequenceNumber>(
550             &seqnum)) {
551       values[i] = seqnum;
552     } else {
553       values[i].reset();
554     }
555   }
556   encoded_deltas = EncodeDeltas(base_transport_sequence_number, values);
557   if (!encoded_deltas.empty()) {
558     proto_batch->set_transport_sequence_number_deltas(encoded_deltas);
559   }
560 
561   // transmission_time_offset (RTP extension)
562   for (size_t i = 0; i < values.size(); ++i) {
563     const EventType* event = batch[i + 1];
564     int32_t offset;
565     if (event->header().template GetExtension<TransmissionOffset>(&offset)) {
566       values[i] = ToUnsigned(offset);
567     } else {
568       values[i].reset();
569     }
570   }
571   encoded_deltas = EncodeDeltas(unsigned_base_transmission_time_offset, values);
572   if (!encoded_deltas.empty()) {
573     proto_batch->set_transmission_time_offset_deltas(encoded_deltas);
574   }
575 
576   // absolute_send_time (RTP extension)
577   for (size_t i = 0; i < values.size(); ++i) {
578     const EventType* event = batch[i + 1];
579     uint32_t sendtime;
580     if (event->header().template GetExtension<AbsoluteSendTime>(&sendtime)) {
581       values[i] = sendtime;
582     } else {
583       values[i].reset();
584     }
585   }
586   encoded_deltas = EncodeDeltas(base_absolute_send_time, values);
587   if (!encoded_deltas.empty()) {
588     proto_batch->set_absolute_send_time_deltas(encoded_deltas);
589   }
590 
591   // video_rotation (RTP extension)
592   for (size_t i = 0; i < values.size(); ++i) {
593     const EventType* event = batch[i + 1];
594     VideoRotation video_rotation;
595     if (event->header().template GetExtension<VideoOrientation>(
596             &video_rotation)) {
597       values[i] = ConvertVideoRotationToCVOByte(video_rotation);
598     } else {
599       values[i].reset();
600     }
601   }
602   encoded_deltas = EncodeDeltas(base_video_rotation, values);
603   if (!encoded_deltas.empty()) {
604     proto_batch->set_video_rotation_deltas(encoded_deltas);
605   }
606 
607   // audio_level (RTP extension)
608   for (size_t i = 0; i < values.size(); ++i) {
609     const EventType* event = batch[i + 1];
610     bool voice_activity;
611     uint8_t audio_level;
612     if (event->header().template GetExtension<AudioLevel>(&voice_activity,
613                                                           &audio_level)) {
614       RTC_DCHECK_LE(audio_level, 0x7Fu);
615       values[i] = audio_level;
616     } else {
617       values[i].reset();
618     }
619   }
620   encoded_deltas = EncodeDeltas(base_audio_level, values);
621   if (!encoded_deltas.empty()) {
622     proto_batch->set_audio_level_deltas(encoded_deltas);
623   }
624 
625   // voice_activity (RTP extension)
626   for (size_t i = 0; i < values.size(); ++i) {
627     const EventType* event = batch[i + 1];
628     bool voice_activity;
629     uint8_t audio_level;
630     if (event->header().template GetExtension<AudioLevel>(&voice_activity,
631                                                           &audio_level)) {
632       RTC_DCHECK_LE(audio_level, 0x7Fu);
633       values[i] = voice_activity;
634     } else {
635       values[i].reset();
636     }
637   }
638   encoded_deltas = EncodeDeltas(base_voice_activity, values);
639   if (!encoded_deltas.empty()) {
640     proto_batch->set_voice_activity_deltas(encoded_deltas);
641   }
642 }
643 }  // namespace
644 
EncodeLogStart(int64_t timestamp_us,int64_t utc_time_us)645 std::string RtcEventLogEncoderNewFormat::EncodeLogStart(int64_t timestamp_us,
646                                                         int64_t utc_time_us) {
647   rtclog2::EventStream event_stream;
648   rtclog2::BeginLogEvent* proto_batch = event_stream.add_begin_log_events();
649   proto_batch->set_timestamp_ms(timestamp_us / 1000);
650   proto_batch->set_version(2);
651   proto_batch->set_utc_time_ms(utc_time_us / 1000);
652   return event_stream.SerializeAsString();
653 }
654 
EncodeLogEnd(int64_t timestamp_us)655 std::string RtcEventLogEncoderNewFormat::EncodeLogEnd(int64_t timestamp_us) {
656   rtclog2::EventStream event_stream;
657   rtclog2::EndLogEvent* proto_batch = event_stream.add_end_log_events();
658   proto_batch->set_timestamp_ms(timestamp_us / 1000);
659   return event_stream.SerializeAsString();
660 }
661 
EncodeBatch(std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,std::deque<std::unique_ptr<RtcEvent>>::const_iterator end)662 std::string RtcEventLogEncoderNewFormat::EncodeBatch(
663     std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
664     std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) {
665   rtclog2::EventStream event_stream;
666   std::string encoded_output;
667 
668   {
669     std::vector<const RtcEventAlrState*> alr_state_events;
670     std::vector<const RtcEventAudioNetworkAdaptation*>
671         audio_network_adaptation_events;
672     std::vector<const RtcEventAudioPlayout*> audio_playout_events;
673     std::vector<const RtcEventAudioReceiveStreamConfig*>
674         audio_recv_stream_configs;
675     std::vector<const RtcEventAudioSendStreamConfig*> audio_send_stream_configs;
676     std::vector<const RtcEventBweUpdateDelayBased*> bwe_delay_based_updates;
677     std::vector<const RtcEventBweUpdateLossBased*> bwe_loss_based_updates;
678     std::vector<const RtcEventDtlsTransportState*> dtls_transport_states;
679     std::vector<const RtcEventDtlsWritableState*> dtls_writable_states;
680     std::vector<const RtcEventGenericAckReceived*> generic_acks_received;
681     std::vector<const RtcEventGenericPacketReceived*> generic_packets_received;
682     std::vector<const RtcEventGenericPacketSent*> generic_packets_sent;
683     std::vector<const RtcEventIceCandidatePair*> ice_candidate_events;
684     std::vector<const RtcEventIceCandidatePairConfig*> ice_candidate_configs;
685     std::vector<const RtcEventProbeClusterCreated*>
686         probe_cluster_created_events;
687     std::vector<const RtcEventProbeResultFailure*> probe_result_failure_events;
688     std::vector<const RtcEventProbeResultSuccess*> probe_result_success_events;
689     std::vector<const RtcEventRouteChange*> route_change_events;
690     std::vector<const RtcEventRemoteEstimate*> remote_estimate_events;
691     std::vector<const RtcEventRtcpPacketIncoming*> incoming_rtcp_packets;
692     std::vector<const RtcEventRtcpPacketOutgoing*> outgoing_rtcp_packets;
693     std::map<uint32_t /* SSRC */, std::vector<const RtcEventRtpPacketIncoming*>>
694         incoming_rtp_packets;
695     std::map<uint32_t /* SSRC */, std::vector<const RtcEventRtpPacketOutgoing*>>
696         outgoing_rtp_packets;
697     std::vector<const RtcEventVideoReceiveStreamConfig*>
698         video_recv_stream_configs;
699     std::vector<const RtcEventVideoSendStreamConfig*> video_send_stream_configs;
700 
701     for (auto it = begin; it != end; ++it) {
702       switch ((*it)->GetType()) {
703         case RtcEvent::Type::AlrStateEvent: {
704           auto* rtc_event =
705               static_cast<const RtcEventAlrState* const>(it->get());
706           alr_state_events.push_back(rtc_event);
707           break;
708         }
709         case RtcEvent::Type::AudioNetworkAdaptation: {
710           auto* rtc_event =
711               static_cast<const RtcEventAudioNetworkAdaptation* const>(
712                   it->get());
713           audio_network_adaptation_events.push_back(rtc_event);
714           break;
715         }
716         case RtcEvent::Type::AudioPlayout: {
717           auto* rtc_event =
718               static_cast<const RtcEventAudioPlayout* const>(it->get());
719           audio_playout_events.push_back(rtc_event);
720           break;
721         }
722         case RtcEvent::Type::AudioReceiveStreamConfig: {
723           auto* rtc_event =
724               static_cast<const RtcEventAudioReceiveStreamConfig* const>(
725                   it->get());
726           audio_recv_stream_configs.push_back(rtc_event);
727           break;
728         }
729         case RtcEvent::Type::AudioSendStreamConfig: {
730           auto* rtc_event =
731               static_cast<const RtcEventAudioSendStreamConfig* const>(
732                   it->get());
733           audio_send_stream_configs.push_back(rtc_event);
734           break;
735         }
736         case RtcEvent::Type::BweUpdateDelayBased: {
737           auto* rtc_event =
738               static_cast<const RtcEventBweUpdateDelayBased* const>(it->get());
739           bwe_delay_based_updates.push_back(rtc_event);
740           break;
741         }
742         case RtcEvent::Type::BweUpdateLossBased: {
743           auto* rtc_event =
744               static_cast<const RtcEventBweUpdateLossBased* const>(it->get());
745           bwe_loss_based_updates.push_back(rtc_event);
746           break;
747         }
748         case RtcEvent::Type::DtlsTransportState: {
749           auto* rtc_event =
750               static_cast<const RtcEventDtlsTransportState* const>(it->get());
751           dtls_transport_states.push_back(rtc_event);
752           break;
753         }
754         case RtcEvent::Type::DtlsWritableState: {
755           auto* rtc_event =
756               static_cast<const RtcEventDtlsWritableState* const>(it->get());
757           dtls_writable_states.push_back(rtc_event);
758           break;
759         }
760         case RtcEvent::Type::ProbeClusterCreated: {
761           auto* rtc_event =
762               static_cast<const RtcEventProbeClusterCreated* const>(it->get());
763           probe_cluster_created_events.push_back(rtc_event);
764           break;
765         }
766         case RtcEvent::Type::ProbeResultFailure: {
767           auto* rtc_event =
768               static_cast<const RtcEventProbeResultFailure* const>(it->get());
769           probe_result_failure_events.push_back(rtc_event);
770           break;
771         }
772         case RtcEvent::Type::ProbeResultSuccess: {
773           auto* rtc_event =
774               static_cast<const RtcEventProbeResultSuccess* const>(it->get());
775           probe_result_success_events.push_back(rtc_event);
776           break;
777         }
778         case RtcEvent::Type::RouteChangeEvent: {
779           auto* rtc_event =
780               static_cast<const RtcEventRouteChange* const>(it->get());
781           route_change_events.push_back(rtc_event);
782           break;
783         }
784         case RtcEvent::Type::RemoteEstimateEvent: {
785           auto* rtc_event =
786               static_cast<const RtcEventRemoteEstimate* const>(it->get());
787           remote_estimate_events.push_back(rtc_event);
788           break;
789         }
790         case RtcEvent::Type::RtcpPacketIncoming: {
791           auto* rtc_event =
792               static_cast<const RtcEventRtcpPacketIncoming* const>(it->get());
793           incoming_rtcp_packets.push_back(rtc_event);
794           break;
795         }
796         case RtcEvent::Type::RtcpPacketOutgoing: {
797           auto* rtc_event =
798               static_cast<const RtcEventRtcpPacketOutgoing* const>(it->get());
799           outgoing_rtcp_packets.push_back(rtc_event);
800           break;
801         }
802         case RtcEvent::Type::RtpPacketIncoming: {
803           auto* rtc_event =
804               static_cast<const RtcEventRtpPacketIncoming* const>(it->get());
805           auto& v = incoming_rtp_packets[rtc_event->header().Ssrc()];
806           v.emplace_back(rtc_event);
807           break;
808         }
809         case RtcEvent::Type::RtpPacketOutgoing: {
810           auto* rtc_event =
811               static_cast<const RtcEventRtpPacketOutgoing* const>(it->get());
812           auto& v = outgoing_rtp_packets[rtc_event->header().Ssrc()];
813           v.emplace_back(rtc_event);
814           break;
815         }
816         case RtcEvent::Type::VideoReceiveStreamConfig: {
817           auto* rtc_event =
818               static_cast<const RtcEventVideoReceiveStreamConfig* const>(
819                   it->get());
820           video_recv_stream_configs.push_back(rtc_event);
821           break;
822         }
823         case RtcEvent::Type::VideoSendStreamConfig: {
824           auto* rtc_event =
825               static_cast<const RtcEventVideoSendStreamConfig* const>(
826                   it->get());
827           video_send_stream_configs.push_back(rtc_event);
828           break;
829         }
830         case RtcEvent::Type::IceCandidatePairConfig: {
831           auto* rtc_event =
832               static_cast<const RtcEventIceCandidatePairConfig* const>(
833                   it->get());
834           ice_candidate_configs.push_back(rtc_event);
835           break;
836         }
837         case RtcEvent::Type::IceCandidatePairEvent: {
838           auto* rtc_event =
839               static_cast<const RtcEventIceCandidatePair* const>(it->get());
840           ice_candidate_events.push_back(rtc_event);
841           break;
842         }
843         case RtcEvent::Type::GenericPacketReceived: {
844           auto* rtc_event =
845               static_cast<const RtcEventGenericPacketReceived* const>(
846                   it->get());
847           generic_packets_received.push_back(rtc_event);
848           break;
849         }
850         case RtcEvent::Type::GenericPacketSent: {
851           auto* rtc_event =
852               static_cast<const RtcEventGenericPacketSent* const>(it->get());
853           generic_packets_sent.push_back(rtc_event);
854           break;
855         }
856         case RtcEvent::Type::GenericAckReceived: {
857           auto* rtc_event =
858               static_cast<const RtcEventGenericAckReceived* const>(it->get());
859           generic_acks_received.push_back(rtc_event);
860           break;
861         }
862       }
863     }
864 
865     EncodeAlrState(alr_state_events, &event_stream);
866     EncodeAudioNetworkAdaptation(audio_network_adaptation_events,
867                                  &event_stream);
868     EncodeAudioPlayout(audio_playout_events, &event_stream);
869     EncodeAudioRecvStreamConfig(audio_recv_stream_configs, &event_stream);
870     EncodeAudioSendStreamConfig(audio_send_stream_configs, &event_stream);
871     EncodeBweUpdateDelayBased(bwe_delay_based_updates, &event_stream);
872     EncodeBweUpdateLossBased(bwe_loss_based_updates, &event_stream);
873     EncodeDtlsTransportState(dtls_transport_states, &event_stream);
874     EncodeDtlsWritableState(dtls_writable_states, &event_stream);
875     EncodeGenericAcksReceived(generic_acks_received, &event_stream);
876     EncodeGenericPacketsReceived(generic_packets_received, &event_stream);
877     EncodeGenericPacketsSent(generic_packets_sent, &event_stream);
878     EncodeIceCandidatePairConfig(ice_candidate_configs, &event_stream);
879     EncodeIceCandidatePairEvent(ice_candidate_events, &event_stream);
880     EncodeProbeClusterCreated(probe_cluster_created_events, &event_stream);
881     EncodeProbeResultFailure(probe_result_failure_events, &event_stream);
882     EncodeProbeResultSuccess(probe_result_success_events, &event_stream);
883     EncodeRouteChange(route_change_events, &event_stream);
884     EncodeRemoteEstimate(remote_estimate_events, &event_stream);
885     EncodeRtcpPacketIncoming(incoming_rtcp_packets, &event_stream);
886     EncodeRtcpPacketOutgoing(outgoing_rtcp_packets, &event_stream);
887     EncodeRtpPacketIncoming(incoming_rtp_packets, &event_stream);
888     EncodeRtpPacketOutgoing(outgoing_rtp_packets, &event_stream);
889     EncodeVideoRecvStreamConfig(video_recv_stream_configs, &event_stream);
890     EncodeVideoSendStreamConfig(video_send_stream_configs, &event_stream);
891   }  // Deallocate the temporary vectors.
892 
893   return event_stream.SerializeAsString();
894 }
895 
EncodeAlrState(rtc::ArrayView<const RtcEventAlrState * > batch,rtclog2::EventStream * event_stream)896 void RtcEventLogEncoderNewFormat::EncodeAlrState(
897     rtc::ArrayView<const RtcEventAlrState*> batch,
898     rtclog2::EventStream* event_stream) {
899   for (const RtcEventAlrState* base_event : batch) {
900     rtclog2::AlrState* proto_batch = event_stream->add_alr_states();
901     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
902     proto_batch->set_in_alr(base_event->in_alr());
903   }
904   // TODO(terelius): Should we delta-compress this event type?
905 }
906 
EncodeAudioNetworkAdaptation(rtc::ArrayView<const RtcEventAudioNetworkAdaptation * > batch,rtclog2::EventStream * event_stream)907 void RtcEventLogEncoderNewFormat::EncodeAudioNetworkAdaptation(
908     rtc::ArrayView<const RtcEventAudioNetworkAdaptation*> batch,
909     rtclog2::EventStream* event_stream) {
910   if (batch.empty())
911     return;
912 
913   // Base event
914   const RtcEventAudioNetworkAdaptation* const base_event = batch[0];
915   rtclog2::AudioNetworkAdaptations* proto_batch =
916       event_stream->add_audio_network_adaptations();
917   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
918   if (base_event->config().bitrate_bps.has_value())
919     proto_batch->set_bitrate_bps(base_event->config().bitrate_bps.value());
920   if (base_event->config().frame_length_ms.has_value()) {
921     proto_batch->set_frame_length_ms(
922         base_event->config().frame_length_ms.value());
923   }
924   absl::optional<uint64_t> base_uplink_packet_loss_fraction;
925   if (base_event->config().uplink_packet_loss_fraction.has_value()) {
926     base_uplink_packet_loss_fraction = ConvertPacketLossFractionToProtoFormat(
927         base_event->config().uplink_packet_loss_fraction.value());
928     proto_batch->set_uplink_packet_loss_fraction(
929         base_uplink_packet_loss_fraction.value());
930   }
931   if (base_event->config().enable_fec.has_value())
932     proto_batch->set_enable_fec(base_event->config().enable_fec.value());
933   if (base_event->config().enable_dtx.has_value())
934     proto_batch->set_enable_dtx(base_event->config().enable_dtx.value());
935   // Note that |num_channels_deltas| encodes N as N-1, to keep deltas smaller,
936   // but there's no reason to do the same for the base event's value, since
937   // no bits will be spared.
938   if (base_event->config().num_channels.has_value())
939     proto_batch->set_num_channels(base_event->config().num_channels.value());
940 
941   if (batch.size() == 1)
942     return;
943 
944   // Delta encoding
945   proto_batch->set_number_of_deltas(batch.size() - 1);
946   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
947   std::string encoded_deltas;
948 
949   // timestamp_ms
950   for (size_t i = 0; i < values.size(); ++i) {
951     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
952     values[i] = ToUnsigned(event->timestamp_ms());
953   }
954   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
955   if (!encoded_deltas.empty()) {
956     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
957   }
958 
959   // bitrate_bps
960   for (size_t i = 0; i < values.size(); ++i) {
961     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
962     if (event->config().bitrate_bps.has_value()) {
963       values[i] = ToUnsigned(event->config().bitrate_bps.value());
964     } else {
965       values[i].reset();
966     }
967   }
968   const absl::optional<uint64_t> unsigned_base_bitrate_bps =
969       base_event->config().bitrate_bps.has_value()
970           ? ToUnsigned(base_event->config().bitrate_bps.value())
971           : absl::optional<uint64_t>();
972   encoded_deltas = EncodeDeltas(unsigned_base_bitrate_bps, values);
973   if (!encoded_deltas.empty()) {
974     proto_batch->set_bitrate_bps_deltas(encoded_deltas);
975   }
976 
977   // frame_length_ms
978   for (size_t i = 0; i < values.size(); ++i) {
979     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
980     if (event->config().frame_length_ms.has_value()) {
981       values[i] = ToUnsigned(event->config().frame_length_ms.value());
982     } else {
983       values[i].reset();
984     }
985   }
986   const absl::optional<uint64_t> unsigned_base_frame_length_ms =
987       base_event->config().frame_length_ms.has_value()
988           ? ToUnsigned(base_event->config().frame_length_ms.value())
989           : absl::optional<uint64_t>();
990   encoded_deltas = EncodeDeltas(unsigned_base_frame_length_ms, values);
991   if (!encoded_deltas.empty()) {
992     proto_batch->set_frame_length_ms_deltas(encoded_deltas);
993   }
994 
995   // uplink_packet_loss_fraction
996   for (size_t i = 0; i < values.size(); ++i) {
997     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
998     if (event->config().uplink_packet_loss_fraction.has_value()) {
999       values[i] = ConvertPacketLossFractionToProtoFormat(
1000           event->config().uplink_packet_loss_fraction.value());
1001     } else {
1002       values[i].reset();
1003     }
1004   }
1005   encoded_deltas = EncodeDeltas(base_uplink_packet_loss_fraction, values);
1006   if (!encoded_deltas.empty()) {
1007     proto_batch->set_uplink_packet_loss_fraction_deltas(encoded_deltas);
1008   }
1009 
1010   // enable_fec
1011   for (size_t i = 0; i < values.size(); ++i) {
1012     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
1013     values[i] = event->config().enable_fec;
1014   }
1015   encoded_deltas = EncodeDeltas(base_event->config().enable_fec, values);
1016   if (!encoded_deltas.empty()) {
1017     proto_batch->set_enable_fec_deltas(encoded_deltas);
1018   }
1019 
1020   // enable_dtx
1021   for (size_t i = 0; i < values.size(); ++i) {
1022     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
1023     values[i] = event->config().enable_dtx;
1024   }
1025   encoded_deltas = EncodeDeltas(base_event->config().enable_dtx, values);
1026   if (!encoded_deltas.empty()) {
1027     proto_batch->set_enable_dtx_deltas(encoded_deltas);
1028   }
1029 
1030   // num_channels
1031   for (size_t i = 0; i < values.size(); ++i) {
1032     const RtcEventAudioNetworkAdaptation* event = batch[i + 1];
1033     const absl::optional<size_t> num_channels = event->config().num_channels;
1034     if (num_channels.has_value()) {
1035       // Since the number of channels is always greater than 0, we can encode
1036       // N channels as N-1, thereby making sure that we get smaller deltas.
1037       // That is, a toggle of 1->2->1 can be encoded as deltas vector (1, 1),
1038       // rather than as (1, 3) or (1, -1), either of which would require two
1039       // bits per delta.
1040       RTC_DCHECK_GT(num_channels.value(), 0u);
1041       values[i] = num_channels.value() - 1;
1042     } else {
1043       values[i].reset();
1044     }
1045   }
1046   // In the base event, N channels encoded as N channels, but for delta
1047   // compression purposes, also shifted down by 1.
1048   absl::optional<size_t> shifted_base_num_channels;
1049   if (base_event->config().num_channels.has_value()) {
1050     RTC_DCHECK_GT(base_event->config().num_channels.value(), 0u);
1051     shifted_base_num_channels = base_event->config().num_channels.value() - 1;
1052   }
1053   encoded_deltas = EncodeDeltas(shifted_base_num_channels, values);
1054   if (!encoded_deltas.empty()) {
1055     proto_batch->set_num_channels_deltas(encoded_deltas);
1056   }
1057 }
1058 
EncodeAudioPlayout(rtc::ArrayView<const RtcEventAudioPlayout * > batch,rtclog2::EventStream * event_stream)1059 void RtcEventLogEncoderNewFormat::EncodeAudioPlayout(
1060     rtc::ArrayView<const RtcEventAudioPlayout*> batch,
1061     rtclog2::EventStream* event_stream) {
1062   if (batch.empty())
1063     return;
1064 
1065   // Base event
1066   const RtcEventAudioPlayout* const base_event = batch[0];
1067   rtclog2::AudioPlayoutEvents* proto_batch =
1068       event_stream->add_audio_playout_events();
1069   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1070   proto_batch->set_local_ssrc(base_event->ssrc());
1071 
1072   if (batch.size() == 1)
1073     return;
1074 
1075   // Delta encoding
1076   proto_batch->set_number_of_deltas(batch.size() - 1);
1077   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
1078   std::string encoded_deltas;
1079 
1080   // timestamp_ms
1081   for (size_t i = 0; i < values.size(); ++i) {
1082     const RtcEventAudioPlayout* event = batch[i + 1];
1083     values[i] = ToUnsigned(event->timestamp_ms());
1084   }
1085   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
1086   if (!encoded_deltas.empty()) {
1087     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
1088   }
1089 
1090   // local_ssrc
1091   for (size_t i = 0; i < values.size(); ++i) {
1092     const RtcEventAudioPlayout* event = batch[i + 1];
1093     values[i] = event->ssrc();
1094   }
1095   encoded_deltas = EncodeDeltas(base_event->ssrc(), values);
1096   if (!encoded_deltas.empty()) {
1097     proto_batch->set_local_ssrc_deltas(encoded_deltas);
1098   }
1099 }
1100 
EncodeAudioRecvStreamConfig(rtc::ArrayView<const RtcEventAudioReceiveStreamConfig * > batch,rtclog2::EventStream * event_stream)1101 void RtcEventLogEncoderNewFormat::EncodeAudioRecvStreamConfig(
1102     rtc::ArrayView<const RtcEventAudioReceiveStreamConfig*> batch,
1103     rtclog2::EventStream* event_stream) {
1104   for (const RtcEventAudioReceiveStreamConfig* base_event : batch) {
1105     rtclog2::AudioRecvStreamConfig* proto_batch =
1106         event_stream->add_audio_recv_stream_configs();
1107     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1108     proto_batch->set_remote_ssrc(base_event->config().remote_ssrc);
1109     proto_batch->set_local_ssrc(base_event->config().local_ssrc);
1110 
1111     rtclog2::RtpHeaderExtensionConfig* proto_config =
1112         proto_batch->mutable_header_extensions();
1113     bool has_recognized_extensions =
1114         ConvertToProtoFormat(base_event->config().rtp_extensions, proto_config);
1115     if (!has_recognized_extensions)
1116       proto_batch->clear_header_extensions();
1117   }
1118 }
1119 
EncodeAudioSendStreamConfig(rtc::ArrayView<const RtcEventAudioSendStreamConfig * > batch,rtclog2::EventStream * event_stream)1120 void RtcEventLogEncoderNewFormat::EncodeAudioSendStreamConfig(
1121     rtc::ArrayView<const RtcEventAudioSendStreamConfig*> batch,
1122     rtclog2::EventStream* event_stream) {
1123   for (const RtcEventAudioSendStreamConfig* base_event : batch) {
1124     rtclog2::AudioSendStreamConfig* proto_batch =
1125         event_stream->add_audio_send_stream_configs();
1126     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1127     proto_batch->set_ssrc(base_event->config().local_ssrc);
1128 
1129     rtclog2::RtpHeaderExtensionConfig* proto_config =
1130         proto_batch->mutable_header_extensions();
1131     bool has_recognized_extensions =
1132         ConvertToProtoFormat(base_event->config().rtp_extensions, proto_config);
1133     if (!has_recognized_extensions)
1134       proto_batch->clear_header_extensions();
1135   }
1136 }
1137 
EncodeBweUpdateDelayBased(rtc::ArrayView<const RtcEventBweUpdateDelayBased * > batch,rtclog2::EventStream * event_stream)1138 void RtcEventLogEncoderNewFormat::EncodeBweUpdateDelayBased(
1139     rtc::ArrayView<const RtcEventBweUpdateDelayBased*> batch,
1140     rtclog2::EventStream* event_stream) {
1141   if (batch.empty())
1142     return;
1143 
1144   // Base event
1145   const RtcEventBweUpdateDelayBased* const base_event = batch[0];
1146   rtclog2::DelayBasedBweUpdates* proto_batch =
1147       event_stream->add_delay_based_bwe_updates();
1148   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1149   proto_batch->set_bitrate_bps(base_event->bitrate_bps());
1150   proto_batch->set_detector_state(
1151       ConvertToProtoFormat(base_event->detector_state()));
1152 
1153   if (batch.size() == 1)
1154     return;
1155 
1156   // Delta encoding
1157   proto_batch->set_number_of_deltas(batch.size() - 1);
1158   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
1159   std::string encoded_deltas;
1160 
1161   // timestamp_ms
1162   for (size_t i = 0; i < values.size(); ++i) {
1163     const RtcEventBweUpdateDelayBased* event = batch[i + 1];
1164     values[i] = ToUnsigned(event->timestamp_ms());
1165   }
1166   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
1167   if (!encoded_deltas.empty()) {
1168     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
1169   }
1170 
1171   // bitrate_bps
1172   for (size_t i = 0; i < values.size(); ++i) {
1173     const RtcEventBweUpdateDelayBased* event = batch[i + 1];
1174     values[i] = event->bitrate_bps();
1175   }
1176   encoded_deltas = EncodeDeltas(base_event->bitrate_bps(), values);
1177   if (!encoded_deltas.empty()) {
1178     proto_batch->set_bitrate_bps_deltas(encoded_deltas);
1179   }
1180 
1181   // detector_state
1182   for (size_t i = 0; i < values.size(); ++i) {
1183     const RtcEventBweUpdateDelayBased* event = batch[i + 1];
1184     values[i] =
1185         static_cast<uint64_t>(ConvertToProtoFormat(event->detector_state()));
1186   }
1187   encoded_deltas = EncodeDeltas(
1188       static_cast<uint64_t>(ConvertToProtoFormat(base_event->detector_state())),
1189       values);
1190   if (!encoded_deltas.empty()) {
1191     proto_batch->set_detector_state_deltas(encoded_deltas);
1192   }
1193 }
1194 
EncodeBweUpdateLossBased(rtc::ArrayView<const RtcEventBweUpdateLossBased * > batch,rtclog2::EventStream * event_stream)1195 void RtcEventLogEncoderNewFormat::EncodeBweUpdateLossBased(
1196     rtc::ArrayView<const RtcEventBweUpdateLossBased*> batch,
1197     rtclog2::EventStream* event_stream) {
1198   if (batch.empty())
1199     return;
1200 
1201   // Base event
1202   const RtcEventBweUpdateLossBased* const base_event = batch[0];
1203   rtclog2::LossBasedBweUpdates* proto_batch =
1204       event_stream->add_loss_based_bwe_updates();
1205   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1206   proto_batch->set_bitrate_bps(base_event->bitrate_bps());
1207   proto_batch->set_fraction_loss(base_event->fraction_loss());
1208   proto_batch->set_total_packets(base_event->total_packets());
1209 
1210   if (batch.size() == 1)
1211     return;
1212 
1213   // Delta encoding
1214   proto_batch->set_number_of_deltas(batch.size() - 1);
1215   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
1216   std::string encoded_deltas;
1217 
1218   // timestamp_ms
1219   for (size_t i = 0; i < values.size(); ++i) {
1220     const RtcEventBweUpdateLossBased* event = batch[i + 1];
1221     values[i] = ToUnsigned(event->timestamp_ms());
1222   }
1223   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
1224   if (!encoded_deltas.empty()) {
1225     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
1226   }
1227 
1228   // bitrate_bps
1229   for (size_t i = 0; i < values.size(); ++i) {
1230     const RtcEventBweUpdateLossBased* event = batch[i + 1];
1231     values[i] = event->bitrate_bps();
1232   }
1233   encoded_deltas = EncodeDeltas(base_event->bitrate_bps(), values);
1234   if (!encoded_deltas.empty()) {
1235     proto_batch->set_bitrate_bps_deltas(encoded_deltas);
1236   }
1237 
1238   // fraction_loss
1239   for (size_t i = 0; i < values.size(); ++i) {
1240     const RtcEventBweUpdateLossBased* event = batch[i + 1];
1241     values[i] = event->fraction_loss();
1242   }
1243   encoded_deltas = EncodeDeltas(base_event->fraction_loss(), values);
1244   if (!encoded_deltas.empty()) {
1245     proto_batch->set_fraction_loss_deltas(encoded_deltas);
1246   }
1247 
1248   // total_packets
1249   for (size_t i = 0; i < values.size(); ++i) {
1250     const RtcEventBweUpdateLossBased* event = batch[i + 1];
1251     values[i] = event->total_packets();
1252   }
1253   encoded_deltas = EncodeDeltas(base_event->total_packets(), values);
1254   if (!encoded_deltas.empty()) {
1255     proto_batch->set_total_packets_deltas(encoded_deltas);
1256   }
1257 }
1258 
EncodeDtlsTransportState(rtc::ArrayView<const RtcEventDtlsTransportState * > batch,rtclog2::EventStream * event_stream)1259 void RtcEventLogEncoderNewFormat::EncodeDtlsTransportState(
1260     rtc::ArrayView<const RtcEventDtlsTransportState*> batch,
1261     rtclog2::EventStream* event_stream) {
1262   for (const RtcEventDtlsTransportState* base_event : batch) {
1263     rtclog2::DtlsTransportStateEvent* proto_batch =
1264         event_stream->add_dtls_transport_state_events();
1265     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1266     proto_batch->set_dtls_transport_state(
1267         ConvertToProtoFormat(base_event->dtls_transport_state()));
1268   }
1269 }
1270 
EncodeDtlsWritableState(rtc::ArrayView<const RtcEventDtlsWritableState * > batch,rtclog2::EventStream * event_stream)1271 void RtcEventLogEncoderNewFormat::EncodeDtlsWritableState(
1272     rtc::ArrayView<const RtcEventDtlsWritableState*> batch,
1273     rtclog2::EventStream* event_stream) {
1274   for (const RtcEventDtlsWritableState* base_event : batch) {
1275     rtclog2::DtlsWritableState* proto_batch =
1276         event_stream->add_dtls_writable_states();
1277     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1278     proto_batch->set_writable(base_event->writable());
1279   }
1280 }
1281 
EncodeProbeClusterCreated(rtc::ArrayView<const RtcEventProbeClusterCreated * > batch,rtclog2::EventStream * event_stream)1282 void RtcEventLogEncoderNewFormat::EncodeProbeClusterCreated(
1283     rtc::ArrayView<const RtcEventProbeClusterCreated*> batch,
1284     rtclog2::EventStream* event_stream) {
1285   for (const RtcEventProbeClusterCreated* base_event : batch) {
1286     rtclog2::BweProbeCluster* proto_batch = event_stream->add_probe_clusters();
1287     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1288     proto_batch->set_id(base_event->id());
1289     proto_batch->set_bitrate_bps(base_event->bitrate_bps());
1290     proto_batch->set_min_packets(base_event->min_probes());
1291     proto_batch->set_min_bytes(base_event->min_bytes());
1292   }
1293 }
1294 
EncodeProbeResultFailure(rtc::ArrayView<const RtcEventProbeResultFailure * > batch,rtclog2::EventStream * event_stream)1295 void RtcEventLogEncoderNewFormat::EncodeProbeResultFailure(
1296     rtc::ArrayView<const RtcEventProbeResultFailure*> batch,
1297     rtclog2::EventStream* event_stream) {
1298   for (const RtcEventProbeResultFailure* base_event : batch) {
1299     rtclog2::BweProbeResultFailure* proto_batch =
1300         event_stream->add_probe_failure();
1301     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1302     proto_batch->set_id(base_event->id());
1303     proto_batch->set_failure(
1304         ConvertToProtoFormat(base_event->failure_reason()));
1305   }
1306   // TODO(terelius): Should we delta-compress this event type?
1307 }
1308 
EncodeProbeResultSuccess(rtc::ArrayView<const RtcEventProbeResultSuccess * > batch,rtclog2::EventStream * event_stream)1309 void RtcEventLogEncoderNewFormat::EncodeProbeResultSuccess(
1310     rtc::ArrayView<const RtcEventProbeResultSuccess*> batch,
1311     rtclog2::EventStream* event_stream) {
1312   for (const RtcEventProbeResultSuccess* base_event : batch) {
1313     rtclog2::BweProbeResultSuccess* proto_batch =
1314         event_stream->add_probe_success();
1315     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1316     proto_batch->set_id(base_event->id());
1317     proto_batch->set_bitrate_bps(base_event->bitrate_bps());
1318   }
1319   // TODO(terelius): Should we delta-compress this event type?
1320 }
1321 
EncodeRouteChange(rtc::ArrayView<const RtcEventRouteChange * > batch,rtclog2::EventStream * event_stream)1322 void RtcEventLogEncoderNewFormat::EncodeRouteChange(
1323     rtc::ArrayView<const RtcEventRouteChange*> batch,
1324     rtclog2::EventStream* event_stream) {
1325   for (const RtcEventRouteChange* base_event : batch) {
1326     rtclog2::RouteChange* proto_batch = event_stream->add_route_changes();
1327     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1328     proto_batch->set_connected(base_event->connected());
1329     proto_batch->set_overhead(base_event->overhead());
1330   }
1331   // TODO(terelius): Should we delta-compress this event type?
1332 }
1333 
EncodeRemoteEstimate(rtc::ArrayView<const RtcEventRemoteEstimate * > batch,rtclog2::EventStream * event_stream)1334 void RtcEventLogEncoderNewFormat::EncodeRemoteEstimate(
1335     rtc::ArrayView<const RtcEventRemoteEstimate*> batch,
1336     rtclog2::EventStream* event_stream) {
1337   if (batch.empty())
1338     return;
1339 
1340   // Base event
1341   const auto* const base_event = batch[0];
1342   rtclog2::RemoteEstimates* proto_batch = event_stream->add_remote_estimates();
1343 
1344   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1345 
1346   absl::optional<uint64_t> base_link_capacity_lower;
1347   if (base_event->link_capacity_lower_.IsFinite()) {
1348     base_link_capacity_lower =
1349         base_event->link_capacity_lower_.kbps<uint32_t>();
1350     proto_batch->set_link_capacity_lower_kbps(*base_link_capacity_lower);
1351   }
1352   absl::optional<uint64_t> base_link_capacity_upper;
1353   if (base_event->link_capacity_upper_.IsFinite()) {
1354     base_link_capacity_upper =
1355         base_event->link_capacity_upper_.kbps<uint32_t>();
1356     proto_batch->set_link_capacity_upper_kbps(*base_link_capacity_upper);
1357   }
1358 
1359   if (batch.size() == 1)
1360     return;
1361 
1362   // Delta encoding
1363   proto_batch->set_number_of_deltas(batch.size() - 1);
1364   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
1365   std::string encoded_deltas;
1366 
1367   // timestamp_ms
1368   for (size_t i = 0; i < values.size(); ++i) {
1369     const auto* event = batch[i + 1];
1370     values[i] = ToUnsigned(event->timestamp_ms());
1371   }
1372   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
1373   if (!encoded_deltas.empty()) {
1374     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
1375   }
1376 
1377   // link_capacity_lower_kbps
1378   for (size_t i = 0; i < values.size(); ++i) {
1379     const auto* event = batch[i + 1];
1380     if (base_event->link_capacity_lower_.IsFinite()) {
1381       values[i] = event->link_capacity_lower_.kbps<uint32_t>();
1382     } else {
1383       values[i].reset();
1384     }
1385   }
1386   encoded_deltas = EncodeDeltas(base_link_capacity_lower, values);
1387   if (!encoded_deltas.empty()) {
1388     proto_batch->set_link_capacity_lower_kbps_deltas(encoded_deltas);
1389   }
1390 
1391   // link_capacity_upper_kbps
1392   for (size_t i = 0; i < values.size(); ++i) {
1393     const auto* event = batch[i + 1];
1394     if (base_event->link_capacity_upper_.IsFinite()) {
1395       values[i] = event->link_capacity_upper_.kbps<uint32_t>();
1396     } else {
1397       values[i].reset();
1398     }
1399   }
1400   encoded_deltas = EncodeDeltas(base_link_capacity_upper, values);
1401   if (!encoded_deltas.empty()) {
1402     proto_batch->set_link_capacity_upper_kbps_deltas(encoded_deltas);
1403   }
1404 }
1405 
EncodeRtcpPacketIncoming(rtc::ArrayView<const RtcEventRtcpPacketIncoming * > batch,rtclog2::EventStream * event_stream)1406 void RtcEventLogEncoderNewFormat::EncodeRtcpPacketIncoming(
1407     rtc::ArrayView<const RtcEventRtcpPacketIncoming*> batch,
1408     rtclog2::EventStream* event_stream) {
1409   if (batch.empty()) {
1410     return;
1411   }
1412   EncodeRtcpPacket(batch, event_stream->add_incoming_rtcp_packets());
1413 }
1414 
EncodeRtcpPacketOutgoing(rtc::ArrayView<const RtcEventRtcpPacketOutgoing * > batch,rtclog2::EventStream * event_stream)1415 void RtcEventLogEncoderNewFormat::EncodeRtcpPacketOutgoing(
1416     rtc::ArrayView<const RtcEventRtcpPacketOutgoing*> batch,
1417     rtclog2::EventStream* event_stream) {
1418   if (batch.empty()) {
1419     return;
1420   }
1421   EncodeRtcpPacket(batch, event_stream->add_outgoing_rtcp_packets());
1422 }
1423 
EncodeRtpPacketIncoming(const std::map<uint32_t,std::vector<const RtcEventRtpPacketIncoming * >> & batch,rtclog2::EventStream * event_stream)1424 void RtcEventLogEncoderNewFormat::EncodeRtpPacketIncoming(
1425     const std::map<uint32_t, std::vector<const RtcEventRtpPacketIncoming*>>&
1426         batch,
1427     rtclog2::EventStream* event_stream) {
1428   for (const auto& it : batch) {
1429     RTC_DCHECK(!it.second.empty());
1430     EncodeRtpPacket(it.second, event_stream->add_incoming_rtp_packets());
1431   }
1432 }
1433 
EncodeGenericPacketsSent(rtc::ArrayView<const RtcEventGenericPacketSent * > batch,rtclog2::EventStream * event_stream)1434 void RtcEventLogEncoderNewFormat::EncodeGenericPacketsSent(
1435     rtc::ArrayView<const RtcEventGenericPacketSent*> batch,
1436     rtclog2::EventStream* event_stream) {
1437   if (batch.empty()) {
1438     return;
1439   }
1440   const RtcEventGenericPacketSent* const base_event = batch[0];
1441   rtclog2::GenericPacketSent* proto_batch =
1442       event_stream->add_generic_packets_sent();
1443   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1444   proto_batch->set_packet_number(base_event->packet_number());
1445   proto_batch->set_overhead_length(base_event->overhead_length());
1446   proto_batch->set_payload_length(base_event->payload_length());
1447   proto_batch->set_padding_length(base_event->padding_length());
1448 
1449   // Delta encoding
1450   proto_batch->set_number_of_deltas(batch.size() - 1);
1451   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
1452   std::string encoded_deltas;
1453 
1454   if (batch.size() == 1) {
1455     return;
1456   }
1457 
1458   // timestamp_ms
1459   for (size_t i = 0; i < values.size(); ++i) {
1460     const RtcEventGenericPacketSent* event = batch[i + 1];
1461     values[i] = ToUnsigned(event->timestamp_ms());
1462   }
1463   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
1464   if (!encoded_deltas.empty()) {
1465     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
1466   }
1467 
1468   // packet_number
1469   for (size_t i = 0; i < values.size(); ++i) {
1470     const RtcEventGenericPacketSent* event = batch[i + 1];
1471     values[i] = ToUnsigned(event->packet_number());
1472   }
1473   encoded_deltas =
1474       EncodeDeltas(ToUnsigned(base_event->packet_number()), values);
1475   if (!encoded_deltas.empty()) {
1476     proto_batch->set_packet_number_deltas(encoded_deltas);
1477   }
1478 
1479   // overhead_length
1480   for (size_t i = 0; i < values.size(); ++i) {
1481     const RtcEventGenericPacketSent* event = batch[i + 1];
1482     values[i] = event->overhead_length();
1483   }
1484   encoded_deltas = EncodeDeltas(base_event->overhead_length(), values);
1485   if (!encoded_deltas.empty()) {
1486     proto_batch->set_overhead_length_deltas(encoded_deltas);
1487   }
1488 
1489   // payload_length
1490   for (size_t i = 0; i < values.size(); ++i) {
1491     const RtcEventGenericPacketSent* event = batch[i + 1];
1492     values[i] = event->payload_length();
1493   }
1494   encoded_deltas = EncodeDeltas(base_event->payload_length(), values);
1495   if (!encoded_deltas.empty()) {
1496     proto_batch->set_payload_length_deltas(encoded_deltas);
1497   }
1498 
1499   // padding_length
1500   for (size_t i = 0; i < values.size(); ++i) {
1501     const RtcEventGenericPacketSent* event = batch[i + 1];
1502     values[i] = event->padding_length();
1503   }
1504   encoded_deltas = EncodeDeltas(base_event->padding_length(), values);
1505   if (!encoded_deltas.empty()) {
1506     proto_batch->set_padding_length_deltas(encoded_deltas);
1507   }
1508 }
1509 
EncodeGenericPacketsReceived(rtc::ArrayView<const RtcEventGenericPacketReceived * > batch,rtclog2::EventStream * event_stream)1510 void RtcEventLogEncoderNewFormat::EncodeGenericPacketsReceived(
1511     rtc::ArrayView<const RtcEventGenericPacketReceived*> batch,
1512     rtclog2::EventStream* event_stream) {
1513   if (batch.empty()) {
1514     return;
1515   }
1516   const RtcEventGenericPacketReceived* const base_event = batch[0];
1517   rtclog2::GenericPacketReceived* proto_batch =
1518       event_stream->add_generic_packets_received();
1519   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1520   proto_batch->set_packet_number(base_event->packet_number());
1521   proto_batch->set_packet_length(base_event->packet_length());
1522 
1523   // Delta encoding
1524   proto_batch->set_number_of_deltas(batch.size() - 1);
1525   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
1526   std::string encoded_deltas;
1527 
1528   if (batch.size() == 1) {
1529     return;
1530   }
1531 
1532   // timestamp_ms
1533   for (size_t i = 0; i < values.size(); ++i) {
1534     const RtcEventGenericPacketReceived* event = batch[i + 1];
1535     values[i] = ToUnsigned(event->timestamp_ms());
1536   }
1537   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
1538   if (!encoded_deltas.empty()) {
1539     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
1540   }
1541 
1542   // packet_number
1543   for (size_t i = 0; i < values.size(); ++i) {
1544     const RtcEventGenericPacketReceived* event = batch[i + 1];
1545     values[i] = ToUnsigned(event->packet_number());
1546   }
1547   encoded_deltas =
1548       EncodeDeltas(ToUnsigned(base_event->packet_number()), values);
1549   if (!encoded_deltas.empty()) {
1550     proto_batch->set_packet_number_deltas(encoded_deltas);
1551   }
1552 
1553   // packet_length
1554   for (size_t i = 0; i < values.size(); ++i) {
1555     const RtcEventGenericPacketReceived* event = batch[i + 1];
1556     values[i] = event->packet_length();
1557   }
1558   encoded_deltas = EncodeDeltas(base_event->packet_length(), values);
1559   if (!encoded_deltas.empty()) {
1560     proto_batch->set_packet_length_deltas(encoded_deltas);
1561   }
1562 }
1563 
EncodeGenericAcksReceived(rtc::ArrayView<const RtcEventGenericAckReceived * > batch,rtclog2::EventStream * event_stream)1564 void RtcEventLogEncoderNewFormat::EncodeGenericAcksReceived(
1565     rtc::ArrayView<const RtcEventGenericAckReceived*> batch,
1566     rtclog2::EventStream* event_stream) {
1567   if (batch.empty()) {
1568     return;
1569   }
1570   const RtcEventGenericAckReceived* const base_event = batch[0];
1571   rtclog2::GenericAckReceived* proto_batch =
1572       event_stream->add_generic_acks_received();
1573   proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1574   proto_batch->set_packet_number(base_event->packet_number());
1575   proto_batch->set_acked_packet_number(base_event->acked_packet_number());
1576   absl::optional<uint64_t> base_receive_timestamp;
1577   if (base_event->receive_acked_packet_time_ms()) {
1578     int64_t receive_acked_packet_time_ms =
1579         base_event->receive_acked_packet_time_ms().value();
1580     base_receive_timestamp = ToUnsigned(receive_acked_packet_time_ms);
1581     proto_batch->set_receive_acked_packet_time_ms(receive_acked_packet_time_ms);
1582   }
1583 
1584   // Delta encoding
1585   proto_batch->set_number_of_deltas(batch.size() - 1);
1586   std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
1587   std::string encoded_deltas;
1588 
1589   if (batch.size() == 1) {
1590     return;
1591   }
1592 
1593   // timestamp_ms
1594   for (size_t i = 0; i < values.size(); ++i) {
1595     const RtcEventGenericAckReceived* event = batch[i + 1];
1596     values[i] = ToUnsigned(event->timestamp_ms());
1597   }
1598   encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
1599   if (!encoded_deltas.empty()) {
1600     proto_batch->set_timestamp_ms_deltas(encoded_deltas);
1601   }
1602 
1603   // packet_number
1604   for (size_t i = 0; i < values.size(); ++i) {
1605     const RtcEventGenericAckReceived* event = batch[i + 1];
1606     values[i] = ToUnsigned(event->packet_number());
1607   }
1608   encoded_deltas =
1609       EncodeDeltas(ToUnsigned(base_event->packet_number()), values);
1610   if (!encoded_deltas.empty()) {
1611     proto_batch->set_packet_number_deltas(encoded_deltas);
1612   }
1613 
1614   // acked packet number
1615   for (size_t i = 0; i < values.size(); ++i) {
1616     const RtcEventGenericAckReceived* event = batch[i + 1];
1617     values[i] = ToUnsigned(event->acked_packet_number());
1618   }
1619   encoded_deltas =
1620       EncodeDeltas(ToUnsigned(base_event->acked_packet_number()), values);
1621   if (!encoded_deltas.empty()) {
1622     proto_batch->set_acked_packet_number_deltas(encoded_deltas);
1623   }
1624 
1625   // receive timestamp
1626   for (size_t i = 0; i < values.size(); ++i) {
1627     const RtcEventGenericAckReceived* event = batch[i + 1];
1628     if (event->receive_acked_packet_time_ms()) {
1629       values[i] = ToUnsigned(event->receive_acked_packet_time_ms().value());
1630     } else {
1631       values[i] = absl::nullopt;
1632     }
1633   }
1634   encoded_deltas = EncodeDeltas(base_receive_timestamp, values);
1635   if (!encoded_deltas.empty()) {
1636     proto_batch->set_receive_acked_packet_time_ms_deltas(encoded_deltas);
1637   }
1638 }
1639 
EncodeRtpPacketOutgoing(const std::map<uint32_t,std::vector<const RtcEventRtpPacketOutgoing * >> & batch,rtclog2::EventStream * event_stream)1640 void RtcEventLogEncoderNewFormat::EncodeRtpPacketOutgoing(
1641     const std::map<uint32_t, std::vector<const RtcEventRtpPacketOutgoing*>>&
1642         batch,
1643     rtclog2::EventStream* event_stream) {
1644   for (const auto& it : batch) {
1645     RTC_DCHECK(!it.second.empty());
1646     EncodeRtpPacket(it.second, event_stream->add_outgoing_rtp_packets());
1647   }
1648 }
1649 
EncodeVideoRecvStreamConfig(rtc::ArrayView<const RtcEventVideoReceiveStreamConfig * > batch,rtclog2::EventStream * event_stream)1650 void RtcEventLogEncoderNewFormat::EncodeVideoRecvStreamConfig(
1651     rtc::ArrayView<const RtcEventVideoReceiveStreamConfig*> batch,
1652     rtclog2::EventStream* event_stream) {
1653   for (const RtcEventVideoReceiveStreamConfig* base_event : batch) {
1654     rtclog2::VideoRecvStreamConfig* proto_batch =
1655         event_stream->add_video_recv_stream_configs();
1656     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1657     proto_batch->set_remote_ssrc(base_event->config().remote_ssrc);
1658     proto_batch->set_local_ssrc(base_event->config().local_ssrc);
1659     proto_batch->set_rtx_ssrc(base_event->config().rtx_ssrc);
1660 
1661     rtclog2::RtpHeaderExtensionConfig* proto_config =
1662         proto_batch->mutable_header_extensions();
1663     bool has_recognized_extensions =
1664         ConvertToProtoFormat(base_event->config().rtp_extensions, proto_config);
1665     if (!has_recognized_extensions)
1666       proto_batch->clear_header_extensions();
1667   }
1668 }
1669 
EncodeVideoSendStreamConfig(rtc::ArrayView<const RtcEventVideoSendStreamConfig * > batch,rtclog2::EventStream * event_stream)1670 void RtcEventLogEncoderNewFormat::EncodeVideoSendStreamConfig(
1671     rtc::ArrayView<const RtcEventVideoSendStreamConfig*> batch,
1672     rtclog2::EventStream* event_stream) {
1673   for (const RtcEventVideoSendStreamConfig* base_event : batch) {
1674     rtclog2::VideoSendStreamConfig* proto_batch =
1675         event_stream->add_video_send_stream_configs();
1676     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1677     proto_batch->set_ssrc(base_event->config().local_ssrc);
1678     proto_batch->set_rtx_ssrc(base_event->config().rtx_ssrc);
1679 
1680     rtclog2::RtpHeaderExtensionConfig* proto_config =
1681         proto_batch->mutable_header_extensions();
1682     bool has_recognized_extensions =
1683         ConvertToProtoFormat(base_event->config().rtp_extensions, proto_config);
1684     if (!has_recognized_extensions)
1685       proto_batch->clear_header_extensions();
1686   }
1687 }
1688 
EncodeIceCandidatePairConfig(rtc::ArrayView<const RtcEventIceCandidatePairConfig * > batch,rtclog2::EventStream * event_stream)1689 void RtcEventLogEncoderNewFormat::EncodeIceCandidatePairConfig(
1690     rtc::ArrayView<const RtcEventIceCandidatePairConfig*> batch,
1691     rtclog2::EventStream* event_stream) {
1692   for (const RtcEventIceCandidatePairConfig* base_event : batch) {
1693     rtclog2::IceCandidatePairConfig* proto_batch =
1694         event_stream->add_ice_candidate_configs();
1695 
1696     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1697     proto_batch->set_config_type(ConvertToProtoFormat(base_event->type()));
1698     proto_batch->set_candidate_pair_id(base_event->candidate_pair_id());
1699     const auto& desc = base_event->candidate_pair_desc();
1700     proto_batch->set_local_candidate_type(
1701         ConvertToProtoFormat(desc.local_candidate_type));
1702     proto_batch->set_local_relay_protocol(
1703         ConvertToProtoFormat(desc.local_relay_protocol));
1704     proto_batch->set_local_network_type(
1705         ConvertToProtoFormat(desc.local_network_type));
1706     proto_batch->set_local_address_family(
1707         ConvertToProtoFormat(desc.local_address_family));
1708     proto_batch->set_remote_candidate_type(
1709         ConvertToProtoFormat(desc.remote_candidate_type));
1710     proto_batch->set_remote_address_family(
1711         ConvertToProtoFormat(desc.remote_address_family));
1712     proto_batch->set_candidate_pair_protocol(
1713         ConvertToProtoFormat(desc.candidate_pair_protocol));
1714   }
1715   // TODO(terelius): Should we delta-compress this event type?
1716 }
1717 
EncodeIceCandidatePairEvent(rtc::ArrayView<const RtcEventIceCandidatePair * > batch,rtclog2::EventStream * event_stream)1718 void RtcEventLogEncoderNewFormat::EncodeIceCandidatePairEvent(
1719     rtc::ArrayView<const RtcEventIceCandidatePair*> batch,
1720     rtclog2::EventStream* event_stream) {
1721   for (const RtcEventIceCandidatePair* base_event : batch) {
1722     rtclog2::IceCandidatePairEvent* proto_batch =
1723         event_stream->add_ice_candidate_events();
1724 
1725     proto_batch->set_timestamp_ms(base_event->timestamp_ms());
1726 
1727     proto_batch->set_event_type(ConvertToProtoFormat(base_event->type()));
1728     proto_batch->set_candidate_pair_id(base_event->candidate_pair_id());
1729     proto_batch->set_transaction_id(base_event->transaction_id());
1730   }
1731   // TODO(terelius): Should we delta-compress this event type?
1732 }
1733 
1734 }  // namespace webrtc
1735