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