xref: /aosp_15_r20/external/webrtc/video/end_to_end_tests/stats_tests.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2018 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 <memory>
12 
13 #include "absl/algorithm/container.h"
14 #include "absl/types/optional.h"
15 #include "api/task_queue/task_queue_base.h"
16 #include "api/test/simulated_network.h"
17 #include "api/test/video/function_video_encoder_factory.h"
18 #include "call/fake_network_pipe.h"
19 #include "call/simulated_network.h"
20 #include "modules/rtp_rtcp/source/rtp_packet.h"
21 #include "modules/video_coding/include/video_coding_defines.h"
22 #include "rtc_base/strings/string_builder.h"
23 #include "rtc_base/synchronization/mutex.h"
24 #include "rtc_base/task_queue_for_test.h"
25 #include "system_wrappers/include/metrics.h"
26 #include "system_wrappers/include/sleep.h"
27 #include "test/call_test.h"
28 #include "test/fake_encoder.h"
29 #include "test/gtest.h"
30 #include "test/rtcp_packet_parser.h"
31 
32 namespace webrtc {
33 namespace {
34 enum : int {  // The first valid value is 1.
35   kVideoContentTypeExtensionId = 1,
36 };
37 }  // namespace
38 
39 class StatsEndToEndTest : public test::CallTest {
40  public:
StatsEndToEndTest()41   StatsEndToEndTest() {
42     RegisterRtpExtension(RtpExtension(RtpExtension::kVideoContentTypeUri,
43                                       kVideoContentTypeExtensionId));
44   }
45 };
46 
TEST_F(StatsEndToEndTest,GetStats)47 TEST_F(StatsEndToEndTest, GetStats) {
48   static const int kStartBitrateBps = 3000000;
49   static const int kExpectedRenderDelayMs = 20;
50 
51   class StatsObserver : public test::EndToEndTest {
52    public:
53     StatsObserver()
54         : EndToEndTest(kLongTimeout), encoder_factory_([]() {
55             return std::make_unique<test::DelayedEncoder>(
56                 Clock::GetRealTimeClock(), 10);
57           }) {}
58 
59    private:
60     Action OnSendRtp(const uint8_t* packet, size_t length) override {
61       // Drop every 25th packet => 4% loss.
62       static const int kPacketLossFrac = 25;
63       RtpPacket header;
64       if (header.Parse(packet, length) &&
65           expected_send_ssrcs_.find(header.Ssrc()) !=
66               expected_send_ssrcs_.end() &&
67           header.SequenceNumber() % kPacketLossFrac == 0) {
68         return DROP_PACKET;
69       }
70       check_stats_event_.Set();
71       return SEND_PACKET;
72     }
73 
74     Action OnSendRtcp(const uint8_t* packet, size_t length) override {
75       check_stats_event_.Set();
76       return SEND_PACKET;
77     }
78 
79     Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
80       check_stats_event_.Set();
81       return SEND_PACKET;
82     }
83 
84     Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
85       check_stats_event_.Set();
86       return SEND_PACKET;
87     }
88 
89     bool CheckReceiveStats() {
90       for (size_t i = 0; i < receive_streams_.size(); ++i) {
91         VideoReceiveStreamInterface::Stats stats =
92             receive_streams_[i]->GetStats();
93         EXPECT_EQ(expected_receive_ssrcs_[i], stats.ssrc);
94 
95         // Make sure all fields have been populated.
96         // TODO(pbos): Use CompoundKey if/when we ever know that all stats are
97         // always filled for all receivers.
98         receive_stats_filled_["IncomingRate"] |=
99             stats.network_frame_rate != 0 || stats.total_bitrate_bps != 0;
100 
101         send_stats_filled_["DecoderImplementationName"] |=
102             stats.decoder_implementation_name ==
103             test::FakeDecoder::kImplementationName;
104         receive_stats_filled_["PowerEfficientDecoder"] =
105             stats.power_efficient_decoder.has_value();
106         receive_stats_filled_["RenderDelayAsHighAsExpected"] |=
107             stats.render_delay_ms >= kExpectedRenderDelayMs;
108 
109         receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0;
110 
111         receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;
112 
113         receive_stats_filled_["StatisticsUpdated"] |=
114             stats.rtp_stats.packets_lost != 0 || stats.rtp_stats.jitter != 0;
115 
116         receive_stats_filled_["DataCountersUpdated"] |=
117             stats.rtp_stats.packet_counter.payload_bytes != 0 ||
118             stats.rtp_stats.packet_counter.header_bytes != 0 ||
119             stats.rtp_stats.packet_counter.packets != 0 ||
120             stats.rtp_stats.packet_counter.padding_bytes != 0;
121 
122         receive_stats_filled_["CodecStats"] |= stats.target_delay_ms != 0;
123 
124         receive_stats_filled_["FrameCounts"] |=
125             stats.frame_counts.key_frames != 0 ||
126             stats.frame_counts.delta_frames != 0;
127 
128         receive_stats_filled_["CName"] |= !stats.c_name.empty();
129 
130         receive_stats_filled_["RtcpPacketTypeCount"] |=
131             stats.rtcp_packet_type_counts.fir_packets != 0 ||
132             stats.rtcp_packet_type_counts.nack_packets != 0 ||
133             stats.rtcp_packet_type_counts.pli_packets != 0 ||
134             stats.rtcp_packet_type_counts.nack_requests != 0 ||
135             stats.rtcp_packet_type_counts.unique_nack_requests != 0;
136 
137         RTC_DCHECK(stats.current_payload_type == -1 ||
138                    stats.current_payload_type == kFakeVideoSendPayloadType);
139         receive_stats_filled_["IncomingPayloadType"] |=
140             stats.current_payload_type == kFakeVideoSendPayloadType;
141       }
142 
143       return AllStatsFilled(receive_stats_filled_);
144     }
145 
146     bool CheckSendStats() {
147       RTC_DCHECK(send_stream_);
148 
149       VideoSendStream::Stats stats;
150       SendTask(task_queue_, [&]() { stats = send_stream_->GetStats(); });
151 
152       size_t expected_num_streams =
153           kNumSimulcastStreams + expected_send_ssrcs_.size();
154       send_stats_filled_["NumStreams"] |=
155           stats.substreams.size() == expected_num_streams;
156 
157       send_stats_filled_["CpuOveruseMetrics"] |=
158           stats.avg_encode_time_ms != 0 && stats.encode_usage_percent != 0 &&
159           stats.total_encode_time_ms != 0;
160 
161       send_stats_filled_["EncoderImplementationName"] |=
162           stats.encoder_implementation_name ==
163           test::FakeEncoder::kImplementationName;
164 
165       send_stats_filled_["PowerEfficientEncoder"] |=
166           stats.power_efficient_encoder == true;
167 
168       for (const auto& kv : stats.substreams) {
169         if (expected_send_ssrcs_.find(kv.first) == expected_send_ssrcs_.end())
170           continue;  // Probably RTX.
171 
172         send_stats_filled_[CompoundKey("CapturedFrameRate", kv.first)] |=
173             stats.input_frame_rate != 0;
174 
175         const VideoSendStream::StreamStats& stream_stats = kv.second;
176 
177         send_stats_filled_[CompoundKey("StatisticsUpdated", kv.first)] |=
178             stream_stats.report_block_data.has_value();
179 
180         send_stats_filled_[CompoundKey("DataCountersUpdated", kv.first)] |=
181             stream_stats.rtp_stats.fec.packets != 0 ||
182             stream_stats.rtp_stats.transmitted.padding_bytes != 0 ||
183             stream_stats.rtp_stats.retransmitted.packets != 0 ||
184             stream_stats.rtp_stats.transmitted.packets != 0;
185 
186         send_stats_filled_[CompoundKey("BitrateStatisticsObserver.Total",
187                                        kv.first)] |=
188             stream_stats.total_bitrate_bps != 0;
189 
190         send_stats_filled_[CompoundKey("BitrateStatisticsObserver.Retransmit",
191                                        kv.first)] |=
192             stream_stats.retransmit_bitrate_bps != 0;
193 
194         send_stats_filled_[CompoundKey("FrameCountObserver", kv.first)] |=
195             stream_stats.frame_counts.delta_frames != 0 ||
196             stream_stats.frame_counts.key_frames != 0;
197 
198         send_stats_filled_[CompoundKey("OutgoingRate", kv.first)] |=
199             stats.encode_frame_rate != 0;
200 
201         send_stats_filled_[CompoundKey("Delay", kv.first)] |=
202             stream_stats.avg_delay_ms != 0 || stream_stats.max_delay_ms != 0;
203 
204         // TODO(pbos): Use CompoundKey when the test makes sure that all SSRCs
205         // report dropped packets.
206         send_stats_filled_["RtcpPacketTypeCount"] |=
207             stream_stats.rtcp_packet_type_counts.fir_packets != 0 ||
208             stream_stats.rtcp_packet_type_counts.nack_packets != 0 ||
209             stream_stats.rtcp_packet_type_counts.pli_packets != 0 ||
210             stream_stats.rtcp_packet_type_counts.nack_requests != 0 ||
211             stream_stats.rtcp_packet_type_counts.unique_nack_requests != 0;
212       }
213 
214       return AllStatsFilled(send_stats_filled_);
215     }
216 
217     std::string CompoundKey(const char* name, uint32_t ssrc) {
218       rtc::StringBuilder oss;
219       oss << name << "_" << ssrc;
220       return oss.Release();
221     }
222 
223     bool AllStatsFilled(const std::map<std::string, bool>& stats_map) {
224       for (const auto& stat : stats_map) {
225         if (!stat.second)
226           return false;
227       }
228       return true;
229     }
230 
231     std::unique_ptr<test::PacketTransport> CreateSendTransport(
232         TaskQueueBase* task_queue,
233         Call* sender_call) override {
234       BuiltInNetworkBehaviorConfig network_config;
235       network_config.loss_percent = 5;
236       return std::make_unique<test::PacketTransport>(
237           task_queue, sender_call, this, test::PacketTransport::kSender,
238           payload_type_map_,
239           std::make_unique<FakeNetworkPipe>(
240               Clock::GetRealTimeClock(),
241               std::make_unique<SimulatedNetwork>(network_config)));
242     }
243 
244     void ModifySenderBitrateConfig(
245         BitrateConstraints* bitrate_config) override {
246       bitrate_config->start_bitrate_bps = kStartBitrateBps;
247     }
248 
249     void ModifyVideoConfigs(
250         VideoSendStream::Config* send_config,
251         std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
252         VideoEncoderConfig* encoder_config) override {
253       // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
254       encoder_config->max_bitrate_bps = 50000;
255       for (auto& layer : encoder_config->simulcast_layers) {
256         layer.min_bitrate_bps = 10000;
257         layer.target_bitrate_bps = 15000;
258         layer.max_bitrate_bps = 20000;
259       }
260 
261       send_config->rtp.c_name = "SomeCName";
262       send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
263       send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
264 
265       const std::vector<uint32_t>& ssrcs = send_config->rtp.ssrcs;
266       for (size_t i = 0; i < ssrcs.size(); ++i) {
267         expected_send_ssrcs_.insert(ssrcs[i]);
268         expected_receive_ssrcs_.push_back(
269             (*receive_configs)[i].rtp.remote_ssrc);
270         (*receive_configs)[i].render_delay_ms = kExpectedRenderDelayMs;
271         (*receive_configs)[i].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
272 
273         (*receive_configs)[i].rtp.rtx_ssrc = kSendRtxSsrcs[i];
274         (*receive_configs)[i]
275             .rtp.rtx_associated_payload_types[kSendRtxPayloadType] =
276             kFakeVideoSendPayloadType;
277       }
278 
279       for (size_t i = 0; i < kNumSimulcastStreams; ++i)
280         send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
281 
282       // Use a delayed encoder to make sure we see CpuOveruseMetrics stats that
283       // are non-zero.
284       send_config->encoder_settings.encoder_factory = &encoder_factory_;
285     }
286 
287     size_t GetNumVideoStreams() const override { return kNumSimulcastStreams; }
288 
289     void OnVideoStreamsCreated(VideoSendStream* send_stream,
290                                const std::vector<VideoReceiveStreamInterface*>&
291                                    receive_streams) override {
292       send_stream_ = send_stream;
293       receive_streams_ = receive_streams;
294       task_queue_ = TaskQueueBase::Current();
295     }
296 
297     void PerformTest() override {
298       Clock* clock = Clock::GetRealTimeClock();
299       int64_t now_ms = clock->TimeInMilliseconds();
300       int64_t stop_time_ms = now_ms + test::CallTest::kLongTimeout.ms();
301       bool receive_ok = false;
302       bool send_ok = false;
303 
304       while (now_ms < stop_time_ms) {
305         if (!receive_ok && task_queue_) {
306           SendTask(task_queue_, [&]() { receive_ok = CheckReceiveStats(); });
307         }
308         if (!send_ok)
309           send_ok = CheckSendStats();
310 
311         if (receive_ok && send_ok)
312           return;
313 
314         int64_t time_until_timeout_ms = stop_time_ms - now_ms;
315         if (time_until_timeout_ms > 0)
316           check_stats_event_.Wait(TimeDelta::Millis(time_until_timeout_ms));
317         now_ms = clock->TimeInMilliseconds();
318       }
319 
320       ADD_FAILURE() << "Timed out waiting for filled stats.";
321       for (const auto& kv : receive_stats_filled_) {
322         if (!kv.second) {
323           ADD_FAILURE() << "Missing receive stats: " << kv.first;
324         }
325       }
326       for (const auto& kv : send_stats_filled_) {
327         if (!kv.second) {
328           ADD_FAILURE() << "Missing send stats: " << kv.first;
329         }
330       }
331     }
332 
333     test::FunctionVideoEncoderFactory encoder_factory_;
334     std::vector<VideoReceiveStreamInterface*> receive_streams_;
335     std::map<std::string, bool> receive_stats_filled_;
336 
337     VideoSendStream* send_stream_ = nullptr;
338     std::map<std::string, bool> send_stats_filled_;
339 
340     std::vector<uint32_t> expected_receive_ssrcs_;
341     std::set<uint32_t> expected_send_ssrcs_;
342 
343     rtc::Event check_stats_event_;
344     TaskQueueBase* task_queue_ = nullptr;
345   } test;
346 
347   RunBaseTest(&test);
348 }
349 
TEST_F(StatsEndToEndTest,TimingFramesAreReported)350 TEST_F(StatsEndToEndTest, TimingFramesAreReported) {
351   static const int kExtensionId = 5;
352 
353   class StatsObserver : public test::EndToEndTest {
354    public:
355     StatsObserver() : EndToEndTest(kLongTimeout) {}
356 
357    private:
358     void ModifyVideoConfigs(
359         VideoSendStream::Config* send_config,
360         std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
361         VideoEncoderConfig* encoder_config) override {
362       send_config->rtp.extensions.clear();
363       send_config->rtp.extensions.push_back(
364           RtpExtension(RtpExtension::kVideoTimingUri, kExtensionId));
365       for (auto& receive_config : *receive_configs) {
366         receive_config.rtp.extensions.clear();
367         receive_config.rtp.extensions.push_back(
368             RtpExtension(RtpExtension::kVideoTimingUri, kExtensionId));
369       }
370     }
371 
372     void OnVideoStreamsCreated(VideoSendStream* send_stream,
373                                const std::vector<VideoReceiveStreamInterface*>&
374                                    receive_streams) override {
375       receive_streams_ = receive_streams;
376       task_queue_ = TaskQueueBase::Current();
377     }
378 
379     void PerformTest() override {
380       // No frames reported initially.
381       SendTask(task_queue_, [&]() {
382         for (const auto& receive_stream : receive_streams_) {
383           EXPECT_FALSE(receive_stream->GetStats().timing_frame_info);
384         }
385       });
386       // Wait for at least one timing frame to be sent with 100ms grace period.
387       SleepMs(kDefaultTimingFramesDelayMs + 100);
388       // Check that timing frames are reported for each stream.
389       SendTask(task_queue_, [&]() {
390         for (const auto& receive_stream : receive_streams_) {
391           EXPECT_TRUE(receive_stream->GetStats().timing_frame_info);
392         }
393       });
394     }
395 
396     std::vector<VideoReceiveStreamInterface*> receive_streams_;
397     TaskQueueBase* task_queue_ = nullptr;
398   } test;
399 
400   RunBaseTest(&test);
401 }
402 
TEST_F(StatsEndToEndTest,TestReceivedRtpPacketStats)403 TEST_F(StatsEndToEndTest, TestReceivedRtpPacketStats) {
404   static const size_t kNumRtpPacketsToSend = 5;
405   class ReceivedRtpStatsObserver : public test::EndToEndTest {
406    public:
407     explicit ReceivedRtpStatsObserver(TaskQueueBase* task_queue)
408         : EndToEndTest(kDefaultTimeout), task_queue_(task_queue) {}
409 
410    private:
411     void OnVideoStreamsCreated(VideoSendStream* send_stream,
412                                const std::vector<VideoReceiveStreamInterface*>&
413                                    receive_streams) override {
414       receive_stream_ = receive_streams[0];
415     }
416 
417     void OnStreamsStopped() override { task_safety_flag_->SetNotAlive(); }
418 
419     Action OnSendRtp(const uint8_t* packet, size_t length) override {
420       if (sent_rtp_ >= kNumRtpPacketsToSend) {
421         // Need to check the stats on the correct thread.
422         task_queue_->PostTask(SafeTask(task_safety_flag_, [this]() {
423           VideoReceiveStreamInterface::Stats stats =
424               receive_stream_->GetStats();
425           if (kNumRtpPacketsToSend == stats.rtp_stats.packet_counter.packets) {
426             observation_complete_.Set();
427           }
428         }));
429         return DROP_PACKET;
430       }
431       ++sent_rtp_;
432       return SEND_PACKET;
433     }
434 
435     void PerformTest() override {
436       EXPECT_TRUE(Wait())
437           << "Timed out while verifying number of received RTP packets.";
438     }
439 
440     VideoReceiveStreamInterface* receive_stream_ = nullptr;
441     uint32_t sent_rtp_ = 0;
442     TaskQueueBase* const task_queue_;
443     rtc::scoped_refptr<PendingTaskSafetyFlag> task_safety_flag_ =
444         PendingTaskSafetyFlag::CreateDetached();
445   } test(task_queue());
446 
447   RunBaseTest(&test);
448 }
449 
450 #if defined(WEBRTC_WIN)
451 // Disabled due to flakiness on Windows (bugs.webrtc.org/7483).
452 #define MAYBE_ContentTypeSwitches DISABLED_ContentTypeSwitches
453 #else
454 #define MAYBE_ContentTypeSwitches ContentTypeSwitches
455 #endif
TEST_F(StatsEndToEndTest,MAYBE_ContentTypeSwitches)456 TEST_F(StatsEndToEndTest, MAYBE_ContentTypeSwitches) {
457   class StatsObserver : public test::BaseTest,
458                         public rtc::VideoSinkInterface<VideoFrame> {
459    public:
460     StatsObserver() : BaseTest(kLongTimeout), num_frames_received_(0) {}
461 
462     bool ShouldCreateReceivers() const override { return true; }
463 
464     void OnFrame(const VideoFrame& video_frame) override {
465       // The RTT is needed to estimate `ntp_time_ms` which is used by
466       // end-to-end delay stats. Therefore, start counting received frames once
467       // `ntp_time_ms` is valid.
468       if (video_frame.ntp_time_ms() > 0 &&
469           Clock::GetRealTimeClock()->CurrentNtpInMilliseconds() >=
470               video_frame.ntp_time_ms()) {
471         MutexLock lock(&mutex_);
472         ++num_frames_received_;
473       }
474     }
475 
476     Action OnSendRtp(const uint8_t* packet, size_t length) override {
477       if (MinNumberOfFramesReceived())
478         observation_complete_.Set();
479       return SEND_PACKET;
480     }
481 
482     bool MinNumberOfFramesReceived() const {
483       // Have some room for frames with wrong content type during switch.
484       const int kMinRequiredHistogramSamples = 200 + 50;
485       MutexLock lock(&mutex_);
486       return num_frames_received_ > kMinRequiredHistogramSamples;
487     }
488 
489     // May be called several times.
490     void PerformTest() override {
491       EXPECT_TRUE(Wait()) << "Timed out waiting for enough packets.";
492       // Reset frame counter so next PerformTest() call will do something.
493       {
494         MutexLock lock(&mutex_);
495         num_frames_received_ = 0;
496       }
497     }
498 
499     mutable Mutex mutex_;
500     int num_frames_received_ RTC_GUARDED_BY(&mutex_);
501   } test;
502 
503   metrics::Reset();
504 
505   Call::Config send_config(send_event_log_.get());
506   test.ModifySenderBitrateConfig(&send_config.bitrate_config);
507   Call::Config recv_config(recv_event_log_.get());
508   test.ModifyReceiverBitrateConfig(&recv_config.bitrate_config);
509 
510   VideoEncoderConfig encoder_config_with_screenshare;
511 
512   SendTask(
513       task_queue(), [this, &test, &send_config, &recv_config,
514                      &encoder_config_with_screenshare]() {
515         CreateSenderCall(send_config);
516         CreateReceiverCall(recv_config);
517 
518         receive_transport_ = test.CreateReceiveTransport(task_queue());
519         send_transport_ =
520             test.CreateSendTransport(task_queue(), sender_call_.get());
521         send_transport_->SetReceiver(receiver_call_->Receiver());
522         receive_transport_->SetReceiver(sender_call_->Receiver());
523 
524         receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
525         CreateSendConfig(1, 0, 0, send_transport_.get());
526         CreateMatchingReceiveConfigs(receive_transport_.get());
527 
528         // Modify send and receive configs.
529         GetVideoSendConfig()->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
530         video_receive_configs_[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
531         video_receive_configs_[0].renderer = &test;
532         // RTT needed for RemoteNtpTimeEstimator for the receive stream.
533         video_receive_configs_[0].rtp.rtcp_xr.receiver_reference_time_report =
534             true;
535         // Start with realtime video.
536         GetVideoEncoderConfig()->content_type =
537             VideoEncoderConfig::ContentType::kRealtimeVideo;
538         // Encoder config for the second part of the test uses screenshare.
539         encoder_config_with_screenshare = GetVideoEncoderConfig()->Copy();
540         encoder_config_with_screenshare.content_type =
541             VideoEncoderConfig::ContentType::kScreen;
542 
543         CreateVideoStreams();
544         CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
545                                      kDefaultHeight);
546         Start();
547       });
548 
549   test.PerformTest();
550 
551   // Replace old send stream.
552   SendTask(task_queue(), [this, &encoder_config_with_screenshare]() {
553     DestroyVideoSendStreams();
554     CreateVideoSendStream(encoder_config_with_screenshare);
555     SetVideoDegradation(DegradationPreference::BALANCED);
556     GetVideoSendStream()->Start();
557   });
558 
559   // Continue to run test but now with screenshare.
560   test.PerformTest();
561 
562   SendTask(task_queue(), [this]() {
563     Stop();
564     DestroyStreams();
565     send_transport_.reset();
566     receive_transport_.reset();
567     DestroyCalls();
568   });
569 
570   // Verify that stats have been updated for both screenshare and video.
571   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.EndToEndDelayInMs"));
572   EXPECT_METRIC_EQ(
573       1, metrics::NumSamples("WebRTC.Video.Screenshare.EndToEndDelayInMs"));
574   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.EndToEndDelayMaxInMs"));
575   EXPECT_METRIC_EQ(
576       1, metrics::NumSamples("WebRTC.Video.Screenshare.EndToEndDelayMaxInMs"));
577   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
578   EXPECT_METRIC_EQ(
579       1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
580   EXPECT_METRIC_EQ(1,
581                    metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
582   EXPECT_METRIC_EQ(1, metrics::NumSamples(
583                           "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
584 }
585 
TEST_F(StatsEndToEndTest,VerifyNackStats)586 TEST_F(StatsEndToEndTest, VerifyNackStats) {
587   static const int kPacketNumberToDrop = 200;
588   class NackObserver : public test::EndToEndTest {
589    public:
590     explicit NackObserver(TaskQueueBase* task_queue)
591         : EndToEndTest(kLongTimeout), task_queue_(task_queue) {}
592 
593    private:
594     Action OnSendRtp(const uint8_t* packet, size_t length) override {
595       {
596         MutexLock lock(&mutex_);
597         if (++sent_rtp_packets_ == kPacketNumberToDrop) {
598           RtpPacket header;
599           EXPECT_TRUE(header.Parse(packet, length));
600           dropped_rtp_packet_ = header.SequenceNumber();
601           return DROP_PACKET;
602         }
603       }
604       task_queue_->PostTask(
605           SafeTask(task_safety_flag_, [this]() { VerifyStats(); }));
606       return SEND_PACKET;
607     }
608 
609     Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
610       MutexLock lock(&mutex_);
611       test::RtcpPacketParser rtcp_parser;
612       rtcp_parser.Parse(packet, length);
613       const std::vector<uint16_t>& nacks = rtcp_parser.nack()->packet_ids();
614       if (!nacks.empty() && absl::c_linear_search(nacks, dropped_rtp_packet_)) {
615         dropped_rtp_packet_requested_ = true;
616       }
617       return SEND_PACKET;
618     }
619 
620     void VerifyStats() {
621       MutexLock lock(&mutex_);
622       if (!dropped_rtp_packet_requested_)
623         return;
624       int send_stream_nack_packets = 0;
625       int receive_stream_nack_packets = 0;
626       VideoSendStream::Stats stats = send_stream_->GetStats();
627       for (const auto& kv : stats.substreams) {
628         const VideoSendStream::StreamStats& stream_stats = kv.second;
629         send_stream_nack_packets +=
630             stream_stats.rtcp_packet_type_counts.nack_packets;
631       }
632       for (const auto& receive_stream : receive_streams_) {
633         VideoReceiveStreamInterface::Stats stats = receive_stream->GetStats();
634         receive_stream_nack_packets +=
635             stats.rtcp_packet_type_counts.nack_packets;
636       }
637       if (send_stream_nack_packets >= 1 && receive_stream_nack_packets >= 1) {
638         // NACK packet sent on receive stream and received on sent stream.
639         if (MinMetricRunTimePassed())
640           observation_complete_.Set();
641       }
642     }
643 
644     bool MinMetricRunTimePassed() {
645       int64_t now_ms = Clock::GetRealTimeClock()->TimeInMilliseconds();
646       if (!start_runtime_ms_)
647         start_runtime_ms_ = now_ms;
648 
649       int64_t elapsed_sec = (now_ms - *start_runtime_ms_) / 1000;
650       return elapsed_sec > metrics::kMinRunTimeInSeconds;
651     }
652 
653     void ModifyVideoConfigs(
654         VideoSendStream::Config* send_config,
655         std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
656         VideoEncoderConfig* encoder_config) override {
657       send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
658       (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
659     }
660 
661     void OnVideoStreamsCreated(VideoSendStream* send_stream,
662                                const std::vector<VideoReceiveStreamInterface*>&
663                                    receive_streams) override {
664       send_stream_ = send_stream;
665       receive_streams_ = receive_streams;
666     }
667 
668     void OnStreamsStopped() override { task_safety_flag_->SetNotAlive(); }
669 
670     void PerformTest() override {
671       EXPECT_TRUE(Wait()) << "Timed out waiting for packet to be NACKed.";
672     }
673 
674     Mutex mutex_;
675     uint64_t sent_rtp_packets_ RTC_GUARDED_BY(&mutex_) = 0;
676     uint16_t dropped_rtp_packet_ RTC_GUARDED_BY(&mutex_) = 0;
677     bool dropped_rtp_packet_requested_ RTC_GUARDED_BY(&mutex_) = false;
678     std::vector<VideoReceiveStreamInterface*> receive_streams_;
679     VideoSendStream* send_stream_ = nullptr;
680     absl::optional<int64_t> start_runtime_ms_;
681     TaskQueueBase* const task_queue_;
682     rtc::scoped_refptr<PendingTaskSafetyFlag> task_safety_flag_ =
683         PendingTaskSafetyFlag::CreateDetached();
684   } test(task_queue());
685 
686   metrics::Reset();
687   RunBaseTest(&test);
688 
689   EXPECT_METRIC_EQ(
690       1, metrics::NumSamples("WebRTC.Video.UniqueNackRequestsSentInPercent"));
691   EXPECT_METRIC_EQ(1, metrics::NumSamples(
692                           "WebRTC.Video.UniqueNackRequestsReceivedInPercent"));
693   EXPECT_METRIC_GT(metrics::MinSample("WebRTC.Video.NackPacketsSentPerMinute"),
694                    0);
695 }
696 
TEST_F(StatsEndToEndTest,CallReportsRttForSender)697 TEST_F(StatsEndToEndTest, CallReportsRttForSender) {
698   static const int kSendDelayMs = 30;
699   static const int kReceiveDelayMs = 70;
700 
701   std::unique_ptr<test::DirectTransport> sender_transport;
702   std::unique_ptr<test::DirectTransport> receiver_transport;
703 
704   SendTask(task_queue(),
705            [this, &sender_transport, &receiver_transport]() {
706              BuiltInNetworkBehaviorConfig config;
707              config.queue_delay_ms = kSendDelayMs;
708              CreateCalls();
709              sender_transport = std::make_unique<test::DirectTransport>(
710                  task_queue(),
711                  std::make_unique<FakeNetworkPipe>(
712                      Clock::GetRealTimeClock(),
713                      std::make_unique<SimulatedNetwork>(config)),
714                  sender_call_.get(), payload_type_map_);
715              config.queue_delay_ms = kReceiveDelayMs;
716              receiver_transport = std::make_unique<test::DirectTransport>(
717                  task_queue(),
718                  std::make_unique<FakeNetworkPipe>(
719                      Clock::GetRealTimeClock(),
720                      std::make_unique<SimulatedNetwork>(config)),
721                  receiver_call_.get(), payload_type_map_);
722              sender_transport->SetReceiver(receiver_call_->Receiver());
723              receiver_transport->SetReceiver(sender_call_->Receiver());
724 
725              CreateSendConfig(1, 0, 0, sender_transport.get());
726              CreateMatchingReceiveConfigs(receiver_transport.get());
727 
728              CreateVideoStreams();
729              CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
730                                           kDefaultHeight);
731              Start();
732            });
733 
734   int64_t start_time_ms = clock_->TimeInMilliseconds();
735   while (true) {
736     Call::Stats stats;
737     SendTask(task_queue(),
738              [this, &stats]() { stats = sender_call_->GetStats(); });
739     ASSERT_GE(start_time_ms + kDefaultTimeout.ms(),
740               clock_->TimeInMilliseconds())
741         << "No RTT stats before timeout!";
742     if (stats.rtt_ms != -1) {
743       // To avoid failures caused by rounding or minor ntp clock adjustments,
744       // relax expectation by 1ms.
745       constexpr int kAllowedErrorMs = 1;
746       EXPECT_GE(stats.rtt_ms, kSendDelayMs + kReceiveDelayMs - kAllowedErrorMs);
747       break;
748     }
749     SleepMs(10);
750   }
751 
752   SendTask(task_queue(), [this, &sender_transport, &receiver_transport]() {
753     Stop();
754     DestroyStreams();
755     sender_transport.reset();
756     receiver_transport.reset();
757     DestroyCalls();
758   });
759 }
760 }  // namespace webrtc
761