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 <cmath>
12 #include <limits>
13 #include <memory>
14 #include <string>
15 #include <utility>
16 
17 #include "api/rtpparameters.h"  // RtpExtension
18 #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h"
19 #include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
20 #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
21 #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
22 #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
23 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
24 #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
25 #include "logging/rtc_event_log/events/rtc_event_logging_started.h"
26 #include "logging/rtc_event_log/events/rtc_event_logging_stopped.h"
27 #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
28 #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
29 #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
30 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
31 #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
32 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
33 #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h"
34 #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
35 #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
36 #include "logging/rtc_event_log/rtc_event_log_parser.h"
37 #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
38 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
39 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"  // Arbitrary RTCP message.
40 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
41 #include "modules/rtp_rtcp/source/rtp_packet_received.h"
42 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
43 #include "rtc_base/arraysize.h"
44 #include "rtc_base/numerics/safe_conversions.h"
45 #include "rtc_base/ptr_util.h"
46 #include "rtc_base/random.h"
47 #include "test/gtest.h"
48 
49 namespace webrtc {
50 
51 namespace {
52 struct ExtensionInfo {
53   RTPExtensionType type;
54   const char* uri;
55 };
56 
57 template <typename Extension>
CreateExtensionInfo()58 constexpr ExtensionInfo CreateExtensionInfo() {
59   return {Extension::kId, Extension::kUri};
60 }
61 
62 constexpr ExtensionInfo kExtensions[] = {
63     CreateExtensionInfo<TransmissionOffset>(),
64     CreateExtensionInfo<AudioLevel>(),
65     CreateExtensionInfo<AbsoluteSendTime>(),
66     CreateExtensionInfo<VideoOrientation>(),
67     CreateExtensionInfo<TransportSequenceNumber>(),
68     CreateExtensionInfo<PlayoutDelayLimits>(),
69     CreateExtensionInfo<VideoContentTypeExtension>(),
70     CreateExtensionInfo<VideoTimingExtension>(),
71     CreateExtensionInfo<RtpStreamId>(),
72     CreateExtensionInfo<RepairedRtpStreamId>(),
73     CreateExtensionInfo<RtpMid>(),
74 };
75 }  // namespace
76 
77 class RtcEventLogEncoderTest : public testing::TestWithParam<int> {
78  protected:
RtcEventLogEncoderTest()79   RtcEventLogEncoderTest()
80       : encoder_(new RtcEventLogEncoderLegacy), prng_(GetParam()) {}
81   ~RtcEventLogEncoderTest() override = default;
82 
83   // ANA events have some optional fields, so we want to make sure that we get
84   // correct behavior both when all of the values are there, as well as when
85   // only some.
86   void TestRtcEventAudioNetworkAdaptation(
87       std::unique_ptr<AudioEncoderRuntimeConfig> runtime_config);
88 
89   // These help prevent code duplication between incoming/outgoing variants.
90   void TestRtcEventRtcpPacket(PacketDirection direction);
91   void TestRtcEventRtpPacket(PacketDirection direction);
92 
RandomInt()93   int RandomInt() {
94     // Don't run this on a SNES.
95     static_assert(8 * sizeof(int) >= 32, "Don't run this on a SNES.");
96     int32_t rand = prng_.Rand(0, std::numeric_limits<int32_t>::max());
97     return rtc::saturated_cast<int>(rand);
98   }
99 
RandomPositiveInt()100   int RandomPositiveInt() {
101     int32_t rand = prng_.Rand(1, std::numeric_limits<int32_t>::max());
102     return rtc::saturated_cast<int>(rand);
103   }
104 
RandomSsrc()105   uint32_t RandomSsrc() {
106     return prng_.Rand(std::numeric_limits<uint32_t>::max());
107   }
108 
RandomRtpExtensions()109   std::vector<RtpExtension> RandomRtpExtensions() {
110     RTC_DCHECK(arraysize(kExtensions) >= 2);
111     size_t id_1 = prng_.Rand(0u, arraysize(kExtensions) - 1);
112     size_t id_2 = prng_.Rand(0u, arraysize(kExtensions) - 2);
113     if (id_2 == id_1)
114       id_2 = arraysize(kExtensions) - 1;
115     return std::vector<RtpExtension>{
116         RtpExtension(kExtensions[id_1].uri, kExtensions[id_1].type),
117         RtpExtension(kExtensions[id_2].uri, kExtensions[id_2].type)};
118   }
119 
RandomBitrate()120   int RandomBitrate() { return RandomInt(); }
121 
122   // TODO(eladalon): Once we have more than once possible encoder, parameterize
123   // encoder selection.
124   std::unique_ptr<RtcEventLogEncoder> encoder_;
125   ParsedRtcEventLog parsed_log_;
126   Random prng_;
127 };
128 
TestRtcEventAudioNetworkAdaptation(std::unique_ptr<AudioEncoderRuntimeConfig> runtime_config)129 void RtcEventLogEncoderTest::TestRtcEventAudioNetworkAdaptation(
130     std::unique_ptr<AudioEncoderRuntimeConfig> runtime_config) {
131   auto original_runtime_config = *runtime_config;
132   auto event = rtc::MakeUnique<RtcEventAudioNetworkAdaptation>(
133       std::move(runtime_config));
134   const int64_t timestamp_us = event->timestamp_us_;
135 
136   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
137   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
138   ASSERT_EQ(parsed_log_.GetEventType(0),
139             ParsedRtcEventLog::AUDIO_NETWORK_ADAPTATION_EVENT);
140 
141   AudioEncoderRuntimeConfig parsed_runtime_config;
142   parsed_log_.GetAudioNetworkAdaptation(0, &parsed_runtime_config);
143 
144   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
145   EXPECT_EQ(parsed_runtime_config, original_runtime_config);
146 }
147 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationBitrate)148 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationBitrate) {
149   auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
150   const int bitrate_bps = RandomBitrate();
151   runtime_config->bitrate_bps = bitrate_bps;
152   TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
153 }
154 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationFrameLength)155 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFrameLength) {
156   auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
157   const int frame_length_ms = prng_.Rand(1, 1000);
158   runtime_config->frame_length_ms = frame_length_ms;
159   TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
160 }
161 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationPacketLoss)162 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationPacketLoss) {
163   // To simplify the test, we just check powers of two.
164   const float plr = std::pow(0.5f, prng_.Rand(1, 8));
165   auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
166   runtime_config->uplink_packet_loss_fraction = plr;
167   TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
168 }
169 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationFec)170 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFec) {
171   // The test might be trivially passing for one of the two boolean values, so
172   // for safety's sake, we test both.
173   for (bool fec_enabled : {false, true}) {
174     auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
175     runtime_config->enable_fec = fec_enabled;
176     TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
177   }
178 }
179 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationDtx)180 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationDtx) {
181   // The test might be trivially passing for one of the two boolean values, so
182   // for safety's sake, we test both.
183   for (bool dtx_enabled : {false, true}) {
184     auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
185     runtime_config->enable_dtx = dtx_enabled;
186     TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
187   }
188 }
189 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationChannels)190 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationChannels) {
191   // The test might be trivially passing for one of the two possible values, so
192   // for safety's sake, we test both.
193   for (size_t channels : {1, 2}) {
194     auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
195     runtime_config->num_channels = channels;
196     TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
197   }
198 }
199 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioNetworkAdaptationAll)200 TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationAll) {
201   const int bitrate_bps = RandomBitrate();
202   const int frame_length_ms = prng_.Rand(1, 1000);
203   const float plr = std::pow(0.5f, prng_.Rand(1, 8));
204   for (bool fec_enabled : {false, true}) {
205     for (bool dtx_enabled : {false, true}) {
206       for (size_t channels : {1, 2}) {
207         auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
208         runtime_config->bitrate_bps = bitrate_bps;
209         runtime_config->frame_length_ms = frame_length_ms;
210         runtime_config->uplink_packet_loss_fraction = plr;
211         runtime_config->enable_fec = fec_enabled;
212         runtime_config->enable_dtx = dtx_enabled;
213         runtime_config->num_channels = channels;
214 
215         TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
216       }
217     }
218   }
219 }
220 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioPlayout)221 TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) {
222   const uint32_t ssrc = RandomSsrc();
223   auto event = rtc::MakeUnique<RtcEventAudioPlayout>(ssrc);
224   const int64_t timestamp_us = event->timestamp_us_;
225 
226   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
227   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
228   ASSERT_EQ(parsed_log_.GetEventType(0),
229             ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT);
230 
231   uint32_t parsed_ssrc;
232   parsed_log_.GetAudioPlayout(0, &parsed_ssrc);
233 
234   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
235   EXPECT_EQ(parsed_ssrc, ssrc);
236 }
237 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioReceiveStreamConfig)238 TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) {
239   auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
240   stream_config->local_ssrc = RandomSsrc();
241   stream_config->remote_ssrc = RandomSsrc();
242   // TODO(eladalon): Verify that the extensions are used correctly when
243   // parsing RTP packets headers. Here and elsewhere.
244   std::vector<RtpExtension> extensions = RandomRtpExtensions();
245   for (const auto& extension : extensions)
246     stream_config->rtp_extensions.push_back(extension);
247 
248   auto original_stream_config = *stream_config;
249 
250   auto event = rtc::MakeUnique<RtcEventAudioReceiveStreamConfig>(
251       std::move(stream_config));
252   const int64_t timestamp_us = event->timestamp_us_;
253 
254   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
255   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
256   ASSERT_EQ(parsed_log_.GetEventType(0),
257             ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT);
258 
259   auto parsed_event = parsed_log_.GetAudioReceiveConfig(0);
260   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
261   EXPECT_EQ(parsed_event, original_stream_config);
262 }
263 
TEST_P(RtcEventLogEncoderTest,RtcEventAudioSendStreamConfig)264 TEST_P(RtcEventLogEncoderTest, RtcEventAudioSendStreamConfig) {
265   auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
266   stream_config->local_ssrc = RandomSsrc();
267   std::vector<RtpExtension> extensions = RandomRtpExtensions();
268   for (const auto& extension : extensions)
269     stream_config->rtp_extensions.push_back(extension);
270 
271   auto original_stream_config = *stream_config;
272 
273   auto event =
274       rtc::MakeUnique<RtcEventAudioSendStreamConfig>(std::move(stream_config));
275   const int64_t timestamp_us = event->timestamp_us_;
276 
277   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
278   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
279   ASSERT_EQ(parsed_log_.GetEventType(0),
280             ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT);
281 
282   auto parsed_event = parsed_log_.GetAudioSendConfig(0);
283   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
284   EXPECT_EQ(parsed_event, original_stream_config);
285 }
286 
TEST_P(RtcEventLogEncoderTest,RtcEventBweUpdateDelayBased)287 TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) {
288   const int32_t bitrate_bps = RandomBitrate();
289   const BandwidthUsage detector_state = static_cast<BandwidthUsage>(
290       prng_.Rand(0, static_cast<int32_t>(BandwidthUsage::kLast) - 1));
291   auto event =
292       rtc::MakeUnique<RtcEventBweUpdateDelayBased>(bitrate_bps, detector_state);
293   const int64_t timestamp_us = event->timestamp_us_;
294 
295   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
296   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
297   ASSERT_EQ(parsed_log_.GetEventType(0),
298             ParsedRtcEventLog::DELAY_BASED_BWE_UPDATE);
299 
300   auto parsed_event = parsed_log_.GetDelayBasedBweUpdate(0);
301 
302   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
303   EXPECT_EQ(parsed_event.bitrate_bps, bitrate_bps);
304   EXPECT_EQ(parsed_event.detector_state, detector_state);
305 }
306 
TEST_P(RtcEventLogEncoderTest,RtcEventBweUpdateLossBased)307 TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) {
308   const int32_t bitrate_bps = RandomBitrate();
309   const uint8_t fraction_loss = rtc::dchecked_cast<uint8_t>(
310       prng_.Rand(0, std::numeric_limits<uint8_t>::max()));
311   const int32_t total_packets = RandomInt();
312 
313   auto event = rtc::MakeUnique<RtcEventBweUpdateLossBased>(
314       bitrate_bps, fraction_loss, total_packets);
315   const int64_t timestamp_us = event->timestamp_us_;
316 
317   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
318   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
319   ASSERT_EQ(parsed_log_.GetEventType(0),
320             ParsedRtcEventLog::LOSS_BASED_BWE_UPDATE);
321 
322   int32_t parsed_bitrate_bps;
323   uint8_t parsed_fraction_loss;
324   int32_t parsed_total_packets;
325   parsed_log_.GetLossBasedBweUpdate(
326       0, &parsed_bitrate_bps, &parsed_fraction_loss, &parsed_total_packets);
327 
328   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
329   EXPECT_EQ(parsed_bitrate_bps, bitrate_bps);
330   EXPECT_EQ(parsed_fraction_loss, fraction_loss);
331   EXPECT_EQ(parsed_total_packets, total_packets);
332 }
333 
TEST_P(RtcEventLogEncoderTest,RtcEventLoggingStarted)334 TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) {
335   auto event = rtc::MakeUnique<RtcEventLoggingStarted>();
336   const int64_t timestamp_us = event->timestamp_us_;
337 
338   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
339   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
340   ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::LOG_START);
341 
342   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
343 }
344 
TEST_P(RtcEventLogEncoderTest,RtcEventLoggingStopped)345 TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) {
346   auto event = rtc::MakeUnique<RtcEventLoggingStopped>();
347   const int64_t timestamp_us = event->timestamp_us_;
348 
349   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
350   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
351   ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::LOG_END);
352 
353   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
354 }
355 
TEST_P(RtcEventLogEncoderTest,RtcEventProbeClusterCreated)356 TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) {
357   const int id = RandomPositiveInt();
358   const int bitrate_bps = RandomBitrate();
359   const int min_probes = RandomPositiveInt();
360   const int min_bytes = RandomPositiveInt();
361 
362   auto event = rtc::MakeUnique<RtcEventProbeClusterCreated>(
363       id, bitrate_bps, min_probes, min_bytes);
364   const int64_t timestamp_us = event->timestamp_us_;
365 
366   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
367   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
368   ASSERT_EQ(parsed_log_.GetEventType(0),
369             ParsedRtcEventLog::BWE_PROBE_CLUSTER_CREATED_EVENT);
370 
371   auto parsed_event = parsed_log_.GetBweProbeClusterCreated(0);
372 
373   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
374   EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.id), id);
375   EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.bitrate_bps), bitrate_bps);
376   EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.min_packets), min_probes);
377   EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.min_bytes), min_bytes);
378 }
379 
TEST_P(RtcEventLogEncoderTest,RtcEventProbeResultFailure)380 TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultFailure) {
381   const int id = RandomPositiveInt();
382   const ProbeFailureReason failure_reason = static_cast<ProbeFailureReason>(
383       prng_.Rand(0, static_cast<int32_t>(ProbeFailureReason::kLast) - 1));
384 
385   auto event = rtc::MakeUnique<RtcEventProbeResultFailure>(id, failure_reason);
386   const int64_t timestamp_us = event->timestamp_us_;
387 
388   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
389   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
390   ASSERT_EQ(parsed_log_.GetEventType(0),
391             ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT);
392 
393   auto parsed_event = parsed_log_.GetBweProbeResult(0);
394 
395   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
396   EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.id), id);
397   ASSERT_FALSE(parsed_event.bitrate_bps);
398   ASSERT_TRUE(parsed_event.failure_reason);
399   EXPECT_EQ(parsed_event.failure_reason, failure_reason);
400 }
401 
TEST_P(RtcEventLogEncoderTest,RtcEventProbeResultSuccess)402 TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultSuccess) {
403   const int id = RandomPositiveInt();
404   const int bitrate_bps = RandomBitrate();
405 
406   auto event = rtc::MakeUnique<RtcEventProbeResultSuccess>(id, bitrate_bps);
407   const int64_t timestamp_us = event->timestamp_us_;
408 
409   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
410   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
411   ASSERT_EQ(parsed_log_.GetEventType(0),
412             ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT);
413 
414   auto parsed_event = parsed_log_.GetBweProbeResult(0);
415 
416   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
417   EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.id), id);
418   ASSERT_TRUE(parsed_event.bitrate_bps);
419   EXPECT_EQ(parsed_event.bitrate_bps, bitrate_bps);
420   ASSERT_FALSE(parsed_event.failure_reason);
421 }
422 
TestRtcEventRtcpPacket(PacketDirection direction)423 void RtcEventLogEncoderTest::TestRtcEventRtcpPacket(PacketDirection direction) {
424   rtcp::Bye bye_packet;  // Arbitrarily chosen RTCP packet type.
425   bye_packet.SetReason("a man's reach should exceed his grasp");
426   auto rtcp_packet = bye_packet.Build();
427 
428   std::unique_ptr<RtcEvent> event;
429   if (direction == PacketDirection::kIncomingPacket) {
430     event = rtc::MakeUnique<RtcEventRtcpPacketIncoming>(rtcp_packet);
431   } else {
432     event = rtc::MakeUnique<RtcEventRtcpPacketOutgoing>(rtcp_packet);
433   }
434   const int64_t timestamp_us = event->timestamp_us_;
435 
436   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
437   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
438   ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::RTCP_EVENT);
439 
440   PacketDirection parsed_direction;
441   uint8_t parsed_packet[IP_PACKET_SIZE];  // "Parsed" = after event-encoding.
442   size_t parsed_packet_length;
443   parsed_log_.GetRtcpPacket(0, &parsed_direction, parsed_packet,
444                             &parsed_packet_length);
445 
446   EXPECT_EQ(parsed_direction, direction);
447   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
448   ASSERT_EQ(parsed_packet_length, rtcp_packet.size());
449   ASSERT_EQ(memcmp(parsed_packet, rtcp_packet.data(), parsed_packet_length), 0);
450 }
451 
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpPacketIncoming)452 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) {
453   TestRtcEventRtcpPacket(PacketDirection::kIncomingPacket);
454 }
455 
TEST_P(RtcEventLogEncoderTest,RtcEventRtcpPacketOutgoing)456 TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketOutgoing) {
457   TestRtcEventRtcpPacket(PacketDirection::kOutgoingPacket);
458 }
459 
TestRtcEventRtpPacket(PacketDirection direction)460 void RtcEventLogEncoderTest::TestRtcEventRtpPacket(PacketDirection direction) {
461   const int probe_cluster_id = RandomPositiveInt();
462 
463   std::unique_ptr<RtpPacketReceived> packet_received;
464   std::unique_ptr<RtpPacketToSend> packet_to_send;
465   RtpPacket* packet;
466   if (direction == PacketDirection::kIncomingPacket) {
467     packet_received = rtc::MakeUnique<RtpPacketReceived>();
468     packet = packet_received.get();
469   } else {
470     packet_to_send = rtc::MakeUnique<RtpPacketToSend>(nullptr);
471     packet = packet_to_send.get();
472   }
473   packet->SetSsrc(RandomSsrc());
474   packet->SetSequenceNumber(static_cast<uint16_t>(RandomInt()));
475   packet->SetPayloadSize(prng_.Rand(0u, 1000u));
476   // TODO(terelius): Add marker bit, capture timestamp, CSRCs, and header
477   // extensions.
478 
479   std::unique_ptr<RtcEvent> event;
480   if (direction == PacketDirection::kIncomingPacket) {
481     event = rtc::MakeUnique<RtcEventRtpPacketIncoming>(*packet_received);
482   } else {
483     event = rtc::MakeUnique<RtcEventRtpPacketOutgoing>(*packet_to_send,
484                                                        probe_cluster_id);
485   }
486   const int64_t timestamp_us = event->timestamp_us_;
487 
488   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
489   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
490   ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::RTP_EVENT);
491 
492   PacketDirection parsed_direction;
493   uint8_t parsed_rtp_header[IP_PACKET_SIZE];
494   size_t parsed_header_length;
495   size_t parsed_total_length;
496   int parsed_probe_cluster_id;
497   parsed_log_.GetRtpHeader(0, &parsed_direction, parsed_rtp_header,
498                            &parsed_header_length, &parsed_total_length,
499                            &parsed_probe_cluster_id);
500 
501   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
502   EXPECT_EQ(parsed_direction, direction);
503   if (parsed_direction == PacketDirection::kOutgoingPacket) {
504     EXPECT_EQ(parsed_probe_cluster_id, probe_cluster_id);
505   }
506   EXPECT_EQ(memcmp(parsed_rtp_header, packet->data(), parsed_header_length), 0);
507   EXPECT_EQ(parsed_header_length, packet->headers_size());
508   EXPECT_EQ(parsed_total_length, packet->size());
509 }
510 
TEST_P(RtcEventLogEncoderTest,RtcEventRtpPacketIncoming)511 TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) {
512   TestRtcEventRtpPacket(PacketDirection::kIncomingPacket);
513 }
514 
TEST_P(RtcEventLogEncoderTest,RtcEventRtpPacketOutgoing)515 TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoing) {
516   TestRtcEventRtpPacket(PacketDirection::kOutgoingPacket);
517 }
518 
TEST_P(RtcEventLogEncoderTest,RtcEventVideoReceiveStreamConfig)519 TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) {
520   auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
521   stream_config->local_ssrc = RandomSsrc();
522   stream_config->remote_ssrc = RandomSsrc();
523   stream_config->rtcp_mode = RtcpMode::kCompound;
524   stream_config->remb = prng_.Rand<bool>();
525   std::vector<RtpExtension> extensions = RandomRtpExtensions();
526   for (const auto& extension : extensions)
527     stream_config->rtp_extensions.push_back(extension);
528   stream_config->codecs.emplace_back("CODEC", 122, 7);
529 
530   auto original_stream_config = *stream_config;
531 
532   auto event = rtc::MakeUnique<RtcEventVideoReceiveStreamConfig>(
533       std::move(stream_config));
534   const int64_t timestamp_us = event->timestamp_us_;
535 
536   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
537   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
538   ASSERT_EQ(parsed_log_.GetEventType(0),
539             ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT);
540 
541   auto parsed_event = parsed_log_.GetVideoReceiveConfig(0);
542   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
543   EXPECT_EQ(parsed_event, original_stream_config);
544 }
545 
TEST_P(RtcEventLogEncoderTest,RtcEventVideoSendStreamConfig)546 TEST_P(RtcEventLogEncoderTest, RtcEventVideoSendStreamConfig) {
547   auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
548   stream_config->local_ssrc = RandomSsrc();
549   std::vector<RtpExtension> extensions = RandomRtpExtensions();
550   for (const auto& extension : extensions)
551     stream_config->rtp_extensions.push_back(extension);
552   stream_config->codecs.emplace_back("CODEC", 120, 3);
553 
554   auto original_stream_config = *stream_config;
555 
556   auto event =
557       rtc::MakeUnique<RtcEventVideoSendStreamConfig>(std::move(stream_config));
558   const int64_t timestamp_us = event->timestamp_us_;
559 
560   ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event)));
561   ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
562   ASSERT_EQ(parsed_log_.GetEventType(0),
563             ParsedRtcEventLog::VIDEO_SENDER_CONFIG_EVENT);
564 
565   auto parsed_event = parsed_log_.GetVideoSendConfig(0)[0];
566   EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
567   EXPECT_EQ(parsed_event, original_stream_config);
568 }
569 
570 INSTANTIATE_TEST_CASE_P(RandomSeeds,
571                         RtcEventLogEncoderTest,
572                         ::testing::Values(1, 2, 3, 4, 5));
573 
574 }  // namespace webrtc
575