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/rtp_headers.h"
19 #include "api/rtp_parameters.h"
20 #include "api/transport/network_types.h"
21 #include "logging/rtc_event_log/events/rtc_event_alr_state.h"
22 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
23 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
24 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
25 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
26 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
27 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
28 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
29 #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
30 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
31 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
32 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
33 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
34 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
35 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
36 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
37 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
38 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
39 #include "logging/rtc_event_log/rtc_stream_config.h"
40 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
41 #include "modules/remote_bitrate_estimator/include/bwe_defines.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 "logging/rtc_event_log/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 // These are unsupported in the old format, but shouldn't crash.
371 return "";
372 }
373
374 int event_type = static_cast<int>(event.GetType());
375 RTC_NOTREACHED() << "Unknown event type (" << event_type << ")";
376 return "";
377 }
378
EncodeAlrState(const RtcEventAlrState & event)379 std::string RtcEventLogEncoderLegacy::EncodeAlrState(
380 const RtcEventAlrState& event) {
381 rtclog::Event rtclog_event;
382 rtclog_event.set_timestamp_us(event.timestamp_us());
383 rtclog_event.set_type(rtclog::Event::ALR_STATE_EVENT);
384
385 auto* alr_state = rtclog_event.mutable_alr_state();
386 alr_state->set_in_alr(event.in_alr());
387 return Serialize(&rtclog_event);
388 }
389
EncodeAudioNetworkAdaptation(const RtcEventAudioNetworkAdaptation & event)390 std::string RtcEventLogEncoderLegacy::EncodeAudioNetworkAdaptation(
391 const RtcEventAudioNetworkAdaptation& event) {
392 rtclog::Event rtclog_event;
393 rtclog_event.set_timestamp_us(event.timestamp_us());
394 rtclog_event.set_type(rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
395
396 auto* audio_network_adaptation =
397 rtclog_event.mutable_audio_network_adaptation();
398 if (event.config().bitrate_bps)
399 audio_network_adaptation->set_bitrate_bps(*event.config().bitrate_bps);
400 if (event.config().frame_length_ms)
401 audio_network_adaptation->set_frame_length_ms(
402 *event.config().frame_length_ms);
403 if (event.config().uplink_packet_loss_fraction) {
404 audio_network_adaptation->set_uplink_packet_loss_fraction(
405 *event.config().uplink_packet_loss_fraction);
406 }
407 if (event.config().enable_fec)
408 audio_network_adaptation->set_enable_fec(*event.config().enable_fec);
409 if (event.config().enable_dtx)
410 audio_network_adaptation->set_enable_dtx(*event.config().enable_dtx);
411 if (event.config().num_channels)
412 audio_network_adaptation->set_num_channels(*event.config().num_channels);
413
414 return Serialize(&rtclog_event);
415 }
416
EncodeAudioPlayout(const RtcEventAudioPlayout & event)417 std::string RtcEventLogEncoderLegacy::EncodeAudioPlayout(
418 const RtcEventAudioPlayout& event) {
419 rtclog::Event rtclog_event;
420 rtclog_event.set_timestamp_us(event.timestamp_us());
421 rtclog_event.set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT);
422
423 auto* playout_event = rtclog_event.mutable_audio_playout_event();
424 playout_event->set_local_ssrc(event.ssrc());
425
426 return Serialize(&rtclog_event);
427 }
428
EncodeAudioReceiveStreamConfig(const RtcEventAudioReceiveStreamConfig & event)429 std::string RtcEventLogEncoderLegacy::EncodeAudioReceiveStreamConfig(
430 const RtcEventAudioReceiveStreamConfig& event) {
431 rtclog::Event rtclog_event;
432 rtclog_event.set_timestamp_us(event.timestamp_us());
433 rtclog_event.set_type(rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT);
434
435 rtclog::AudioReceiveConfig* receiver_config =
436 rtclog_event.mutable_audio_receiver_config();
437 receiver_config->set_remote_ssrc(event.config().remote_ssrc);
438 receiver_config->set_local_ssrc(event.config().local_ssrc);
439
440 for (const auto& e : event.config().rtp_extensions) {
441 rtclog::RtpHeaderExtension* extension =
442 receiver_config->add_header_extensions();
443 extension->set_name(e.uri);
444 extension->set_id(e.id);
445 }
446
447 return Serialize(&rtclog_event);
448 }
449
EncodeAudioSendStreamConfig(const RtcEventAudioSendStreamConfig & event)450 std::string RtcEventLogEncoderLegacy::EncodeAudioSendStreamConfig(
451 const RtcEventAudioSendStreamConfig& event) {
452 rtclog::Event rtclog_event;
453 rtclog_event.set_timestamp_us(event.timestamp_us());
454 rtclog_event.set_type(rtclog::Event::AUDIO_SENDER_CONFIG_EVENT);
455
456 rtclog::AudioSendConfig* sender_config =
457 rtclog_event.mutable_audio_sender_config();
458
459 sender_config->set_ssrc(event.config().local_ssrc);
460
461 for (const auto& e : event.config().rtp_extensions) {
462 rtclog::RtpHeaderExtension* extension =
463 sender_config->add_header_extensions();
464 extension->set_name(e.uri);
465 extension->set_id(e.id);
466 }
467
468 return Serialize(&rtclog_event);
469 }
470
EncodeBweUpdateDelayBased(const RtcEventBweUpdateDelayBased & event)471 std::string RtcEventLogEncoderLegacy::EncodeBweUpdateDelayBased(
472 const RtcEventBweUpdateDelayBased& event) {
473 rtclog::Event rtclog_event;
474 rtclog_event.set_timestamp_us(event.timestamp_us());
475 rtclog_event.set_type(rtclog::Event::DELAY_BASED_BWE_UPDATE);
476
477 auto* bwe_event = rtclog_event.mutable_delay_based_bwe_update();
478 bwe_event->set_bitrate_bps(event.bitrate_bps());
479 bwe_event->set_detector_state(ConvertDetectorState(event.detector_state()));
480
481 return Serialize(&rtclog_event);
482 }
483
EncodeBweUpdateLossBased(const RtcEventBweUpdateLossBased & event)484 std::string RtcEventLogEncoderLegacy::EncodeBweUpdateLossBased(
485 const RtcEventBweUpdateLossBased& event) {
486 rtclog::Event rtclog_event;
487 rtclog_event.set_timestamp_us(event.timestamp_us());
488 rtclog_event.set_type(rtclog::Event::LOSS_BASED_BWE_UPDATE);
489
490 auto* bwe_event = rtclog_event.mutable_loss_based_bwe_update();
491 bwe_event->set_bitrate_bps(event.bitrate_bps());
492 bwe_event->set_fraction_loss(event.fraction_loss());
493 bwe_event->set_total_packets(event.total_packets());
494
495 return Serialize(&rtclog_event);
496 }
497
EncodeIceCandidatePairConfig(const RtcEventIceCandidatePairConfig & event)498 std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairConfig(
499 const RtcEventIceCandidatePairConfig& event) {
500 rtclog::Event encoded_rtc_event;
501 encoded_rtc_event.set_timestamp_us(event.timestamp_us());
502 encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG);
503
504 auto* encoded_ice_event =
505 encoded_rtc_event.mutable_ice_candidate_pair_config();
506 encoded_ice_event->set_config_type(
507 ConvertIceCandidatePairConfigType(event.type()));
508 encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id());
509 const auto& desc = event.candidate_pair_desc();
510 encoded_ice_event->set_local_candidate_type(
511 ConvertIceCandidateType(desc.local_candidate_type));
512 encoded_ice_event->set_local_relay_protocol(
513 ConvertIceCandidatePairProtocol(desc.local_relay_protocol));
514 encoded_ice_event->set_local_network_type(
515 ConvertIceCandidateNetworkType(desc.local_network_type));
516 encoded_ice_event->set_local_address_family(
517 ConvertIceCandidatePairAddressFamily(desc.local_address_family));
518 encoded_ice_event->set_remote_candidate_type(
519 ConvertIceCandidateType(desc.remote_candidate_type));
520 encoded_ice_event->set_remote_address_family(
521 ConvertIceCandidatePairAddressFamily(desc.remote_address_family));
522 encoded_ice_event->set_candidate_pair_protocol(
523 ConvertIceCandidatePairProtocol(desc.candidate_pair_protocol));
524 return Serialize(&encoded_rtc_event);
525 }
526
EncodeIceCandidatePairEvent(const RtcEventIceCandidatePair & event)527 std::string RtcEventLogEncoderLegacy::EncodeIceCandidatePairEvent(
528 const RtcEventIceCandidatePair& event) {
529 rtclog::Event encoded_rtc_event;
530 encoded_rtc_event.set_timestamp_us(event.timestamp_us());
531 encoded_rtc_event.set_type(rtclog::Event::ICE_CANDIDATE_PAIR_EVENT);
532
533 auto* encoded_ice_event =
534 encoded_rtc_event.mutable_ice_candidate_pair_event();
535 encoded_ice_event->set_event_type(
536 ConvertIceCandidatePairEventType(event.type()));
537 encoded_ice_event->set_candidate_pair_id(event.candidate_pair_id());
538 return Serialize(&encoded_rtc_event);
539 }
540
EncodeProbeClusterCreated(const RtcEventProbeClusterCreated & event)541 std::string RtcEventLogEncoderLegacy::EncodeProbeClusterCreated(
542 const RtcEventProbeClusterCreated& event) {
543 rtclog::Event rtclog_event;
544 rtclog_event.set_timestamp_us(event.timestamp_us());
545 rtclog_event.set_type(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
546
547 auto* probe_cluster = rtclog_event.mutable_probe_cluster();
548 probe_cluster->set_id(event.id());
549 probe_cluster->set_bitrate_bps(event.bitrate_bps());
550 probe_cluster->set_min_packets(event.min_probes());
551 probe_cluster->set_min_bytes(event.min_bytes());
552
553 return Serialize(&rtclog_event);
554 }
555
EncodeProbeResultFailure(const RtcEventProbeResultFailure & event)556 std::string RtcEventLogEncoderLegacy::EncodeProbeResultFailure(
557 const RtcEventProbeResultFailure& event) {
558 rtclog::Event rtclog_event;
559 rtclog_event.set_timestamp_us(event.timestamp_us());
560 rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
561
562 auto* probe_result = rtclog_event.mutable_probe_result();
563 probe_result->set_id(event.id());
564 probe_result->set_result(ConvertProbeResultType(event.failure_reason()));
565
566 return Serialize(&rtclog_event);
567 }
568
EncodeProbeResultSuccess(const RtcEventProbeResultSuccess & event)569 std::string RtcEventLogEncoderLegacy::EncodeProbeResultSuccess(
570 const RtcEventProbeResultSuccess& event) {
571 rtclog::Event rtclog_event;
572 rtclog_event.set_timestamp_us(event.timestamp_us());
573 rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
574
575 auto* probe_result = rtclog_event.mutable_probe_result();
576 probe_result->set_id(event.id());
577 probe_result->set_result(rtclog::BweProbeResult::SUCCESS);
578 probe_result->set_bitrate_bps(event.bitrate_bps());
579
580 return Serialize(&rtclog_event);
581 }
582
EncodeRtcpPacketIncoming(const RtcEventRtcpPacketIncoming & event)583 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketIncoming(
584 const RtcEventRtcpPacketIncoming& event) {
585 return EncodeRtcpPacket(event.timestamp_us(), event.packet(), true);
586 }
587
EncodeRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing & event)588 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketOutgoing(
589 const RtcEventRtcpPacketOutgoing& event) {
590 return EncodeRtcpPacket(event.timestamp_us(), event.packet(), false);
591 }
592
EncodeRtpPacketIncoming(const RtcEventRtpPacketIncoming & event)593 std::string RtcEventLogEncoderLegacy::EncodeRtpPacketIncoming(
594 const RtcEventRtpPacketIncoming& event) {
595 return EncodeRtpPacket(event.timestamp_us(), event.header(),
596 event.packet_length(), PacedPacketInfo::kNotAProbe,
597 true);
598 }
599
EncodeRtpPacketOutgoing(const RtcEventRtpPacketOutgoing & event)600 std::string RtcEventLogEncoderLegacy::EncodeRtpPacketOutgoing(
601 const RtcEventRtpPacketOutgoing& event) {
602 return EncodeRtpPacket(event.timestamp_us(), event.header(),
603 event.packet_length(), event.probe_cluster_id(),
604 false);
605 }
606
EncodeVideoReceiveStreamConfig(const RtcEventVideoReceiveStreamConfig & event)607 std::string RtcEventLogEncoderLegacy::EncodeVideoReceiveStreamConfig(
608 const RtcEventVideoReceiveStreamConfig& event) {
609 rtclog::Event rtclog_event;
610 rtclog_event.set_timestamp_us(event.timestamp_us());
611 rtclog_event.set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
612
613 rtclog::VideoReceiveConfig* receiver_config =
614 rtclog_event.mutable_video_receiver_config();
615 receiver_config->set_remote_ssrc(event.config().remote_ssrc);
616 receiver_config->set_local_ssrc(event.config().local_ssrc);
617
618 // TODO(perkj): Add field for rsid.
619 receiver_config->set_rtcp_mode(ConvertRtcpMode(event.config().rtcp_mode));
620 receiver_config->set_remb(event.config().remb);
621
622 for (const auto& e : event.config().rtp_extensions) {
623 rtclog::RtpHeaderExtension* extension =
624 receiver_config->add_header_extensions();
625 extension->set_name(e.uri);
626 extension->set_id(e.id);
627 }
628
629 for (const auto& d : event.config().codecs) {
630 rtclog::DecoderConfig* decoder = receiver_config->add_decoders();
631 decoder->set_name(d.payload_name);
632 decoder->set_payload_type(d.payload_type);
633 if (d.rtx_payload_type != 0) {
634 rtclog::RtxMap* rtx = receiver_config->add_rtx_map();
635 rtx->set_payload_type(d.payload_type);
636 rtx->mutable_config()->set_rtx_ssrc(event.config().rtx_ssrc);
637 rtx->mutable_config()->set_rtx_payload_type(d.rtx_payload_type);
638 }
639 }
640
641 return Serialize(&rtclog_event);
642 }
643
EncodeVideoSendStreamConfig(const RtcEventVideoSendStreamConfig & event)644 std::string RtcEventLogEncoderLegacy::EncodeVideoSendStreamConfig(
645 const RtcEventVideoSendStreamConfig& event) {
646 rtclog::Event rtclog_event;
647 rtclog_event.set_timestamp_us(event.timestamp_us());
648 rtclog_event.set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
649
650 rtclog::VideoSendConfig* sender_config =
651 rtclog_event.mutable_video_sender_config();
652
653 // TODO(perkj): rtclog::VideoSendConfig should only contain one SSRC.
654 sender_config->add_ssrcs(event.config().local_ssrc);
655 if (event.config().rtx_ssrc != 0) {
656 sender_config->add_rtx_ssrcs(event.config().rtx_ssrc);
657 }
658
659 for (const auto& e : event.config().rtp_extensions) {
660 rtclog::RtpHeaderExtension* extension =
661 sender_config->add_header_extensions();
662 extension->set_name(e.uri);
663 extension->set_id(e.id);
664 }
665
666 // TODO(perkj): rtclog::VideoSendConfig should contain many possible codec
667 // configurations.
668 for (const auto& codec : event.config().codecs) {
669 sender_config->set_rtx_payload_type(codec.rtx_payload_type);
670 rtclog::EncoderConfig* encoder = sender_config->mutable_encoder();
671 encoder->set_name(codec.payload_name);
672 encoder->set_payload_type(codec.payload_type);
673
674 if (event.config().codecs.size() > 1) {
675 RTC_LOG(WARNING)
676 << "LogVideoSendStreamConfig currently only supports one "
677 "codec. Logging codec :"
678 << codec.payload_name;
679 break;
680 }
681 }
682
683 return Serialize(&rtclog_event);
684 }
685
EncodeRtcpPacket(int64_t timestamp_us,const rtc::Buffer & packet,bool is_incoming)686 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket(
687 int64_t timestamp_us,
688 const rtc::Buffer& packet,
689 bool is_incoming) {
690 rtclog::Event rtclog_event;
691 rtclog_event.set_timestamp_us(timestamp_us);
692 rtclog_event.set_type(rtclog::Event::RTCP_EVENT);
693 rtclog_event.mutable_rtcp_packet()->set_incoming(is_incoming);
694
695 rtcp::CommonHeader header;
696 const uint8_t* block_begin = packet.data();
697 const uint8_t* packet_end = packet.data() + packet.size();
698 RTC_DCHECK(packet.size() <= IP_PACKET_SIZE);
699 uint8_t buffer[IP_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 + 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, buffer_length);
732
733 return Serialize(&rtclog_event);
734 }
735
EncodeRtpPacket(int64_t timestamp_us,const webrtc::RtpPacket & header,size_t packet_length,int probe_cluster_id,bool is_incoming)736 std::string RtcEventLogEncoderLegacy::EncodeRtpPacket(
737 int64_t timestamp_us,
738 const webrtc::RtpPacket& header,
739 size_t packet_length,
740 int probe_cluster_id,
741 bool is_incoming) {
742 rtclog::Event rtclog_event;
743 rtclog_event.set_timestamp_us(timestamp_us);
744 rtclog_event.set_type(rtclog::Event::RTP_EVENT);
745
746 rtclog_event.mutable_rtp_packet()->set_incoming(is_incoming);
747 rtclog_event.mutable_rtp_packet()->set_packet_length(packet_length);
748 rtclog_event.mutable_rtp_packet()->set_header(header.data(), header.size());
749 if (probe_cluster_id != PacedPacketInfo::kNotAProbe) {
750 RTC_DCHECK(!is_incoming);
751 rtclog_event.mutable_rtp_packet()->set_probe_cluster_id(probe_cluster_id);
752 }
753
754 return Serialize(&rtclog_event);
755 }
756
Serialize(rtclog::Event * event)757 std::string RtcEventLogEncoderLegacy::Serialize(rtclog::Event* event) {
758 // Even though we're only serializing a single event during this call, what
759 // we intend to get is a list of events, with a tag and length preceding
760 // each actual event. To produce that, we serialize a list of a single event.
761 // If we later concatenate several results from this function, the result will
762 // be a proper concatenation of all those events.
763
764 rtclog::EventStream event_stream;
765 event_stream.add_stream();
766
767 // As a tweak, we swap the new event into the event-stream, write that to
768 // file, then swap back. This saves on some copying, while making sure that
769 // the caller wouldn't be surprised by Serialize() modifying the object.
770 rtclog::Event* output_event = event_stream.mutable_stream(0);
771 output_event->Swap(event);
772
773 std::string output_string = event_stream.SerializeAsString();
774 RTC_DCHECK(!output_string.empty());
775
776 // When the function returns, the original Event will be unchanged.
777 output_event->Swap(event);
778
779 return output_string;
780 }
781
782 } // namespace webrtc
783