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