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 "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
14 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
15 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
16 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
17 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
18 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
19 #include "logging/rtc_event_log/events/rtc_event_logging_started.h"
20 #include "logging/rtc_event_log/events/rtc_event_logging_stopped.h"
21 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
22 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
23 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
24 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
25 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
26 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
27 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
28 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
29 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
30 #include "logging/rtc_event_log/rtc_stream_config.h"
31 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
32 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
33 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
34 #include "modules/rtp_rtcp/source/rtcp_packet/app.h"
35 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
36 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
37 #include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h"
38 #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
39 #include "modules/rtp_rtcp/source/rtcp_packet/psfb.h"
40 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
41 #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
42 #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
43 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
44 #include "modules/rtp_rtcp/source/rtp_packet.h"
45 #include "rtc_base/checks.h"
46 #include "rtc_base/ignore_wundef.h"
47 #include "rtc_base/logging.h"
48 
49 #ifdef ENABLE_RTC_EVENT_LOG
50 
51 // *.pb.h files are generated at build-time by the protobuf compiler.
52 RTC_PUSH_IGNORING_WUNDEF()
53 #ifdef WEBRTC_ANDROID_PLATFORM_BUILD
54 #include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
55 #else
56 #include "logging/rtc_event_log/rtc_event_log.pb.h"
57 #endif
58 RTC_POP_IGNORING_WUNDEF()
59 
60 namespace webrtc {
61 
62 namespace {
ConvertDetectorState(BandwidthUsage state)63 rtclog::DelayBasedBweUpdate::DetectorState ConvertDetectorState(
64     BandwidthUsage state) {
65   switch (state) {
66     case BandwidthUsage::kBwNormal:
67       return rtclog::DelayBasedBweUpdate::BWE_NORMAL;
68     case BandwidthUsage::kBwUnderusing:
69       return rtclog::DelayBasedBweUpdate::BWE_UNDERUSING;
70     case BandwidthUsage::kBwOverusing:
71       return rtclog::DelayBasedBweUpdate::BWE_OVERUSING;
72     case BandwidthUsage::kLast:
73       RTC_NOTREACHED();
74   }
75   RTC_NOTREACHED();
76   return rtclog::DelayBasedBweUpdate::BWE_NORMAL;
77 }
78 
ConvertProbeResultType(ProbeFailureReason failure_reason)79 rtclog::BweProbeResult::ResultType ConvertProbeResultType(
80     ProbeFailureReason failure_reason) {
81   switch (failure_reason) {
82     case ProbeFailureReason::kInvalidSendReceiveInterval:
83       return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL;
84     case ProbeFailureReason::kInvalidSendReceiveRatio:
85       return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO;
86     case ProbeFailureReason::kTimeout:
87       return rtclog::BweProbeResult::TIMEOUT;
88     case ProbeFailureReason::kLast:
89       RTC_NOTREACHED();
90   }
91   RTC_NOTREACHED();
92   return rtclog::BweProbeResult::SUCCESS;
93 }
94 
ConvertRtcpMode(RtcpMode rtcp_mode)95 rtclog::VideoReceiveConfig_RtcpMode ConvertRtcpMode(RtcpMode rtcp_mode) {
96   switch (rtcp_mode) {
97     case RtcpMode::kCompound:
98       return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
99     case RtcpMode::kReducedSize:
100       return rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE;
101     case RtcpMode::kOff:
102       RTC_NOTREACHED();
103   }
104   RTC_NOTREACHED();
105   return rtclog::VideoReceiveConfig::RTCP_COMPOUND;
106 }
107 }  // namespace
108 
Encode(const RtcEvent & event)109 std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) {
110   switch (event.GetType()) {
111     case RtcEvent::Type::AudioNetworkAdaptation: {
112       auto& rtc_event =
113           static_cast<const RtcEventAudioNetworkAdaptation&>(event);
114       return EncodeAudioNetworkAdaptation(rtc_event);
115     }
116 
117     case RtcEvent::Type::AudioPlayout: {
118       auto& rtc_event = static_cast<const RtcEventAudioPlayout&>(event);
119       return EncodeAudioPlayout(rtc_event);
120     }
121 
122     case RtcEvent::Type::AudioReceiveStreamConfig: {
123       auto& rtc_event =
124           static_cast<const RtcEventAudioReceiveStreamConfig&>(event);
125       return EncodeAudioReceiveStreamConfig(rtc_event);
126     }
127 
128     case RtcEvent::Type::AudioSendStreamConfig: {
129       auto& rtc_event =
130           static_cast<const RtcEventAudioSendStreamConfig&>(event);
131       return EncodeAudioSendStreamConfig(rtc_event);
132     }
133 
134     case RtcEvent::Type::BweUpdateDelayBased: {
135       auto& rtc_event = static_cast<const RtcEventBweUpdateDelayBased&>(event);
136       return EncodeBweUpdateDelayBased(rtc_event);
137     }
138 
139     case RtcEvent::Type::BweUpdateLossBased: {
140       auto& rtc_event = static_cast<const RtcEventBweUpdateLossBased&>(event);
141       return EncodeBweUpdateLossBased(rtc_event);
142     }
143 
144     case RtcEvent::Type::LoggingStarted: {
145       auto& rtc_event = static_cast<const RtcEventLoggingStarted&>(event);
146       return EncodeLoggingStarted(rtc_event);
147     }
148 
149     case RtcEvent::Type::LoggingStopped: {
150       auto& rtc_event = static_cast<const RtcEventLoggingStopped&>(event);
151       return EncodeLoggingStopped(rtc_event);
152     }
153 
154     case RtcEvent::Type::ProbeClusterCreated: {
155       auto& rtc_event = static_cast<const RtcEventProbeClusterCreated&>(event);
156       return EncodeProbeClusterCreated(rtc_event);
157     }
158 
159     case RtcEvent::Type::ProbeResultFailure: {
160       auto& rtc_event = static_cast<const RtcEventProbeResultFailure&>(event);
161       return EncodeProbeResultFailure(rtc_event);
162     }
163 
164     case RtcEvent::Type::ProbeResultSuccess: {
165       auto& rtc_event = static_cast<const RtcEventProbeResultSuccess&>(event);
166       return EncodeProbeResultSuccess(rtc_event);
167     }
168 
169     case RtcEvent::Type::RtcpPacketIncoming: {
170       auto& rtc_event = static_cast<const RtcEventRtcpPacketIncoming&>(event);
171       return EncodeRtcpPacketIncoming(rtc_event);
172     }
173 
174     case RtcEvent::Type::RtcpPacketOutgoing: {
175       auto& rtc_event = static_cast<const RtcEventRtcpPacketOutgoing&>(event);
176       return EncodeRtcpPacketOutgoing(rtc_event);
177     }
178 
179     case RtcEvent::Type::RtpPacketIncoming: {
180       auto& rtc_event = static_cast<const RtcEventRtpPacketIncoming&>(event);
181       return EncodeRtpPacketIncoming(rtc_event);
182     }
183 
184     case RtcEvent::Type::RtpPacketOutgoing: {
185       auto& rtc_event = static_cast<const RtcEventRtpPacketOutgoing&>(event);
186       return EncodeRtpPacketOutgoing(rtc_event);
187     }
188 
189     case RtcEvent::Type::VideoReceiveStreamConfig: {
190       auto& rtc_event =
191           static_cast<const RtcEventVideoReceiveStreamConfig&>(event);
192       return EncodeVideoReceiveStreamConfig(rtc_event);
193     }
194 
195     case RtcEvent::Type::VideoSendStreamConfig: {
196       auto& rtc_event =
197           static_cast<const RtcEventVideoSendStreamConfig&>(event);
198       return EncodeVideoSendStreamConfig(rtc_event);
199     }
200   }
201 
202   int event_type = static_cast<int>(event.GetType());
203   RTC_NOTREACHED() << "Unknown event type (" << event_type << ")";
204   return "";
205 }
206 
EncodeAudioNetworkAdaptation(const RtcEventAudioNetworkAdaptation & event)207 std::string RtcEventLogEncoderLegacy::EncodeAudioNetworkAdaptation(
208     const RtcEventAudioNetworkAdaptation& event) {
209   rtclog::Event rtclog_event;
210   rtclog_event.set_timestamp_us(event.timestamp_us_);
211   rtclog_event.set_type(rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT);
212 
213   auto audio_network_adaptation =
214       rtclog_event.mutable_audio_network_adaptation();
215   if (event.config_->bitrate_bps)
216     audio_network_adaptation->set_bitrate_bps(*event.config_->bitrate_bps);
217   if (event.config_->frame_length_ms)
218     audio_network_adaptation->set_frame_length_ms(
219         *event.config_->frame_length_ms);
220   if (event.config_->uplink_packet_loss_fraction) {
221     audio_network_adaptation->set_uplink_packet_loss_fraction(
222         *event.config_->uplink_packet_loss_fraction);
223   }
224   if (event.config_->enable_fec)
225     audio_network_adaptation->set_enable_fec(*event.config_->enable_fec);
226   if (event.config_->enable_dtx)
227     audio_network_adaptation->set_enable_dtx(*event.config_->enable_dtx);
228   if (event.config_->num_channels)
229     audio_network_adaptation->set_num_channels(*event.config_->num_channels);
230 
231   return Serialize(&rtclog_event);
232 }
233 
EncodeAudioPlayout(const RtcEventAudioPlayout & event)234 std::string RtcEventLogEncoderLegacy::EncodeAudioPlayout(
235     const RtcEventAudioPlayout& event) {
236   rtclog::Event rtclog_event;
237   rtclog_event.set_timestamp_us(event.timestamp_us_);
238   rtclog_event.set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT);
239 
240   auto playout_event = rtclog_event.mutable_audio_playout_event();
241   playout_event->set_local_ssrc(event.ssrc_);
242 
243   return Serialize(&rtclog_event);
244 }
245 
EncodeAudioReceiveStreamConfig(const RtcEventAudioReceiveStreamConfig & event)246 std::string RtcEventLogEncoderLegacy::EncodeAudioReceiveStreamConfig(
247     const RtcEventAudioReceiveStreamConfig& event) {
248   rtclog::Event rtclog_event;
249   rtclog_event.set_timestamp_us(event.timestamp_us_);
250   rtclog_event.set_type(rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT);
251 
252   rtclog::AudioReceiveConfig* receiver_config =
253       rtclog_event.mutable_audio_receiver_config();
254   receiver_config->set_remote_ssrc(event.config_->remote_ssrc);
255   receiver_config->set_local_ssrc(event.config_->local_ssrc);
256 
257   for (const auto& e : event.config_->rtp_extensions) {
258     rtclog::RtpHeaderExtension* extension =
259         receiver_config->add_header_extensions();
260     extension->set_name(e.uri);
261     extension->set_id(e.id);
262   }
263 
264   return Serialize(&rtclog_event);
265 }
266 
EncodeAudioSendStreamConfig(const RtcEventAudioSendStreamConfig & event)267 std::string RtcEventLogEncoderLegacy::EncodeAudioSendStreamConfig(
268     const RtcEventAudioSendStreamConfig& event) {
269   rtclog::Event rtclog_event;
270   rtclog_event.set_timestamp_us(event.timestamp_us_);
271   rtclog_event.set_type(rtclog::Event::AUDIO_SENDER_CONFIG_EVENT);
272 
273   rtclog::AudioSendConfig* sender_config =
274       rtclog_event.mutable_audio_sender_config();
275 
276   sender_config->set_ssrc(event.config_->local_ssrc);
277 
278   for (const auto& e : event.config_->rtp_extensions) {
279     rtclog::RtpHeaderExtension* extension =
280         sender_config->add_header_extensions();
281     extension->set_name(e.uri);
282     extension->set_id(e.id);
283   }
284 
285   return Serialize(&rtclog_event);
286 }
287 
EncodeBweUpdateDelayBased(const RtcEventBweUpdateDelayBased & event)288 std::string RtcEventLogEncoderLegacy::EncodeBweUpdateDelayBased(
289     const RtcEventBweUpdateDelayBased& event) {
290   rtclog::Event rtclog_event;
291   rtclog_event.set_timestamp_us(event.timestamp_us_);
292   rtclog_event.set_type(rtclog::Event::DELAY_BASED_BWE_UPDATE);
293 
294   auto bwe_event = rtclog_event.mutable_delay_based_bwe_update();
295   bwe_event->set_bitrate_bps(event.bitrate_bps_);
296   bwe_event->set_detector_state(ConvertDetectorState(event.detector_state_));
297 
298   return Serialize(&rtclog_event);
299 }
300 
EncodeBweUpdateLossBased(const RtcEventBweUpdateLossBased & event)301 std::string RtcEventLogEncoderLegacy::EncodeBweUpdateLossBased(
302     const RtcEventBweUpdateLossBased& event) {
303   rtclog::Event rtclog_event;
304   rtclog_event.set_timestamp_us(event.timestamp_us_);
305   rtclog_event.set_type(rtclog::Event::LOSS_BASED_BWE_UPDATE);
306 
307   auto bwe_event = rtclog_event.mutable_loss_based_bwe_update();
308   bwe_event->set_bitrate_bps(event.bitrate_bps_);
309   bwe_event->set_fraction_loss(event.fraction_loss_);
310   bwe_event->set_total_packets(event.total_packets_);
311 
312   return Serialize(&rtclog_event);
313 }
314 
EncodeLoggingStarted(const RtcEventLoggingStarted & event)315 std::string RtcEventLogEncoderLegacy::EncodeLoggingStarted(
316     const RtcEventLoggingStarted& event) {
317   rtclog::Event rtclog_event;
318   rtclog_event.set_timestamp_us(event.timestamp_us_);
319   rtclog_event.set_type(rtclog::Event::LOG_START);
320   return Serialize(&rtclog_event);
321 }
322 
EncodeLoggingStopped(const RtcEventLoggingStopped & event)323 std::string RtcEventLogEncoderLegacy::EncodeLoggingStopped(
324     const RtcEventLoggingStopped& event) {
325   rtclog::Event rtclog_event;
326   rtclog_event.set_timestamp_us(event.timestamp_us_);
327   rtclog_event.set_type(rtclog::Event::LOG_END);
328   return Serialize(&rtclog_event);
329 }
330 
EncodeProbeClusterCreated(const RtcEventProbeClusterCreated & event)331 std::string RtcEventLogEncoderLegacy::EncodeProbeClusterCreated(
332     const RtcEventProbeClusterCreated& event) {
333   rtclog::Event rtclog_event;
334   rtclog_event.set_timestamp_us(event.timestamp_us_);
335   rtclog_event.set_type(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT);
336 
337   auto probe_cluster = rtclog_event.mutable_probe_cluster();
338   probe_cluster->set_id(event.id_);
339   probe_cluster->set_bitrate_bps(event.bitrate_bps_);
340   probe_cluster->set_min_packets(event.min_probes_);
341   probe_cluster->set_min_bytes(event.min_bytes_);
342 
343   return Serialize(&rtclog_event);
344 }
345 
EncodeProbeResultFailure(const RtcEventProbeResultFailure & event)346 std::string RtcEventLogEncoderLegacy::EncodeProbeResultFailure(
347     const RtcEventProbeResultFailure& event) {
348   rtclog::Event rtclog_event;
349   rtclog_event.set_timestamp_us(event.timestamp_us_);
350   rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
351 
352   auto probe_result = rtclog_event.mutable_probe_result();
353   probe_result->set_id(event.id_);
354   probe_result->set_result(ConvertProbeResultType(event.failure_reason_));
355 
356   return Serialize(&rtclog_event);
357 }
358 
EncodeProbeResultSuccess(const RtcEventProbeResultSuccess & event)359 std::string RtcEventLogEncoderLegacy::EncodeProbeResultSuccess(
360     const RtcEventProbeResultSuccess& event) {
361   rtclog::Event rtclog_event;
362   rtclog_event.set_timestamp_us(event.timestamp_us_);
363   rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT);
364 
365   auto probe_result = rtclog_event.mutable_probe_result();
366   probe_result->set_id(event.id_);
367   probe_result->set_result(rtclog::BweProbeResult::SUCCESS);
368   probe_result->set_bitrate_bps(event.bitrate_bps_);
369 
370   return Serialize(&rtclog_event);
371 }
372 
EncodeRtcpPacketIncoming(const RtcEventRtcpPacketIncoming & event)373 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketIncoming(
374     const RtcEventRtcpPacketIncoming& event) {
375   return EncodeRtcpPacket(event.timestamp_us_, event.packet_, true);
376 }
377 
EncodeRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing & event)378 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketOutgoing(
379     const RtcEventRtcpPacketOutgoing& event) {
380   return EncodeRtcpPacket(event.timestamp_us_, event.packet_, false);
381 }
382 
EncodeRtpPacketIncoming(const RtcEventRtpPacketIncoming & event)383 std::string RtcEventLogEncoderLegacy::EncodeRtpPacketIncoming(
384     const RtcEventRtpPacketIncoming& event) {
385   return EncodeRtpPacket(event.timestamp_us_, event.header_,
386                          event.packet_length_, PacedPacketInfo::kNotAProbe,
387                          true);
388 }
389 
EncodeRtpPacketOutgoing(const RtcEventRtpPacketOutgoing & event)390 std::string RtcEventLogEncoderLegacy::EncodeRtpPacketOutgoing(
391     const RtcEventRtpPacketOutgoing& event) {
392   return EncodeRtpPacket(event.timestamp_us_, event.header_,
393                          event.packet_length_, event.probe_cluster_id_, false);
394 }
395 
EncodeVideoReceiveStreamConfig(const RtcEventVideoReceiveStreamConfig & event)396 std::string RtcEventLogEncoderLegacy::EncodeVideoReceiveStreamConfig(
397     const RtcEventVideoReceiveStreamConfig& event) {
398   rtclog::Event rtclog_event;
399   rtclog_event.set_timestamp_us(event.timestamp_us_);
400   rtclog_event.set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT);
401 
402   rtclog::VideoReceiveConfig* receiver_config =
403       rtclog_event.mutable_video_receiver_config();
404   receiver_config->set_remote_ssrc(event.config_->remote_ssrc);
405   receiver_config->set_local_ssrc(event.config_->local_ssrc);
406 
407   // TODO(perkj): Add field for rsid.
408   receiver_config->set_rtcp_mode(ConvertRtcpMode(event.config_->rtcp_mode));
409   receiver_config->set_remb(event.config_->remb);
410 
411   for (const auto& e : event.config_->rtp_extensions) {
412     rtclog::RtpHeaderExtension* extension =
413         receiver_config->add_header_extensions();
414     extension->set_name(e.uri);
415     extension->set_id(e.id);
416   }
417 
418   for (const auto& d : event.config_->codecs) {
419     rtclog::DecoderConfig* decoder = receiver_config->add_decoders();
420     decoder->set_name(d.payload_name);
421     decoder->set_payload_type(d.payload_type);
422     if (d.rtx_payload_type != 0) {
423       rtclog::RtxMap* rtx = receiver_config->add_rtx_map();
424       rtx->set_payload_type(d.payload_type);
425       rtx->mutable_config()->set_rtx_ssrc(event.config_->rtx_ssrc);
426       rtx->mutable_config()->set_rtx_payload_type(d.rtx_payload_type);
427     }
428   }
429 
430   return Serialize(&rtclog_event);
431 }
432 
EncodeVideoSendStreamConfig(const RtcEventVideoSendStreamConfig & event)433 std::string RtcEventLogEncoderLegacy::EncodeVideoSendStreamConfig(
434     const RtcEventVideoSendStreamConfig& event) {
435   rtclog::Event rtclog_event;
436   rtclog_event.set_timestamp_us(event.timestamp_us_);
437   rtclog_event.set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT);
438 
439   rtclog::VideoSendConfig* sender_config =
440       rtclog_event.mutable_video_sender_config();
441 
442   // TODO(perkj): rtclog::VideoSendConfig should only contain one SSRC.
443   sender_config->add_ssrcs(event.config_->local_ssrc);
444   if (event.config_->rtx_ssrc != 0) {
445     sender_config->add_rtx_ssrcs(event.config_->rtx_ssrc);
446   }
447 
448   for (const auto& e : event.config_->rtp_extensions) {
449     rtclog::RtpHeaderExtension* extension =
450         sender_config->add_header_extensions();
451     extension->set_name(e.uri);
452     extension->set_id(e.id);
453   }
454 
455   // TODO(perkj): rtclog::VideoSendConfig should contain many possible codec
456   // configurations.
457   for (const auto& codec : event.config_->codecs) {
458     sender_config->set_rtx_payload_type(codec.rtx_payload_type);
459     rtclog::EncoderConfig* encoder = sender_config->mutable_encoder();
460     encoder->set_name(codec.payload_name);
461     encoder->set_payload_type(codec.payload_type);
462 
463     if (event.config_->codecs.size() > 1) {
464       RTC_LOG(WARNING)
465           << "LogVideoSendStreamConfig currently only supports one "
466           << "codec. Logging codec :" << codec.payload_name;
467       break;
468     }
469   }
470 
471   return Serialize(&rtclog_event);
472 }
473 
EncodeRtcpPacket(int64_t timestamp_us,const rtc::Buffer & packet,bool is_incoming)474 std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket(
475     int64_t timestamp_us,
476     const rtc::Buffer& packet,
477     bool is_incoming) {
478   rtclog::Event rtclog_event;
479   rtclog_event.set_timestamp_us(timestamp_us);
480   rtclog_event.set_type(rtclog::Event::RTCP_EVENT);
481   rtclog_event.mutable_rtcp_packet()->set_incoming(is_incoming);
482 
483   rtcp::CommonHeader header;
484   const uint8_t* block_begin = packet.data();
485   const uint8_t* packet_end = packet.data() + packet.size();
486   RTC_DCHECK(packet.size() <= IP_PACKET_SIZE);
487   uint8_t buffer[IP_PACKET_SIZE];
488   uint32_t buffer_length = 0;
489   while (block_begin < packet_end) {
490     if (!header.Parse(block_begin, packet_end - block_begin)) {
491       break;  // Incorrect message header.
492     }
493     const uint8_t* next_block = header.NextPacket();
494     uint32_t block_size = next_block - block_begin;
495     switch (header.type()) {
496       case rtcp::Bye::kPacketType:
497       case rtcp::ExtendedJitterReport::kPacketType:
498       case rtcp::ExtendedReports::kPacketType:
499       case rtcp::Psfb::kPacketType:
500       case rtcp::ReceiverReport::kPacketType:
501       case rtcp::Rtpfb::kPacketType:
502       case rtcp::SenderReport::kPacketType:
503         // We log sender reports, receiver reports, bye messages
504         // inter-arrival jitter, third-party loss reports, payload-specific
505         // feedback and extended reports.
506         memcpy(buffer + buffer_length, block_begin, block_size);
507         buffer_length += block_size;
508         break;
509       case rtcp::App::kPacketType:
510       case rtcp::Sdes::kPacketType:
511       default:
512         // We don't log sender descriptions, application defined messages
513         // or message blocks of unknown type.
514         break;
515     }
516 
517     block_begin += block_size;
518   }
519   rtclog_event.mutable_rtcp_packet()->set_packet_data(buffer, buffer_length);
520 
521   return Serialize(&rtclog_event);
522 }
523 
EncodeRtpPacket(int64_t timestamp_us,const webrtc::RtpPacket & header,size_t packet_length,int probe_cluster_id,bool is_incoming)524 std::string RtcEventLogEncoderLegacy::EncodeRtpPacket(
525     int64_t timestamp_us,
526     const webrtc::RtpPacket& header,
527     size_t packet_length,
528     int probe_cluster_id,
529     bool is_incoming) {
530   rtclog::Event rtclog_event;
531   rtclog_event.set_timestamp_us(timestamp_us);
532   rtclog_event.set_type(rtclog::Event::RTP_EVENT);
533 
534   rtclog_event.mutable_rtp_packet()->set_incoming(is_incoming);
535   rtclog_event.mutable_rtp_packet()->set_packet_length(packet_length);
536   rtclog_event.mutable_rtp_packet()->set_header(header.data(), header.size());
537   if (probe_cluster_id != PacedPacketInfo::kNotAProbe) {
538     RTC_DCHECK(!is_incoming);
539     rtclog_event.mutable_rtp_packet()->set_probe_cluster_id(probe_cluster_id);
540   }
541 
542   return Serialize(&rtclog_event);
543 }
544 
Serialize(rtclog::Event * event)545 std::string RtcEventLogEncoderLegacy::Serialize(rtclog::Event* event) {
546   // Even though we're only serializing a single event during this call, what
547   // we intend to get is a list of events, with a tag and length preceding
548   // each actual event. To produce that, we serialize a list of a single event.
549   // If we later concatenate several results from this function, the result will
550   // be a proper concatenation of all those events.
551 
552   rtclog::EventStream event_stream;
553   event_stream.add_stream();
554 
555   // As a tweak, we swap the new event into the event-stream, write that to
556   // file, then swap back. This saves on some copying, while making sure that
557   // the caller wouldn't be surprised by Serialize() modifying the object.
558   rtclog::Event* output_event = event_stream.mutable_stream(0);
559   output_event->Swap(event);
560 
561   std::string output_string = event_stream.SerializeAsString();
562   RTC_DCHECK(!output_string.empty());
563 
564   // When the function returns, the original Event will be unchanged.
565   output_event->Swap(event);
566 
567   return output_string;
568 }
569 
570 }  // namespace webrtc
571 
572 #endif  // ENABLE_RTC_EVENT_LOG
573