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