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