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