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