1 /*
2  *  Copyright (c) 2013 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 "video/send_statistics_proxy.h"
12 
13 #include <algorithm>
14 #include <map>
15 #include <memory>
16 #include <string>
17 #include <vector>
18 
19 #include "absl/algorithm/container.h"
20 #include "api/units/timestamp.h"
21 #include "api/video/video_adaptation_reason.h"
22 #include "api/video/video_bitrate_allocation.h"
23 #include "api/video/video_codec_type.h"
24 #include "api/video_codecs/video_codec.h"
25 #include "api/video_codecs/video_encoder_config.h"
26 #include "rtc_base/fake_clock.h"
27 #include "system_wrappers/include/metrics.h"
28 #include "test/field_trial.h"
29 #include "test/gtest.h"
30 
31 namespace webrtc {
32 namespace {
33 const uint32_t kFirstSsrc = 17;
34 const uint32_t kSecondSsrc = 42;
35 const uint32_t kFirstRtxSsrc = 18;
36 const uint32_t kSecondRtxSsrc = 43;
37 const uint32_t kFlexFecSsrc = 55;
38 const int kFpsPeriodicIntervalMs = 2000;
39 const int kWidth = 640;
40 const int kHeight = 480;
41 const int kQpIdx0 = 21;
42 const int kQpIdx1 = 39;
43 const int kRtpClockRateHz = 90000;
__anon22cd38330202() 44 const CodecSpecificInfo kDefaultCodecInfo = []() {
45   CodecSpecificInfo codec_info;
46   codec_info.codecType = kVideoCodecVP8;
47   return codec_info;
48 }();
49 
50 const VideoStreamEncoderObserver::AdaptationSettings kScalingEnabled(true,
51                                                                      true);
52 const VideoStreamEncoderObserver::AdaptationSettings kFramerateScalingDisabled(
53     true,
54     false);
55 const VideoStreamEncoderObserver::AdaptationSettings kResolutionScalingDisabled(
56     false,
57     true);
58 const VideoStreamEncoderObserver::AdaptationSettings kScalingDisabled;
59 }  // namespace
60 
61 class SendStatisticsProxyTest : public ::testing::Test {
62  public:
SendStatisticsProxyTest()63   SendStatisticsProxyTest() : SendStatisticsProxyTest("") {}
SendStatisticsProxyTest(const std::string & field_trials)64   explicit SendStatisticsProxyTest(const std::string& field_trials)
65       : override_field_trials_(field_trials),
66         fake_clock_(1234),
67         config_(GetTestConfig()),
68         avg_delay_ms_(0),
69         max_delay_ms_(0) {}
~SendStatisticsProxyTest()70   virtual ~SendStatisticsProxyTest() {}
71 
72  protected:
SetUp()73   virtual void SetUp() {
74     metrics::Reset();
75     statistics_proxy_.reset(new SendStatisticsProxy(
76         &fake_clock_, GetTestConfig(),
77         VideoEncoderConfig::ContentType::kRealtimeVideo));
78     expected_ = VideoSendStream::Stats();
79     for (const auto& ssrc : config_.rtp.ssrcs) {
80       expected_.substreams[ssrc].type =
81           VideoSendStream::StreamStats::StreamType::kMedia;
82     }
83     for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) {
84       uint32_t ssrc = config_.rtp.rtx.ssrcs[i];
85       expected_.substreams[ssrc].type =
86           VideoSendStream::StreamStats::StreamType::kRtx;
87       expected_.substreams[ssrc].referenced_media_ssrc = config_.rtp.ssrcs[i];
88     }
89   }
90 
GetTestConfig()91   VideoSendStream::Config GetTestConfig() {
92     VideoSendStream::Config config(nullptr);
93     config.rtp.ssrcs.push_back(kFirstSsrc);
94     config.rtp.ssrcs.push_back(kSecondSsrc);
95     config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
96     config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
97     config.rtp.ulpfec.red_payload_type = 17;
98     return config;
99   }
100 
GetTestConfigWithFlexFec()101   VideoSendStream::Config GetTestConfigWithFlexFec() {
102     VideoSendStream::Config config(nullptr);
103     config.rtp.ssrcs.push_back(kFirstSsrc);
104     config.rtp.ssrcs.push_back(kSecondSsrc);
105     config.rtp.rtx.ssrcs.push_back(kFirstRtxSsrc);
106     config.rtp.rtx.ssrcs.push_back(kSecondRtxSsrc);
107     config.rtp.flexfec.payload_type = 50;
108     config.rtp.flexfec.ssrc = kFlexFecSsrc;
109     config.rtp.flexfec.protected_media_ssrcs = {kFirstSsrc};
110     return config;
111   }
112 
GetStreamStats(uint32_t ssrc)113   VideoSendStream::StreamStats GetStreamStats(uint32_t ssrc) {
114     VideoSendStream::Stats stats = statistics_proxy_->GetStats();
115     std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
116         stats.substreams.find(ssrc);
117     EXPECT_NE(it, stats.substreams.end());
118     return it->second;
119   }
120 
UpdateDataCounters(uint32_t ssrc)121   void UpdateDataCounters(uint32_t ssrc) {
122     StreamDataCountersCallback* proxy =
123         static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
124     StreamDataCounters counters;
125     proxy->DataCountersUpdated(counters, ssrc);
126   }
127 
ExpectEqual(VideoSendStream::Stats one,VideoSendStream::Stats other)128   void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
129     EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
130     EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
131     EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps);
132     EXPECT_EQ(one.suspended, other.suspended);
133 
134     EXPECT_EQ(one.substreams.size(), other.substreams.size());
135     for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
136              one.substreams.begin();
137          it != one.substreams.end(); ++it) {
138       std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
139           corresponding_it = other.substreams.find(it->first);
140       ASSERT_TRUE(corresponding_it != other.substreams.end());
141       const VideoSendStream::StreamStats& a = it->second;
142       const VideoSendStream::StreamStats& b = corresponding_it->second;
143 
144       EXPECT_EQ(a.type, b.type);
145       EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames);
146       EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames);
147       EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps);
148       EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
149       EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
150 
151       EXPECT_EQ(a.rtp_stats.transmitted.payload_bytes,
152                 b.rtp_stats.transmitted.payload_bytes);
153       EXPECT_EQ(a.rtp_stats.transmitted.header_bytes,
154                 b.rtp_stats.transmitted.header_bytes);
155       EXPECT_EQ(a.rtp_stats.transmitted.padding_bytes,
156                 b.rtp_stats.transmitted.padding_bytes);
157       EXPECT_EQ(a.rtp_stats.transmitted.packets,
158                 b.rtp_stats.transmitted.packets);
159       EXPECT_EQ(a.rtp_stats.retransmitted.packets,
160                 b.rtp_stats.retransmitted.packets);
161       EXPECT_EQ(a.rtp_stats.fec.packets, b.rtp_stats.fec.packets);
162 
163       EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
164       EXPECT_EQ(a.rtcp_stats.packets_lost, b.rtcp_stats.packets_lost);
165       EXPECT_EQ(a.rtcp_stats.extended_highest_sequence_number,
166                 b.rtcp_stats.extended_highest_sequence_number);
167       EXPECT_EQ(a.rtcp_stats.jitter, b.rtcp_stats.jitter);
168     }
169   }
170 
171   test::ScopedFieldTrials override_field_trials_;
172   SimulatedClock fake_clock_;
173   std::unique_ptr<SendStatisticsProxy> statistics_proxy_;
174   VideoSendStream::Config config_;
175   int avg_delay_ms_;
176   int max_delay_ms_;
177   VideoSendStream::Stats expected_;
178   typedef std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
179       StreamIterator;
180 };
181 
TEST_F(SendStatisticsProxyTest,RtcpStatistics)182 TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
183   RtcpStatisticsCallback* callback = statistics_proxy_.get();
184   for (const auto& ssrc : config_.rtp.ssrcs) {
185     VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
186 
187     // Add statistics with some arbitrary, but unique, numbers.
188     uint32_t offset = ssrc * sizeof(RtcpStatistics);
189     ssrc_stats.rtcp_stats.packets_lost = offset;
190     ssrc_stats.rtcp_stats.extended_highest_sequence_number = offset + 1;
191     ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
192     ssrc_stats.rtcp_stats.jitter = offset + 3;
193     callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
194   }
195   for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
196     VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
197 
198     // Add statistics with some arbitrary, but unique, numbers.
199     uint32_t offset = ssrc * sizeof(RtcpStatistics);
200     ssrc_stats.rtcp_stats.packets_lost = offset;
201     ssrc_stats.rtcp_stats.extended_highest_sequence_number = offset + 1;
202     ssrc_stats.rtcp_stats.fraction_lost = offset + 2;
203     ssrc_stats.rtcp_stats.jitter = offset + 3;
204     callback->StatisticsUpdated(ssrc_stats.rtcp_stats, ssrc);
205   }
206   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
207   ExpectEqual(expected_, stats);
208 }
209 
TEST_F(SendStatisticsProxyTest,Suspended)210 TEST_F(SendStatisticsProxyTest, Suspended) {
211   // Verify that the value is false by default.
212   EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
213 
214   // Verify that we can set it to true.
215   statistics_proxy_->OnSuspendChange(true);
216   EXPECT_TRUE(statistics_proxy_->GetStats().suspended);
217 
218   // Verify that we can set it back to false again.
219   statistics_proxy_->OnSuspendChange(false);
220   EXPECT_FALSE(statistics_proxy_->GetStats().suspended);
221 }
222 
TEST_F(SendStatisticsProxyTest,FrameCounts)223 TEST_F(SendStatisticsProxyTest, FrameCounts) {
224   FrameCountObserver* observer = statistics_proxy_.get();
225   for (const auto& ssrc : config_.rtp.ssrcs) {
226     // Add statistics with some arbitrary, but unique, numbers.
227     VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
228     uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
229     FrameCounts frame_counts;
230     frame_counts.key_frames = offset;
231     frame_counts.delta_frames = offset + 1;
232     stats.frame_counts = frame_counts;
233     observer->FrameCountUpdated(frame_counts, ssrc);
234   }
235   for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
236     // Add statistics with some arbitrary, but unique, numbers.
237     VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
238     uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
239     FrameCounts frame_counts;
240     frame_counts.key_frames = offset;
241     frame_counts.delta_frames = offset + 1;
242     stats.frame_counts = frame_counts;
243     observer->FrameCountUpdated(frame_counts, ssrc);
244   }
245 
246   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
247   ExpectEqual(expected_, stats);
248 }
249 
TEST_F(SendStatisticsProxyTest,DataCounters)250 TEST_F(SendStatisticsProxyTest, DataCounters) {
251   StreamDataCountersCallback* callback = statistics_proxy_.get();
252   for (const auto& ssrc : config_.rtp.ssrcs) {
253     StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
254     // Add statistics with some arbitrary, but unique, numbers.
255     size_t offset = ssrc * sizeof(StreamDataCounters);
256     uint32_t offset_uint32 = static_cast<uint32_t>(offset);
257     counters.transmitted.payload_bytes = offset;
258     counters.transmitted.header_bytes = offset + 1;
259     counters.fec.packets = offset_uint32 + 2;
260     counters.transmitted.padding_bytes = offset + 3;
261     counters.retransmitted.packets = offset_uint32 + 4;
262     counters.transmitted.packets = offset_uint32 + 5;
263     callback->DataCountersUpdated(counters, ssrc);
264   }
265   for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
266     StreamDataCounters& counters = expected_.substreams[ssrc].rtp_stats;
267     // Add statistics with some arbitrary, but unique, numbers.
268     size_t offset = ssrc * sizeof(StreamDataCounters);
269     uint32_t offset_uint32 = static_cast<uint32_t>(offset);
270     counters.transmitted.payload_bytes = offset;
271     counters.transmitted.header_bytes = offset + 1;
272     counters.fec.packets = offset_uint32 + 2;
273     counters.transmitted.padding_bytes = offset + 3;
274     counters.retransmitted.packets = offset_uint32 + 4;
275     counters.transmitted.packets = offset_uint32 + 5;
276     callback->DataCountersUpdated(counters, ssrc);
277   }
278 
279   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
280   ExpectEqual(expected_, stats);
281 }
282 
TEST_F(SendStatisticsProxyTest,Bitrate)283 TEST_F(SendStatisticsProxyTest, Bitrate) {
284   BitrateStatisticsObserver* observer = statistics_proxy_.get();
285   for (const auto& ssrc : config_.rtp.ssrcs) {
286     uint32_t total;
287     uint32_t retransmit;
288     // Use ssrc as bitrate_bps to get a unique value for each stream.
289     total = ssrc;
290     retransmit = ssrc + 1;
291     observer->Notify(total, retransmit, ssrc);
292     expected_.substreams[ssrc].total_bitrate_bps = total;
293     expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
294   }
295   for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
296     uint32_t total;
297     uint32_t retransmit;
298     // Use ssrc as bitrate_bps to get a unique value for each stream.
299     total = ssrc;
300     retransmit = ssrc + 1;
301     observer->Notify(total, retransmit, ssrc);
302     expected_.substreams[ssrc].total_bitrate_bps = total;
303     expected_.substreams[ssrc].retransmit_bitrate_bps = retransmit;
304   }
305 
306   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
307   ExpectEqual(expected_, stats);
308 }
309 
TEST_F(SendStatisticsProxyTest,SendSideDelay)310 TEST_F(SendStatisticsProxyTest, SendSideDelay) {
311   SendSideDelayObserver* observer = statistics_proxy_.get();
312   for (const auto& ssrc : config_.rtp.ssrcs) {
313     // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
314     // stream.
315     int avg_delay_ms = ssrc;
316     int max_delay_ms = ssrc + 1;
317     uint64_t total_packet_send_delay_ms = ssrc + 2;
318     observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms,
319                                    total_packet_send_delay_ms, ssrc);
320     expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
321     expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
322     expected_.substreams[ssrc].total_packet_send_delay_ms =
323         total_packet_send_delay_ms;
324   }
325   for (const auto& ssrc : config_.rtp.rtx.ssrcs) {
326     // Use ssrc as avg_delay_ms and max_delay_ms to get a unique value for each
327     // stream.
328     int avg_delay_ms = ssrc;
329     int max_delay_ms = ssrc + 1;
330     uint64_t total_packet_send_delay_ms = ssrc + 2;
331     observer->SendSideDelayUpdated(avg_delay_ms, max_delay_ms,
332                                    total_packet_send_delay_ms, ssrc);
333     expected_.substreams[ssrc].avg_delay_ms = avg_delay_ms;
334     expected_.substreams[ssrc].max_delay_ms = max_delay_ms;
335     expected_.substreams[ssrc].total_packet_send_delay_ms =
336         total_packet_send_delay_ms;
337   }
338   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
339   ExpectEqual(expected_, stats);
340 }
341 
TEST_F(SendStatisticsProxyTest,OnEncodedFrameTimeMeasured)342 TEST_F(SendStatisticsProxyTest, OnEncodedFrameTimeMeasured) {
343   const int kEncodeTimeMs = 11;
344   int encode_usage_percent = 80;
345   statistics_proxy_->OnEncodedFrameTimeMeasured(kEncodeTimeMs,
346                                                 encode_usage_percent);
347 
348   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
349   EXPECT_EQ(kEncodeTimeMs, stats.avg_encode_time_ms);
350   EXPECT_EQ(encode_usage_percent, stats.encode_usage_percent);
351 }
352 
TEST_F(SendStatisticsProxyTest,TotalEncodeTimeIncreasesPerFrameMeasured)353 TEST_F(SendStatisticsProxyTest, TotalEncodeTimeIncreasesPerFrameMeasured) {
354   const int kEncodeUsagePercent = 0;  // Don't care for this test.
355   EXPECT_EQ(0u, statistics_proxy_->GetStats().total_encode_time_ms);
356   statistics_proxy_->OnEncodedFrameTimeMeasured(10, kEncodeUsagePercent);
357   EXPECT_EQ(10u, statistics_proxy_->GetStats().total_encode_time_ms);
358   statistics_proxy_->OnEncodedFrameTimeMeasured(20, kEncodeUsagePercent);
359   EXPECT_EQ(30u, statistics_proxy_->GetStats().total_encode_time_ms);
360 }
361 
TEST_F(SendStatisticsProxyTest,OnSendEncodedImageIncreasesFramesEncoded)362 TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesFramesEncoded) {
363   EncodedImage encoded_image;
364   CodecSpecificInfo codec_info;
365   EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_encoded);
366   for (uint32_t i = 1; i <= 3; ++i) {
367     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
368     EXPECT_EQ(i, statistics_proxy_->GetStats().frames_encoded);
369   }
370 }
371 
TEST_F(SendStatisticsProxyTest,OnSendEncodedImageIncreasesQpSum)372 TEST_F(SendStatisticsProxyTest, OnSendEncodedImageIncreasesQpSum) {
373   EncodedImage encoded_image;
374   CodecSpecificInfo codec_info;
375   auto ssrc = config_.rtp.ssrcs[0];
376   EXPECT_EQ(absl::nullopt,
377             statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
378   encoded_image.qp_ = 3;
379   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
380   EXPECT_EQ(3u, statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
381   encoded_image.qp_ = 127;
382   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
383   EXPECT_EQ(130u, statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
384 }
385 
TEST_F(SendStatisticsProxyTest,OnSendEncodedImageWithoutQpQpSumWontExist)386 TEST_F(SendStatisticsProxyTest, OnSendEncodedImageWithoutQpQpSumWontExist) {
387   EncodedImage encoded_image;
388   CodecSpecificInfo codec_info;
389   auto ssrc = config_.rtp.ssrcs[0];
390   encoded_image.qp_ = -1;
391   EXPECT_EQ(absl::nullopt,
392             statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
393   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
394   EXPECT_EQ(absl::nullopt,
395             statistics_proxy_->GetStats().substreams[ssrc].qp_sum);
396 }
397 
TEST_F(SendStatisticsProxyTest,TotalEncodedBytesTargetFirstFrame)398 TEST_F(SendStatisticsProxyTest, TotalEncodedBytesTargetFirstFrame) {
399   const uint32_t kTargetBytesPerSecond = 100000;
400   statistics_proxy_->OnSetEncoderTargetRate(kTargetBytesPerSecond * 8);
401   EXPECT_EQ(0u, statistics_proxy_->GetStats().total_encoded_bytes_target);
402 
403   EncodedImage encoded_image;
404   statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
405   // On the first frame we don't know the frame rate yet, calculation yields
406   // zero. Our estimate assumes at least 1 FPS, so we expect the frame size to
407   // increment by a full |kTargetBytesPerSecond|.
408   EXPECT_EQ(kTargetBytesPerSecond,
409             statistics_proxy_->GetStats().total_encoded_bytes_target);
410 }
411 
TEST_F(SendStatisticsProxyTest,TotalEncodedBytesTargetIncrementsBasedOnFrameRate)412 TEST_F(SendStatisticsProxyTest,
413        TotalEncodedBytesTargetIncrementsBasedOnFrameRate) {
414   const uint32_t kTargetBytesPerSecond = 100000;
415   const int kInterframeDelayMs = 100;
416 
417   // SendStatisticsProxy uses a RateTracker internally. SendStatisticsProxy uses
418   // |fake_clock_| for testing, but the RateTracker relies on a global clock.
419   // This test relies on rtc::ScopedFakeClock to synchronize these two clocks.
420   // TODO(https://crbug.com/webrtc/10640): When the RateTracker uses a Clock
421   // this test can stop relying on rtc::ScopedFakeClock.
422   rtc::ScopedFakeClock fake_global_clock;
423   fake_global_clock.SetTime(
424       Timestamp::Millis(fake_clock_.TimeInMilliseconds()));
425 
426   statistics_proxy_->OnSetEncoderTargetRate(kTargetBytesPerSecond * 8);
427   EncodedImage encoded_image;
428 
429   // First frame
430   statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
431   uint64_t first_total_encoded_bytes_target =
432       statistics_proxy_->GetStats().total_encoded_bytes_target;
433   // Second frame
434   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs);
435   fake_global_clock.SetTime(
436       Timestamp::Millis(fake_clock_.TimeInMilliseconds()));
437   encoded_image.SetTimestamp(encoded_image.Timestamp() +
438                              90 * kInterframeDelayMs);
439   statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
440 
441   auto stats = statistics_proxy_->GetStats();
442   // By the time the second frame arrives, one frame has previously arrived
443   // during a |kInterframeDelayMs| interval. The estimated encode frame rate at
444   // the second frame's arrival should be 10 FPS.
445   uint64_t delta_encoded_bytes_target =
446       stats.total_encoded_bytes_target - first_total_encoded_bytes_target;
447   EXPECT_EQ(kTargetBytesPerSecond / 10, delta_encoded_bytes_target);
448 }
449 
TEST_F(SendStatisticsProxyTest,EncodeFrameRateInSubStream)450 TEST_F(SendStatisticsProxyTest, EncodeFrameRateInSubStream) {
451   const int kInterframeDelayMs = 100;
452   auto ssrc = config_.rtp.ssrcs[0];
453   rtc::ScopedFakeClock fake_global_clock;
454   fake_global_clock.SetTime(
455       Timestamp::Millis(fake_clock_.TimeInMilliseconds()));
456 
457   EncodedImage encoded_image;
458 
459   // First frame
460   statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
461   // Second frame
462   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs);
463   fake_global_clock.SetTime(
464       Timestamp::Millis(fake_clock_.TimeInMilliseconds()));
465   encoded_image.SetTimestamp(encoded_image.Timestamp() +
466                              90 * kInterframeDelayMs);
467   statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
468 
469   auto stats = statistics_proxy_->GetStats();
470   EXPECT_EQ(stats.substreams[ssrc].encode_frame_rate, 10);
471 }
472 
TEST_F(SendStatisticsProxyTest,GetCpuAdaptationStats)473 TEST_F(SendStatisticsProxyTest, GetCpuAdaptationStats) {
474   VideoAdaptationCounters cpu_counts;
475   VideoAdaptationCounters quality_counts;
476   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
477   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
478   cpu_counts.fps_adaptations = 1;
479   cpu_counts.resolution_adaptations = 0;
480   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
481   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
482                                          cpu_counts, quality_counts);
483   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
484   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
485   cpu_counts.fps_adaptations = 0;
486   cpu_counts.resolution_adaptations = 1;
487   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
488                                          cpu_counts, quality_counts);
489   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
490   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
491   cpu_counts.fps_adaptations = 1;
492   statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
493                                               kResolutionScalingDisabled);
494   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
495                                          cpu_counts, quality_counts);
496   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
497   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
498   statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
499                                               kScalingDisabled);
500   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
501                                          cpu_counts, quality_counts);
502   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
503   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
504 }
505 
TEST_F(SendStatisticsProxyTest,GetQualityAdaptationStats)506 TEST_F(SendStatisticsProxyTest, GetQualityAdaptationStats) {
507   VideoAdaptationCounters cpu_counts;
508   VideoAdaptationCounters quality_counts;
509   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
510   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
511   quality_counts.fps_adaptations = 1;
512   quality_counts.resolution_adaptations = 0;
513   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
514   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
515                                          cpu_counts, quality_counts);
516   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
517   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
518   quality_counts.fps_adaptations = 0;
519   quality_counts.resolution_adaptations = 1;
520   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
521                                          cpu_counts, quality_counts);
522   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
523   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
524   quality_counts.fps_adaptations = 1;
525   statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
526                                               kResolutionScalingDisabled);
527   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
528                                          cpu_counts, quality_counts);
529   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
530   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
531   statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
532                                               kScalingDisabled);
533   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
534                                          cpu_counts, quality_counts);
535   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
536   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
537 }
538 
TEST_F(SendStatisticsProxyTest,GetStatsReportsCpuAdaptChanges)539 TEST_F(SendStatisticsProxyTest, GetStatsReportsCpuAdaptChanges) {
540   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
541   VideoAdaptationCounters cpu_counts;
542   VideoAdaptationCounters quality_counts;
543   EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
544 
545   cpu_counts.resolution_adaptations = 1;
546   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
547                                          cpu_counts, quality_counts);
548   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
549   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
550   EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
551 
552   cpu_counts.resolution_adaptations = 2;
553   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
554                                          cpu_counts, quality_counts);
555   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
556   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
557   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
558   EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
559 }
560 
TEST_F(SendStatisticsProxyTest,GetStatsReportsQualityAdaptChanges)561 TEST_F(SendStatisticsProxyTest, GetStatsReportsQualityAdaptChanges) {
562   VideoAdaptationCounters cpu_counts;
563   VideoAdaptationCounters quality_counts;
564   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
565   EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
566 
567   quality_counts.fps_adaptations = 1;
568   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
569                                          cpu_counts, quality_counts);
570   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
571   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
572   EXPECT_EQ(1, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
573 
574   quality_counts.fps_adaptations = 0;
575   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
576                                          cpu_counts, quality_counts);
577   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
578   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
579   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
580   EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
581 }
582 
TEST_F(SendStatisticsProxyTest,TestAdaptationStatisticsMasking)583 TEST_F(SendStatisticsProxyTest, TestAdaptationStatisticsMasking) {
584   VideoAdaptationCounters cpu_counts;
585   VideoAdaptationCounters quality_counts;
586   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
587   EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
588   EXPECT_EQ(0, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
589 
590   quality_counts.resolution_adaptations = 1;
591   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
592                                          cpu_counts, quality_counts);
593   quality_counts.fps_adaptations = 1;
594   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
595                                          cpu_counts, quality_counts);
596   cpu_counts.resolution_adaptations = 1;
597   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
598                                          cpu_counts, quality_counts);
599   cpu_counts.fps_adaptations = 1;
600   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
601                                          cpu_counts, quality_counts);
602   // We have 1 fps and resolution reduction for both cpu and quality
603   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
604   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
605   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
606   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
607   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
608   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
609 
610   // Disable quality scaling. Expect quality scaling not limited.
611   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
612                                               kScalingDisabled);
613   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
614   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
615   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
616   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
617   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
618   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
619 
620   // Disable framerate scaling.
621   statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
622                                               kFramerateScalingDisabled);
623   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
624   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
625   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_framerate);
626   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
627   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
628   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
629 
630   // Disable resolution scaling.
631   statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
632                                               kResolutionScalingDisabled);
633   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
634   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
635   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
636   EXPECT_FALSE(statistics_proxy_->GetStats().cpu_limited_resolution);
637   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
638   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
639 
640   // Enable all
641   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
642   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
643   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
644   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_framerate);
645   EXPECT_TRUE(statistics_proxy_->GetStats().cpu_limited_resolution);
646   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_quality_adapt_changes);
647   EXPECT_EQ(2, statistics_proxy_->GetStats().number_of_cpu_adapt_changes);
648 }
649 
TEST_F(SendStatisticsProxyTest,AdaptChangesNotReported_AdaptationNotEnabled)650 TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_AdaptationNotEnabled) {
651   // First RTP packet sent.
652   UpdateDataCounters(kFirstSsrc);
653   // Min runtime has passed.
654   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
655   statistics_proxy_.reset();
656   EXPECT_METRIC_EQ(
657       0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
658   EXPECT_METRIC_EQ(
659       0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
660 }
661 
TEST_F(SendStatisticsProxyTest,AdaptChangesNotReported_MinRuntimeNotPassed)662 TEST_F(SendStatisticsProxyTest, AdaptChangesNotReported_MinRuntimeNotPassed) {
663   // First RTP packet sent.
664   UpdateDataCounters(kFirstSsrc);
665   // Enable adaptation.
666   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
667   // Min runtime has not passed.
668   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
669   statistics_proxy_.reset();
670   EXPECT_METRIC_EQ(
671       0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
672   EXPECT_METRIC_EQ(
673       0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
674 }
675 
TEST_F(SendStatisticsProxyTest,ZeroAdaptChangesReported)676 TEST_F(SendStatisticsProxyTest, ZeroAdaptChangesReported) {
677   // First RTP packet sent.
678   UpdateDataCounters(kFirstSsrc);
679   // Enable adaptation.
680   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
681   // Min runtime has passed.
682   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
683   statistics_proxy_.reset();
684   EXPECT_METRIC_EQ(
685       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
686   EXPECT_METRIC_EQ(
687       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 0));
688   EXPECT_METRIC_EQ(
689       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
690   EXPECT_METRIC_EQ(
691       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 0));
692 }
693 
TEST_F(SendStatisticsProxyTest,CpuAdaptChangesReported)694 TEST_F(SendStatisticsProxyTest, CpuAdaptChangesReported) {
695   // First RTP packet sent.
696   UpdateDataCounters(kFirstSsrc);
697   // Enable adaptation.
698   VideoAdaptationCounters cpu_counts;
699   VideoAdaptationCounters quality_counts;
700   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
701   // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
702   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
703                                          cpu_counts, quality_counts);
704   fake_clock_.AdvanceTimeMilliseconds(10000);
705   statistics_proxy_.reset();
706   EXPECT_METRIC_EQ(
707       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
708   EXPECT_METRIC_EQ(
709       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 6));
710 }
711 
TEST_F(SendStatisticsProxyTest,ExcludesInitialQualityAdaptDownChange)712 TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownChange) {
713   // First RTP packet sent.
714   UpdateDataCounters(kFirstSsrc);
715   // Enable adaptation.
716   VideoAdaptationCounters cpu_counts;
717   VideoAdaptationCounters quality_counts;
718   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
719   // Adapt changes: 1 (1 initial) = 0, elapsed time: 10 sec => 0 per minute.
720   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
721                                          cpu_counts, quality_counts);
722   statistics_proxy_->OnInitialQualityResolutionAdaptDown();
723   fake_clock_.AdvanceTimeMilliseconds(10000);
724   statistics_proxy_.reset();
725   EXPECT_METRIC_EQ(
726       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
727   EXPECT_METRIC_EQ(
728       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 0));
729 }
730 
TEST_F(SendStatisticsProxyTest,ExcludesInitialQualityAdaptDownChanges)731 TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownChanges) {
732   // First RTP packet sent.
733   UpdateDataCounters(kFirstSsrc);
734   // Enable adaptation.
735   VideoAdaptationCounters cpu_counts;
736   VideoAdaptationCounters quality_counts;
737   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
738   // Adapt changes: 3 (2 initial) = 1, elapsed time: 10 sec => 6 per minute.
739   quality_counts.resolution_adaptations = 1;
740   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
741                                          cpu_counts, quality_counts);
742   statistics_proxy_->OnInitialQualityResolutionAdaptDown();
743   quality_counts.resolution_adaptations = 2;
744   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
745                                          cpu_counts, quality_counts);
746   statistics_proxy_->OnInitialQualityResolutionAdaptDown();
747   quality_counts.resolution_adaptations = 3;
748   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
749                                          cpu_counts, quality_counts);
750   fake_clock_.AdvanceTimeMilliseconds(10000);
751   statistics_proxy_.reset();
752   EXPECT_METRIC_EQ(
753       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
754   EXPECT_METRIC_EQ(
755       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
756 }
757 
TEST_F(SendStatisticsProxyTest,InitialQualityAdaptChangesNotExcludedOnError)758 TEST_F(SendStatisticsProxyTest, InitialQualityAdaptChangesNotExcludedOnError) {
759   // First RTP packet sent.
760   UpdateDataCounters(kFirstSsrc);
761   // Enable adaptation.
762   VideoAdaptationCounters cpu_counts;
763   VideoAdaptationCounters quality_counts;
764   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
765   // Adapt changes: 1 (2 initial) = 1, elapsed time: 10 sec => 6 per minute.
766   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
767                                          cpu_counts, quality_counts);
768   statistics_proxy_->OnInitialQualityResolutionAdaptDown();
769   statistics_proxy_->OnInitialQualityResolutionAdaptDown();
770   fake_clock_.AdvanceTimeMilliseconds(10000);
771   statistics_proxy_.reset();
772   EXPECT_METRIC_EQ(
773       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
774   EXPECT_METRIC_EQ(
775       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
776 }
777 
TEST_F(SendStatisticsProxyTest,ExcludesInitialQualityAdaptDownAndUpChanges)778 TEST_F(SendStatisticsProxyTest, ExcludesInitialQualityAdaptDownAndUpChanges) {
779   // First RTP packet sent.
780   UpdateDataCounters(kFirstSsrc);
781   // Enable adaptation.
782   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
783   VideoAdaptationCounters cpu_counts;
784   VideoAdaptationCounters quality_counts;
785   statistics_proxy_->ClearAdaptationStats();
786   // Adapt changes: 8 (4 initial) = 4, elapsed time: 10 sec => 24 per minute.
787   quality_counts.resolution_adaptations = 1;
788   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
789                                          cpu_counts, quality_counts);
790   statistics_proxy_->OnInitialQualityResolutionAdaptDown();
791   quality_counts.resolution_adaptations = 2;
792   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
793                                          cpu_counts, quality_counts);
794   statistics_proxy_->OnInitialQualityResolutionAdaptDown();
795   quality_counts.resolution_adaptations = 3;
796   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
797                                          cpu_counts, quality_counts);
798   quality_counts.fps_adaptations = 1;
799   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
800                                          cpu_counts, quality_counts);
801   quality_counts.fps_adaptations = 0;
802   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
803                                          cpu_counts, quality_counts);
804   quality_counts.resolution_adaptations = 2;  // Initial resolution up.
805   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
806                                          cpu_counts, quality_counts);
807   quality_counts.resolution_adaptations = 1;  // Initial resolution up.
808   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
809                                          cpu_counts, quality_counts);
810   quality_counts.resolution_adaptations = 0;
811   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
812                                          cpu_counts, quality_counts);
813 
814   fake_clock_.AdvanceTimeMilliseconds(10000);
815   statistics_proxy_.reset();
816   EXPECT_METRIC_EQ(
817       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
818   EXPECT_METRIC_EQ(
819       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 24));
820 }
821 
TEST_F(SendStatisticsProxyTest,AdaptChangesStatsExcludesDisabledTime)822 TEST_F(SendStatisticsProxyTest, AdaptChangesStatsExcludesDisabledTime) {
823   // First RTP packet sent.
824   UpdateDataCounters(kFirstSsrc);
825 
826   // Disable quality adaptation.
827   VideoAdaptationCounters cpu_counts;
828   VideoAdaptationCounters quality_counts;
829   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
830                                               kScalingDisabled);
831   fake_clock_.AdvanceTimeMilliseconds(10000);
832 
833   // Enable quality adaptation.
834   // Adapt changes: 2, elapsed time: 20 sec.
835   quality_counts.fps_adaptations = 0;
836   statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
837                                               kResolutionScalingDisabled);
838   fake_clock_.AdvanceTimeMilliseconds(5000);
839   statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
840                                               kResolutionScalingDisabled);
841   fake_clock_.AdvanceTimeMilliseconds(9000);
842   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
843                                          cpu_counts, quality_counts);
844   fake_clock_.AdvanceTimeMilliseconds(6000);
845   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
846                                          cpu_counts, quality_counts);
847 
848   // Disable quality adaptation.
849   statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
850                                               kScalingDisabled);
851   fake_clock_.AdvanceTimeMilliseconds(30000);
852 
853   // Enable quality adaptation.
854   // Adapt changes: 1, elapsed time: 10 sec.
855   quality_counts.resolution_adaptations = 0;
856   statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
857                                               kFramerateScalingDisabled);
858   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
859                                          cpu_counts, quality_counts);
860   fake_clock_.AdvanceTimeMilliseconds(10000);
861 
862   // Disable quality adaptation.
863   statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
864                                               kScalingDisabled);
865   fake_clock_.AdvanceTimeMilliseconds(5000);
866   statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
867                                               kScalingDisabled);
868   fake_clock_.AdvanceTimeMilliseconds(20000);
869 
870   // Adapt changes: 3, elapsed time: 30 sec => 6 per minute.
871   statistics_proxy_.reset();
872   EXPECT_METRIC_EQ(
873       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
874   EXPECT_METRIC_EQ(
875       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
876 }
877 
TEST_F(SendStatisticsProxyTest,AdaptChangesNotReported_ScalingNotEnabledVideoResumed)878 TEST_F(SendStatisticsProxyTest,
879        AdaptChangesNotReported_ScalingNotEnabledVideoResumed) {
880   // First RTP packet sent.
881   UpdateDataCounters(kFirstSsrc);
882 
883   // Suspend and resume video.
884   statistics_proxy_->OnSuspendChange(true);
885   fake_clock_.AdvanceTimeMilliseconds(5000);
886   statistics_proxy_->OnSuspendChange(false);
887 
888   // Min runtime has passed but scaling not enabled.
889   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
890   statistics_proxy_.reset();
891   EXPECT_METRIC_EQ(
892       0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
893   EXPECT_METRIC_EQ(
894       0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
895 }
896 
TEST_F(SendStatisticsProxyTest,QualityAdaptChangesStatsExcludesSuspendedTime)897 TEST_F(SendStatisticsProxyTest, QualityAdaptChangesStatsExcludesSuspendedTime) {
898   // First RTP packet sent.
899   UpdateDataCounters(kFirstSsrc);
900 
901   // Enable adaptation.
902   VideoAdaptationCounters cpu_counts;
903   VideoAdaptationCounters quality_counts;
904   // Adapt changes: 2, elapsed time: 20 sec.
905   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
906   fake_clock_.AdvanceTimeMilliseconds(20000);
907   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
908                                          cpu_counts, quality_counts);
909   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
910                                          cpu_counts, quality_counts);
911 
912   // Suspend and resume video.
913   statistics_proxy_->OnSuspendChange(true);
914   fake_clock_.AdvanceTimeMilliseconds(30000);
915   statistics_proxy_->OnSuspendChange(false);
916 
917   // Adapt changes: 1, elapsed time: 10 sec.
918   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
919                                          cpu_counts, quality_counts);
920   fake_clock_.AdvanceTimeMilliseconds(10000);
921 
922   // Adapt changes: 3, elapsed time: 30 sec => 6 per minute.
923   statistics_proxy_.reset();
924   EXPECT_METRIC_EQ(
925       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
926   EXPECT_METRIC_EQ(
927       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
928 }
929 
TEST_F(SendStatisticsProxyTest,CpuAdaptChangesStatsExcludesSuspendedTime)930 TEST_F(SendStatisticsProxyTest, CpuAdaptChangesStatsExcludesSuspendedTime) {
931   // First RTP packet sent.
932   UpdateDataCounters(kFirstSsrc);
933 
934   // Video not suspended.
935   statistics_proxy_->OnSuspendChange(false);
936   fake_clock_.AdvanceTimeMilliseconds(30000);
937 
938   // Enable adaptation.
939   VideoAdaptationCounters cpu_counts;
940   VideoAdaptationCounters quality_counts;
941   // Adapt changes: 1, elapsed time: 20 sec.
942   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
943   fake_clock_.AdvanceTimeMilliseconds(10000);
944   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
945                                          cpu_counts, quality_counts);
946 
947   // Video not suspended, stats time already started.
948   statistics_proxy_->OnSuspendChange(false);
949   fake_clock_.AdvanceTimeMilliseconds(10000);
950 
951   // Disable adaptation.
952   statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
953                                               kScalingDisabled);
954   fake_clock_.AdvanceTimeMilliseconds(30000);
955 
956   // Suspend and resume video, stats time not started when scaling not enabled.
957   statistics_proxy_->OnSuspendChange(true);
958   fake_clock_.AdvanceTimeMilliseconds(30000);
959   statistics_proxy_->OnSuspendChange(false);
960   fake_clock_.AdvanceTimeMilliseconds(30000);
961 
962   // Enable adaptation.
963   // Adapt changes: 1, elapsed time: 10 sec.
964   cpu_counts.fps_adaptations = 0;
965   cpu_counts.resolution_adaptations = 0;
966   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
967   fake_clock_.AdvanceTimeMilliseconds(10000);
968   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
969                                          cpu_counts, quality_counts);
970 
971   // Adapt changes: 2, elapsed time: 30 sec => 4 per minute.
972   statistics_proxy_.reset();
973   EXPECT_METRIC_EQ(
974       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
975   EXPECT_METRIC_EQ(
976       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 4));
977 }
978 
TEST_F(SendStatisticsProxyTest,AdaptChangesStatsNotStartedIfVideoSuspended)979 TEST_F(SendStatisticsProxyTest, AdaptChangesStatsNotStartedIfVideoSuspended) {
980   // First RTP packet sent.
981   UpdateDataCounters(kFirstSsrc);
982 
983   // Video suspended.
984   statistics_proxy_->OnSuspendChange(true);
985 
986   // Enable adaptation, stats time not started when suspended.
987   VideoAdaptationCounters cpu_counts;
988   VideoAdaptationCounters quality_counts;
989   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
990   fake_clock_.AdvanceTimeMilliseconds(10000);
991 
992   // Resume video, stats time started.
993   // Adapt changes: 1, elapsed time: 10 sec.
994   statistics_proxy_->OnSuspendChange(false);
995   fake_clock_.AdvanceTimeMilliseconds(10000);
996   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
997                                          cpu_counts, quality_counts);
998 
999   // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
1000   statistics_proxy_.reset();
1001   EXPECT_METRIC_EQ(
1002       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
1003   EXPECT_METRIC_EQ(
1004       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 6));
1005 }
1006 
TEST_F(SendStatisticsProxyTest,AdaptChangesStatsRestartsOnFirstSentPacket)1007 TEST_F(SendStatisticsProxyTest, AdaptChangesStatsRestartsOnFirstSentPacket) {
1008   // Send first packet, adaptation enabled.
1009   // Elapsed time before first packet is sent should be excluded.
1010   VideoAdaptationCounters cpu_counts;
1011   VideoAdaptationCounters quality_counts;
1012   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1013   fake_clock_.AdvanceTimeMilliseconds(10000);
1014   UpdateDataCounters(kFirstSsrc);
1015 
1016   // Adapt changes: 1, elapsed time: 10 sec.
1017   fake_clock_.AdvanceTimeMilliseconds(10000);
1018   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
1019                                          cpu_counts, quality_counts);
1020   UpdateDataCounters(kFirstSsrc);
1021 
1022   // Adapt changes: 1, elapsed time: 10 sec => 6 per minute.
1023   statistics_proxy_.reset();
1024   EXPECT_METRIC_EQ(
1025       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
1026   EXPECT_METRIC_EQ(
1027       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Quality", 6));
1028 }
1029 
TEST_F(SendStatisticsProxyTest,AdaptChangesStatsStartedAfterFirstSentPacket)1030 TEST_F(SendStatisticsProxyTest, AdaptChangesStatsStartedAfterFirstSentPacket) {
1031   // Enable and disable adaptation.
1032   VideoAdaptationCounters cpu_counts;
1033   VideoAdaptationCounters quality_counts;
1034   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1035   fake_clock_.AdvanceTimeMilliseconds(60000);
1036   statistics_proxy_->UpdateAdaptationSettings(kScalingDisabled,
1037                                               kScalingDisabled);
1038 
1039   // Send first packet, scaling disabled.
1040   // Elapsed time before first packet is sent should be excluded.
1041   UpdateDataCounters(kFirstSsrc);
1042   fake_clock_.AdvanceTimeMilliseconds(60000);
1043 
1044   // Enable adaptation.
1045   cpu_counts.resolution_adaptations = 0;
1046   statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
1047                                               kScalingDisabled);
1048   fake_clock_.AdvanceTimeMilliseconds(10000);
1049   UpdateDataCounters(kFirstSsrc);
1050 
1051   // Adapt changes: 1, elapsed time: 20 sec.
1052   fake_clock_.AdvanceTimeMilliseconds(10000);
1053   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1054                                          cpu_counts, quality_counts);
1055 
1056   // Adapt changes: 1, elapsed time: 20 sec => 3 per minute.
1057   statistics_proxy_.reset();
1058   EXPECT_METRIC_EQ(
1059       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
1060   EXPECT_METRIC_EQ(
1061       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 3));
1062 }
1063 
TEST_F(SendStatisticsProxyTest,AdaptChangesReportedAfterContentSwitch)1064 TEST_F(SendStatisticsProxyTest, AdaptChangesReportedAfterContentSwitch) {
1065   // First RTP packet sent, cpu adaptation enabled.
1066   UpdateDataCounters(kFirstSsrc);
1067   VideoAdaptationCounters cpu_counts;
1068   VideoAdaptationCounters quality_counts;
1069   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
1070                                               kScalingDisabled);
1071 
1072   // Adapt changes: 2, elapsed time: 15 sec => 8 per minute.
1073   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1074                                          cpu_counts, quality_counts);
1075   fake_clock_.AdvanceTimeMilliseconds(6000);
1076   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1077                                          cpu_counts, quality_counts);
1078   fake_clock_.AdvanceTimeMilliseconds(9000);
1079 
1080   // Switch content type, real-time stats should be updated.
1081   VideoEncoderConfig config;
1082   config.content_type = VideoEncoderConfig::ContentType::kScreen;
1083   statistics_proxy_->OnEncoderReconfigured(config, {});
1084   EXPECT_METRIC_EQ(
1085       1, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Cpu"));
1086   EXPECT_METRIC_EQ(
1087       1, metrics::NumEvents("WebRTC.Video.AdaptChangesPerMinute.Cpu", 8));
1088   EXPECT_METRIC_EQ(
1089       0, metrics::NumSamples("WebRTC.Video.AdaptChangesPerMinute.Quality"));
1090 
1091   // First RTP packet sent, scaling enabled.
1092   UpdateDataCounters(kFirstSsrc);
1093   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled,
1094                                               kScalingDisabled);
1095 
1096   // Adapt changes: 4, elapsed time: 120 sec => 2 per minute.
1097   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1098                                          cpu_counts, quality_counts);
1099   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1100                                          cpu_counts, quality_counts);
1101   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1102                                          cpu_counts, quality_counts);
1103   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1104                                          cpu_counts, quality_counts);
1105   fake_clock_.AdvanceTimeMilliseconds(120000);
1106 
1107   statistics_proxy_.reset();
1108   EXPECT_METRIC_EQ(1,
1109                    metrics::NumSamples(
1110                        "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Cpu"));
1111   EXPECT_METRIC_EQ(
1112       1, metrics::NumEvents(
1113              "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Cpu", 2));
1114   EXPECT_METRIC_EQ(
1115       0, metrics::NumSamples(
1116              "WebRTC.Video.Screenshare.AdaptChangesPerMinute.Quality"));
1117 }
1118 
TEST_F(SendStatisticsProxyTest,QualityLimitationReasonIsCpuWhenCpuIsResolutionLimited)1119 TEST_F(SendStatisticsProxyTest,
1120        QualityLimitationReasonIsCpuWhenCpuIsResolutionLimited) {
1121   VideoAdaptationCounters cpu_counts;
1122   VideoAdaptationCounters quality_counts;
1123 
1124   cpu_counts.resolution_adaptations = 1;
1125   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1126   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1127                                          cpu_counts, quality_counts);
1128 
1129   EXPECT_EQ(QualityLimitationReason::kCpu,
1130             statistics_proxy_->GetStats().quality_limitation_reason);
1131 }
1132 
TEST_F(SendStatisticsProxyTest,QualityLimitationReasonIsCpuWhenCpuIsFramerateLimited)1133 TEST_F(SendStatisticsProxyTest,
1134        QualityLimitationReasonIsCpuWhenCpuIsFramerateLimited) {
1135   VideoAdaptationCounters cpu_counts;
1136   VideoAdaptationCounters quality_counts;
1137 
1138   cpu_counts.fps_adaptations = 1;
1139 
1140   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1141   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1142                                          cpu_counts, quality_counts);
1143 
1144   EXPECT_EQ(QualityLimitationReason::kCpu,
1145             statistics_proxy_->GetStats().quality_limitation_reason);
1146 }
1147 
TEST_F(SendStatisticsProxyTest,QualityLimitationReasonIsBandwidthWhenQualityIsResolutionLimited)1148 TEST_F(SendStatisticsProxyTest,
1149        QualityLimitationReasonIsBandwidthWhenQualityIsResolutionLimited) {
1150   VideoAdaptationCounters cpu_counts;
1151   VideoAdaptationCounters quality_counts;
1152 
1153   quality_counts.resolution_adaptations = 1;
1154 
1155   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1156   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
1157                                          cpu_counts, quality_counts);
1158 
1159   EXPECT_EQ(QualityLimitationReason::kBandwidth,
1160             statistics_proxy_->GetStats().quality_limitation_reason);
1161 }
1162 
TEST_F(SendStatisticsProxyTest,QualityLimitationReasonIsBandwidthWhenQualityIsFramerateLimited)1163 TEST_F(SendStatisticsProxyTest,
1164        QualityLimitationReasonIsBandwidthWhenQualityIsFramerateLimited) {
1165   VideoAdaptationCounters cpu_counts;
1166   VideoAdaptationCounters quality_counts;
1167 
1168   quality_counts.fps_adaptations = 1;
1169 
1170   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1171   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
1172                                          cpu_counts, quality_counts);
1173 
1174   EXPECT_EQ(QualityLimitationReason::kBandwidth,
1175             statistics_proxy_->GetStats().quality_limitation_reason);
1176 }
1177 
TEST_F(SendStatisticsProxyTest,QualityLimitationReasonIsBandwidthWhenBothCpuAndQualityIsLimited)1178 TEST_F(SendStatisticsProxyTest,
1179        QualityLimitationReasonIsBandwidthWhenBothCpuAndQualityIsLimited) {
1180   VideoAdaptationCounters cpu_counts;
1181   VideoAdaptationCounters quality_counts;
1182 
1183   cpu_counts.resolution_adaptations = 1;
1184   quality_counts.resolution_adaptations = 1;
1185   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1186 
1187   // Even if the last adaptation reason is kCpu, if the counters indicate being
1188   // both CPU and quality (=bandwidth) limited, kBandwidth takes precedence.
1189   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1190                                          cpu_counts, quality_counts);
1191 
1192   EXPECT_EQ(QualityLimitationReason::kBandwidth,
1193             statistics_proxy_->GetStats().quality_limitation_reason);
1194 }
1195 
TEST_F(SendStatisticsProxyTest,QualityLimitationReasonIsNoneWhenNotLimited)1196 TEST_F(SendStatisticsProxyTest, QualityLimitationReasonIsNoneWhenNotLimited) {
1197   VideoAdaptationCounters cpu_counts;
1198   VideoAdaptationCounters quality_counts;
1199 
1200   // Observe a limitation due to CPU. This makes sure the test doesn't pass
1201   // due to "none" being the default value.
1202   cpu_counts.resolution_adaptations = 1;
1203   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1204   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1205                                          cpu_counts, quality_counts);
1206   // Go back to not being limited.
1207   cpu_counts.resolution_adaptations = 0;
1208   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1209                                          cpu_counts, quality_counts);
1210 
1211   EXPECT_EQ(QualityLimitationReason::kNone,
1212             statistics_proxy_->GetStats().quality_limitation_reason);
1213 }
1214 
TEST_F(SendStatisticsProxyTest,QualityLimitationDurationIncreasesWithTime)1215 TEST_F(SendStatisticsProxyTest, QualityLimitationDurationIncreasesWithTime) {
1216   VideoAdaptationCounters cpu_counts;
1217   VideoAdaptationCounters quality_counts;
1218 
1219   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1220   // Not limited for 3000 ms
1221   fake_clock_.AdvanceTimeMilliseconds(3000);
1222   // CPU limited for 2000 ms
1223   cpu_counts.resolution_adaptations = 1;
1224   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1225                                          cpu_counts, quality_counts);
1226   fake_clock_.AdvanceTimeMilliseconds(2000);
1227   // Bandwidth limited for 1000 ms
1228   cpu_counts.resolution_adaptations = 0;
1229   quality_counts.resolution_adaptations = 1;
1230   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
1231                                          cpu_counts, quality_counts);
1232   fake_clock_.AdvanceTimeMilliseconds(1000);
1233   // CPU limited for another 2000 ms
1234   cpu_counts.resolution_adaptations = 1;
1235   quality_counts.resolution_adaptations = 0;
1236   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1237                                          cpu_counts, quality_counts);
1238   fake_clock_.AdvanceTimeMilliseconds(2000);
1239 
1240   auto quality_limitation_durations_ms =
1241       statistics_proxy_->GetStats().quality_limitation_durations_ms;
1242 
1243   EXPECT_EQ(3000,
1244             quality_limitation_durations_ms[QualityLimitationReason::kNone]);
1245   EXPECT_EQ(4000,
1246             quality_limitation_durations_ms[QualityLimitationReason::kCpu]);
1247   EXPECT_EQ(
1248       1000,
1249       quality_limitation_durations_ms[QualityLimitationReason::kBandwidth]);
1250   EXPECT_EQ(0,
1251             quality_limitation_durations_ms[QualityLimitationReason::kOther]);
1252 }
1253 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionChangesDefaultZero)1254 TEST_F(SendStatisticsProxyTest, QualityLimitationResolutionChangesDefaultZero) {
1255   EXPECT_EQ(
1256       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1257 }
1258 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionChangesNotChangesWithOnlyDefaultAllocation)1259 TEST_F(SendStatisticsProxyTest,
1260        QualityLimitationResolutionChangesNotChangesWithOnlyDefaultAllocation) {
1261   VideoCodec codec;
1262   VideoBitrateAllocation allocation;
1263   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1264   EXPECT_EQ(
1265       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1266 }
1267 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionChangesDoesNotIncreaseOnFirstAllocation)1268 TEST_F(SendStatisticsProxyTest,
1269        QualityLimitationResolutionChangesDoesNotIncreaseOnFirstAllocation) {
1270   VideoCodec codec;
1271   codec.simulcastStream[0].active = true;
1272   codec.simulcastStream[1].active = true;
1273   codec.simulcastStream[2].active = true;
1274   VideoBitrateAllocation allocation;
1275   allocation.SetBitrate(0, 0, 100);
1276   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1277   EXPECT_EQ(
1278       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1279 }
1280 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionChangesWhenNewLayerGetsBandwidth)1281 TEST_F(SendStatisticsProxyTest,
1282        QualityLimitationResolutionChangesWhenNewLayerGetsBandwidth) {
1283   VideoCodec codec;
1284   codec.simulcastStream[0].active = true;
1285   codec.simulcastStream[1].active = true;
1286   codec.simulcastStream[2].active = true;
1287   VideoBitrateAllocation allocation;
1288   allocation.SetBitrate(0, 0, 100);
1289   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1290   allocation.SetBitrate(1, 0, 100);
1291   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1292   EXPECT_EQ(
1293       1u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1294 }
1295 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionDoesNotChangeWhenLayerSame)1296 TEST_F(SendStatisticsProxyTest,
1297        QualityLimitationResolutionDoesNotChangeWhenLayerSame) {
1298   VideoCodec codec;
1299   codec.simulcastStream[0].active = true;
1300   VideoBitrateAllocation allocation;
1301   allocation.SetBitrate(0, 0, 100);
1302   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1303   // Layer 0 got more bandwidth, but still only one layer on
1304   allocation.SetBitrate(0, 0, 200);
1305   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1306   EXPECT_EQ(
1307       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1308 }
1309 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionChangesWithTogglingLayers)1310 TEST_F(SendStatisticsProxyTest,
1311        QualityLimitationResolutionChangesWithTogglingLayers) {
1312   VideoCodec codec;
1313   codec.simulcastStream[0].active = true;
1314   codec.simulcastStream[1].active = true;
1315   codec.simulcastStream[2].active = true;
1316   VideoBitrateAllocation allocation;
1317   allocation.SetBitrate(0, 0, 100);
1318   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1319   EXPECT_EQ(
1320       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1321   allocation.SetBitrate(1, 0, 300);
1322   allocation.SetBitrate(2, 0, 500);
1323   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1324   EXPECT_EQ(
1325       1u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1326   // Layer 2 off
1327   allocation.SetBitrate(2, 0, 0);
1328   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1329   EXPECT_EQ(
1330       2u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1331   // Layer 2 back on
1332   allocation.SetBitrate(2, 0, 500);
1333   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1334   EXPECT_EQ(
1335       3u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1336   allocation.SetBitrate(0, 0, 0);
1337   allocation.SetBitrate(1, 0, 0);
1338   allocation.SetBitrate(2, 0, 0);
1339   // All layers off
1340   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1341   EXPECT_EQ(
1342       4u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1343 }
1344 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionDoesNotUpdateOnCodecSimulcastStreamChanges)1345 TEST_F(SendStatisticsProxyTest,
1346        QualityLimitationResolutionDoesNotUpdateOnCodecSimulcastStreamChanges) {
1347   VideoCodec codec;
1348   // 3 layers
1349   codec.simulcastStream[0].active = true;
1350   codec.simulcastStream[1].active = true;
1351   codec.simulcastStream[2].active = true;
1352   VideoBitrateAllocation allocation;
1353   allocation.SetBitrate(0, 0, 500);
1354   allocation.SetBitrate(1, 0, 500);
1355   allocation.SetBitrate(2, 0, 500);
1356   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1357   EXPECT_EQ(
1358       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1359 
1360   // Down to one layer now, triggered by a config change
1361   codec.numberOfSimulcastStreams = 1;
1362   codec.simulcastStream[1].active = false;
1363   codec.simulcastStream[2].active = false;
1364   allocation.SetBitrate(0, 0, 100);
1365   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1366   EXPECT_EQ(
1367       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1368 
1369   // Up to 3 layers again.
1370   codec.numberOfSimulcastStreams = 3;
1371   codec.simulcastStream[1].active = true;
1372   codec.simulcastStream[2].active = true;
1373   allocation.SetBitrate(0, 0, 500);
1374   allocation.SetBitrate(1, 0, 500);
1375   allocation.SetBitrate(2, 0, 500);
1376   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1377   EXPECT_EQ(
1378       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1379 }
1380 
TEST_F(SendStatisticsProxyTest,QualityLimitationResolutionDoesNotUpdateForSpatialLayerChanges)1381 TEST_F(SendStatisticsProxyTest,
1382        QualityLimitationResolutionDoesNotUpdateForSpatialLayerChanges) {
1383   VideoCodec codec;
1384   codec.simulcastStream[0].active = true;
1385   codec.spatialLayers[0].active = true;
1386   codec.spatialLayers[1].active = true;
1387   codec.spatialLayers[2].active = true;
1388   VideoBitrateAllocation allocation;
1389   allocation.SetBitrate(0, 0, 500);
1390   allocation.SetBitrate(1, 0, 500);
1391   allocation.SetBitrate(2, 0, 500);
1392   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1393   EXPECT_EQ(
1394       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1395 
1396   // Down to one layer now, triggered by a config change
1397   codec.spatialLayers[1].active = false;
1398   codec.spatialLayers[2].active = false;
1399   allocation.SetBitrate(0, 0, 100);
1400   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1401   EXPECT_EQ(
1402       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1403 
1404   // Up to 3 layers again.
1405   codec.spatialLayers[1].active = true;
1406   codec.spatialLayers[2].active = true;
1407   allocation.SetBitrate(0, 0, 500);
1408   allocation.SetBitrate(1, 0, 500);
1409   allocation.SetBitrate(2, 0, 500);
1410   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1411   EXPECT_EQ(
1412       0u, statistics_proxy_->GetStats().quality_limitation_resolution_changes);
1413 }
1414 
TEST_F(SendStatisticsProxyTest,QualityLimitationReasonsAreCorrectForContentType)1415 TEST_F(SendStatisticsProxyTest,
1416        QualityLimitationReasonsAreCorrectForContentType) {
1417   // Realtime case.
1418   // Configure two streams.
1419   VideoEncoderConfig config;
1420   config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
1421   config.number_of_streams = 2;
1422   VideoStream stream1;
1423   stream1.width = kWidth / 2;
1424   stream1.height = kHeight / 2;
1425   VideoStream stream2;
1426   stream2.width = kWidth;
1427   stream2.height = kHeight;
1428   statistics_proxy_->OnEncoderReconfigured(config, {stream1, stream2});
1429   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1430   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
1431   EXPECT_EQ(statistics_proxy_->GetStats().quality_limitation_reason,
1432             QualityLimitationReason::kNone);
1433   // Bw disabled one layer.
1434   VideoCodec codec;
1435   codec.numberOfSimulcastStreams = 2;
1436   codec.simulcastStream[0].active = true;
1437   codec.simulcastStream[1].active = true;
1438   VideoBitrateAllocation allocation;
1439   // Some positive bitrate only on the first stream.
1440   allocation.SetBitrate(0, 0, 10000);
1441   allocation.SetBitrate(1, 0, 0);
1442   allocation.set_bw_limited(true);
1443   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1444   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
1445   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
1446   EXPECT_EQ(statistics_proxy_->GetStats().quality_limitation_reason,
1447             QualityLimitationReason::kBandwidth);
1448   // Bw enabled all layers.
1449   allocation.SetBitrate(1, 0, 10000);
1450   allocation.set_bw_limited(false);
1451   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1452   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1453   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
1454   EXPECT_EQ(statistics_proxy_->GetStats().quality_limitation_reason,
1455             QualityLimitationReason::kNone);
1456 
1457   // Screencast case
1458   // Configure two streams.
1459   config.content_type = VideoEncoderConfig::ContentType::kScreen;
1460   config.number_of_streams = 2;
1461   stream1.width = kWidth;
1462   stream1.height = kHeight;
1463   statistics_proxy_->OnEncoderReconfigured(config, {stream1, stream2});
1464   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_framerate);
1465   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1466   EXPECT_EQ(statistics_proxy_->GetStats().quality_limitation_reason,
1467             QualityLimitationReason::kNone);
1468   // Bw disabled one layer.
1469   // Some positive bitrate only on the second stream.
1470   allocation.SetBitrate(0, 0, 10000);
1471   allocation.SetBitrate(1, 0, 0);
1472   allocation.set_bw_limited(true);
1473   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1474   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_framerate);
1475   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1476   EXPECT_EQ(statistics_proxy_->GetStats().quality_limitation_reason,
1477             QualityLimitationReason::kBandwidth);
1478   // Bw enabled all layers.
1479   allocation.SetBitrate(1, 0, 10000);
1480   allocation.set_bw_limited(false);
1481   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
1482   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1483   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
1484   EXPECT_EQ(statistics_proxy_->GetStats().quality_limitation_reason,
1485             QualityLimitationReason::kNone);
1486 }
1487 
TEST_F(SendStatisticsProxyTest,SwitchContentTypeUpdatesHistograms)1488 TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
1489   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
1490     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1491 
1492   // No switch, stats should not be updated.
1493   VideoEncoderConfig config;
1494   config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
1495   statistics_proxy_->OnEncoderReconfigured(config, {});
1496   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
1497 
1498   // Switch to screenshare, real-time stats should be updated.
1499   config.content_type = VideoEncoderConfig::ContentType::kScreen;
1500   statistics_proxy_->OnEncoderReconfigured(config, {});
1501   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
1502 }
1503 
TEST_F(SendStatisticsProxyTest,InputResolutionHistogramsAreUpdated)1504 TEST_F(SendStatisticsProxyTest, InputResolutionHistogramsAreUpdated) {
1505   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
1506     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1507 
1508   statistics_proxy_.reset();
1509   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InputWidthInPixels"));
1510   EXPECT_METRIC_EQ(
1511       1, metrics::NumEvents("WebRTC.Video.InputWidthInPixels", kWidth));
1512   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InputHeightInPixels"));
1513   EXPECT_METRIC_EQ(
1514       1, metrics::NumEvents("WebRTC.Video.InputHeightInPixels", kHeight));
1515 }
1516 
TEST_F(SendStatisticsProxyTest,SentResolutionHistogramsAreUpdated)1517 TEST_F(SendStatisticsProxyTest, SentResolutionHistogramsAreUpdated) {
1518   const int64_t kMaxEncodedFrameWindowMs = 800;
1519   const int kFps = 5;
1520   const int kNumFramesPerWindow = kFps * kMaxEncodedFrameWindowMs / 1000;
1521   const int kMinSamples =  // Sample added when removed from EncodedFrameMap.
1522       SendStatisticsProxy::kMinRequiredMetricsSamples + kNumFramesPerWindow;
1523   EncodedImage encoded_image;
1524 
1525   // Not enough samples, stats should not be updated.
1526   for (int i = 0; i < kMinSamples - 1; ++i) {
1527     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1528     encoded_image.SetTimestamp(encoded_image.Timestamp() + 90 * 1000 / kFps);
1529     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1530   }
1531   SetUp();  // Reset stats proxy also causes histograms to be reported.
1532   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
1533   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
1534 
1535   // Enough samples, max resolution per frame should be reported.
1536   encoded_image.SetTimestamp(0xffff0000);  // Will wrap.
1537   for (int i = 0; i < kMinSamples; ++i) {
1538     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1539     encoded_image.SetTimestamp(encoded_image.Timestamp() + 90 * 1000 / kFps);
1540     encoded_image._encodedWidth = kWidth;
1541     encoded_image._encodedHeight = kHeight;
1542     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1543     encoded_image._encodedWidth = kWidth / 2;
1544     encoded_image._encodedHeight = kHeight / 2;
1545     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1546   }
1547 
1548   statistics_proxy_.reset();
1549   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.SentWidthInPixels"));
1550   EXPECT_METRIC_EQ(
1551       1, metrics::NumEvents("WebRTC.Video.SentWidthInPixels", kWidth));
1552   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.SentHeightInPixels"));
1553   EXPECT_METRIC_EQ(
1554       1, metrics::NumEvents("WebRTC.Video.SentHeightInPixels", kHeight));
1555 }
1556 
TEST_F(SendStatisticsProxyTest,InputFpsHistogramIsUpdated)1557 TEST_F(SendStatisticsProxyTest, InputFpsHistogramIsUpdated) {
1558   const int kFps = 20;
1559   const int kMinPeriodicSamples = 6;
1560   int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
1561   for (int i = 0; i <= frames; ++i) {
1562     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1563     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1564   }
1565   statistics_proxy_.reset();
1566   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
1567   EXPECT_METRIC_EQ(
1568       1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
1569 }
1570 
TEST_F(SendStatisticsProxyTest,SentFpsHistogramIsUpdated)1571 TEST_F(SendStatisticsProxyTest, SentFpsHistogramIsUpdated) {
1572   EncodedImage encoded_image;
1573   const int kFps = 20;
1574   const int kMinPeriodicSamples = 6;
1575   int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000 + 1;
1576   for (int i = 0; i < frames; ++i) {
1577     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1578     encoded_image.SetTimestamp(encoded_image.Timestamp() + 1);
1579     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1580     // Frame with same timestamp should not be counted.
1581     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1582   }
1583   statistics_proxy_.reset();
1584   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
1585   EXPECT_METRIC_EQ(
1586       1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
1587 }
1588 
TEST_F(SendStatisticsProxyTest,InputFpsHistogramExcludesSuspendedTime)1589 TEST_F(SendStatisticsProxyTest, InputFpsHistogramExcludesSuspendedTime) {
1590   const int kFps = 20;
1591   const int kSuspendTimeMs = 10000;
1592   const int kMinPeriodicSamples = 6;
1593   int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
1594   for (int i = 0; i < frames; ++i) {
1595     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1596     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1597   }
1598   // Suspend.
1599   statistics_proxy_->OnSuspendChange(true);
1600   fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
1601 
1602   for (int i = 0; i < frames; ++i) {
1603     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1604     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1605   }
1606   // Suspended time interval should not affect the framerate.
1607   statistics_proxy_.reset();
1608   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InputFramesPerSecond"));
1609   EXPECT_METRIC_EQ(
1610       1, metrics::NumEvents("WebRTC.Video.InputFramesPerSecond", kFps));
1611 }
1612 
TEST_F(SendStatisticsProxyTest,SentFpsHistogramExcludesSuspendedTime)1613 TEST_F(SendStatisticsProxyTest, SentFpsHistogramExcludesSuspendedTime) {
1614   EncodedImage encoded_image;
1615   const int kFps = 20;
1616   const int kSuspendTimeMs = 10000;
1617   const int kMinPeriodicSamples = 6;
1618   int frames = kMinPeriodicSamples * kFpsPeriodicIntervalMs * kFps / 1000;
1619   for (int i = 0; i < frames; ++i) {
1620     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1621     encoded_image.SetTimestamp(i + 1);
1622     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1623   }
1624   // Suspend.
1625   statistics_proxy_->OnSuspendChange(true);
1626   fake_clock_.AdvanceTimeMilliseconds(kSuspendTimeMs);
1627 
1628   for (int i = 0; i < frames; ++i) {
1629     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1630     encoded_image.SetTimestamp(i + 1);
1631     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1632   }
1633   // Suspended time interval should not affect the framerate.
1634   statistics_proxy_.reset();
1635   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.SentFramesPerSecond"));
1636   EXPECT_METRIC_EQ(
1637       1, metrics::NumEvents("WebRTC.Video.SentFramesPerSecond", kFps));
1638 }
1639 
TEST_F(SendStatisticsProxyTest,CpuLimitedHistogramNotUpdatedWhenDisabled)1640 TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramNotUpdatedWhenDisabled) {
1641   statistics_proxy_->UpdateAdaptationSettings(kResolutionScalingDisabled,
1642                                               kResolutionScalingDisabled);
1643 
1644   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
1645     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1646 
1647   statistics_proxy_.reset();
1648   EXPECT_METRIC_EQ(
1649       0, metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
1650 }
1651 
TEST_F(SendStatisticsProxyTest,CpuLimitedHistogramUpdated)1652 TEST_F(SendStatisticsProxyTest, CpuLimitedHistogramUpdated) {
1653   VideoAdaptationCounters cpu_counts;
1654   VideoAdaptationCounters quality_counts;
1655   cpu_counts.resolution_adaptations = 0;
1656   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
1657 
1658   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
1659     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1660 
1661   cpu_counts.resolution_adaptations = 1;
1662   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kCpu,
1663                                          cpu_counts, quality_counts);
1664 
1665   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
1666     statistics_proxy_->OnIncomingFrame(kWidth, kHeight);
1667 
1668   statistics_proxy_.reset();
1669   EXPECT_METRIC_EQ(
1670       1, metrics::NumSamples("WebRTC.Video.CpuLimitedResolutionInPercent"));
1671   EXPECT_METRIC_EQ(
1672       1, metrics::NumEvents("WebRTC.Video.CpuLimitedResolutionInPercent", 50));
1673 }
1674 
TEST_F(SendStatisticsProxyTest,LifetimeHistogramIsUpdated)1675 TEST_F(SendStatisticsProxyTest, LifetimeHistogramIsUpdated) {
1676   const int64_t kTimeSec = 3;
1677   fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
1678   statistics_proxy_.reset();
1679   EXPECT_METRIC_EQ(
1680       1, metrics::NumSamples("WebRTC.Video.SendStreamLifetimeInSeconds"));
1681   EXPECT_METRIC_EQ(
1682       1,
1683       metrics::NumEvents("WebRTC.Video.SendStreamLifetimeInSeconds", kTimeSec));
1684 }
1685 
TEST_F(SendStatisticsProxyTest,CodecTypeHistogramIsUpdated)1686 TEST_F(SendStatisticsProxyTest, CodecTypeHistogramIsUpdated) {
1687   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1688   statistics_proxy_.reset();
1689   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoder.CodecType"));
1690 }
1691 
TEST_F(SendStatisticsProxyTest,PauseEventHistogramIsUpdated)1692 TEST_F(SendStatisticsProxyTest, PauseEventHistogramIsUpdated) {
1693   // First RTP packet sent.
1694   UpdateDataCounters(kFirstSsrc);
1695 
1696   // Min runtime has passed.
1697   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1698   statistics_proxy_.reset();
1699   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1700   EXPECT_METRIC_EQ(1,
1701                    metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 0));
1702 }
1703 
TEST_F(SendStatisticsProxyTest,PauseEventHistogramIsNotUpdatedIfMinRuntimeHasNotPassed)1704 TEST_F(SendStatisticsProxyTest,
1705        PauseEventHistogramIsNotUpdatedIfMinRuntimeHasNotPassed) {
1706   // First RTP packet sent.
1707   UpdateDataCounters(kFirstSsrc);
1708 
1709   // Min runtime has not passed.
1710   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
1711   statistics_proxy_.reset();
1712   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1713   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1714 }
1715 
TEST_F(SendStatisticsProxyTest,PauseEventHistogramIsNotUpdatedIfNoMediaIsSent)1716 TEST_F(SendStatisticsProxyTest,
1717        PauseEventHistogramIsNotUpdatedIfNoMediaIsSent) {
1718   // First RTP packet not sent.
1719   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1720   statistics_proxy_.reset();
1721   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1722 }
1723 
TEST_F(SendStatisticsProxyTest,NoPauseEvent)1724 TEST_F(SendStatisticsProxyTest, NoPauseEvent) {
1725   // First RTP packet sent and min runtime passed.
1726   UpdateDataCounters(kFirstSsrc);
1727 
1728   // No change. Video: 10000 ms, paused: 0 ms (0%).
1729   statistics_proxy_->OnSetEncoderTargetRate(50000);
1730   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1731   statistics_proxy_->OnSetEncoderTargetRate(0);  // VideoSendStream::Stop
1732 
1733   statistics_proxy_.reset();
1734   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1735   EXPECT_METRIC_EQ(1,
1736                    metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 0));
1737   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1738   EXPECT_METRIC_EQ(1,
1739                    metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 0));
1740 }
1741 
TEST_F(SendStatisticsProxyTest,OnePauseEvent)1742 TEST_F(SendStatisticsProxyTest, OnePauseEvent) {
1743   // First RTP packet sent and min runtime passed.
1744   UpdateDataCounters(kFirstSsrc);
1745 
1746   // One change. Video: 7000 ms, paused: 3000 ms (30%).
1747   statistics_proxy_->OnSetEncoderTargetRate(50000);
1748   fake_clock_.AdvanceTimeMilliseconds(7000);
1749   statistics_proxy_->OnSetEncoderTargetRate(0);
1750   fake_clock_.AdvanceTimeMilliseconds(3000);
1751   statistics_proxy_->OnSetEncoderTargetRate(0);  // VideoSendStream::Stop
1752 
1753   statistics_proxy_.reset();
1754   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1755   EXPECT_METRIC_EQ(1,
1756                    metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 1));
1757   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1758   EXPECT_METRIC_EQ(1,
1759                    metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 30));
1760 }
1761 
TEST_F(SendStatisticsProxyTest,TwoPauseEvents)1762 TEST_F(SendStatisticsProxyTest, TwoPauseEvents) {
1763   // First RTP packet sent.
1764   UpdateDataCounters(kFirstSsrc);
1765 
1766   // Two changes. Video: 19000 ms, paused: 1000 ms (5%).
1767   statistics_proxy_->OnSetEncoderTargetRate(0);
1768   fake_clock_.AdvanceTimeMilliseconds(1000);
1769   statistics_proxy_->OnSetEncoderTargetRate(50000);  // Starts on bitrate > 0.
1770   fake_clock_.AdvanceTimeMilliseconds(7000);
1771   statistics_proxy_->OnSetEncoderTargetRate(60000);
1772   fake_clock_.AdvanceTimeMilliseconds(3000);
1773   statistics_proxy_->OnSetEncoderTargetRate(0);
1774   fake_clock_.AdvanceTimeMilliseconds(250);
1775   statistics_proxy_->OnSetEncoderTargetRate(0);
1776   fake_clock_.AdvanceTimeMilliseconds(750);
1777   statistics_proxy_->OnSetEncoderTargetRate(60000);
1778   fake_clock_.AdvanceTimeMilliseconds(5000);
1779   statistics_proxy_->OnSetEncoderTargetRate(50000);
1780   fake_clock_.AdvanceTimeMilliseconds(4000);
1781   statistics_proxy_->OnSetEncoderTargetRate(0);  // VideoSendStream::Stop
1782 
1783   statistics_proxy_.reset();
1784   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.NumberOfPauseEvents"));
1785   EXPECT_METRIC_EQ(1,
1786                    metrics::NumEvents("WebRTC.Video.NumberOfPauseEvents", 2));
1787   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1788   EXPECT_METRIC_EQ(1,
1789                    metrics::NumEvents("WebRTC.Video.PausedTimeInPercent", 5));
1790 }
1791 
TEST_F(SendStatisticsProxyTest,PausedTimeHistogramIsNotUpdatedIfMinRuntimeHasNotPassed)1792 TEST_F(SendStatisticsProxyTest,
1793        PausedTimeHistogramIsNotUpdatedIfMinRuntimeHasNotPassed) {
1794   // First RTP packet sent.
1795   UpdateDataCounters(kFirstSsrc);
1796   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1797 
1798   // Min runtime has not passed.
1799   statistics_proxy_->OnSetEncoderTargetRate(50000);
1800   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000 - 1);
1801   statistics_proxy_->OnSetEncoderTargetRate(0);  // VideoSendStream::Stop
1802 
1803   statistics_proxy_.reset();
1804   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.PausedTimeInPercent"));
1805 }
1806 
TEST_F(SendStatisticsProxyTest,VerifyQpHistogramStats_Vp8)1807 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) {
1808   EncodedImage encoded_image;
1809   CodecSpecificInfo codec_info;
1810   codec_info.codecType = kVideoCodecVP8;
1811 
1812   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1813     encoded_image.SetSpatialIndex(0);
1814     encoded_image.qp_ = kQpIdx0;
1815     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1816     encoded_image.SetSpatialIndex(1);
1817     encoded_image.qp_ = kQpIdx1;
1818     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1819   }
1820   statistics_proxy_.reset();
1821   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S0"));
1822   EXPECT_METRIC_EQ(
1823       1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S0", kQpIdx0));
1824   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8.S1"));
1825   EXPECT_METRIC_EQ(
1826       1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8.S1", kQpIdx1));
1827 }
1828 
TEST_F(SendStatisticsProxyTest,VerifyQpHistogramStats_Vp8OneSsrc)1829 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
1830   VideoSendStream::Config config(nullptr);
1831   config.rtp.ssrcs.push_back(kFirstSsrc);
1832   statistics_proxy_.reset(new SendStatisticsProxy(
1833       &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1834 
1835   EncodedImage encoded_image;
1836   CodecSpecificInfo codec_info;
1837   codec_info.codecType = kVideoCodecVP8;
1838 
1839   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1840     encoded_image.SetSpatialIndex(0);
1841     encoded_image.qp_ = kQpIdx0;
1842     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1843   }
1844   statistics_proxy_.reset();
1845   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp8"));
1846   EXPECT_METRIC_EQ(1,
1847                    metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp8", kQpIdx0));
1848 }
1849 
TEST_F(SendStatisticsProxyTest,VerifyQpHistogramStats_Vp9)1850 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) {
1851   EncodedImage encoded_image;
1852   CodecSpecificInfo codec_info;
1853   codec_info.codecType = kVideoCodecVP9;
1854   codec_info.codecSpecific.VP9.num_spatial_layers = 2;
1855 
1856   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1857     encoded_image.qp_ = kQpIdx0;
1858     encoded_image.SetSpatialIndex(0);
1859     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1860     encoded_image.qp_ = kQpIdx1;
1861     encoded_image.SetSpatialIndex(1);
1862     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1863   }
1864   statistics_proxy_.reset();
1865   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S0"));
1866   EXPECT_METRIC_EQ(
1867       1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S0", kQpIdx0));
1868   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9.S1"));
1869   EXPECT_METRIC_EQ(
1870       1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9.S1", kQpIdx1));
1871 }
1872 
TEST_F(SendStatisticsProxyTest,VerifyQpHistogramStats_Vp9OneSpatialLayer)1873 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) {
1874   VideoSendStream::Config config(nullptr);
1875   config.rtp.ssrcs.push_back(kFirstSsrc);
1876   statistics_proxy_.reset(new SendStatisticsProxy(
1877       &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
1878 
1879   EncodedImage encoded_image;
1880   CodecSpecificInfo codec_info;
1881   codec_info.codecType = kVideoCodecVP9;
1882   codec_info.codecSpecific.VP9.num_spatial_layers = 1;
1883 
1884   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1885     encoded_image.qp_ = kQpIdx0;
1886     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1887   }
1888   statistics_proxy_.reset();
1889   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.Vp9"));
1890   EXPECT_METRIC_EQ(1,
1891                    metrics::NumEvents("WebRTC.Video.Encoded.Qp.Vp9", kQpIdx0));
1892 }
1893 
TEST_F(SendStatisticsProxyTest,VerifyQpHistogramStats_H264)1894 TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_H264) {
1895   EncodedImage encoded_image;
1896   CodecSpecificInfo codec_info;
1897   codec_info.codecType = kVideoCodecH264;
1898 
1899   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i) {
1900     encoded_image.SetSpatialIndex(0);
1901     encoded_image.qp_ = kQpIdx0;
1902     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1903     encoded_image.SetSpatialIndex(1);
1904     encoded_image.qp_ = kQpIdx1;
1905     statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
1906   }
1907   statistics_proxy_.reset();
1908   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.H264.S0"));
1909   EXPECT_METRIC_EQ(
1910       1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.H264.S0", kQpIdx0));
1911   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Encoded.Qp.H264.S1"));
1912   EXPECT_METRIC_EQ(
1913       1, metrics::NumEvents("WebRTC.Video.Encoded.Qp.H264.S1", kQpIdx1));
1914 }
1915 
TEST_F(SendStatisticsProxyTest,BandwidthLimitedHistogramsNotUpdatedForOneStream)1916 TEST_F(SendStatisticsProxyTest,
1917        BandwidthLimitedHistogramsNotUpdatedForOneStream) {
1918   // Configure one stream.
1919   VideoEncoderConfig config;
1920   config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
1921   VideoStream stream1;
1922   stream1.width = kWidth;
1923   stream1.height = kHeight;
1924   statistics_proxy_->OnEncoderReconfigured(config, {stream1});
1925 
1926   const int64_t kMaxEncodedFrameWindowMs = 800;
1927   const int kFps = 20;
1928   const int kNumFramesPerWindow = kFps * kMaxEncodedFrameWindowMs / 1000;
1929   const int kMinSamples =  // Sample added when removed from EncodedFrameMap.
1930       SendStatisticsProxy::kMinRequiredMetricsSamples + kNumFramesPerWindow;
1931 
1932   // Stream encoded.
1933   EncodedImage encoded_image;
1934   encoded_image._encodedWidth = kWidth;
1935   encoded_image._encodedHeight = kHeight;
1936   for (int i = 0; i < kMinSamples; ++i) {
1937     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1938     encoded_image.SetTimestamp(encoded_image.Timestamp() +
1939                                (kRtpClockRateHz / kFps));
1940     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1941   }
1942 
1943   // Histograms are updated when the statistics_proxy_ is deleted.
1944   statistics_proxy_.reset();
1945   EXPECT_METRIC_EQ(0, metrics::NumSamples(
1946                           "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1947   EXPECT_METRIC_EQ(0, metrics::NumSamples(
1948                           "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1949 }
1950 
TEST_F(SendStatisticsProxyTest,BandwidthLimitedHistogramsUpdatedForTwoStreams_NoResolutionDisabled)1951 TEST_F(SendStatisticsProxyTest,
1952        BandwidthLimitedHistogramsUpdatedForTwoStreams_NoResolutionDisabled) {
1953   // Configure two streams.
1954   VideoEncoderConfig config;
1955   config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
1956   VideoStream stream1;
1957   stream1.width = kWidth / 2;
1958   stream1.height = kHeight / 2;
1959   VideoStream stream2;
1960   stream2.width = kWidth;
1961   stream2.height = kHeight;
1962   statistics_proxy_->OnEncoderReconfigured(config, {stream1, stream2});
1963 
1964   const int64_t kMaxEncodedFrameWindowMs = 800;
1965   const int kFps = 20;
1966   const int kNumFramesPerWindow = kFps * kMaxEncodedFrameWindowMs / 1000;
1967   const int kMinSamples =  // Sample added when removed from EncodedFrameMap.
1968       SendStatisticsProxy::kMinRequiredMetricsSamples + kNumFramesPerWindow;
1969 
1970   // Two streams encoded.
1971   EncodedImage encoded_image;
1972   for (int i = 0; i < kMinSamples; ++i) {
1973     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
1974     encoded_image.SetTimestamp(encoded_image.Timestamp() +
1975                                (kRtpClockRateHz / kFps));
1976     encoded_image._encodedWidth = kWidth;
1977     encoded_image._encodedHeight = kHeight;
1978     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1979     encoded_image._encodedWidth = kWidth / 2;
1980     encoded_image._encodedHeight = kHeight / 2;
1981     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
1982   }
1983 
1984   // Histograms are updated when the statistics_proxy_ is deleted.
1985   statistics_proxy_.reset();
1986   EXPECT_METRIC_EQ(1, metrics::NumSamples(
1987                           "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
1988   EXPECT_METRIC_EQ(
1989       1, metrics::NumEvents("WebRTC.Video.BandwidthLimitedResolutionInPercent",
1990                             0));
1991   // No resolution disabled.
1992   EXPECT_METRIC_EQ(0, metrics::NumSamples(
1993                           "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
1994 }
1995 
TEST_F(SendStatisticsProxyTest,BandwidthLimitedHistogramsUpdatedForTwoStreams_OneResolutionDisabled)1996 TEST_F(SendStatisticsProxyTest,
1997        BandwidthLimitedHistogramsUpdatedForTwoStreams_OneResolutionDisabled) {
1998   // Configure two streams.
1999   VideoEncoderConfig config;
2000   config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
2001   VideoStream stream1;
2002   stream1.width = kWidth / 2;
2003   stream1.height = kHeight / 2;
2004   VideoStream stream2;
2005   stream2.width = kWidth;
2006   stream2.height = kHeight;
2007   statistics_proxy_->OnEncoderReconfigured(config, {stream1, stream2});
2008 
2009   const int64_t kMaxEncodedFrameWindowMs = 800;
2010   const int kFps = 20;
2011   const int kNumFramesPerWindow = kFps * kMaxEncodedFrameWindowMs / 1000;
2012   const int kMinSamples =  // Sample added when removed from EncodedFrameMap.
2013       SendStatisticsProxy::kMinRequiredMetricsSamples + kNumFramesPerWindow;
2014 
2015   // One stream encoded.
2016   EncodedImage encoded_image;
2017   encoded_image._encodedWidth = kWidth / 2;
2018   encoded_image._encodedHeight = kHeight / 2;
2019   for (int i = 0; i < kMinSamples; ++i) {
2020     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
2021     encoded_image.SetTimestamp(encoded_image.Timestamp() +
2022                                (kRtpClockRateHz / kFps));
2023     statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
2024   }
2025 
2026   // Histograms are updated when the statistics_proxy_ is deleted.
2027   statistics_proxy_.reset();
2028   EXPECT_METRIC_EQ(1, metrics::NumSamples(
2029                           "WebRTC.Video.BandwidthLimitedResolutionInPercent"));
2030   EXPECT_METRIC_EQ(
2031       1, metrics::NumEvents("WebRTC.Video.BandwidthLimitedResolutionInPercent",
2032                             100));
2033   // One resolution disabled.
2034   EXPECT_METRIC_EQ(1, metrics::NumSamples(
2035                           "WebRTC.Video.BandwidthLimitedResolutionsDisabled"));
2036   EXPECT_METRIC_EQ(
2037       1, metrics::NumEvents("WebRTC.Video.BandwidthLimitedResolutionsDisabled",
2038                             1));
2039 }
2040 
TEST_F(SendStatisticsProxyTest,QualityLimitedHistogramsNotUpdatedWhenDisabled)2041 TEST_F(SendStatisticsProxyTest,
2042        QualityLimitedHistogramsNotUpdatedWhenDisabled) {
2043   statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
2044                                               kScalingDisabled);
2045   EncodedImage encoded_image;
2046   encoded_image.SetSpatialIndex(0);
2047   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
2048     statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
2049 
2050   // Histograms are updated when the statistics_proxy_ is deleted.
2051   statistics_proxy_.reset();
2052   EXPECT_METRIC_EQ(
2053       0, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
2054   EXPECT_METRIC_EQ(0, metrics::NumSamples(
2055                           "WebRTC.Video.QualityLimitedResolutionDownscales"));
2056 }
2057 
TEST_F(SendStatisticsProxyTest,QualityLimitedHistogramsUpdatedWhenEnabled_NoResolutionDownscale)2058 TEST_F(SendStatisticsProxyTest,
2059        QualityLimitedHistogramsUpdatedWhenEnabled_NoResolutionDownscale) {
2060   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
2061   EncodedImage encoded_image;
2062   encoded_image.SetSpatialIndex(0);
2063   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
2064     statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
2065 
2066   // Histograms are updated when the statistics_proxy_ is deleted.
2067   statistics_proxy_.reset();
2068   EXPECT_METRIC_EQ(
2069       1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
2070   EXPECT_METRIC_EQ(1, metrics::NumEvents(
2071                           "WebRTC.Video.QualityLimitedResolutionInPercent", 0));
2072   // No resolution downscale.
2073   EXPECT_METRIC_EQ(0, metrics::NumSamples(
2074                           "WebRTC.Video.QualityLimitedResolutionDownscales"));
2075 }
2076 
TEST_F(SendStatisticsProxyTest,QualityLimitedHistogramsUpdatedWhenEnabled_TwoResolutionDownscales)2077 TEST_F(SendStatisticsProxyTest,
2078        QualityLimitedHistogramsUpdatedWhenEnabled_TwoResolutionDownscales) {
2079   const int kDownscales = 2;
2080   VideoAdaptationCounters cpu_counts;
2081   VideoAdaptationCounters quality_counts;
2082   quality_counts.resolution_adaptations = kDownscales;
2083   statistics_proxy_->UpdateAdaptationSettings(kScalingEnabled, kScalingEnabled);
2084   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
2085                                          cpu_counts, quality_counts);
2086   EncodedImage encoded_image;
2087   encoded_image.SetSpatialIndex(0);
2088   for (int i = 0; i < SendStatisticsProxy::kMinRequiredMetricsSamples; ++i)
2089     statistics_proxy_->OnSendEncodedImage(encoded_image, &kDefaultCodecInfo);
2090   // Histograms are updated when the statistics_proxy_ is deleted.
2091   statistics_proxy_.reset();
2092   EXPECT_METRIC_EQ(
2093       1, metrics::NumSamples("WebRTC.Video.QualityLimitedResolutionInPercent"));
2094   EXPECT_METRIC_EQ(
2095       1, metrics::NumEvents("WebRTC.Video.QualityLimitedResolutionInPercent",
2096                             100));
2097   // Resolution downscales.
2098   EXPECT_METRIC_EQ(1, metrics::NumSamples(
2099                           "WebRTC.Video.QualityLimitedResolutionDownscales"));
2100   EXPECT_METRIC_EQ(
2101       1, metrics::NumEvents("WebRTC.Video.QualityLimitedResolutionDownscales",
2102                             kDownscales));
2103 }
2104 
TEST_F(SendStatisticsProxyTest,GetStatsReportsBandwidthLimitedResolution)2105 TEST_F(SendStatisticsProxyTest, GetStatsReportsBandwidthLimitedResolution) {
2106   // Initially false.
2107   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
2108 
2109   // Configure two streams.
2110   VideoEncoderConfig config;
2111   config.content_type = VideoEncoderConfig::ContentType::kRealtimeVideo;
2112   config.number_of_streams = 2;
2113   VideoStream stream1;
2114   stream1.width = kWidth / 2;
2115   stream1.height = kHeight / 2;
2116   VideoStream stream2;
2117   stream2.width = kWidth;
2118   stream2.height = kHeight;
2119   statistics_proxy_->OnEncoderReconfigured(config, {stream1, stream2});
2120 
2121   // One stream encoded.
2122   EncodedImage encoded_image;
2123   encoded_image._encodedWidth = kWidth / 2;
2124   encoded_image._encodedHeight = kHeight / 2;
2125 
2126   // Resolution scaled due to quality.
2127   VideoAdaptationCounters cpu_counts;
2128   VideoAdaptationCounters quality_counts;
2129   quality_counts.resolution_adaptations = 1;
2130   statistics_proxy_->UpdateAdaptationSettings(kFramerateScalingDisabled,
2131                                               kFramerateScalingDisabled);
2132   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
2133                                          cpu_counts, quality_counts);
2134   statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
2135   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
2136 
2137   // Adapt up.
2138   quality_counts.resolution_adaptations = 0;
2139   statistics_proxy_->OnAdaptationChanged(VideoAdaptationReason::kQuality,
2140                                          cpu_counts, quality_counts);
2141   statistics_proxy_->OnSendEncodedImage(encoded_image, nullptr);
2142   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
2143 
2144   // Bw disabled one layer.
2145   VideoCodec codec;
2146   codec.numberOfSimulcastStreams = 2;
2147   codec.simulcastStream[0].active = true;
2148   codec.simulcastStream[1].active = true;
2149   VideoBitrateAllocation allocation;
2150   // Some positive bitrate only on the second stream.
2151   allocation.SetBitrate(1, 0, 10000);
2152   allocation.set_bw_limited(true);
2153   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
2154   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
2155 
2156   // Revert for the next test.
2157   allocation.set_bw_limited(false);
2158   statistics_proxy_->OnBitrateAllocationUpdated(codec, allocation);
2159   EXPECT_FALSE(statistics_proxy_->GetStats().bw_limited_resolution);
2160 
2161   // Internal encoder scaler reduced resolution.
2162   statistics_proxy_->OnEncoderInternalScalerUpdate(/*scaled=*/true);
2163   EXPECT_TRUE(statistics_proxy_->GetStats().bw_limited_resolution);
2164 }
2165 
TEST_F(SendStatisticsProxyTest,GetStatsReportsTargetMediaBitrate)2166 TEST_F(SendStatisticsProxyTest, GetStatsReportsTargetMediaBitrate) {
2167   // Initially zero.
2168   EXPECT_EQ(0, statistics_proxy_->GetStats().target_media_bitrate_bps);
2169 
2170   const int kBitrate = 100000;
2171   statistics_proxy_->OnSetEncoderTargetRate(kBitrate);
2172   EXPECT_EQ(kBitrate, statistics_proxy_->GetStats().target_media_bitrate_bps);
2173 
2174   statistics_proxy_->OnSetEncoderTargetRate(0);
2175   EXPECT_EQ(0, statistics_proxy_->GetStats().target_media_bitrate_bps);
2176 }
2177 
TEST_F(SendStatisticsProxyTest,NoSubstreams)2178 TEST_F(SendStatisticsProxyTest, NoSubstreams) {
2179   uint32_t excluded_ssrc =
2180       std::max(*absl::c_max_element(config_.rtp.ssrcs),
2181                *absl::c_max_element(config_.rtp.rtx.ssrcs)) +
2182       1;
2183   // From RtcpStatisticsCallback.
2184   RtcpStatistics rtcp_stats;
2185   RtcpStatisticsCallback* rtcp_callback = statistics_proxy_.get();
2186   rtcp_callback->StatisticsUpdated(rtcp_stats, excluded_ssrc);
2187 
2188   // From BitrateStatisticsObserver.
2189   uint32_t total = 0;
2190   uint32_t retransmit = 0;
2191   BitrateStatisticsObserver* bitrate_observer = statistics_proxy_.get();
2192   bitrate_observer->Notify(total, retransmit, excluded_ssrc);
2193 
2194   // From FrameCountObserver.
2195   FrameCountObserver* fps_observer = statistics_proxy_.get();
2196   FrameCounts frame_counts;
2197   frame_counts.key_frames = 1;
2198   fps_observer->FrameCountUpdated(frame_counts, excluded_ssrc);
2199 
2200   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
2201   EXPECT_TRUE(stats.substreams.empty());
2202 }
2203 
TEST_F(SendStatisticsProxyTest,EncodedResolutionTimesOut)2204 TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
2205   static const int kEncodedWidth = 123;
2206   static const int kEncodedHeight = 81;
2207   EncodedImage encoded_image;
2208   encoded_image._encodedWidth = kEncodedWidth;
2209   encoded_image._encodedHeight = kEncodedHeight;
2210   encoded_image.SetSpatialIndex(0);
2211 
2212   CodecSpecificInfo codec_info;
2213   codec_info.codecType = kVideoCodecVP8;
2214 
2215   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2216   encoded_image.SetSpatialIndex(1);
2217   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2218 
2219   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
2220   EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
2221   EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
2222   EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
2223   EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
2224 
2225   // Forward almost to timeout, this should not have removed stats.
2226   fake_clock_.AdvanceTimeMilliseconds(SendStatisticsProxy::kStatsTimeoutMs - 1);
2227   stats = statistics_proxy_->GetStats();
2228   EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
2229   EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
2230 
2231   // Update the first SSRC with bogus RTCP stats to make sure that encoded
2232   // resolution still times out (no global timeout for all stats).
2233   RtcpStatistics rtcp_statistics;
2234   RtcpStatisticsCallback* rtcp_stats = statistics_proxy_.get();
2235   rtcp_stats->StatisticsUpdated(rtcp_statistics, config_.rtp.ssrcs[0]);
2236 
2237   // Report stats for second SSRC to make sure it's not outdated along with the
2238   // first SSRC.
2239   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2240 
2241   // Forward 1 ms, reach timeout, substream 0 should have no resolution
2242   // reported, but substream 1 should.
2243   fake_clock_.AdvanceTimeMilliseconds(1);
2244   stats = statistics_proxy_->GetStats();
2245   EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].width);
2246   EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].height);
2247   EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
2248   EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
2249 }
2250 
TEST_F(SendStatisticsProxyTest,ClearsResolutionFromInactiveSsrcs)2251 TEST_F(SendStatisticsProxyTest, ClearsResolutionFromInactiveSsrcs) {
2252   static const int kEncodedWidth = 123;
2253   static const int kEncodedHeight = 81;
2254   EncodedImage encoded_image;
2255   encoded_image._encodedWidth = kEncodedWidth;
2256   encoded_image._encodedHeight = kEncodedHeight;
2257   encoded_image.SetSpatialIndex(0);
2258 
2259   CodecSpecificInfo codec_info;
2260   codec_info.codecType = kVideoCodecVP8;
2261 
2262   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2263   encoded_image.SetSpatialIndex(1);
2264   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2265 
2266   statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
2267   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
2268   EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
2269   EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
2270   EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].width);
2271   EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].height);
2272 }
2273 
TEST_F(SendStatisticsProxyTest,ClearsBitratesFromInactiveSsrcs)2274 TEST_F(SendStatisticsProxyTest, ClearsBitratesFromInactiveSsrcs) {
2275   uint32_t bitrate = 42;
2276   BitrateStatisticsObserver* observer = statistics_proxy_.get();
2277   observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[0]);
2278   observer->Notify(bitrate, bitrate, config_.rtp.ssrcs[1]);
2279 
2280   statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
2281 
2282   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
2283   EXPECT_EQ(static_cast<int>(bitrate),
2284             stats.substreams[config_.rtp.ssrcs[0]].total_bitrate_bps);
2285   EXPECT_EQ(static_cast<int>(bitrate),
2286             stats.substreams[config_.rtp.ssrcs[0]].retransmit_bitrate_bps);
2287   EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].total_bitrate_bps);
2288   EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[1]].retransmit_bitrate_bps);
2289 }
2290 
TEST_F(SendStatisticsProxyTest,ResetsRtcpCountersOnContentChange)2291 TEST_F(SendStatisticsProxyTest, ResetsRtcpCountersOnContentChange) {
2292   RtcpPacketTypeCounterObserver* proxy =
2293       static_cast<RtcpPacketTypeCounterObserver*>(statistics_proxy_.get());
2294   RtcpPacketTypeCounter counters;
2295   counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
2296   proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
2297   proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
2298 
2299   fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
2300 
2301   counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
2302   counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
2303   counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
2304   counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
2305   counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
2306 
2307   proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
2308   proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
2309 
2310   // Changing content type causes histograms to be reported.
2311   VideoEncoderConfig config;
2312   config.content_type = VideoEncoderConfig::ContentType::kScreen;
2313   statistics_proxy_->OnEncoderReconfigured(config, {});
2314 
2315   EXPECT_METRIC_EQ(
2316       1, metrics::NumSamples("WebRTC.Video.NackPacketsReceivedPerMinute"));
2317   EXPECT_METRIC_EQ(
2318       1, metrics::NumSamples("WebRTC.Video.FirPacketsReceivedPerMinute"));
2319   EXPECT_METRIC_EQ(
2320       1, metrics::NumSamples("WebRTC.Video.PliPacketsReceivedPerMinute"));
2321   EXPECT_METRIC_EQ(1, metrics::NumSamples(
2322                           "WebRTC.Video.UniqueNackRequestsReceivedInPercent"));
2323 
2324   const int kRate = 60 * 2;  // Packets per minute with two streams.
2325 
2326   EXPECT_METRIC_EQ(
2327       1, metrics::NumEvents("WebRTC.Video.NackPacketsReceivedPerMinute",
2328                             1 * kRate));
2329   EXPECT_METRIC_EQ(
2330       1, metrics::NumEvents("WebRTC.Video.FirPacketsReceivedPerMinute",
2331                             2 * kRate));
2332   EXPECT_METRIC_EQ(
2333       1, metrics::NumEvents("WebRTC.Video.PliPacketsReceivedPerMinute",
2334                             3 * kRate));
2335   EXPECT_METRIC_EQ(
2336       1, metrics::NumEvents("WebRTC.Video.UniqueNackRequestsReceivedInPercent",
2337                             4 * 100 / 5));
2338 
2339   // New start time but same counter values.
2340   proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
2341   proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
2342 
2343   fake_clock_.AdvanceTimeMilliseconds(1000 * metrics::kMinRunTimeInSeconds);
2344 
2345   counters.nack_packets += 1 * metrics::kMinRunTimeInSeconds;
2346   counters.fir_packets += 2 * metrics::kMinRunTimeInSeconds;
2347   counters.pli_packets += 3 * metrics::kMinRunTimeInSeconds;
2348   counters.unique_nack_requests += 4 * metrics::kMinRunTimeInSeconds;
2349   counters.nack_requests += 5 * metrics::kMinRunTimeInSeconds;
2350 
2351   proxy->RtcpPacketTypesCounterUpdated(kFirstSsrc, counters);
2352   proxy->RtcpPacketTypesCounterUpdated(kSecondSsrc, counters);
2353 
2354   SetUp();  // Reset stats proxy also causes histograms to be reported.
2355 
2356   EXPECT_METRIC_EQ(
2357       1, metrics::NumSamples(
2358              "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute"));
2359   EXPECT_METRIC_EQ(1,
2360                    metrics::NumSamples(
2361                        "WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute"));
2362   EXPECT_METRIC_EQ(1,
2363                    metrics::NumSamples(
2364                        "WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute"));
2365   EXPECT_METRIC_EQ(
2366       1, metrics::NumSamples(
2367              "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent"));
2368 
2369   EXPECT_METRIC_EQ(
2370       1,
2371       metrics::NumEvents(
2372           "WebRTC.Video.Screenshare.NackPacketsReceivedPerMinute", 1 * kRate));
2373   EXPECT_METRIC_EQ(
2374       1,
2375       metrics::NumEvents("WebRTC.Video.Screenshare.FirPacketsReceivedPerMinute",
2376                          2 * kRate));
2377   EXPECT_METRIC_EQ(
2378       1,
2379       metrics::NumEvents("WebRTC.Video.Screenshare.PliPacketsReceivedPerMinute",
2380                          3 * kRate));
2381   EXPECT_METRIC_EQ(
2382       1, metrics::NumEvents(
2383              "WebRTC.Video.Screenshare.UniqueNackRequestsReceivedInPercent",
2384              4 * 100 / 5));
2385 }
2386 
TEST_F(SendStatisticsProxyTest,GetStatsReportsIsRtx)2387 TEST_F(SendStatisticsProxyTest, GetStatsReportsIsRtx) {
2388   StreamDataCountersCallback* proxy =
2389       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2390   StreamDataCounters counters;
2391   proxy->DataCountersUpdated(counters, kFirstSsrc);
2392   proxy->DataCountersUpdated(counters, kFirstRtxSsrc);
2393 
2394   EXPECT_NE(GetStreamStats(kFirstSsrc).type,
2395             VideoSendStream::StreamStats::StreamType::kRtx);
2396   EXPECT_EQ(GetStreamStats(kFirstSsrc).referenced_media_ssrc, absl::nullopt);
2397   EXPECT_EQ(GetStreamStats(kFirstRtxSsrc).type,
2398             VideoSendStream::StreamStats::StreamType::kRtx);
2399   EXPECT_EQ(GetStreamStats(kFirstRtxSsrc).referenced_media_ssrc, kFirstSsrc);
2400 }
2401 
TEST_F(SendStatisticsProxyTest,GetStatsReportsIsFlexFec)2402 TEST_F(SendStatisticsProxyTest, GetStatsReportsIsFlexFec) {
2403   statistics_proxy_.reset(
2404       new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
2405                               VideoEncoderConfig::ContentType::kRealtimeVideo));
2406 
2407   StreamDataCountersCallback* proxy =
2408       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2409   StreamDataCounters counters;
2410   proxy->DataCountersUpdated(counters, kFirstSsrc);
2411   proxy->DataCountersUpdated(counters, kFlexFecSsrc);
2412 
2413   EXPECT_NE(GetStreamStats(kFirstSsrc).type,
2414             VideoSendStream::StreamStats::StreamType::kFlexfec);
2415   EXPECT_EQ(GetStreamStats(kFirstSsrc).referenced_media_ssrc, absl::nullopt);
2416   EXPECT_EQ(GetStreamStats(kFlexFecSsrc).type,
2417             VideoSendStream::StreamStats::StreamType::kFlexfec);
2418   EXPECT_EQ(GetStreamStats(kFlexFecSsrc).referenced_media_ssrc, kFirstSsrc);
2419 }
2420 
TEST_F(SendStatisticsProxyTest,SendBitratesAreReportedWithFlexFecEnabled)2421 TEST_F(SendStatisticsProxyTest, SendBitratesAreReportedWithFlexFecEnabled) {
2422   statistics_proxy_.reset(
2423       new SendStatisticsProxy(&fake_clock_, GetTestConfigWithFlexFec(),
2424                               VideoEncoderConfig::ContentType::kRealtimeVideo));
2425 
2426   StreamDataCountersCallback* proxy =
2427       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2428   StreamDataCounters counters;
2429   StreamDataCounters rtx_counters;
2430 
2431   const int kMinRequiredPeriodSamples = 8;
2432   const int kPeriodIntervalMs = 2000;
2433   for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
2434     counters.transmitted.packets += 20;
2435     counters.transmitted.header_bytes += 500;
2436     counters.transmitted.padding_bytes += 1000;
2437     counters.transmitted.payload_bytes += 2000;
2438     counters.retransmitted.packets += 2;
2439     counters.retransmitted.header_bytes += 25;
2440     counters.retransmitted.padding_bytes += 100;
2441     counters.retransmitted.payload_bytes += 250;
2442     counters.fec = counters.retransmitted;
2443     rtx_counters.transmitted = counters.transmitted;
2444     // Advance one interval and update counters.
2445     fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
2446     proxy->DataCountersUpdated(counters, kFirstSsrc);
2447     proxy->DataCountersUpdated(counters, kSecondSsrc);
2448     proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
2449     proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
2450     proxy->DataCountersUpdated(counters, kFlexFecSsrc);
2451   }
2452 
2453   statistics_proxy_.reset();
2454   // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec  = 56 kbps
2455   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
2456   EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.BitrateSentInKbps", 56));
2457   // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec  = 28 kbps
2458   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
2459   EXPECT_METRIC_EQ(1,
2460                    metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 28));
2461   // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec  = 12 kbps
2462   EXPECT_METRIC_EQ(1,
2463                    metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
2464   EXPECT_METRIC_EQ(
2465       1, metrics::NumEvents("WebRTC.Video.MediaBitrateSentInKbps", 12));
2466   // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
2467   EXPECT_METRIC_EQ(
2468       1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
2469   EXPECT_METRIC_EQ(
2470       1, metrics::NumEvents("WebRTC.Video.PaddingBitrateSentInKbps", 16));
2471   // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
2472   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
2473   EXPECT_METRIC_EQ(1,
2474                    metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 3));
2475   // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
2476   EXPECT_METRIC_EQ(
2477       1, metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
2478   EXPECT_METRIC_EQ(
2479       1, metrics::NumEvents("WebRTC.Video.RetransmittedBitrateSentInKbps", 3));
2480 }
2481 
TEST_F(SendStatisticsProxyTest,ResetsRtpCountersOnContentChange)2482 TEST_F(SendStatisticsProxyTest, ResetsRtpCountersOnContentChange) {
2483   StreamDataCountersCallback* proxy =
2484       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2485   StreamDataCounters counters;
2486   StreamDataCounters rtx_counters;
2487   counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
2488 
2489   const int kMinRequiredPeriodSamples = 8;
2490   const int kPeriodIntervalMs = 2000;
2491   for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
2492     counters.transmitted.packets += 20;
2493     counters.transmitted.header_bytes += 500;
2494     counters.transmitted.padding_bytes += 1000;
2495     counters.transmitted.payload_bytes += 2000;
2496     counters.retransmitted.packets += 2;
2497     counters.retransmitted.header_bytes += 25;
2498     counters.retransmitted.padding_bytes += 100;
2499     counters.retransmitted.payload_bytes += 250;
2500     counters.fec = counters.retransmitted;
2501     rtx_counters.transmitted = counters.transmitted;
2502     // Advance one interval and update counters.
2503     fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
2504     proxy->DataCountersUpdated(counters, kFirstSsrc);
2505     proxy->DataCountersUpdated(counters, kSecondSsrc);
2506     proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
2507     proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
2508   }
2509 
2510   // Changing content type causes histograms to be reported.
2511   VideoEncoderConfig config;
2512   config.content_type = VideoEncoderConfig::ContentType::kScreen;
2513   statistics_proxy_->OnEncoderReconfigured(config, {});
2514 
2515   // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec  = 56 kbps
2516   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateSentInKbps"));
2517   EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.BitrateSentInKbps", 56));
2518   // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec  = 28 kbps
2519   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
2520   EXPECT_METRIC_EQ(1,
2521                    metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 28));
2522   // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec  = 12 kbps
2523   EXPECT_METRIC_EQ(1,
2524                    metrics::NumSamples("WebRTC.Video.MediaBitrateSentInKbps"));
2525   EXPECT_METRIC_EQ(
2526       1, metrics::NumEvents("WebRTC.Video.MediaBitrateSentInKbps", 12));
2527   // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
2528   EXPECT_METRIC_EQ(
2529       1, metrics::NumSamples("WebRTC.Video.PaddingBitrateSentInKbps"));
2530   EXPECT_METRIC_EQ(
2531       1, metrics::NumEvents("WebRTC.Video.PaddingBitrateSentInKbps", 16));
2532   // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
2533   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
2534   EXPECT_METRIC_EQ(1,
2535                    metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 3));
2536   // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
2537   EXPECT_METRIC_EQ(
2538       1, metrics::NumSamples("WebRTC.Video.RetransmittedBitrateSentInKbps"));
2539   EXPECT_METRIC_EQ(
2540       1, metrics::NumEvents("WebRTC.Video.RetransmittedBitrateSentInKbps", 3));
2541 
2542   // New metric counters but same data counters.
2543   // Double counter values, this should result in the same counts as before but
2544   // with new histogram names.
2545   for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
2546     counters.transmitted.packets += 20;
2547     counters.transmitted.header_bytes += 500;
2548     counters.transmitted.padding_bytes += 1000;
2549     counters.transmitted.payload_bytes += 2000;
2550     counters.retransmitted.packets += 2;
2551     counters.retransmitted.header_bytes += 25;
2552     counters.retransmitted.padding_bytes += 100;
2553     counters.retransmitted.payload_bytes += 250;
2554     counters.fec = counters.retransmitted;
2555     rtx_counters.transmitted = counters.transmitted;
2556     // Advance one interval and update counters.
2557     fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
2558     proxy->DataCountersUpdated(counters, kFirstSsrc);
2559     proxy->DataCountersUpdated(counters, kSecondSsrc);
2560     proxy->DataCountersUpdated(rtx_counters, kFirstRtxSsrc);
2561     proxy->DataCountersUpdated(rtx_counters, kSecondRtxSsrc);
2562   }
2563 
2564   // Reset stats proxy also causes histograms to be reported.
2565   statistics_proxy_.reset();
2566 
2567   // Interval: 3500 bytes * 4 / 2 sec = 7000 bytes / sec  = 56 kbps
2568   EXPECT_METRIC_EQ(
2569       1, metrics::NumSamples("WebRTC.Video.Screenshare.BitrateSentInKbps"));
2570   EXPECT_METRIC_EQ(
2571       1, metrics::NumEvents("WebRTC.Video.Screenshare.BitrateSentInKbps", 56));
2572   // Interval: 3500 bytes * 2 / 2 sec = 3500 bytes / sec  = 28 kbps
2573   EXPECT_METRIC_EQ(
2574       1, metrics::NumSamples("WebRTC.Video.Screenshare.RtxBitrateSentInKbps"));
2575   EXPECT_METRIC_EQ(1, metrics::NumEvents(
2576                           "WebRTC.Video.Screenshare.RtxBitrateSentInKbps", 28));
2577   // Interval: (2000 - 2 * 250) bytes / 2 sec = 1500 bytes / sec  = 12 kbps
2578   EXPECT_METRIC_EQ(1, metrics::NumSamples(
2579                           "WebRTC.Video.Screenshare.MediaBitrateSentInKbps"));
2580   EXPECT_METRIC_EQ(
2581       1, metrics::NumEvents("WebRTC.Video.Screenshare.MediaBitrateSentInKbps",
2582                             12));
2583   // Interval: 1000 bytes * 4 / 2 sec = 2000 bytes / sec = 16 kbps
2584   EXPECT_METRIC_EQ(1, metrics::NumSamples(
2585                           "WebRTC.Video.Screenshare.PaddingBitrateSentInKbps"));
2586   EXPECT_METRIC_EQ(
2587       1, metrics::NumEvents("WebRTC.Video.Screenshare.PaddingBitrateSentInKbps",
2588                             16));
2589   // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
2590   EXPECT_METRIC_EQ(
2591       1, metrics::NumSamples("WebRTC.Video.Screenshare.FecBitrateSentInKbps"));
2592   EXPECT_METRIC_EQ(1, metrics::NumEvents(
2593                           "WebRTC.Video.Screenshare.FecBitrateSentInKbps", 3));
2594   // Interval: 375 bytes * 2 / 2 sec = 375 bytes / sec = 3 kbps
2595   EXPECT_METRIC_EQ(
2596       1, metrics::NumSamples(
2597              "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps"));
2598   EXPECT_METRIC_EQ(
2599       1, metrics::NumEvents(
2600              "WebRTC.Video.Screenshare.RetransmittedBitrateSentInKbps", 3));
2601 }
2602 
TEST_F(SendStatisticsProxyTest,RtxBitrateIsZeroWhenEnabledAndNoRtxDataIsSent)2603 TEST_F(SendStatisticsProxyTest, RtxBitrateIsZeroWhenEnabledAndNoRtxDataIsSent) {
2604   StreamDataCountersCallback* proxy =
2605       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2606   StreamDataCounters counters;
2607   StreamDataCounters rtx_counters;
2608 
2609   const int kMinRequiredPeriodSamples = 8;
2610   const int kPeriodIntervalMs = 2000;
2611   for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
2612     counters.transmitted.packets += 20;
2613     counters.transmitted.header_bytes += 500;
2614     counters.transmitted.payload_bytes += 2000;
2615     counters.fec = counters.retransmitted;
2616     // Advance one interval and update counters.
2617     fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
2618     proxy->DataCountersUpdated(counters, kFirstSsrc);
2619   }
2620 
2621   // RTX enabled. No data sent over RTX.
2622   statistics_proxy_.reset();
2623   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
2624   EXPECT_METRIC_EQ(1,
2625                    metrics::NumEvents("WebRTC.Video.RtxBitrateSentInKbps", 0));
2626 }
2627 
TEST_F(SendStatisticsProxyTest,RtxBitrateNotReportedWhenNotEnabled)2628 TEST_F(SendStatisticsProxyTest, RtxBitrateNotReportedWhenNotEnabled) {
2629   VideoSendStream::Config config(nullptr);
2630   config.rtp.ssrcs.push_back(kFirstSsrc);  // RTX not configured.
2631   statistics_proxy_.reset(new SendStatisticsProxy(
2632       &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
2633 
2634   StreamDataCountersCallback* proxy =
2635       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2636   StreamDataCounters counters;
2637 
2638   const int kMinRequiredPeriodSamples = 8;
2639   const int kPeriodIntervalMs = 2000;
2640   for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
2641     counters.transmitted.packets += 20;
2642     counters.transmitted.header_bytes += 500;
2643     counters.transmitted.payload_bytes += 2000;
2644     counters.fec = counters.retransmitted;
2645     // Advance one interval and update counters.
2646     fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
2647     proxy->DataCountersUpdated(counters, kFirstSsrc);
2648   }
2649 
2650   // RTX not enabled.
2651   statistics_proxy_.reset();
2652   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
2653 }
2654 
TEST_F(SendStatisticsProxyTest,FecBitrateIsZeroWhenEnabledAndNoFecDataIsSent)2655 TEST_F(SendStatisticsProxyTest, FecBitrateIsZeroWhenEnabledAndNoFecDataIsSent) {
2656   StreamDataCountersCallback* proxy =
2657       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2658   StreamDataCounters counters;
2659   StreamDataCounters rtx_counters;
2660 
2661   const int kMinRequiredPeriodSamples = 8;
2662   const int kPeriodIntervalMs = 2000;
2663   for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
2664     counters.transmitted.packets += 20;
2665     counters.transmitted.header_bytes += 500;
2666     counters.transmitted.payload_bytes += 2000;
2667     // Advance one interval and update counters.
2668     fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
2669     proxy->DataCountersUpdated(counters, kFirstSsrc);
2670   }
2671 
2672   // FEC enabled. No FEC data sent.
2673   statistics_proxy_.reset();
2674   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
2675   EXPECT_METRIC_EQ(1,
2676                    metrics::NumEvents("WebRTC.Video.FecBitrateSentInKbps", 0));
2677 }
2678 
TEST_F(SendStatisticsProxyTest,FecBitrateNotReportedWhenNotEnabled)2679 TEST_F(SendStatisticsProxyTest, FecBitrateNotReportedWhenNotEnabled) {
2680   VideoSendStream::Config config(nullptr);
2681   config.rtp.ssrcs.push_back(kFirstSsrc);  // FEC not configured.
2682   statistics_proxy_.reset(new SendStatisticsProxy(
2683       &fake_clock_, config, VideoEncoderConfig::ContentType::kRealtimeVideo));
2684 
2685   StreamDataCountersCallback* proxy =
2686       static_cast<StreamDataCountersCallback*>(statistics_proxy_.get());
2687   StreamDataCounters counters;
2688 
2689   const int kMinRequiredPeriodSamples = 8;
2690   const int kPeriodIntervalMs = 2000;
2691   for (int i = 0; i < kMinRequiredPeriodSamples; ++i) {
2692     counters.transmitted.packets += 20;
2693     counters.transmitted.header_bytes += 500;
2694     counters.transmitted.payload_bytes += 2000;
2695     counters.fec = counters.retransmitted;
2696     // Advance one interval and update counters.
2697     fake_clock_.AdvanceTimeMilliseconds(kPeriodIntervalMs);
2698     proxy->DataCountersUpdated(counters, kFirstSsrc);
2699   }
2700 
2701   // FEC not enabled.
2702   statistics_proxy_.reset();
2703   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
2704 }
2705 
TEST_F(SendStatisticsProxyTest,GetStatsReportsEncoderImplementationName)2706 TEST_F(SendStatisticsProxyTest, GetStatsReportsEncoderImplementationName) {
2707   const std::string kName = "encoderName";
2708   statistics_proxy_->OnEncoderImplementationChanged(kName);
2709   EXPECT_EQ(kName, statistics_proxy_->GetStats().encoder_implementation_name);
2710 }
2711 
TEST_F(SendStatisticsProxyTest,Vp9SvcLowSpatialLayerDoesNotUpdateResolution)2712 TEST_F(SendStatisticsProxyTest, Vp9SvcLowSpatialLayerDoesNotUpdateResolution) {
2713   static const int kEncodedWidth = 123;
2714   static const int kEncodedHeight = 81;
2715   EncodedImage encoded_image;
2716   encoded_image._encodedWidth = kEncodedWidth;
2717   encoded_image._encodedHeight = kEncodedHeight;
2718   encoded_image.SetSpatialIndex(0);
2719 
2720   CodecSpecificInfo codec_info;
2721   codec_info.codecType = kVideoCodecVP9;
2722 
2723   // For first picture, it is expected that low layer updates resolution.
2724   codec_info.codecSpecific.VP9.end_of_picture = false;
2725   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2726   VideoSendStream::Stats stats = statistics_proxy_->GetStats();
2727   EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
2728   EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
2729 
2730   // Top layer updates resolution.
2731   encoded_image._encodedWidth = kEncodedWidth * 2;
2732   encoded_image._encodedHeight = kEncodedHeight * 2;
2733   codec_info.codecSpecific.VP9.end_of_picture = true;
2734   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2735   stats = statistics_proxy_->GetStats();
2736   EXPECT_EQ(kEncodedWidth * 2, stats.substreams[config_.rtp.ssrcs[0]].width);
2737   EXPECT_EQ(kEncodedHeight * 2, stats.substreams[config_.rtp.ssrcs[0]].height);
2738 
2739   // Low layer of next frame doesn't update resolution.
2740   encoded_image._encodedWidth = kEncodedWidth;
2741   encoded_image._encodedHeight = kEncodedHeight;
2742   codec_info.codecSpecific.VP9.end_of_picture = false;
2743   statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
2744   stats = statistics_proxy_->GetStats();
2745   EXPECT_EQ(kEncodedWidth * 2, stats.substreams[config_.rtp.ssrcs[0]].width);
2746   EXPECT_EQ(kEncodedHeight * 2, stats.substreams[config_.rtp.ssrcs[0]].height);
2747 }
2748 
2749 class ForcedFallbackTest : public SendStatisticsProxyTest {
2750  public:
ForcedFallbackTest(const std::string & field_trials)2751   explicit ForcedFallbackTest(const std::string& field_trials)
2752       : SendStatisticsProxyTest(field_trials) {
2753     codec_info_.codecType = kVideoCodecVP8;
2754     codec_info_.codecSpecific.VP8.temporalIdx = 0;
2755     encoded_image_._encodedWidth = kWidth;
2756     encoded_image_._encodedHeight = kHeight;
2757     encoded_image_.SetSpatialIndex(0);
2758   }
2759 
~ForcedFallbackTest()2760   ~ForcedFallbackTest() override {}
2761 
2762  protected:
InsertEncodedFrames(int num_frames,int interval_ms)2763   void InsertEncodedFrames(int num_frames, int interval_ms) {
2764     statistics_proxy_->OnEncoderImplementationChanged(codec_name_);
2765 
2766     // First frame is not updating stats, insert initial frame.
2767     if (statistics_proxy_->GetStats().frames_encoded == 0) {
2768       statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
2769     }
2770     for (int i = 0; i < num_frames; ++i) {
2771       statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
2772       fake_clock_.AdvanceTimeMilliseconds(interval_ms);
2773     }
2774     // Add frame to include last time interval.
2775     statistics_proxy_->OnSendEncodedImage(encoded_image_, &codec_info_);
2776   }
2777 
2778   EncodedImage encoded_image_;
2779   CodecSpecificInfo codec_info_;
2780   std::string codec_name_;
2781   const std::string kPrefix = "WebRTC.Video.Encoder.ForcedSw";
2782   const int kFrameIntervalMs = 1000;
2783   const int kMinFrames = 20;  // Min run time 20 sec.
2784 };
2785 
2786 class ForcedFallbackDisabled : public ForcedFallbackTest {
2787  public:
ForcedFallbackDisabled()2788   ForcedFallbackDisabled()
2789       : ForcedFallbackTest("WebRTC-VP8-Forced-Fallback-Encoder-v2/Disabled-1," +
2790                            std::to_string(kWidth * kHeight) + ",3/") {}
2791 };
2792 
2793 class ForcedFallbackEnabled : public ForcedFallbackTest {
2794  public:
ForcedFallbackEnabled()2795   ForcedFallbackEnabled()
2796       : ForcedFallbackTest("WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1," +
2797                            std::to_string(kWidth * kHeight) + ",3/") {}
2798 };
2799 
TEST_F(ForcedFallbackEnabled,StatsNotUpdatedIfMinRunTimeHasNotPassed)2800 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedIfMinRunTimeHasNotPassed) {
2801   InsertEncodedFrames(kMinFrames, kFrameIntervalMs - 1);
2802   statistics_proxy_.reset();
2803   EXPECT_METRIC_EQ(0,
2804                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2805   EXPECT_METRIC_EQ(
2806       0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2807 }
2808 
TEST_F(ForcedFallbackEnabled,StatsUpdated)2809 TEST_F(ForcedFallbackEnabled, StatsUpdated) {
2810   InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
2811   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2812   statistics_proxy_.reset();
2813   EXPECT_METRIC_EQ(1,
2814                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2815   EXPECT_METRIC_EQ(
2816       1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 0));
2817   EXPECT_METRIC_EQ(
2818       1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2819   EXPECT_METRIC_EQ(
2820       1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 0));
2821 }
2822 
TEST_F(ForcedFallbackEnabled,StatsNotUpdatedIfNotVp8)2823 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedIfNotVp8) {
2824   codec_info_.codecType = kVideoCodecVP9;
2825   InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
2826   statistics_proxy_.reset();
2827   EXPECT_METRIC_EQ(0,
2828                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2829   EXPECT_METRIC_EQ(
2830       0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2831 }
2832 
TEST_F(ForcedFallbackEnabled,StatsNotUpdatedForTemporalLayers)2833 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedForTemporalLayers) {
2834   codec_info_.codecSpecific.VP8.temporalIdx = 1;
2835   InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
2836   statistics_proxy_.reset();
2837   EXPECT_METRIC_EQ(0,
2838                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2839   EXPECT_METRIC_EQ(
2840       0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2841 }
2842 
TEST_F(ForcedFallbackEnabled,StatsNotUpdatedForSimulcast)2843 TEST_F(ForcedFallbackEnabled, StatsNotUpdatedForSimulcast) {
2844   encoded_image_.SetSpatialIndex(1);
2845   InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
2846   statistics_proxy_.reset();
2847   EXPECT_METRIC_EQ(0,
2848                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2849   EXPECT_METRIC_EQ(
2850       0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2851 }
2852 
TEST_F(ForcedFallbackDisabled,StatsNotUpdatedIfNoFieldTrial)2853 TEST_F(ForcedFallbackDisabled, StatsNotUpdatedIfNoFieldTrial) {
2854   InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
2855   statistics_proxy_.reset();
2856   EXPECT_METRIC_EQ(0,
2857                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2858   EXPECT_METRIC_EQ(
2859       0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2860 }
2861 
TEST_F(ForcedFallbackDisabled,EnteredLowResolutionSetIfAtMaxPixels)2862 TEST_F(ForcedFallbackDisabled, EnteredLowResolutionSetIfAtMaxPixels) {
2863   InsertEncodedFrames(1, kFrameIntervalMs);
2864   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2865 }
2866 
TEST_F(ForcedFallbackEnabled,EnteredLowResolutionNotSetIfNotLibvpx)2867 TEST_F(ForcedFallbackEnabled, EnteredLowResolutionNotSetIfNotLibvpx) {
2868   InsertEncodedFrames(1, kFrameIntervalMs);
2869   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2870 }
2871 
TEST_F(ForcedFallbackEnabled,EnteredLowResolutionSetIfLibvpx)2872 TEST_F(ForcedFallbackEnabled, EnteredLowResolutionSetIfLibvpx) {
2873   codec_name_ = "libvpx";
2874   InsertEncodedFrames(1, kFrameIntervalMs);
2875   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2876 }
2877 
TEST_F(ForcedFallbackDisabled,EnteredLowResolutionNotSetIfAboveMaxPixels)2878 TEST_F(ForcedFallbackDisabled, EnteredLowResolutionNotSetIfAboveMaxPixels) {
2879   encoded_image_._encodedWidth = kWidth + 1;
2880   InsertEncodedFrames(1, kFrameIntervalMs);
2881   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2882 }
2883 
TEST_F(ForcedFallbackDisabled,EnteredLowResolutionNotSetIfLibvpx)2884 TEST_F(ForcedFallbackDisabled, EnteredLowResolutionNotSetIfLibvpx) {
2885   codec_name_ = "libvpx";
2886   InsertEncodedFrames(1, kFrameIntervalMs);
2887   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2888 }
2889 
TEST_F(ForcedFallbackDisabled,EnteredLowResolutionSetIfOnMinPixelLimitReached)2890 TEST_F(ForcedFallbackDisabled,
2891        EnteredLowResolutionSetIfOnMinPixelLimitReached) {
2892   encoded_image_._encodedWidth = kWidth + 1;
2893   statistics_proxy_->OnMinPixelLimitReached();
2894   InsertEncodedFrames(1, kFrameIntervalMs);
2895   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2896 }
2897 
TEST_F(ForcedFallbackEnabled,OneFallbackEvent)2898 TEST_F(ForcedFallbackEnabled, OneFallbackEvent) {
2899   // One change. Video: 20000 ms, fallback: 5000 ms (25%).
2900   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2901   InsertEncodedFrames(15, 1000);
2902   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2903   codec_name_ = "libvpx";
2904   InsertEncodedFrames(5, 1000);
2905   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2906 
2907   statistics_proxy_.reset();
2908   EXPECT_METRIC_EQ(1,
2909                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2910   EXPECT_METRIC_EQ(
2911       1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 25));
2912   EXPECT_METRIC_EQ(
2913       1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2914   EXPECT_METRIC_EQ(
2915       1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 3));
2916 }
2917 
TEST_F(ForcedFallbackEnabled,ThreeFallbackEvents)2918 TEST_F(ForcedFallbackEnabled, ThreeFallbackEvents) {
2919   codec_info_.codecSpecific.VP8.temporalIdx = kNoTemporalIdx;  // Should work.
2920   const int kMaxFrameDiffMs = 2000;
2921 
2922   // Three changes. Video: 60000 ms, fallback: 15000 ms (25%).
2923   InsertEncodedFrames(10, 1000);
2924   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2925   codec_name_ = "libvpx";
2926   InsertEncodedFrames(15, 500);
2927   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2928   codec_name_ = "notlibvpx";
2929   InsertEncodedFrames(20, 1000);
2930   InsertEncodedFrames(3, kMaxFrameDiffMs);  // Should not be included.
2931   InsertEncodedFrames(10, 1000);
2932   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2933   codec_name_ = "notlibvpx2";
2934   InsertEncodedFrames(10, 500);
2935   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2936   codec_name_ = "libvpx";
2937   InsertEncodedFrames(15, 500);
2938   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2939 
2940   statistics_proxy_.reset();
2941   EXPECT_METRIC_EQ(1,
2942                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2943   EXPECT_METRIC_EQ(
2944       1, metrics::NumEvents(kPrefix + "FallbackTimeInPercent.Vp8", 25));
2945   EXPECT_METRIC_EQ(
2946       1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2947   EXPECT_METRIC_EQ(
2948       1, metrics::NumEvents(kPrefix + "FallbackChangesPerMinute.Vp8", 3));
2949 }
2950 
TEST_F(ForcedFallbackEnabled,NoFallbackIfAboveMaxPixels)2951 TEST_F(ForcedFallbackEnabled, NoFallbackIfAboveMaxPixels) {
2952   encoded_image_._encodedWidth = kWidth + 1;
2953   codec_name_ = "libvpx";
2954   InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
2955 
2956   EXPECT_FALSE(statistics_proxy_->GetStats().has_entered_low_resolution);
2957   statistics_proxy_.reset();
2958   EXPECT_METRIC_EQ(0,
2959                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2960   EXPECT_METRIC_EQ(
2961       0, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2962 }
2963 
TEST_F(ForcedFallbackEnabled,FallbackIfAtMaxPixels)2964 TEST_F(ForcedFallbackEnabled, FallbackIfAtMaxPixels) {
2965   encoded_image_._encodedWidth = kWidth;
2966   codec_name_ = "libvpx";
2967   InsertEncodedFrames(kMinFrames, kFrameIntervalMs);
2968 
2969   EXPECT_TRUE(statistics_proxy_->GetStats().has_entered_low_resolution);
2970   statistics_proxy_.reset();
2971   EXPECT_METRIC_EQ(1,
2972                    metrics::NumSamples(kPrefix + "FallbackTimeInPercent.Vp8"));
2973   EXPECT_METRIC_EQ(
2974       1, metrics::NumSamples(kPrefix + "FallbackChangesPerMinute.Vp8"));
2975 }
2976 
2977 }  // namespace webrtc
2978