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