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_legacy.h"
12
13 #include <string.h>
14
15 #include <vector>
16
17 #include "absl/types/optional.h"
18 #include "api/network_state_predictor.h"
19 #include "api/rtp_headers.h"
20 #include "api/rtp_parameters.h"
21 #include "api/transport/network_types.h"
22 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
23 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
24 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
25 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
26 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
27 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
28 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
29 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
30 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
31 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
32 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
33 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
34 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
35 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
36 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
37 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
38 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
39 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
40 #include "logging/rtc_event_log/rtc_stream_config.h"
41 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
42 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
43 #include "modules/rtp_rtcp/source/rtcp_packet/app.h"
44 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
45 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
46 #include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
47 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
48 #include "modules/rtp_rtcp/source/rtcp_packet/psfb.h"
49 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
50 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
51 #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
52 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
53 #include "modules/rtp_rtcp/source/rtp_packet.h"
54 #include "rtc_base/checks.h"
55 #include "rtc_base/ignore_wundef.h"
56 #include "rtc_base/logging.h"
57
58 // *.pb.h files are generated at build-time by the protobuf compiler.
59 RTC_PUSH_IGNORING_WUNDEF()
60 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
61 #include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
62 #else
63 #include <rtc_event_log.pb.h>
64 #endif
65 RTC_POP_IGNORING_WUNDEF()
66
67 namespace webrtc {
68
69 namespace {
ConvertDetectorState(BandwidthUsage state)70 rtclog::DelayBasedBweUpdate::DetectorState ConvertDetectorState(
71 BandwidthUsage state) {
72 switch (state) {
73 case BandwidthUsage::kBwNormal:
74 return rtclog::DelayBasedBweUpdate::BWE_NORMAL;
75 case BandwidthUsage::kBwUnderusing:
76 return rtclog::DelayBasedBweUpdate::BWE_UNDERUSING;
77 case BandwidthUsage::kBwOverusing:
78 return rtclog::DelayBasedBweUpdate::BWE_OVERUSING;
79 case BandwidthUsage::kLast:
80 RTC_NOTREACHED();
81 }
82 RTC_NOTREACHED();
83 return rtclog::DelayBasedBweUpdate::BWE_NORMAL;
84 }
85
ConvertProbeResultType(ProbeFailureReason failure_reason)86 rtclog::BweProbeResult::ResultType ConvertProbeResultType(
87 ProbeFailureReason failure_reason) {
88 switch (failure_reason) {
89 case ProbeFailureReason::kInvalidSendReceiveInterval:
90 return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL;
91 case ProbeFailureReason::kInvalidSendReceiveRatio:
92 return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO;
93 case ProbeFailureReason::kTimeout:
94 return rtclog::BweProbeResult::TIMEOUT;
95 case ProbeFailureReason::kLast:
96 RTC_NOTREACHED();
97 }
98 RTC_NOTREACHED();
99 return rtclog::BweProbeResult::SUCCESS;
100 }
101
ConvertRtcpMode(RtcpMode rtcp_mode)102 rtclog::VideoReceiveConfig_RtcpMode ConvertRtcpMode(RtcpMode rtcp_mode) {
103 switch (rtcp_mode) {
104 case RtcpMode::kCompound:
105 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
106 case RtcpMode::kReducedSize:
107 return rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE;
108 case RtcpMode::kOff:
109 RTC_NOTREACHED();
110 }
111 RTC_NOTREACHED();
112 return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
113 }
114
115 rtclog::IceCandidatePairConfig::IceCandidatePairConfigType
ConvertIceCandidatePairConfigType(IceCandidatePairConfigType type)116 ConvertIceCandidatePairConfigType(IceCandidatePairConfigType type) {
117 switch (type) {
118 case IceCandidatePairConfigType::kAdded:
119 return rtclog::IceCandidatePairConfig::ADDED;
120 case IceCandidatePairConfigType::kUpdated:
121 return rtclog::IceCandidatePairConfig::UPDATED;
122 case IceCandidatePairConfigType::kDestroyed:
123 return rtclog::IceCandidatePairConfig::DESTROYED;
124 case IceCandidatePairConfigType::kSelected:
125 return rtclog::IceCandidatePairConfig::SELECTED;
126 case IceCandidatePairConfigType::kNumValues:
127 RTC_NOTREACHED();
128 }
129 RTC_NOTREACHED();
130 return rtclog::IceCandidatePairConfig::ADDED;
131 }
132
ConvertIceCandidateType(IceCandidateType type)133 rtclog::IceCandidatePairConfig::IceCandidateType ConvertIceCandidateType(
134 IceCandidateType type) {
135 switch (type) {
136 case IceCandidateType::kUnknown:
137 return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE;
138 case IceCandidateType::kLocal:
139 return rtclog::IceCandidatePairConfig::LOCAL;
140 case IceCandidateType::kStun:
141 return rtclog::IceCandidatePairConfig::STUN;
142 case IceCandidateType::kPrflx:
143 return rtclog::IceCandidatePairConfig::PRFLX;
144 case IceCandidateType::kRelay:
145 return rtclog::IceCandidatePairConfig::RELAY;
146 case IceCandidateType::kNumValues:
147 RTC_NOTREACHED();
148 }
149 RTC_NOTREACHED();
150 return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE;
151 }
152
ConvertIceCandidatePairProtocol(IceCandidatePairProtocol protocol)153 rtclog::IceCandidatePairConfig::Protocol ConvertIceCandidatePairProtocol(
154 IceCandidatePairProtocol protocol) {
155 switch (protocol) {
156 case IceCandidatePairProtocol::kUnknown:
157 return rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
158 case IceCandidatePairProtocol::kUdp:
159 return rtclog::IceCandidatePairConfig::UDP;
160 case IceCandidatePairProtocol::kTcp:
161 return rtclog::IceCandidatePairConfig::TCP;
162 case IceCandidatePairProtocol::kSsltcp:
163 return rtclog::IceCandidatePairConfig::SSLTCP;
164 case IceCandidatePairProtocol::kTls:
165 return rtclog::IceCandidatePairConfig::TLS;
166 case IceCandidatePairProtocol::kNumValues:
167 RTC_NOTREACHED();
168 }
169 RTC_NOTREACHED();
170 return rtclog::IceCandidatePairConfig::UNKNOWN_PROTOCOL;
171 }
172
173 rtclog::IceCandidatePairConfig::AddressFamily
ConvertIceCandidatePairAddressFamily(IceCandidatePairAddressFamily address_family)174 ConvertIceCandidatePairAddressFamily(
175 IceCandidatePairAddressFamily address_family) {
176 switch (address_family) {
177 case IceCandidatePairAddressFamily::kUnknown:
178 return rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
179 case IceCandidatePairAddressFamily::kIpv4:
180 return rtclog::IceCandidatePairConfig::IPV4;
181 case IceCandidatePairAddressFamily::kIpv6:
182 return rtclog::IceCandidatePairConfig::IPV6;
183 case IceCandidatePairAddressFamily::kNumValues:
184 RTC_NOTREACHED();
185 }
186 RTC_NOTREACHED();
187 return rtclog::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY;
188 }
189
ConvertIceCandidateNetworkType(IceCandidateNetworkType network_type)190 rtclog::IceCandidatePairConfig::NetworkType ConvertIceCandidateNetworkType(
191 IceCandidateNetworkType network_type) {
192 switch (network_type) {
193 case IceCandidateNetworkType::kUnknown:
194 return rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
195 case IceCandidateNetworkType::kEthernet:
196 return rtclog::IceCandidatePairConfig::ETHERNET;
197 case IceCandidateNetworkType::kLoopback:
198 return rtclog::IceCandidatePairConfig::LOOPBACK;
199 case IceCandidateNetworkType::kWifi:
200 return rtclog::IceCandidatePairConfig::WIFI;
201 case IceCandidateNetworkType::kVpn:
202 return rtclog::IceCandidatePairConfig::VPN;
203 case IceCandidateNetworkType::kCellular:
204 return rtclog::IceCandidatePairConfig::CELLULAR;
205 case IceCandidateNetworkType::kNumValues:
206 RTC_NOTREACHED();
207 }
208 RTC_NOTREACHED();
209 return rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE;
210 }
211
212 rtclog::IceCandidatePairEvent::IceCandidatePairEventType
ConvertIceCandidatePairEventType(IceCandidatePairEventType type)213 ConvertIceCandidatePairEventType(IceCandidatePairEventType type) {
214 switch (type) {
215 case IceCandidatePairEventType::kCheckSent:
216 return rtclog::IceCandidatePairEvent::CHECK_SENT;
217 case IceCandidatePairEventType::kCheckReceived:
218 return rtclog::IceCandidatePairEvent::CHECK_RECEIVED;
219 case IceCandidatePairEventType::kCheckResponseSent:
220 return rtclog::IceCandidatePairEvent::CHECK_RESPONSE_SENT;
221 case IceCandidatePairEventType::kCheckResponseReceived:
222 return rtclog::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED;
223 case IceCandidatePairEventType::kNumValues:
224 RTC_NOTREACHED();
225 }
226 RTC_NOTREACHED();
227 return rtclog::IceCandidatePairEvent::CHECK_SENT;
228 }
229
230 } // namespace
231
EncodeLogStart(int64_t timestamp_us,int64_t utc_time_us)232 std::string RtcEventLogEncoderLegacy::EncodeLogStart(int64_t timestamp_us,
233 int64_t utc_time_us) {
234 rtclog::Event rtclog_event;
235 rtclog_event.set_timestamp_us(timestamp_us);
236 rtclog_event.set_type(rtclog::Event::LOG_START);
237 return Serialize(&rtclog_event);
238 }
239
EncodeLogEnd(int64_t timestamp_us)240 std::string RtcEventLogEncoderLegacy::EncodeLogEnd(int64_t timestamp_us) {
241 rtclog::Event rtclog_event;
242 rtclog_event.set_timestamp_us(timestamp_us);
243 rtclog_event.set_type(rtclog::Event::LOG_END);
244 return Serialize(&rtclog_event);
245 }
246
EncodeBatch(std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,std::deque<std::unique_ptr<RtcEvent>>::const_iterator end)247 std::string RtcEventLogEncoderLegacy::EncodeBatch(
248 std::deque<std::unique_ptr<RtcEvent>>::const_iterator begin,
249 std::deque<std::unique_ptr<RtcEvent>>::const_iterator end) {
250 std::string encoded_output;
251 for (auto it = begin; it != end; ++it) {
252 // TODO(terelius): Can we avoid the slight inefficiency of reallocating the
253 // string?
254 RTC_CHECK(it->get() != nullptr);
255 encoded_output += Encode(**it);
256 }
257 return encoded_output;
258 }
259
Encode(const RtcEvent & event)260 std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) {
261 switch (event.GetType()) {
262 case RtcEvent::Type::AudioNetworkAdaptation: {
263 auto& rtc_event =
264 static_cast<const RtcEventAudioNetworkAdaptation&>(event);
265 return EncodeAudioNetworkAdaptation(rtc_event);
266 }
267
268 case RtcEvent::Type::AlrStateEvent: {
269 auto& rtc_event = static_cast<const RtcEventAlrState&>(event);
270 return EncodeAlrState(rtc_event);
271 }
272
273 case RtcEvent::Type::AudioPlayout: {
274 auto& rtc_event = static_cast<const RtcEventAudioPlayout&>(event);
275 return EncodeAudioPlayout(rtc_event);
276 }
277
278 case RtcEvent::Type::AudioReceiveStreamConfig: {
279 auto& rtc_event =
280 static_cast<const RtcEventAudioReceiveStreamConfig&>(event);
281 return EncodeAudioReceiveStreamConfig(rtc_event);
282 }
283
284 case RtcEvent::Type::AudioSendStreamConfig: {
285 auto& rtc_event =
286 static_cast<const RtcEventAudioSendStreamConfig&>(event);
287 return EncodeAudioSendStreamConfig(rtc_event);
288 }
289
290 case RtcEvent::Type::BweUpdateDelayBased: {
291 auto& rtc_event = static_cast<const RtcEventBweUpdateDelayBased&>(event);
292 return EncodeBweUpdateDelayBased(rtc_event);
293 }
294
295 case RtcEvent::Type::BweUpdateLossBased: {
296 auto& rtc_event = static_cast<const RtcEventBweUpdateLossBased&>(event);
297 return EncodeBweUpdateLossBased(rtc_event);
298 }
299
300 case RtcEvent::Type::DtlsTransportState: {
301 return "";
302 }
303
304 case RtcEvent::Type::DtlsWritableState: {
305 return "";
306 }
307
308 case RtcEvent::Type::IceCandidatePairConfig: {
309 auto& rtc_event =
310 static_cast<const RtcEventIceCandidatePairConfig&>(event);
311 return EncodeIceCandidatePairConfig(rtc_event);
312 }
313
314 case RtcEvent::Type::IceCandidatePairEvent: {
315 auto& rtc_event = static_cast<const RtcEventIceCandidatePair&>(event);
316 return EncodeIceCandidatePairEvent(rtc_event);
317 }
318
319 case RtcEvent::Type::ProbeClusterCreated: {
320 auto& rtc_event = static_cast<const RtcEventProbeClusterCreated&>(event);
321 return EncodeProbeClusterCreated(rtc_event);
322 }
323
324 case RtcEvent::Type::ProbeResultFailure: {
325 auto& rtc_event = static_cast<const RtcEventProbeResultFailure&>(event);
326 return EncodeProbeResultFailure(rtc_event);
327 }
328
329 case RtcEvent::Type::ProbeResultSuccess: {
330 auto& rtc_event = static_cast<const RtcEventProbeResultSuccess&>(event);
331 return EncodeProbeResultSuccess(rtc_event);
332 }
333
334 case RtcEvent::Type::RtcpPacketIncoming: {
335 auto& rtc_event = static_cast<const RtcEventRtcpPacketIncoming&>(event);
336 return EncodeRtcpPacketIncoming(rtc_event);
337 }
338
339 case RtcEvent::Type::RtcpPacketOutgoing: {
340 auto& rtc_event = static_cast<const RtcEventRtcpPacketOutgoing&>(event);
341 return EncodeRtcpPacketOutgoing(rtc_event);
342 }
343
344 case RtcEvent::Type::RtpPacketIncoming: {
345 auto& rtc_event = static_cast<const RtcEventRtpPacketIncoming&>(event);
346 return EncodeRtpPacketIncoming(rtc_event);
347 }
348
349 case RtcEvent::Type::RtpPacketOutgoing: {
350 auto& rtc_event = static_cast<const RtcEventRtpPacketOutgoing&>(event);
351 return EncodeRtpPacketOutgoing(rtc_event);
352 }
353
354 case RtcEvent::Type::VideoReceiveStreamConfig: {
355 auto& rtc_event =
356 static_cast<const RtcEventVideoReceiveStreamConfig&>(event);
357 return EncodeVideoReceiveStreamConfig(rtc_event);
358 }
359
360 case RtcEvent::Type::VideoSendStreamConfig: {
361 auto& rtc_event =
362 static_cast<const RtcEventVideoSendStreamConfig&>(event);
363 return EncodeVideoSendStreamConfig(rtc_event);
364 }
365 case RtcEvent::Type::RouteChangeEvent:
366 case RtcEvent::Type::RemoteEstimateEvent:
367 case RtcEvent::Type::GenericPacketReceived:
368 case RtcEvent::Type::GenericPacketSent:
369 case RtcEvent::Type::GenericAckReceived:
370 case RtcEvent::Type::FrameDecoded:
371 // These are unsupported in the old format, but shouldn't crash.
372 return "";
373 }
374
375 int event_type = static_cast<int>(event.GetType());
376 RTC_NOTREACHED() << "Unknown event type (" << event_type << ")";
377 return "";
378 }
379
EncodeAlrState(const RtcEventAlrState & event)380 std::string RtcEventLogEncoderLegacy::EncodeAlrState(
381 const RtcEventAlrState& event) {
382 rtclog::Event rtclog_event;
383 rtclog_event.set_timestamp_us(event.timestamp_us());
384 rtclog_event.set_type(rtclog::Event::ALR_STATE_EVENT);
385
386 auto* alr_state = rtclog_event.mutable_alr_state();
387 alr_state->set_in_alr(event.in_alr());
388 return Serialize(&rtclog_event);
389 }
390
EncodeAudioNetworkAdaptation(const RtcEventAudioNetworkAdaptation & event)391 std::string RtcEventLogEncoderLegacy::EncodeAudioNetworkAdaptation(
392 const RtcEventAudioNetworkAdaptation& event) {
393 rtclog::Event rtclog_event;
394 rtclog_event.set_timestamp_us(event.timestamp_us());
395 rtclog_event.set_type(rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
396
397 auto* audio_network_adaptation =
398 rtclog_event.mutable_audio_network_adaptation();
399 if (event.config().bitrate_bps)
400 audio_network_adaptation->set_bitrate_bps(*event.config().bitrate_bps);
401 if (event.config().frame_length_ms)
402 audio_network_adaptation->set_frame_length_ms(
403 *event.config().frame_length_ms);
404 if (event.config().uplink_packet_loss_fraction) {
405 audio_network_adaptation->set_uplink_packet_loss_fraction(
406 *event.config().uplink_packet_loss_fraction);
407 }
408 if (event.config().enable_fec)
409 audio_network_adaptation->set_enable_fec(*event.config().enable_fec);
410 if (event.config().enable_dtx)
411 audio_network_adaptation->set_enable_dtx(*event.config().enable_dtx);
412 if (event.config().num_channels)
413 audio_network_adaptation->set_num_channels(*event.config().num_channels);
414
415 return Serialize(&rtclog_event);
416 }
417
EncodeAudioPlayout(const RtcEventAudioPlayout & event)418 std::string RtcEventLogEncoderLegacy::EncodeAudioPlayout(
419 const RtcEventAudioPlayout& event) {
420 rtclog::Event rtclog_event;
421 rtclog_event.set_timestamp_us(event.timestamp_us());
422 rtclog_event.set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT);
423
424 auto* playout_event = rtclog_event.mutable_audio_playout_event();
425 playout_event->set_local_ssrc(event.ssrc());
426
427 return Serialize(&rtclog_event);
428 }
429
EncodeAudioReceiveStreamConfig(const RtcEventAudioReceiveStreamConfig & event)430 std::string RtcEventLogEncoderLegacy::EncodeAudioReceiveStreamConfig(
431 const RtcEventAudioReceiveStreamConfig& event) {
432 rtclog::Event rtclog_event;
433 rtclog_event.set_timestamp_us(event.timestamp_us());
434 rtclog_event.set_type(rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT);
435
436 rtclog::AudioReceiveConfig* receiver_config =
437 rtclog_event.mutable_audio_receiver_config();
438 receiver_config->set_remote_ssrc(event.config().remote_ssrc);
439 receiver_config->set_local_ssrc(event.config().local_ssrc);
440
441 for (const auto& e : event.config().rtp_extensions) {
442 rtclog::RtpHeaderExtension* extension =
443 receiver_config->add_header_extensions();
444 extension->set_name(e.uri);
445 extension->set_id(e.id);
446 }
447
448 return Serialize(&rtclog_event);
449 }
450
EncodeAudioSendStreamConfig(const RtcEventAudioSendStreamConfig & event)451 std::string RtcEventLogEncoderLegacy::EncodeAudioSendStreamConfig(
452 const RtcEventAudioSendStreamConfig& event) {
453 rtclog::Event rtclog_event;
454 rtclog_event.set_timestamp_us(event.timestamp_us());
455 rtclog_event.set_type(rtclog::Event::AUDIO_SENDER_CONFIG_EVENT);
456
457 rtclog::AudioSendConfig* sender_config =
458 rtclog_event.mutable_audio_sender_config();
459
460 sender_config->set_ssrc(event.config().local_ssrc);
461
462 for (const auto& e : event.config().rtp_extensions) {
463 rtclog::RtpHeaderExtension* extension =
464 sender_config->add_header_extensions();
465 extension->set_name(e.uri);
466 extension->set_id(e.id);
467 }
468
469 return Serialize(&rtclog_event);
470 }
471
EncodeBweUpdateDelayBased(const RtcEventBweUpdateDelayBased & event)472 std::string RtcEventLogEncoderLegacy::EncodeBweUpdateDelayBased(
473 const RtcEventBweUpdateDelayBased& event) {
474 rtclog::Event rtclog_event;
475 rtclog_event.set_timestamp_us(event.timestamp_us());
476 rtclog_event.set_type(rtclog::Event::DELAY_BASED_BWE_UPDATE);
477
478 auto* bwe_event = rtclog_event.mutable_delay_based_bwe_update();
479 bwe_event->set_bitrate_bps(event.bitrate_bps());
480 bwe_event->set_detector_state(ConvertDetectorState(event.detector_state()));
481
482 return Serialize(&rtclog_event);
483 }
484
EncodeBweUpdateLossBased(const RtcEventBweUpdateLossBased & event)485 std::string RtcEventLogEncoderLegacy::EncodeBweUpdateLossBased(
486 const RtcEventBweUpdateLossBased& event) {
487 rtclog::Event rtclog_event;
488 rtclog_event.set_timestamp_us(event.timestamp_us());
489 rtclog_event.set_type(rtclog::Event::LOSS_BASED_BWE_UPDATE);
490
491 auto* bwe_event = rtclog_event.mutable_loss_based_bwe_update();
492 bwe_event->set_bitrate_bps(event.bitrate_bps());
493 bwe_event->set_fraction_loss(event.fraction_loss());
494 bwe_event->set_total_packets(event.total_packets());
495
496 return Serialize(&rtclog_event);
497 }
498
EncodeIceCandidatePairConfig(const RtcEventIceCandidatePairConfig & event)499 std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairConfig(
500 const RtcEventIceCandidatePairConfig& event) {
501 rtclog::Event encoded_rtc_event;
502 encoded_rtc_event.set_timestamp_us(event.timestamp_us());
503 encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
504
505 auto* encoded_ice_event =
506 encoded_rtc_event.mutable_ice_candidate_pair_config();
507 encoded_ice_event->set_config_type(
508 ConvertIceCandidatePairConfigType(event.type()));
509 encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id());
510 const auto& desc = event.candidate_pair_desc();
511 encoded_ice_event->set_local_candidate_type(
512 ConvertIceCandidateType(desc.local_candidate_type));
513 encoded_ice_event->set_local_relay_protocol(
514 ConvertIceCandidatePairProtocol(desc.local_relay_protocol));
515 encoded_ice_event->set_local_network_type(
516 ConvertIceCandidateNetworkType(desc.local_network_type));
517 encoded_ice_event->set_local_address_family(
518 ConvertIceCandidatePairAddressFamily(desc.local_address_family));
519 encoded_ice_event->set_remote_candidate_type(
520 ConvertIceCandidateType(desc.remote_candidate_type));
521 encoded_ice_event->set_remote_address_family(
522 ConvertIceCandidatePairAddressFamily(desc.remote_address_family));
523 encoded_ice_event->set_candidate_pair_protocol(
524 ConvertIceCandidatePairProtocol(desc.candidate_pair_protocol));
525 return Serialize(&encoded_rtc_event);
526 }
527
EncodeIceCandidatePairEvent(const RtcEventIceCandidatePair & event)528 std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairEvent(
529 const RtcEventIceCandidatePair& event) {
530 rtclog::Event encoded_rtc_event;
531 encoded_rtc_event.set_timestamp_us(event.timestamp_us());
532 encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
533
534 auto* encoded_ice_event =
535 encoded_rtc_event.mutable_ice_candidate_pair_event();
536 encoded_ice_event->set_event_type(
537 ConvertIceCandidatePairEventType(event.type()));
538 encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id());
539 return Serialize(&encoded_rtc_event);
540 }
541
EncodeProbeClusterCreated(const RtcEventProbeClusterCreated & event)542 std::string RtcEventLogEncoderLegacy::EncodeProbeClusterCreated(
543 const RtcEventProbeClusterCreated& event) {
544 rtclog::Event rtclog_event;
545 rtclog_event.set_timestamp_us(event.timestamp_us());
546 rtclog_event.set_type(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
547
548 auto* probe_cluster = rtclog_event.mutable_probe_cluster();
549 probe_cluster->set_id(event.id());
550 probe_cluster->set_bitrate_bps(event.bitrate_bps());
551 probe_cluster->set_min_packets(event.min_probes());
552 probe_cluster->set_min_bytes(event.min_bytes());
553
554 return Serialize(&rtclog_event);
555 }
556
EncodeProbeResultFailure(const RtcEventProbeResultFailure & event)557 std::string RtcEventLogEncoderLegacy::EncodeProbeResultFailure(
558 const RtcEventProbeResultFailure& event) {
559 rtclog::Event rtclog_event;
560 rtclog_event.set_timestamp_us(event.timestamp_us());
561 rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
562
563 auto* probe_result = rtclog_event.mutable_probe_result();
564 probe_result->set_id(event.id());
565 probe_result->set_result(ConvertProbeResultType(event.failure_reason()));
566
567 return Serialize(&rtclog_event);
568 }
569
EncodeProbeResultSuccess(const RtcEventProbeResultSuccess & event)570 std::string RtcEventLogEncoderLegacy::EncodeProbeResultSuccess(
571 const RtcEventProbeResultSuccess& event) {
572 rtclog::Event rtclog_event;
573 rtclog_event.set_timestamp_us(event.timestamp_us());
574 rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
575
576 auto* probe_result = rtclog_event.mutable_probe_result();
577 probe_result->set_id(event.id());
578 probe_result->set_result(rtclog::BweProbeResult::SUCCESS);
579 probe_result->set_bitrate_bps(event.bitrate_bps());
580
581 return Serialize(&rtclog_event);
582 }
583
EncodeRtcpPacketIncoming(const RtcEventRtcpPacketIncoming & event)584 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketIncoming(
585 const RtcEventRtcpPacketIncoming& event) {
586 return EncodeRtcpPacket(event.timestamp_us(), event.packet(), true);
587 }
588
EncodeRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing & event)589 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketOutgoing(
590 const RtcEventRtcpPacketOutgoing& event) {
591 return EncodeRtcpPacket(event.timestamp_us(), event.packet(), false);
592 }
593
EncodeRtpPacketIncoming(const RtcEventRtpPacketIncoming & event)594 std::string RtcEventLogEncoderLegacy::EncodeRtpPacketIncoming(
595 const RtcEventRtpPacketIncoming& event) {
596 return EncodeRtpPacket(event.timestamp_us(), event.header(),
597 event.packet_length(), PacedPacketInfo::kNotAProbe,
598 true);
599 }
600
EncodeRtpPacketOutgoing(const RtcEventRtpPacketOutgoing & event)601 std::string RtcEventLogEncoderLegacy::EncodeRtpPacketOutgoing(
602 const RtcEventRtpPacketOutgoing& event) {
603 return EncodeRtpPacket(event.timestamp_us(), event.header(),
604 event.packet_length(), event.probe_cluster_id(),
605 false);
606 }
607
EncodeVideoReceiveStreamConfig(const RtcEventVideoReceiveStreamConfig & event)608 std::string RtcEventLogEncoderLegacy::EncodeVideoReceiveStreamConfig(
609 const RtcEventVideoReceiveStreamConfig& event) {
610 rtclog::Event rtclog_event;
611 rtclog_event.set_timestamp_us(event.timestamp_us());
612 rtclog_event.set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
613
614 rtclog::VideoReceiveConfig* receiver_config =
615 rtclog_event.mutable_video_receiver_config();
616 receiver_config->set_remote_ssrc(event.config().remote_ssrc);
617 receiver_config->set_local_ssrc(event.config().local_ssrc);
618
619 // TODO(perkj): Add field for rsid.
620 receiver_config->set_rtcp_mode(ConvertRtcpMode(event.config().rtcp_mode));
621 receiver_config->set_remb(event.config().remb);
622
623 for (const auto& e : event.config().rtp_extensions) {
624 rtclog::RtpHeaderExtension* extension =
625 receiver_config->add_header_extensions();
626 extension->set_name(e.uri);
627 extension->set_id(e.id);
628 }
629
630 for (const auto& d : event.config().codecs) {
631 rtclog::DecoderConfig* decoder = receiver_config->add_decoders();
632 decoder->set_name(d.payload_name);
633 decoder->set_payload_type(d.payload_type);
634 if (d.rtx_payload_type != 0) {
635 rtclog::RtxMap* rtx = receiver_config->add_rtx_map();
636 rtx->set_payload_type(d.payload_type);
637 rtx->mutable_config()->set_rtx_ssrc(event.config().rtx_ssrc);
638 rtx->mutable_config()->set_rtx_payload_type(d.rtx_payload_type);
639 }
640 }
641
642 return Serialize(&rtclog_event);
643 }
644
EncodeVideoSendStreamConfig(const RtcEventVideoSendStreamConfig & event)645 std::string RtcEventLogEncoderLegacy::EncodeVideoSendStreamConfig(
646 const RtcEventVideoSendStreamConfig& event) {
647 rtclog::Event rtclog_event;
648 rtclog_event.set_timestamp_us(event.timestamp_us());
649 rtclog_event.set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
650
651 rtclog::VideoSendConfig* sender_config =
652 rtclog_event.mutable_video_sender_config();
653
654 // TODO(perkj): rtclog::VideoSendConfig should only contain one SSRC.
655 sender_config->add_ssrcs(event.config().local_ssrc);
656 if (event.config().rtx_ssrc != 0) {
657 sender_config->add_rtx_ssrcs(event.config().rtx_ssrc);
658 }
659
660 for (const auto& e : event.config().rtp_extensions) {
661 rtclog::RtpHeaderExtension* extension =
662 sender_config->add_header_extensions();
663 extension->set_name(e.uri);
664 extension->set_id(e.id);
665 }
666
667 // TODO(perkj): rtclog::VideoSendConfig should contain many possible codec
668 // configurations.
669 for (const auto& codec : event.config().codecs) {
670 sender_config->set_rtx_payload_type(codec.rtx_payload_type);
671 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder();
672 encoder->set_name(codec.payload_name);
673 encoder->set_payload_type(codec.payload_type);
674
675 if (event.config().codecs.size() > 1) {
676 RTC_LOG(WARNING)
677 << "LogVideoSendStreamConfig currently only supports one "
678 "codec. Logging codec :"
679 << codec.payload_name;
680 break;
681 }
682 }
683
684 return Serialize(&rtclog_event);
685 }
686
EncodeRtcpPacket(int64_t timestamp_us,const rtc::Buffer & packet,bool is_incoming)687 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket(
688 int64_t timestamp_us,
689 const rtc::Buffer& packet,
690 bool is_incoming) {
691 rtclog::Event rtclog_event;
692 rtclog_event.set_timestamp_us(timestamp_us);
693 rtclog_event.set_type(rtclog::Event::RTCP_EVENT);
694 rtclog_event.mutable_rtcp_packet()->set_incoming(is_incoming);
695
696 rtcp::CommonHeader header;
697 const uint8_t* block_begin = packet.data();
698 const uint8_t* packet_end = packet.data() + packet.size();
699 std::vector<uint8_t> buffer(packet.size());
700 uint32_t buffer_length = 0;
701 while (block_begin < packet_end) {
702 if (!header.Parse(block_begin, packet_end - block_begin)) {
703 break; // Incorrect message header.
704 }
705 const uint8_t* next_block = header.NextPacket();
706 uint32_t block_size = next_block - block_begin;
707 switch (header.type()) {
708 case rtcp::Bye::kPacketType:
709 case rtcp::ExtendedJitterReport::kPacketType:
710 case rtcp::ExtendedReports::kPacketType:
711 case rtcp::Psfb::kPacketType:
712 case rtcp::ReceiverReport::kPacketType:
713 case rtcp::Rtpfb::kPacketType:
714 case rtcp::SenderReport::kPacketType:
715 // We log sender reports, receiver reports, bye messages
716 // inter-arrival jitter, third-party loss reports, payload-specific
717 // feedback and extended reports.
718 memcpy(buffer.data() + buffer_length, block_begin, block_size);
719 buffer_length += block_size;
720 break;
721 case rtcp::App::kPacketType:
722 case rtcp::Sdes::kPacketType:
723 default:
724 // We don't log sender descriptions, application defined messages
725 // or message blocks of unknown type.
726 break;
727 }
728
729 block_begin += block_size;
730 }
731 rtclog_event.mutable_rtcp_packet()->set_packet_data(buffer.data(),
732 buffer_length);
733
734 return Serialize(&rtclog_event);
735 }
736
EncodeRtpPacket(int64_t timestamp_us,const webrtc::RtpPacket & header,size_t packet_length,int probe_cluster_id,bool is_incoming)737 std::string RtcEventLogEncoderLegacy::EncodeRtpPacket(
738 int64_t timestamp_us,
739 const webrtc::RtpPacket& header,
740 size_t packet_length,
741 int probe_cluster_id,
742 bool is_incoming) {
743 rtclog::Event rtclog_event;
744 rtclog_event.set_timestamp_us(timestamp_us);
745 rtclog_event.set_type(rtclog::Event::RTP_EVENT);
746
747 rtclog_event.mutable_rtp_packet()->set_incoming(is_incoming);
748 rtclog_event.mutable_rtp_packet()->set_packet_length(packet_length);
749 rtclog_event.mutable_rtp_packet()->set_header(header.data(), header.size());
750 if (probe_cluster_id != PacedPacketInfo::kNotAProbe) {
751 RTC_DCHECK(!is_incoming);
752 rtclog_event.mutable_rtp_packet()->set_probe_cluster_id(probe_cluster_id);
753 }
754
755 return Serialize(&rtclog_event);
756 }
757
Serialize(rtclog::Event * event)758 std::string RtcEventLogEncoderLegacy::Serialize(rtclog::Event* event) {
759 // Even though we're only serializing a single event during this call, what
760 // we intend to get is a list of events, with a tag and length preceding
761 // each actual event. To produce that, we serialize a list of a single event.
762 // If we later concatenate several results from this function, the result will
763 // be a proper concatenation of all those events.
764
765 rtclog::EventStream event_stream;
766 event_stream.add_stream();
767
768 // As a tweak, we swap the new event into the event-stream, write that to
769 // file, then swap back. This saves on some copying, while making sure that
770 // the caller wouldn't be surprised by Serialize() modifying the object.
771 rtclog::Event* output_event = event_stream.mutable_stream(0);
772 output_event->Swap(event);
773
774 std::string output_string = event_stream.SerializeAsString();
775 RTC_DCHECK(!output_string.empty());
776
777 // When the function returns, the original Event will be unchanged.
778 output_event->Swap(event);
779
780 return output_string;
781 }
782
783 } // namespace webrtc
784