1 /*
2  *  Copyright 2020 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/receive_statistics_proxy2.h"
12 
13 #include <limits>
14 #include <memory>
15 #include <string>
16 #include <tuple>
17 #include <utility>
18 
19 #include "absl/types/optional.h"
20 #include "api/scoped_refptr.h"
21 #include "api/video/i420_buffer.h"
22 #include "api/video/video_frame.h"
23 #include "api/video/video_frame_buffer.h"
24 #include "api/video/video_rotation.h"
25 #include "rtc_base/task_utils/to_queued_task.h"
26 #include "rtc_base/thread.h"
27 #include "system_wrappers/include/metrics.h"
28 #include "test/field_trial.h"
29 #include "test/gtest.h"
30 #include "test/run_loop.h"
31 #include "video/video_receive_stream2.h"
32 
33 namespace webrtc {
34 namespace internal {
35 namespace {
36 const int64_t kFreqOffsetProcessIntervalInMs = 40000;
37 const uint32_t kLocalSsrc = 123;
38 const uint32_t kRemoteSsrc = 456;
39 const int kMinRequiredSamples = 200;
40 const int kWidth = 1280;
41 const int kHeight = 720;
42 }  // namespace
43 
44 // TODO(sakal): ReceiveStatisticsProxy is lacking unittesting.
45 class ReceiveStatisticsProxy2Test : public ::testing::Test {
46  public:
ReceiveStatisticsProxy2Test()47   ReceiveStatisticsProxy2Test() : fake_clock_(1234), config_(GetTestConfig()) {
48     metrics::Reset();
49     statistics_proxy_.reset(
50         new ReceiveStatisticsProxy(&config_, &fake_clock_, loop_.task_queue()));
51   }
52 
~ReceiveStatisticsProxy2Test()53   ~ReceiveStatisticsProxy2Test() override { statistics_proxy_.reset(); }
54 
55  protected:
56   // Convenience method to avoid too many explict flushes.
FlushAndGetStats()57   VideoReceiveStream::Stats FlushAndGetStats() {
58     loop_.Flush();
59     return statistics_proxy_->GetStats();
60   }
61 
FlushAndUpdateHistograms(absl::optional<int> fraction_lost,const StreamDataCounters & rtp_stats,const StreamDataCounters * rtx_stats)62   void FlushAndUpdateHistograms(absl::optional<int> fraction_lost,
63                                 const StreamDataCounters& rtp_stats,
64                                 const StreamDataCounters* rtx_stats) {
65     loop_.Flush();
66     statistics_proxy_->UpdateHistograms(fraction_lost, rtp_stats, rtx_stats);
67   }
68 
GetTestConfig()69   VideoReceiveStream::Config GetTestConfig() {
70     VideoReceiveStream::Config config(nullptr);
71     config.rtp.local_ssrc = kLocalSsrc;
72     config.rtp.remote_ssrc = kRemoteSsrc;
73     return config;
74   }
75 
CreateFrame(int width,int height)76   VideoFrame CreateFrame(int width, int height) {
77     return CreateVideoFrame(width, height, 0);
78   }
79 
CreateFrameWithRenderTime(Timestamp render_time)80   VideoFrame CreateFrameWithRenderTime(Timestamp render_time) {
81     return CreateFrameWithRenderTimeMs(render_time.ms());
82   }
83 
CreateFrameWithRenderTimeMs(int64_t render_time_ms)84   VideoFrame CreateFrameWithRenderTimeMs(int64_t render_time_ms) {
85     return CreateVideoFrame(kWidth, kHeight, render_time_ms);
86   }
87 
CreateVideoFrame(int width,int height,int64_t render_time_ms)88   VideoFrame CreateVideoFrame(int width, int height, int64_t render_time_ms) {
89     VideoFrame frame =
90         VideoFrame::Builder()
91             .set_video_frame_buffer(I420Buffer::Create(width, height))
92             .set_timestamp_rtp(0)
93             .set_timestamp_ms(render_time_ms)
94             .set_rotation(kVideoRotation_0)
95             .build();
96     frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
97     return frame;
98   }
99 
100   // Return the current fake time as a Timestamp.
Now()101   Timestamp Now() { return fake_clock_.CurrentTime(); }
102 
103   // Creates a VideoFrameMetaData instance with a timestamp.
MetaData(const VideoFrame & frame,Timestamp ts)104   VideoFrameMetaData MetaData(const VideoFrame& frame, Timestamp ts) {
105     return VideoFrameMetaData(frame, ts);
106   }
107 
108   // Creates a VideoFrameMetaData instance with the current fake time.
MetaData(const VideoFrame & frame)109   VideoFrameMetaData MetaData(const VideoFrame& frame) {
110     return VideoFrameMetaData(frame, Now());
111   }
112 
113   SimulatedClock fake_clock_;
114   const VideoReceiveStream::Config config_;
115   std::unique_ptr<ReceiveStatisticsProxy> statistics_proxy_;
116   test::RunLoop loop_;
117 };
118 
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesFramesDecoded)119 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesFramesDecoded) {
120   EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
121   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
122   for (uint32_t i = 1; i <= 3; ++i) {
123     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
124                                       VideoContentType::UNSPECIFIED);
125     EXPECT_EQ(i, FlushAndGetStats().frames_decoded);
126   }
127 }
128 
TEST_F(ReceiveStatisticsProxy2Test,DecodedFpsIsReported)129 TEST_F(ReceiveStatisticsProxy2Test, DecodedFpsIsReported) {
130   const int kFps = 20;
131   const int kRequiredSamples = metrics::kMinRunTimeInSeconds * kFps;
132   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
133   for (int i = 0; i < kRequiredSamples; ++i) {
134     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
135                                       VideoContentType::UNSPECIFIED);
136     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
137   }
138   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
139   EXPECT_METRIC_EQ(1,
140                    metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
141   EXPECT_METRIC_EQ(
142       1, metrics::NumEvents("WebRTC.Video.DecodedFramesPerSecond", kFps));
143 }
144 
TEST_F(ReceiveStatisticsProxy2Test,DecodedFpsIsNotReportedForTooFewSamples)145 TEST_F(ReceiveStatisticsProxy2Test, DecodedFpsIsNotReportedForTooFewSamples) {
146   const int kFps = 20;
147   const int kRequiredSamples = metrics::kMinRunTimeInSeconds * kFps;
148   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
149   for (int i = 0; i < kRequiredSamples - 1; ++i) {
150     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
151                                       VideoContentType::UNSPECIFIED);
152     fake_clock_.AdvanceTimeMilliseconds(1000 / kFps);
153   }
154   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
155   EXPECT_METRIC_EQ(0,
156                    metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
157 }
158 
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameWithQpDoesNotResetFramesDecodedOrTotalDecodeTime)159 TEST_F(ReceiveStatisticsProxy2Test,
160        OnDecodedFrameWithQpDoesNotResetFramesDecodedOrTotalDecodeTime) {
161   EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded);
162   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
163   unsigned int expected_total_decode_time_ms = 0;
164   unsigned int expected_frames_decoded = 0;
165   for (uint32_t i = 1; i <= 3; ++i) {
166     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 1,
167                                       VideoContentType::UNSPECIFIED);
168     expected_total_decode_time_ms += 1;
169     ++expected_frames_decoded;
170     loop_.Flush();
171     EXPECT_EQ(expected_frames_decoded,
172               statistics_proxy_->GetStats().frames_decoded);
173     EXPECT_EQ(expected_total_decode_time_ms,
174               statistics_proxy_->GetStats().total_decode_time_ms);
175   }
176   statistics_proxy_->OnDecodedFrame(frame, 1u, 3,
177                                     VideoContentType::UNSPECIFIED);
178   ++expected_frames_decoded;
179   expected_total_decode_time_ms += 3;
180   loop_.Flush();
181   EXPECT_EQ(expected_frames_decoded,
182             statistics_proxy_->GetStats().frames_decoded);
183   EXPECT_EQ(expected_total_decode_time_ms,
184             statistics_proxy_->GetStats().total_decode_time_ms);
185 }
186 
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesQpSum)187 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesQpSum) {
188   EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
189   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
190   statistics_proxy_->OnDecodedFrame(frame, 3u, 0,
191                                     VideoContentType::UNSPECIFIED);
192   EXPECT_EQ(3u, FlushAndGetStats().qp_sum);
193   statistics_proxy_->OnDecodedFrame(frame, 127u, 0,
194                                     VideoContentType::UNSPECIFIED);
195   EXPECT_EQ(130u, FlushAndGetStats().qp_sum);
196 }
197 
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameIncreasesTotalDecodeTime)198 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameIncreasesTotalDecodeTime) {
199   EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
200   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
201   statistics_proxy_->OnDecodedFrame(frame, 3u, 4,
202                                     VideoContentType::UNSPECIFIED);
203   EXPECT_EQ(4u, FlushAndGetStats().total_decode_time_ms);
204   statistics_proxy_->OnDecodedFrame(frame, 127u, 7,
205                                     VideoContentType::UNSPECIFIED);
206   EXPECT_EQ(11u, FlushAndGetStats().total_decode_time_ms);
207 }
208 
TEST_F(ReceiveStatisticsProxy2Test,ReportsContentType)209 TEST_F(ReceiveStatisticsProxy2Test, ReportsContentType) {
210   const std::string kRealtimeString("realtime");
211   const std::string kScreenshareString("screen");
212   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
213   EXPECT_EQ(kRealtimeString, videocontenttypehelpers::ToString(
214                                  statistics_proxy_->GetStats().content_type));
215   statistics_proxy_->OnDecodedFrame(frame, 3u, 0,
216                                     VideoContentType::SCREENSHARE);
217   EXPECT_EQ(kScreenshareString,
218             videocontenttypehelpers::ToString(FlushAndGetStats().content_type));
219   statistics_proxy_->OnDecodedFrame(frame, 3u, 0,
220                                     VideoContentType::UNSPECIFIED);
221   EXPECT_EQ(kRealtimeString,
222             videocontenttypehelpers::ToString(FlushAndGetStats().content_type));
223 }
224 
TEST_F(ReceiveStatisticsProxy2Test,ReportsMaxTotalInterFrameDelay)225 TEST_F(ReceiveStatisticsProxy2Test, ReportsMaxTotalInterFrameDelay) {
226   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
227   const TimeDelta kInterFrameDelay1 = TimeDelta::Millis(100);
228   const TimeDelta kInterFrameDelay2 = TimeDelta::Millis(200);
229   const TimeDelta kInterFrameDelay3 = TimeDelta::Millis(300);
230   double expected_total_inter_frame_delay = 0;
231   double expected_total_squared_inter_frame_delay = 0;
232   EXPECT_EQ(expected_total_inter_frame_delay,
233             statistics_proxy_->GetStats().total_inter_frame_delay);
234   EXPECT_EQ(expected_total_squared_inter_frame_delay,
235             statistics_proxy_->GetStats().total_squared_inter_frame_delay);
236 
237   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
238                                     VideoContentType::UNSPECIFIED);
239   EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
240                    FlushAndGetStats().total_inter_frame_delay);
241   EXPECT_DOUBLE_EQ(expected_total_squared_inter_frame_delay,
242                    FlushAndGetStats().total_squared_inter_frame_delay);
243 
244   fake_clock_.AdvanceTime(kInterFrameDelay1);
245   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
246                                     VideoContentType::UNSPECIFIED);
247   expected_total_inter_frame_delay += kInterFrameDelay1.seconds<double>();
248   expected_total_squared_inter_frame_delay +=
249       pow(kInterFrameDelay1.seconds<double>(), 2.0);
250   EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
251                    FlushAndGetStats().total_inter_frame_delay);
252   EXPECT_DOUBLE_EQ(
253       expected_total_squared_inter_frame_delay,
254       statistics_proxy_->GetStats().total_squared_inter_frame_delay);
255 
256   fake_clock_.AdvanceTime(kInterFrameDelay2);
257   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
258                                     VideoContentType::UNSPECIFIED);
259   expected_total_inter_frame_delay += kInterFrameDelay2.seconds<double>();
260   expected_total_squared_inter_frame_delay +=
261       pow(kInterFrameDelay2.seconds<double>(), 2.0);
262   EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
263                    FlushAndGetStats().total_inter_frame_delay);
264   EXPECT_DOUBLE_EQ(
265       expected_total_squared_inter_frame_delay,
266       statistics_proxy_->GetStats().total_squared_inter_frame_delay);
267 
268   fake_clock_.AdvanceTime(kInterFrameDelay3);
269   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
270                                     VideoContentType::UNSPECIFIED);
271   expected_total_inter_frame_delay += kInterFrameDelay3.seconds<double>();
272   expected_total_squared_inter_frame_delay +=
273       pow(kInterFrameDelay3.seconds<double>(), 2.0);
274   EXPECT_DOUBLE_EQ(expected_total_inter_frame_delay,
275                    FlushAndGetStats().total_inter_frame_delay);
276   EXPECT_DOUBLE_EQ(
277       expected_total_squared_inter_frame_delay,
278       statistics_proxy_->GetStats().total_squared_inter_frame_delay);
279 }
280 
TEST_F(ReceiveStatisticsProxy2Test,ReportsMaxInterframeDelay)281 TEST_F(ReceiveStatisticsProxy2Test, ReportsMaxInterframeDelay) {
282   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
283   const int64_t kInterframeDelayMs1 = 100;
284   const int64_t kInterframeDelayMs2 = 200;
285   const int64_t kInterframeDelayMs3 = 100;
286   EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
287   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
288                                     VideoContentType::UNSPECIFIED);
289   EXPECT_EQ(-1, FlushAndGetStats().interframe_delay_max_ms);
290 
291   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
292   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
293                                     VideoContentType::UNSPECIFIED);
294   EXPECT_EQ(kInterframeDelayMs1, FlushAndGetStats().interframe_delay_max_ms);
295 
296   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
297   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
298                                     VideoContentType::UNSPECIFIED);
299   EXPECT_EQ(kInterframeDelayMs2, FlushAndGetStats().interframe_delay_max_ms);
300 
301   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
302   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
303                                     VideoContentType::UNSPECIFIED);
304   // kInterframeDelayMs3 is smaller than kInterframeDelayMs2.
305   EXPECT_EQ(kInterframeDelayMs2, FlushAndGetStats().interframe_delay_max_ms);
306 }
307 
TEST_F(ReceiveStatisticsProxy2Test,ReportInterframeDelayInWindow)308 TEST_F(ReceiveStatisticsProxy2Test, ReportInterframeDelayInWindow) {
309   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
310   const int64_t kInterframeDelayMs1 = 900;
311   const int64_t kInterframeDelayMs2 = 750;
312   const int64_t kInterframeDelayMs3 = 700;
313   EXPECT_EQ(-1, statistics_proxy_->GetStats().interframe_delay_max_ms);
314   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
315                                     VideoContentType::UNSPECIFIED);
316   EXPECT_EQ(-1, FlushAndGetStats().interframe_delay_max_ms);
317 
318   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1);
319   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
320                                     VideoContentType::UNSPECIFIED);
321   EXPECT_EQ(kInterframeDelayMs1, FlushAndGetStats().interframe_delay_max_ms);
322 
323   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2);
324   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
325                                     VideoContentType::UNSPECIFIED);
326   // Still first delay is the maximum
327   EXPECT_EQ(kInterframeDelayMs1, FlushAndGetStats().interframe_delay_max_ms);
328 
329   fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs3);
330   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
331                                     VideoContentType::UNSPECIFIED);
332   // Now the first sample is out of the window, so the second is the maximum.
333   EXPECT_EQ(kInterframeDelayMs2, FlushAndGetStats().interframe_delay_max_ms);
334 }
335 
TEST_F(ReceiveStatisticsProxy2Test,ReportsFreezeMetrics)336 TEST_F(ReceiveStatisticsProxy2Test, ReportsFreezeMetrics) {
337   const int64_t kFreezeDurationMs = 1000;
338 
339   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
340   EXPECT_EQ(0u, stats.freeze_count);
341   EXPECT_FALSE(stats.total_freezes_duration_ms);
342 
343   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
344   for (size_t i = 0; i < VideoQualityObserver::kMinFrameSamplesToDetectFreeze;
345        ++i) {
346     fake_clock_.AdvanceTimeMilliseconds(30);
347     statistics_proxy_->OnRenderedFrame(MetaData(frame));
348   }
349 
350   // Freeze.
351   fake_clock_.AdvanceTimeMilliseconds(kFreezeDurationMs);
352   statistics_proxy_->OnRenderedFrame(MetaData(frame));
353 
354   stats = statistics_proxy_->GetStats();
355   EXPECT_EQ(1u, stats.freeze_count);
356   EXPECT_EQ(kFreezeDurationMs, stats.total_freezes_duration_ms);
357 }
358 
TEST_F(ReceiveStatisticsProxy2Test,ReportsPauseMetrics)359 TEST_F(ReceiveStatisticsProxy2Test, ReportsPauseMetrics) {
360   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
361   ASSERT_EQ(0u, stats.pause_count);
362   ASSERT_EQ(0u, stats.total_pauses_duration_ms);
363 
364   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
365   statistics_proxy_->OnRenderedFrame(MetaData(frame));
366 
367   // Pause.
368   fake_clock_.AdvanceTimeMilliseconds(5432);
369   statistics_proxy_->OnStreamInactive();
370   statistics_proxy_->OnRenderedFrame(MetaData(frame));
371 
372   stats = statistics_proxy_->GetStats();
373   EXPECT_EQ(1u, stats.pause_count);
374   EXPECT_EQ(5432u, stats.total_pauses_duration_ms);
375 }
376 
TEST_F(ReceiveStatisticsProxy2Test,PauseBeforeFirstAndAfterLastFrameIgnored)377 TEST_F(ReceiveStatisticsProxy2Test, PauseBeforeFirstAndAfterLastFrameIgnored) {
378   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
379   ASSERT_EQ(0u, stats.pause_count);
380   ASSERT_EQ(0u, stats.total_pauses_duration_ms);
381 
382   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
383 
384   // Pause -> Frame -> Pause
385   fake_clock_.AdvanceTimeMilliseconds(5000);
386   statistics_proxy_->OnStreamInactive();
387   statistics_proxy_->OnRenderedFrame(MetaData(frame));
388 
389   fake_clock_.AdvanceTimeMilliseconds(30);
390   statistics_proxy_->OnRenderedFrame(MetaData(frame));
391 
392   fake_clock_.AdvanceTimeMilliseconds(5000);
393   statistics_proxy_->OnStreamInactive();
394 
395   stats = statistics_proxy_->GetStats();
396   EXPECT_EQ(0u, stats.pause_count);
397   EXPECT_EQ(0u, stats.total_pauses_duration_ms);
398 }
399 
TEST_F(ReceiveStatisticsProxy2Test,ReportsFramesDuration)400 TEST_F(ReceiveStatisticsProxy2Test, ReportsFramesDuration) {
401   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
402   ASSERT_EQ(0u, stats.total_frames_duration_ms);
403 
404   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
405 
406   // Emulate delay before first frame is rendered. This is needed to ensure
407   // that frame duration only covers time since first frame is rendered and
408   // not the total time.
409   fake_clock_.AdvanceTimeMilliseconds(5432);
410 
411   for (int i = 0; i <= 10; ++i) {
412     fake_clock_.AdvanceTimeMilliseconds(30);
413     statistics_proxy_->OnRenderedFrame(MetaData(frame));
414   }
415 
416   stats = statistics_proxy_->GetStats();
417   EXPECT_EQ(10 * 30u, stats.total_frames_duration_ms);
418 }
419 
TEST_F(ReceiveStatisticsProxy2Test,ReportsSumSquaredFrameDurations)420 TEST_F(ReceiveStatisticsProxy2Test, ReportsSumSquaredFrameDurations) {
421   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
422   ASSERT_EQ(0u, stats.sum_squared_frame_durations);
423 
424   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
425   for (int i = 0; i <= 10; ++i) {
426     fake_clock_.AdvanceTimeMilliseconds(30);
427     statistics_proxy_->OnRenderedFrame(MetaData(frame));
428   }
429 
430   stats = statistics_proxy_->GetStats();
431   const double kExpectedSumSquaredFrameDurationsSecs =
432       10 * (30 / 1000.0 * 30 / 1000.0);
433   EXPECT_EQ(kExpectedSumSquaredFrameDurationsSecs,
434             stats.sum_squared_frame_durations);
435 }
436 
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameWithoutQpQpSumWontExist)437 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameWithoutQpQpSumWontExist) {
438   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
439   EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
440   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
441                                     VideoContentType::UNSPECIFIED);
442   EXPECT_EQ(absl::nullopt, FlushAndGetStats().qp_sum);
443 }
444 
TEST_F(ReceiveStatisticsProxy2Test,OnDecodedFrameWithoutQpResetsQpSum)445 TEST_F(ReceiveStatisticsProxy2Test, OnDecodedFrameWithoutQpResetsQpSum) {
446   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
447   EXPECT_EQ(absl::nullopt, statistics_proxy_->GetStats().qp_sum);
448   statistics_proxy_->OnDecodedFrame(frame, 3u, 0,
449                                     VideoContentType::UNSPECIFIED);
450   EXPECT_EQ(3u, FlushAndGetStats().qp_sum);
451   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
452                                     VideoContentType::UNSPECIFIED);
453   EXPECT_EQ(absl::nullopt, FlushAndGetStats().qp_sum);
454 }
455 
TEST_F(ReceiveStatisticsProxy2Test,OnRenderedFrameIncreasesFramesRendered)456 TEST_F(ReceiveStatisticsProxy2Test, OnRenderedFrameIncreasesFramesRendered) {
457   EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
458   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
459   for (uint32_t i = 1; i <= 3; ++i) {
460     statistics_proxy_->OnRenderedFrame(MetaData(frame));
461     EXPECT_EQ(i, statistics_proxy_->GetStats().frames_rendered);
462   }
463 }
464 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsSsrc)465 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsSsrc) {
466   EXPECT_EQ(kRemoteSsrc, statistics_proxy_->GetStats().ssrc);
467 }
468 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsIncomingPayloadType)469 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsIncomingPayloadType) {
470   const int kPayloadType = 111;
471   statistics_proxy_->OnIncomingPayloadType(kPayloadType);
472   loop_.Flush();
473   EXPECT_EQ(kPayloadType, statistics_proxy_->GetStats().current_payload_type);
474 }
475 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsDecoderImplementationName)476 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsDecoderImplementationName) {
477   const char* kName = "decoderName";
478   statistics_proxy_->OnDecoderImplementationName(kName);
479   loop_.Flush();
480   EXPECT_STREQ(
481       kName, statistics_proxy_->GetStats().decoder_implementation_name.c_str());
482 }
483 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsOnCompleteFrame)484 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsOnCompleteFrame) {
485   const int kFrameSizeBytes = 1000;
486   statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
487                                      VideoContentType::UNSPECIFIED);
488   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
489   EXPECT_EQ(1, stats.network_frame_rate);
490   EXPECT_EQ(1, stats.frame_counts.key_frames);
491   EXPECT_EQ(0, stats.frame_counts.delta_frames);
492 }
493 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsOnDroppedFrame)494 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsOnDroppedFrame) {
495   unsigned int dropped_frames = 0;
496   for (int i = 0; i < 10; ++i) {
497     statistics_proxy_->OnDroppedFrames(i);
498     dropped_frames += i;
499   }
500   VideoReceiveStream::Stats stats = FlushAndGetStats();
501   EXPECT_EQ(dropped_frames, stats.frames_dropped);
502 }
503 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsDecodeTimingStats)504 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsDecodeTimingStats) {
505   const int kMaxDecodeMs = 2;
506   const int kCurrentDelayMs = 3;
507   const int kTargetDelayMs = 4;
508   const int kJitterBufferMs = 5;
509   const int kMinPlayoutDelayMs = 6;
510   const int kRenderDelayMs = 7;
511   const int64_t kRttMs = 8;
512   statistics_proxy_->OnRttUpdate(kRttMs);
513   statistics_proxy_->OnFrameBufferTimingsUpdated(
514       kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
515       kMinPlayoutDelayMs, kRenderDelayMs);
516   VideoReceiveStream::Stats stats = FlushAndGetStats();
517   EXPECT_EQ(kMaxDecodeMs, stats.max_decode_ms);
518   EXPECT_EQ(kCurrentDelayMs, stats.current_delay_ms);
519   EXPECT_EQ(kTargetDelayMs, stats.target_delay_ms);
520   EXPECT_EQ(kJitterBufferMs, stats.jitter_buffer_ms);
521   EXPECT_EQ(kMinPlayoutDelayMs, stats.min_playout_delay_ms);
522   EXPECT_EQ(kRenderDelayMs, stats.render_delay_ms);
523 }
524 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsRtcpPacketTypeCounts)525 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsRtcpPacketTypeCounts) {
526   const uint32_t kFirPackets = 33;
527   const uint32_t kPliPackets = 44;
528   const uint32_t kNackPackets = 55;
529   RtcpPacketTypeCounter counter;
530   counter.fir_packets = kFirPackets;
531   counter.pli_packets = kPliPackets;
532   counter.nack_packets = kNackPackets;
533   statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
534   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
535   EXPECT_EQ(kFirPackets, stats.rtcp_packet_type_counts.fir_packets);
536   EXPECT_EQ(kPliPackets, stats.rtcp_packet_type_counts.pli_packets);
537   EXPECT_EQ(kNackPackets, stats.rtcp_packet_type_counts.nack_packets);
538 }
539 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc)540 TEST_F(ReceiveStatisticsProxy2Test,
541        GetStatsReportsNoRtcpPacketTypeCountsForUnknownSsrc) {
542   RtcpPacketTypeCounter counter;
543   counter.fir_packets = 33;
544   statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc + 1, counter);
545   EXPECT_EQ(0u,
546             statistics_proxy_->GetStats().rtcp_packet_type_counts.fir_packets);
547 }
548 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsFrameCounts)549 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsFrameCounts) {
550   const int kKeyFrames = 3;
551   const int kDeltaFrames = 22;
552   for (int i = 0; i < kKeyFrames; i++) {
553     statistics_proxy_->OnCompleteFrame(true, 0, VideoContentType::UNSPECIFIED);
554   }
555   for (int i = 0; i < kDeltaFrames; i++) {
556     statistics_proxy_->OnCompleteFrame(false, 0, VideoContentType::UNSPECIFIED);
557   }
558 
559   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
560   EXPECT_EQ(kKeyFrames, stats.frame_counts.key_frames);
561   EXPECT_EQ(kDeltaFrames, stats.frame_counts.delta_frames);
562 }
563 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsCName)564 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsCName) {
565   const char* kName = "cName";
566   statistics_proxy_->OnCname(kRemoteSsrc, kName);
567   EXPECT_STREQ(kName, statistics_proxy_->GetStats().c_name.c_str());
568 }
569 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsNoCNameForUnknownSsrc)570 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsNoCNameForUnknownSsrc) {
571   const char* kName = "cName";
572   statistics_proxy_->OnCname(kRemoteSsrc + 1, kName);
573   EXPECT_STREQ("", statistics_proxy_->GetStats().c_name.c_str());
574 }
575 
TEST_F(ReceiveStatisticsProxy2Test,ReportsLongestTimingFrameInfo)576 TEST_F(ReceiveStatisticsProxy2Test, ReportsLongestTimingFrameInfo) {
577   const int64_t kShortEndToEndDelay = 10;
578   const int64_t kMedEndToEndDelay = 20;
579   const int64_t kLongEndToEndDelay = 100;
580   const uint32_t kExpectedRtpTimestamp = 2;
581   TimingFrameInfo info;
582   absl::optional<TimingFrameInfo> result;
583   info.rtp_timestamp = kExpectedRtpTimestamp - 1;
584   info.capture_time_ms = 0;
585   info.decode_finish_ms = kShortEndToEndDelay;
586   statistics_proxy_->OnTimingFrameInfoUpdated(info);
587   info.rtp_timestamp =
588       kExpectedRtpTimestamp;  // this frame should be reported in the end.
589   info.capture_time_ms = 0;
590   info.decode_finish_ms = kLongEndToEndDelay;
591   statistics_proxy_->OnTimingFrameInfoUpdated(info);
592   info.rtp_timestamp = kExpectedRtpTimestamp + 1;
593   info.capture_time_ms = 0;
594   info.decode_finish_ms = kMedEndToEndDelay;
595   statistics_proxy_->OnTimingFrameInfoUpdated(info);
596   result = FlushAndGetStats().timing_frame_info;
597   EXPECT_TRUE(result);
598   EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
599 }
600 
TEST_F(ReceiveStatisticsProxy2Test,RespectsReportingIntervalForTimingFrames)601 TEST_F(ReceiveStatisticsProxy2Test, RespectsReportingIntervalForTimingFrames) {
602   TimingFrameInfo info;
603   const int64_t kShortEndToEndDelay = 10;
604   const uint32_t kExpectedRtpTimestamp = 2;
605   const int64_t kShortDelayMs = 1000;
606   const int64_t kLongDelayMs = 10000;
607   absl::optional<TimingFrameInfo> result;
608   info.rtp_timestamp = kExpectedRtpTimestamp;
609   info.capture_time_ms = 0;
610   info.decode_finish_ms = kShortEndToEndDelay;
611   statistics_proxy_->OnTimingFrameInfoUpdated(info);
612   fake_clock_.AdvanceTimeMilliseconds(kShortDelayMs);
613   result = FlushAndGetStats().timing_frame_info;
614   EXPECT_TRUE(result);
615   EXPECT_EQ(kExpectedRtpTimestamp, result->rtp_timestamp);
616   fake_clock_.AdvanceTimeMilliseconds(kLongDelayMs);
617   result = statistics_proxy_->GetStats().timing_frame_info;
618   EXPECT_FALSE(result);
619 }
620 
TEST_F(ReceiveStatisticsProxy2Test,LifetimeHistogramIsUpdated)621 TEST_F(ReceiveStatisticsProxy2Test, LifetimeHistogramIsUpdated) {
622   const int64_t kTimeSec = 3;
623   fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
624   // Need at least one frame to report stream lifetime.
625   statistics_proxy_->OnCompleteFrame(true, 1000, VideoContentType::UNSPECIFIED);
626   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
627                                       nullptr);
628   EXPECT_METRIC_EQ(
629       1, metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
630   EXPECT_METRIC_EQ(
631       1, metrics::NumEvents("WebRTC.Video.ReceiveStreamLifetimeInSeconds",
632                             kTimeSec));
633 }
634 
TEST_F(ReceiveStatisticsProxy2Test,LifetimeHistogramNotReportedForEmptyStreams)635 TEST_F(ReceiveStatisticsProxy2Test,
636        LifetimeHistogramNotReportedForEmptyStreams) {
637   const int64_t kTimeSec = 3;
638   fake_clock_.AdvanceTimeMilliseconds(kTimeSec * 1000);
639   // No frames received.
640   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
641                                       nullptr);
642   EXPECT_METRIC_EQ(
643       0, metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));
644 }
645 
TEST_F(ReceiveStatisticsProxy2Test,BadCallHistogramsAreUpdated)646 TEST_F(ReceiveStatisticsProxy2Test, BadCallHistogramsAreUpdated) {
647   // Based on the tuning parameters this will produce 7 uncertain states,
648   // then 10 certainly bad states. There has to be 10 certain states before
649   // any histograms are recorded.
650   const int kNumBadSamples = 17;
651   // We only count one sample per second.
652   const int kBadFameIntervalMs = 1100;
653 
654   StreamDataCounters counters;
655   counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
656 
657   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
658 
659   for (int i = 0; i < kNumBadSamples; ++i) {
660     fake_clock_.AdvanceTimeMilliseconds(kBadFameIntervalMs);
661     statistics_proxy_->OnRenderedFrame(MetaData(frame));
662   }
663   statistics_proxy_->UpdateHistograms(absl::nullopt, counters, nullptr);
664   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.Any"));
665   EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.BadCall.Any", 100));
666 
667   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.BadCall.FrameRate"));
668   EXPECT_METRIC_EQ(1,
669                    metrics::NumEvents("WebRTC.Video.BadCall.FrameRate", 100));
670 
671   EXPECT_METRIC_EQ(
672       0, metrics::NumSamples("WebRTC.Video.BadCall.FrameRateVariance"));
673 
674   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.BadCall.Qp"));
675 }
676 
TEST_F(ReceiveStatisticsProxy2Test,PacketLossHistogramIsUpdated)677 TEST_F(ReceiveStatisticsProxy2Test, PacketLossHistogramIsUpdated) {
678   statistics_proxy_->UpdateHistograms(10, StreamDataCounters(), nullptr);
679   EXPECT_METRIC_EQ(
680       0, metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
681 
682   // Restart
683   SetUp();
684 
685   // Min run time has passed.
686   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
687   statistics_proxy_->UpdateHistograms(10, StreamDataCounters(), nullptr);
688   EXPECT_METRIC_EQ(
689       1, metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
690   EXPECT_METRIC_EQ(
691       1, metrics::NumEvents("WebRTC.Video.ReceivedPacketsLostInPercent", 10));
692 }
693 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsPlayoutTimestamp)694 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsPlayoutTimestamp) {
695   const int64_t kVideoNtpMs = 21;
696   const int64_t kSyncOffsetMs = 22;
697   const double kFreqKhz = 90.0;
698   EXPECT_EQ(absl::nullopt,
699             statistics_proxy_->GetStats().estimated_playout_ntp_timestamp_ms);
700   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
701   EXPECT_EQ(kVideoNtpMs, FlushAndGetStats().estimated_playout_ntp_timestamp_ms);
702   fake_clock_.AdvanceTimeMilliseconds(13);
703   EXPECT_EQ(kVideoNtpMs + 13,
704             statistics_proxy_->GetStats().estimated_playout_ntp_timestamp_ms);
705   fake_clock_.AdvanceTimeMilliseconds(5);
706   EXPECT_EQ(kVideoNtpMs + 13 + 5,
707             statistics_proxy_->GetStats().estimated_playout_ntp_timestamp_ms);
708 }
709 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsAvSyncOffset)710 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsAvSyncOffset) {
711   const int64_t kVideoNtpMs = 21;
712   const int64_t kSyncOffsetMs = 22;
713   const double kFreqKhz = 90.0;
714   EXPECT_EQ(std::numeric_limits<int>::max(),
715             statistics_proxy_->GetStats().sync_offset_ms);
716   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
717   EXPECT_EQ(kSyncOffsetMs, FlushAndGetStats().sync_offset_ms);
718 }
719 
TEST_F(ReceiveStatisticsProxy2Test,AvSyncOffsetHistogramIsUpdated)720 TEST_F(ReceiveStatisticsProxy2Test, AvSyncOffsetHistogramIsUpdated) {
721   const int64_t kVideoNtpMs = 21;
722   const int64_t kSyncOffsetMs = 22;
723   const double kFreqKhz = 90.0;
724   for (int i = 0; i < kMinRequiredSamples; ++i) {
725     statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
726                                            kFreqKhz);
727   }
728   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
729   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
730   EXPECT_METRIC_EQ(
731       1, metrics::NumEvents("WebRTC.Video.AVSyncOffsetInMs", kSyncOffsetMs));
732 }
733 
TEST_F(ReceiveStatisticsProxy2Test,RtpToNtpFrequencyOffsetHistogramIsUpdated)734 TEST_F(ReceiveStatisticsProxy2Test, RtpToNtpFrequencyOffsetHistogramIsUpdated) {
735   const int64_t kVideoNtpMs = 21;
736   const int64_t kSyncOffsetMs = 22;
737   const double kFreqKhz = 90.0;
738   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
739   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
740                                          kFreqKhz + 2.2);
741   loop_.Flush();
742   fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
743   // Process interval passed, max diff: 2.
744   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
745                                          kFreqKhz + 1.1);
746   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
747                                          kFreqKhz - 4.2);
748   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs,
749                                          kFreqKhz - 0.9);
750   loop_.Flush();
751   fake_clock_.AdvanceTimeMilliseconds(kFreqOffsetProcessIntervalInMs);
752   // Process interval passed, max diff: 4.
753   statistics_proxy_->OnSyncOffsetUpdated(kVideoNtpMs, kSyncOffsetMs, kFreqKhz);
754   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
755   // Average reported: (2 + 4) / 2 = 3.
756   EXPECT_METRIC_EQ(1,
757                    metrics::NumSamples("WebRTC.Video.RtpToNtpFreqOffsetInKhz"));
758   EXPECT_METRIC_EQ(
759       1, metrics::NumEvents("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 3));
760 }
761 
TEST_F(ReceiveStatisticsProxy2Test,Vp8QpHistogramIsUpdated)762 TEST_F(ReceiveStatisticsProxy2Test, Vp8QpHistogramIsUpdated) {
763   const int kQp = 22;
764 
765   for (int i = 0; i < kMinRequiredSamples; ++i)
766     statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
767 
768   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
769   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
770   EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.Decoded.Vp8.Qp", kQp));
771 }
772 
TEST_F(ReceiveStatisticsProxy2Test,Vp8QpHistogramIsNotUpdatedForTooFewSamples)773 TEST_F(ReceiveStatisticsProxy2Test,
774        Vp8QpHistogramIsNotUpdatedForTooFewSamples) {
775   const int kQp = 22;
776 
777   for (int i = 0; i < kMinRequiredSamples - 1; ++i)
778     statistics_proxy_->OnPreDecode(kVideoCodecVP8, kQp);
779 
780   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
781                                       nullptr);
782   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
783 }
784 
TEST_F(ReceiveStatisticsProxy2Test,Vp8QpHistogramIsNotUpdatedIfNoQpValue)785 TEST_F(ReceiveStatisticsProxy2Test, Vp8QpHistogramIsNotUpdatedIfNoQpValue) {
786   for (int i = 0; i < kMinRequiredSamples; ++i)
787     statistics_proxy_->OnPreDecode(kVideoCodecVP8, -1);
788 
789   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
790                                       nullptr);
791   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.Decoded.Vp8.Qp"));
792 }
793 
TEST_F(ReceiveStatisticsProxy2Test,KeyFrameHistogramNotUpdatedForTooFewSamples)794 TEST_F(ReceiveStatisticsProxy2Test,
795        KeyFrameHistogramNotUpdatedForTooFewSamples) {
796   const bool kIsKeyFrame = false;
797   const int kFrameSizeBytes = 1000;
798 
799   for (int i = 0; i < kMinRequiredSamples - 1; ++i)
800     statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
801                                        VideoContentType::UNSPECIFIED);
802 
803   EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
804   EXPECT_EQ(kMinRequiredSamples - 1,
805             statistics_proxy_->GetStats().frame_counts.delta_frames);
806 
807   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
808                                       nullptr);
809   EXPECT_METRIC_EQ(
810       0, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
811 }
812 
TEST_F(ReceiveStatisticsProxy2Test,KeyFrameHistogramUpdatedForMinRequiredSamples)813 TEST_F(ReceiveStatisticsProxy2Test,
814        KeyFrameHistogramUpdatedForMinRequiredSamples) {
815   const bool kIsKeyFrame = false;
816   const int kFrameSizeBytes = 1000;
817 
818   for (int i = 0; i < kMinRequiredSamples; ++i)
819     statistics_proxy_->OnCompleteFrame(kIsKeyFrame, kFrameSizeBytes,
820                                        VideoContentType::UNSPECIFIED);
821 
822   EXPECT_EQ(0, statistics_proxy_->GetStats().frame_counts.key_frames);
823   EXPECT_EQ(kMinRequiredSamples,
824             statistics_proxy_->GetStats().frame_counts.delta_frames);
825 
826   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
827                                       nullptr);
828   EXPECT_METRIC_EQ(
829       1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
830   EXPECT_METRIC_EQ(
831       1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 0));
832 }
833 
TEST_F(ReceiveStatisticsProxy2Test,KeyFrameHistogramIsUpdated)834 TEST_F(ReceiveStatisticsProxy2Test, KeyFrameHistogramIsUpdated) {
835   const int kFrameSizeBytes = 1000;
836 
837   for (int i = 0; i < kMinRequiredSamples; ++i)
838     statistics_proxy_->OnCompleteFrame(true, kFrameSizeBytes,
839                                        VideoContentType::UNSPECIFIED);
840 
841   for (int i = 0; i < kMinRequiredSamples; ++i)
842     statistics_proxy_->OnCompleteFrame(false, kFrameSizeBytes,
843                                        VideoContentType::UNSPECIFIED);
844 
845   EXPECT_EQ(kMinRequiredSamples,
846             statistics_proxy_->GetStats().frame_counts.key_frames);
847   EXPECT_EQ(kMinRequiredSamples,
848             statistics_proxy_->GetStats().frame_counts.delta_frames);
849 
850   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
851                                       nullptr);
852   EXPECT_METRIC_EQ(
853       1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
854   EXPECT_METRIC_EQ(
855       1, metrics::NumEvents("WebRTC.Video.KeyFramesReceivedInPermille", 500));
856 }
857 
TEST_F(ReceiveStatisticsProxy2Test,TimingHistogramsNotUpdatedForTooFewSamples)858 TEST_F(ReceiveStatisticsProxy2Test,
859        TimingHistogramsNotUpdatedForTooFewSamples) {
860   const int kMaxDecodeMs = 2;
861   const int kCurrentDelayMs = 3;
862   const int kTargetDelayMs = 4;
863   const int kJitterBufferMs = 5;
864   const int kMinPlayoutDelayMs = 6;
865   const int kRenderDelayMs = 7;
866 
867   for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
868     statistics_proxy_->OnFrameBufferTimingsUpdated(
869         kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
870         kMinPlayoutDelayMs, kRenderDelayMs);
871   }
872 
873   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
874                                       nullptr);
875   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
876   EXPECT_METRIC_EQ(0,
877                    metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
878   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
879   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
880   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
881 }
882 
TEST_F(ReceiveStatisticsProxy2Test,TimingHistogramsAreUpdated)883 TEST_F(ReceiveStatisticsProxy2Test, TimingHistogramsAreUpdated) {
884   const int kMaxDecodeMs = 2;
885   const int kCurrentDelayMs = 3;
886   const int kTargetDelayMs = 4;
887   const int kJitterBufferMs = 5;
888   const int kMinPlayoutDelayMs = 6;
889   const int kRenderDelayMs = 7;
890 
891   for (int i = 0; i < kMinRequiredSamples; ++i) {
892     statistics_proxy_->OnFrameBufferTimingsUpdated(
893         kMaxDecodeMs, kCurrentDelayMs, kTargetDelayMs, kJitterBufferMs,
894         kMinPlayoutDelayMs, kRenderDelayMs);
895   }
896 
897   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
898   EXPECT_METRIC_EQ(1,
899                    metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
900   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
901   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
902   EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
903 
904   EXPECT_METRIC_EQ(1, metrics::NumEvents("WebRTC.Video.JitterBufferDelayInMs",
905                                          kJitterBufferMs));
906   EXPECT_METRIC_EQ(
907       1, metrics::NumEvents("WebRTC.Video.TargetDelayInMs", kTargetDelayMs));
908   EXPECT_METRIC_EQ(
909       1, metrics::NumEvents("WebRTC.Video.CurrentDelayInMs", kCurrentDelayMs));
910   EXPECT_METRIC_EQ(
911       1, metrics::NumEvents("WebRTC.Video.OnewayDelayInMs", kTargetDelayMs));
912 }
913 
TEST_F(ReceiveStatisticsProxy2Test,DoesNotReportStaleFramerates)914 TEST_F(ReceiveStatisticsProxy2Test, DoesNotReportStaleFramerates) {
915   const int kDefaultFps = 30;
916   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
917 
918   for (int i = 0; i < kDefaultFps; ++i) {
919     // Since OnRenderedFrame is never called the fps in each sample will be 0,
920     // i.e. bad
921     frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds());
922     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
923                                       VideoContentType::UNSPECIFIED);
924     statistics_proxy_->OnRenderedFrame(MetaData(frame));
925     fake_clock_.AdvanceTimeMilliseconds(1000 / kDefaultFps);
926   }
927 
928   loop_.Flush();
929   EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().decode_frame_rate);
930   EXPECT_EQ(kDefaultFps, statistics_proxy_->GetStats().render_frame_rate);
931 
932   // FPS trackers in stats proxy have a 1000ms sliding window.
933   fake_clock_.AdvanceTimeMilliseconds(1000);
934   EXPECT_EQ(0, statistics_proxy_->GetStats().decode_frame_rate);
935   EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate);
936 }
937 
TEST_F(ReceiveStatisticsProxy2Test,GetStatsReportsReceivedFrameStats)938 TEST_F(ReceiveStatisticsProxy2Test, GetStatsReportsReceivedFrameStats) {
939   EXPECT_EQ(0, statistics_proxy_->GetStats().width);
940   EXPECT_EQ(0, statistics_proxy_->GetStats().height);
941   EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered);
942 
943   statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
944 
945   EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width);
946   EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height);
947   EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered);
948 }
949 
TEST_F(ReceiveStatisticsProxy2Test,ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples)950 TEST_F(ReceiveStatisticsProxy2Test,
951        ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) {
952   for (int i = 0; i < kMinRequiredSamples - 1; ++i) {
953     statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
954   }
955 
956   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
957                                       nullptr);
958   EXPECT_METRIC_EQ(0,
959                    metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
960   EXPECT_METRIC_EQ(0,
961                    metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
962   EXPECT_METRIC_EQ(0,
963                    metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
964   EXPECT_METRIC_EQ(
965       0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
966 }
967 
TEST_F(ReceiveStatisticsProxy2Test,ReceivedFrameHistogramsAreUpdated)968 TEST_F(ReceiveStatisticsProxy2Test, ReceivedFrameHistogramsAreUpdated) {
969   for (int i = 0; i < kMinRequiredSamples; ++i) {
970     statistics_proxy_->OnRenderedFrame(MetaData(CreateFrame(kWidth, kHeight)));
971   }
972 
973   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
974                                       nullptr);
975   EXPECT_METRIC_EQ(1,
976                    metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
977   EXPECT_METRIC_EQ(1,
978                    metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
979   EXPECT_METRIC_EQ(1,
980                    metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
981   EXPECT_METRIC_EQ(
982       1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
983   EXPECT_METRIC_EQ(
984       1, metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth));
985   EXPECT_METRIC_EQ(
986       1, metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight));
987 }
988 
TEST_F(ReceiveStatisticsProxy2Test,ZeroDelayReportedIfFrameNotDelayed)989 TEST_F(ReceiveStatisticsProxy2Test, ZeroDelayReportedIfFrameNotDelayed) {
990   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
991   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
992                                     VideoContentType::UNSPECIFIED);
993 
994   // Frame not delayed, delayed frames to render: 0%.
995   statistics_proxy_->OnRenderedFrame(
996       MetaData(CreateFrameWithRenderTime(Now())));
997 
998   // Min run time has passed.
999   fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
1000   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1001   EXPECT_METRIC_EQ(1,
1002                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1003   EXPECT_METRIC_EQ(
1004       1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 0));
1005   EXPECT_METRIC_EQ(0, metrics::NumSamples(
1006                           "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1007 }
1008 
TEST_F(ReceiveStatisticsProxy2Test,DelayedFrameHistogramsAreNotUpdatedIfMinRuntimeHasNotPassed)1009 TEST_F(ReceiveStatisticsProxy2Test,
1010        DelayedFrameHistogramsAreNotUpdatedIfMinRuntimeHasNotPassed) {
1011   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1012   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
1013                                     VideoContentType::UNSPECIFIED);
1014 
1015   // Frame not delayed, delayed frames to render: 0%.
1016   statistics_proxy_->OnRenderedFrame(
1017       MetaData(CreateFrameWithRenderTime(Now())));
1018 
1019   // Min run time has not passed.
1020   fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
1021                                       1);
1022   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1023                                       nullptr);
1024   EXPECT_METRIC_EQ(0,
1025                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1026   EXPECT_METRIC_EQ(0, metrics::NumSamples(
1027                           "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1028 }
1029 
TEST_F(ReceiveStatisticsProxy2Test,DelayedFramesHistogramsAreNotUpdatedIfNoRenderedFrames)1030 TEST_F(ReceiveStatisticsProxy2Test,
1031        DelayedFramesHistogramsAreNotUpdatedIfNoRenderedFrames) {
1032   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1033   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
1034                                     VideoContentType::UNSPECIFIED);
1035 
1036   // Min run time has passed. No rendered frames.
1037   fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
1038   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1039                                       nullptr);
1040   EXPECT_METRIC_EQ(0,
1041                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1042   EXPECT_METRIC_EQ(0, metrics::NumSamples(
1043                           "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1044 }
1045 
TEST_F(ReceiveStatisticsProxy2Test,DelayReportedIfFrameIsDelayed)1046 TEST_F(ReceiveStatisticsProxy2Test, DelayReportedIfFrameIsDelayed) {
1047   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1048   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
1049                                     VideoContentType::UNSPECIFIED);
1050 
1051   // Frame delayed 1 ms, delayed frames to render: 100%.
1052   statistics_proxy_->OnRenderedFrame(
1053       MetaData(CreateFrameWithRenderTimeMs(Now().ms() - 1)));
1054 
1055   // Min run time has passed.
1056   fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
1057   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1058   EXPECT_METRIC_EQ(1,
1059                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1060   EXPECT_METRIC_EQ(
1061       1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 100));
1062   EXPECT_METRIC_EQ(1, metrics::NumSamples(
1063                           "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1064   EXPECT_METRIC_EQ(
1065       1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs",
1066                             1));
1067 }
1068 
TEST_F(ReceiveStatisticsProxy2Test,AverageDelayOfDelayedFramesIsReported)1069 TEST_F(ReceiveStatisticsProxy2Test, AverageDelayOfDelayedFramesIsReported) {
1070   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1071   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0,
1072                                     VideoContentType::UNSPECIFIED);
1073 
1074   // Two frames delayed (6 ms, 10 ms), delayed frames to render: 50%.
1075   const int64_t kNowMs = Now().ms();
1076 
1077   statistics_proxy_->OnRenderedFrame(
1078       MetaData(CreateFrameWithRenderTimeMs(kNowMs - 10)));
1079   statistics_proxy_->OnRenderedFrame(
1080       MetaData(CreateFrameWithRenderTimeMs(kNowMs - 6)));
1081   statistics_proxy_->OnRenderedFrame(
1082       MetaData(CreateFrameWithRenderTimeMs(kNowMs)));
1083   statistics_proxy_->OnRenderedFrame(
1084       MetaData(CreateFrameWithRenderTimeMs(kNowMs + 1)));
1085 
1086   // Min run time has passed.
1087   fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000));
1088   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1089   EXPECT_METRIC_EQ(1,
1090                    metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));
1091   EXPECT_METRIC_EQ(
1092       1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer", 50));
1093   EXPECT_METRIC_EQ(1, metrics::NumSamples(
1094                           "WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs"));
1095   EXPECT_METRIC_EQ(
1096       1, metrics::NumEvents("WebRTC.Video.DelayedFramesToRenderer_AvgDelayInMs",
1097                             8));
1098 }
1099 
TEST_F(ReceiveStatisticsProxy2Test,RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed)1100 TEST_F(ReceiveStatisticsProxy2Test,
1101        RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) {
1102   StreamDataCounters data_counters;
1103   data_counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
1104 
1105   fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) -
1106                                       1);
1107 
1108   RtcpPacketTypeCounter counter;
1109   statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
1110 
1111   statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
1112   EXPECT_METRIC_EQ(0,
1113                    metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
1114   EXPECT_METRIC_EQ(0,
1115                    metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
1116   EXPECT_METRIC_EQ(
1117       0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
1118 }
1119 
TEST_F(ReceiveStatisticsProxy2Test,RtcpHistogramsAreUpdated)1120 TEST_F(ReceiveStatisticsProxy2Test, RtcpHistogramsAreUpdated) {
1121   StreamDataCounters data_counters;
1122   data_counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds();
1123   fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
1124 
1125   const uint32_t kFirPackets = 100;
1126   const uint32_t kPliPackets = 200;
1127   const uint32_t kNackPackets = 300;
1128 
1129   RtcpPacketTypeCounter counter;
1130   counter.fir_packets = kFirPackets;
1131   counter.pli_packets = kPliPackets;
1132   counter.nack_packets = kNackPackets;
1133   statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter);
1134 
1135   statistics_proxy_->UpdateHistograms(absl::nullopt, data_counters, nullptr);
1136   EXPECT_METRIC_EQ(1,
1137                    metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
1138   EXPECT_METRIC_EQ(1,
1139                    metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
1140   EXPECT_METRIC_EQ(
1141       1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
1142   EXPECT_METRIC_EQ(
1143       1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute",
1144                             kFirPackets * 60 / metrics::kMinRunTimeInSeconds));
1145   EXPECT_METRIC_EQ(
1146       1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute",
1147                             kPliPackets * 60 / metrics::kMinRunTimeInSeconds));
1148   EXPECT_METRIC_EQ(
1149       1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute",
1150                             kNackPackets * 60 / metrics::kMinRunTimeInSeconds));
1151 }
1152 
1153 class ReceiveStatisticsProxy2TestWithFreezeDuration
1154     : public ReceiveStatisticsProxy2Test,
1155       public ::testing::WithParamInterface<
1156           std::tuple<uint32_t, uint32_t, uint32_t>> {
1157  protected:
1158   const uint32_t frame_duration_ms_ = {std::get<0>(GetParam())};
1159   const uint32_t freeze_duration_ms_ = {std::get<1>(GetParam())};
1160   const uint32_t expected_freeze_count_ = {std::get<2>(GetParam())};
1161 };
1162 
1163 // It is a freeze if:
1164 // frame_duration_ms >= max(3 * avg_frame_duration, avg_frame_duration + 150)
1165 // where avg_frame_duration is average duration of last 30 frames including
1166 // the current one.
1167 //
1168 // Condition 1: 3 * avg_frame_duration > avg_frame_duration + 150
1169 const auto kFreezeDetectionCond1Freeze = std::make_tuple(150, 483, 1);
1170 const auto kFreezeDetectionCond1NotFreeze = std::make_tuple(150, 482, 0);
1171 // Condition 2: 3 * avg_frame_duration < avg_frame_duration + 150
1172 const auto kFreezeDetectionCond2Freeze = std::make_tuple(30, 185, 1);
1173 const auto kFreezeDetectionCond2NotFreeze = std::make_tuple(30, 184, 0);
1174 
1175 INSTANTIATE_TEST_SUITE_P(_,
1176                          ReceiveStatisticsProxy2TestWithFreezeDuration,
1177                          ::testing::Values(kFreezeDetectionCond1Freeze,
1178                                            kFreezeDetectionCond1NotFreeze,
1179                                            kFreezeDetectionCond2Freeze,
1180                                            kFreezeDetectionCond2NotFreeze));
1181 
TEST_P(ReceiveStatisticsProxy2TestWithFreezeDuration,FreezeDetection)1182 TEST_P(ReceiveStatisticsProxy2TestWithFreezeDuration, FreezeDetection) {
1183   VideoReceiveStream::Stats stats = statistics_proxy_->GetStats();
1184   EXPECT_EQ(0u, stats.freeze_count);
1185   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1186 
1187   // Add a very long frame. This is need to verify that average frame
1188   // duration, which is supposed to be calculated as mean of durations of
1189   // last 30 frames, is calculated correctly.
1190   statistics_proxy_->OnRenderedFrame(MetaData(frame));
1191   fake_clock_.AdvanceTimeMilliseconds(2000);
1192 
1193   for (size_t i = 0;
1194        i <= VideoQualityObserver::kAvgInterframeDelaysWindowSizeFrames; ++i) {
1195     fake_clock_.AdvanceTimeMilliseconds(frame_duration_ms_);
1196     statistics_proxy_->OnRenderedFrame(MetaData(frame));
1197   }
1198 
1199   fake_clock_.AdvanceTimeMilliseconds(freeze_duration_ms_);
1200   statistics_proxy_->OnRenderedFrame(MetaData(frame));
1201 
1202   stats = statistics_proxy_->GetStats();
1203   EXPECT_EQ(stats.freeze_count, expected_freeze_count_);
1204 }
1205 
1206 class ReceiveStatisticsProxy2TestWithContent
1207     : public ReceiveStatisticsProxy2Test,
1208       public ::testing::WithParamInterface<webrtc::VideoContentType> {
1209  protected:
1210   const webrtc::VideoContentType content_type_{GetParam()};
1211 };
1212 
1213 INSTANTIATE_TEST_SUITE_P(ContentTypes,
1214                          ReceiveStatisticsProxy2TestWithContent,
1215                          ::testing::Values(VideoContentType::UNSPECIFIED,
1216                                            VideoContentType::SCREENSHARE));
1217 
TEST_P(ReceiveStatisticsProxy2TestWithContent,InterFrameDelaysAreReported)1218 TEST_P(ReceiveStatisticsProxy2TestWithContent, InterFrameDelaysAreReported) {
1219   const int kInterFrameDelayMs = 33;
1220   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1221 
1222   for (int i = 0; i < kMinRequiredSamples; ++i) {
1223     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1224     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1225   }
1226   // One extra with double the interval.
1227   fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1228   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1229 
1230   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1231   const int kExpectedInterFrame =
1232       (kInterFrameDelayMs * (kMinRequiredSamples - 1) +
1233        kInterFrameDelayMs * 2) /
1234       kMinRequiredSamples;
1235   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1236     EXPECT_METRIC_EQ(
1237         kExpectedInterFrame,
1238         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1239     EXPECT_METRIC_EQ(
1240         kInterFrameDelayMs * 2,
1241         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1242   } else {
1243     EXPECT_METRIC_EQ(kExpectedInterFrame,
1244                      metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1245     EXPECT_METRIC_EQ(kInterFrameDelayMs * 2,
1246                      metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1247   }
1248 }
1249 
TEST_P(ReceiveStatisticsProxy2TestWithContent,InterFrameDelaysPercentilesAreReported)1250 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1251        InterFrameDelaysPercentilesAreReported) {
1252   const int kInterFrameDelayMs = 33;
1253   const int kLastFivePercentsSamples = kMinRequiredSamples * 5 / 100;
1254   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1255 
1256   for (int i = 0; i <= kMinRequiredSamples - kLastFivePercentsSamples; ++i) {
1257     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1258     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1259   }
1260   // Last 5% of intervals are double in size.
1261   for (int i = 0; i < kLastFivePercentsSamples; ++i) {
1262     fake_clock_.AdvanceTimeMilliseconds(2 * kInterFrameDelayMs);
1263     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1264   }
1265   // Final sample is outlier and 10 times as big.
1266   fake_clock_.AdvanceTimeMilliseconds(10 * kInterFrameDelayMs);
1267   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1268 
1269   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1270   const int kExpectedInterFrame = kInterFrameDelayMs * 2;
1271   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1272     EXPECT_METRIC_EQ(
1273         kExpectedInterFrame,
1274         metrics::MinSample(
1275             "WebRTC.Video.Screenshare.InterframeDelay95PercentileInMs"));
1276   } else {
1277     EXPECT_METRIC_EQ(
1278         kExpectedInterFrame,
1279         metrics::MinSample("WebRTC.Video.InterframeDelay95PercentileInMs"));
1280   }
1281 }
1282 
TEST_P(ReceiveStatisticsProxy2TestWithContent,MaxInterFrameDelayOnlyWithValidAverage)1283 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1284        MaxInterFrameDelayOnlyWithValidAverage) {
1285   const int kInterFrameDelayMs = 33;
1286   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1287 
1288   for (int i = 0; i < kMinRequiredSamples; ++i) {
1289     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1290     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1291   }
1292 
1293   // |kMinRequiredSamples| samples, and thereby intervals, is required. That
1294   // means we're one frame short of having a valid data set.
1295   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1296                                       nullptr);
1297   EXPECT_METRIC_EQ(0, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1298   EXPECT_METRIC_EQ(0,
1299                    metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1300   EXPECT_METRIC_EQ(
1301       0, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1302   EXPECT_METRIC_EQ(0, metrics::NumSamples(
1303                           "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1304 }
1305 
TEST_P(ReceiveStatisticsProxy2TestWithContent,MaxInterFrameDelayOnlyWithPause)1306 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1307        MaxInterFrameDelayOnlyWithPause) {
1308   const int kInterFrameDelayMs = 33;
1309   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1310 
1311   for (int i = 0; i <= kMinRequiredSamples; ++i) {
1312     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1313     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1314   }
1315 
1316   loop_.Flush();
1317   // At this state, we should have a valid inter-frame delay.
1318   // Indicate stream paused and make a large jump in time.
1319   statistics_proxy_->OnStreamInactive();
1320   fake_clock_.AdvanceTimeMilliseconds(5000);
1321 
1322   // Insert two more frames. The interval during the pause should be
1323   // disregarded in the stats.
1324   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1325   fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1326   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1327 
1328   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1329   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1330     EXPECT_METRIC_EQ(
1331         1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1332     EXPECT_METRIC_EQ(1, metrics::NumSamples(
1333                             "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1334     EXPECT_METRIC_EQ(
1335         kInterFrameDelayMs,
1336         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1337     EXPECT_METRIC_EQ(
1338         kInterFrameDelayMs,
1339         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1340   } else {
1341     EXPECT_METRIC_EQ(1,
1342                      metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1343     EXPECT_METRIC_EQ(
1344         1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1345     EXPECT_METRIC_EQ(kInterFrameDelayMs,
1346                      metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1347     EXPECT_METRIC_EQ(kInterFrameDelayMs,
1348                      metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1349   }
1350 }
1351 
TEST_P(ReceiveStatisticsProxy2TestWithContent,FreezesAreReported)1352 TEST_P(ReceiveStatisticsProxy2TestWithContent, FreezesAreReported) {
1353   const int kInterFrameDelayMs = 33;
1354   const int kFreezeDelayMs = 200;
1355   const int kCallDurationMs =
1356       kMinRequiredSamples * kInterFrameDelayMs + kFreezeDelayMs;
1357   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1358 
1359   for (int i = 0; i < kMinRequiredSamples; ++i) {
1360     VideoFrameMetaData meta = MetaData(frame);
1361     statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, 0, content_type_);
1362     statistics_proxy_->OnRenderedFrame(meta);
1363     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1364   }
1365   // Add extra freeze.
1366   fake_clock_.AdvanceTimeMilliseconds(kFreezeDelayMs);
1367   VideoFrameMetaData meta = MetaData(frame);
1368   statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, 0, content_type_);
1369   statistics_proxy_->OnRenderedFrame(meta);
1370 
1371   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1372   const int kExpectedTimeBetweenFreezes =
1373       kInterFrameDelayMs * (kMinRequiredSamples - 1);
1374   const int kExpectedNumberFreezesPerMinute = 60 * 1000 / kCallDurationMs;
1375   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1376     EXPECT_METRIC_EQ(
1377         kFreezeDelayMs + kInterFrameDelayMs,
1378         metrics::MinSample("WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1379     EXPECT_METRIC_EQ(kExpectedTimeBetweenFreezes,
1380                      metrics::MinSample(
1381                          "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
1382     EXPECT_METRIC_EQ(
1383         kExpectedNumberFreezesPerMinute,
1384         metrics::MinSample("WebRTC.Video.Screenshare.NumberFreezesPerMinute"));
1385   } else {
1386     EXPECT_METRIC_EQ(kFreezeDelayMs + kInterFrameDelayMs,
1387                      metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1388     EXPECT_METRIC_EQ(
1389         kExpectedTimeBetweenFreezes,
1390         metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
1391     EXPECT_METRIC_EQ(kExpectedNumberFreezesPerMinute,
1392                      metrics::MinSample("WebRTC.Video.NumberFreezesPerMinute"));
1393   }
1394 }
1395 
TEST_P(ReceiveStatisticsProxy2TestWithContent,HarmonicFrameRateIsReported)1396 TEST_P(ReceiveStatisticsProxy2TestWithContent, HarmonicFrameRateIsReported) {
1397   const int kFrameDurationMs = 33;
1398   const int kFreezeDurationMs = 200;
1399   const int kPauseDurationMs = 10000;
1400   const int kCallDurationMs = kMinRequiredSamples * kFrameDurationMs +
1401                               kFreezeDurationMs + kPauseDurationMs;
1402   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1403 
1404   for (int i = 0; i < kMinRequiredSamples; ++i) {
1405     fake_clock_.AdvanceTimeMilliseconds(kFrameDurationMs);
1406     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1407     statistics_proxy_->OnRenderedFrame(MetaData(frame));
1408   }
1409 
1410   // Freezes and pauses should be included into harmonic frame rate.
1411   // Add freeze.
1412   loop_.Flush();
1413   fake_clock_.AdvanceTimeMilliseconds(kFreezeDurationMs);
1414   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1415   statistics_proxy_->OnRenderedFrame(MetaData(frame));
1416 
1417   // Add pause.
1418   loop_.Flush();
1419   fake_clock_.AdvanceTimeMilliseconds(kPauseDurationMs);
1420   statistics_proxy_->OnStreamInactive();
1421   statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1422   statistics_proxy_->OnRenderedFrame(MetaData(frame));
1423 
1424   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1425   double kSumSquaredFrameDurationSecs =
1426       (kMinRequiredSamples - 1) *
1427       (kFrameDurationMs / 1000.0 * kFrameDurationMs / 1000.0);
1428   kSumSquaredFrameDurationSecs +=
1429       kFreezeDurationMs / 1000.0 * kFreezeDurationMs / 1000.0;
1430   kSumSquaredFrameDurationSecs +=
1431       kPauseDurationMs / 1000.0 * kPauseDurationMs / 1000.0;
1432   const int kExpectedHarmonicFrameRateFps =
1433       std::round(kCallDurationMs / (1000 * kSumSquaredFrameDurationSecs));
1434   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1435     EXPECT_METRIC_EQ(
1436         kExpectedHarmonicFrameRateFps,
1437         metrics::MinSample("WebRTC.Video.Screenshare.HarmonicFrameRate"));
1438   } else {
1439     EXPECT_METRIC_EQ(kExpectedHarmonicFrameRateFps,
1440                      metrics::MinSample("WebRTC.Video.HarmonicFrameRate"));
1441   }
1442 }
1443 
TEST_P(ReceiveStatisticsProxy2TestWithContent,PausesAreIgnored)1444 TEST_P(ReceiveStatisticsProxy2TestWithContent, PausesAreIgnored) {
1445   const int kInterFrameDelayMs = 33;
1446   const int kPauseDurationMs = 10000;
1447   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1448 
1449   for (int i = 0; i <= kMinRequiredSamples; ++i) {
1450     VideoFrameMetaData meta = MetaData(frame);
1451     statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, 0, content_type_);
1452     statistics_proxy_->OnRenderedFrame(meta);
1453     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1454   }
1455   // Add a pause.
1456   fake_clock_.AdvanceTimeMilliseconds(kPauseDurationMs);
1457   statistics_proxy_->OnStreamInactive();
1458   // Second playback interval with triple the length.
1459   for (int i = 0; i <= kMinRequiredSamples * 3; ++i) {
1460     VideoFrameMetaData meta = MetaData(frame);
1461     statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, 0, content_type_);
1462     statistics_proxy_->OnRenderedFrame(meta);
1463     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1464   }
1465 
1466   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1467   // Average of two playback intervals.
1468   const int kExpectedTimeBetweenFreezes =
1469       kInterFrameDelayMs * kMinRequiredSamples * 2;
1470   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1471     EXPECT_METRIC_EQ(-1, metrics::MinSample(
1472                              "WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1473     EXPECT_METRIC_EQ(kExpectedTimeBetweenFreezes,
1474                      metrics::MinSample(
1475                          "WebRTC.Video.Screenshare.MeanTimeBetweenFreezesMs"));
1476   } else {
1477     EXPECT_METRIC_EQ(-1,
1478                      metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1479     EXPECT_METRIC_EQ(
1480         kExpectedTimeBetweenFreezes,
1481         metrics::MinSample("WebRTC.Video.MeanTimeBetweenFreezesMs"));
1482   }
1483 }
1484 
TEST_P(ReceiveStatisticsProxy2TestWithContent,ManyPausesAtTheBeginning)1485 TEST_P(ReceiveStatisticsProxy2TestWithContent, ManyPausesAtTheBeginning) {
1486   const int kInterFrameDelayMs = 33;
1487   const int kPauseDurationMs = 10000;
1488   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1489 
1490   for (int i = 0; i <= kMinRequiredSamples; ++i) {
1491     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1492     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1493 
1494     statistics_proxy_->OnStreamInactive();
1495     fake_clock_.AdvanceTimeMilliseconds(kPauseDurationMs);
1496 
1497     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type_);
1498     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1499   }
1500 
1501   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1502                                       nullptr);
1503   // No freezes should be detected, as all long inter-frame delays were
1504   // pauses.
1505   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1506     EXPECT_METRIC_EQ(-1, metrics::MinSample(
1507                              "WebRTC.Video.Screenshare.MeanFreezeDurationMs"));
1508   } else {
1509     EXPECT_METRIC_EQ(-1,
1510                      metrics::MinSample("WebRTC.Video.MeanFreezeDurationMs"));
1511   }
1512 }
1513 
TEST_P(ReceiveStatisticsProxy2TestWithContent,TimeInHdReported)1514 TEST_P(ReceiveStatisticsProxy2TestWithContent, TimeInHdReported) {
1515   const int kInterFrameDelayMs = 20;
1516   webrtc::VideoFrame frame_hd = CreateFrame(1280, 720);
1517   webrtc::VideoFrame frame_sd = CreateFrame(640, 360);
1518 
1519   // HD frames.
1520   for (int i = 0; i < kMinRequiredSamples; ++i) {
1521     VideoFrameMetaData meta = MetaData(frame_hd);
1522     statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, 0, content_type_);
1523     statistics_proxy_->OnRenderedFrame(meta);
1524     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1525   }
1526   // SD frames.
1527   for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
1528     VideoFrameMetaData meta = MetaData(frame_sd);
1529     statistics_proxy_->OnDecodedFrame(meta, absl::nullopt, 0, content_type_);
1530     statistics_proxy_->OnRenderedFrame(meta);
1531     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1532   }
1533   // Extra last frame.
1534   statistics_proxy_->OnRenderedFrame(MetaData(frame_sd));
1535 
1536   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1537                                       nullptr);
1538   const int kExpectedTimeInHdPercents = 33;
1539   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1540     EXPECT_METRIC_EQ(
1541         kExpectedTimeInHdPercents,
1542         metrics::MinSample("WebRTC.Video.Screenshare.TimeInHdPercentage"));
1543   } else {
1544     EXPECT_METRIC_EQ(kExpectedTimeInHdPercents,
1545                      metrics::MinSample("WebRTC.Video.TimeInHdPercentage"));
1546   }
1547 }
1548 
TEST_P(ReceiveStatisticsProxy2TestWithContent,TimeInBlockyVideoReported)1549 TEST_P(ReceiveStatisticsProxy2TestWithContent, TimeInBlockyVideoReported) {
1550   const int kInterFrameDelayMs = 20;
1551   const int kHighQp = 80;
1552   const int kLowQp = 30;
1553   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1554 
1555   // High quality frames.
1556   for (int i = 0; i < kMinRequiredSamples; ++i) {
1557     VideoFrameMetaData meta = MetaData(frame);
1558     statistics_proxy_->OnDecodedFrame(meta, kLowQp, 0, content_type_);
1559     statistics_proxy_->OnRenderedFrame(meta);
1560     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1561   }
1562   // Blocky frames.
1563   for (int i = 0; i < 2 * kMinRequiredSamples; ++i) {
1564     VideoFrameMetaData meta = MetaData(frame);
1565     statistics_proxy_->OnDecodedFrame(meta, kHighQp, 0, content_type_);
1566     statistics_proxy_->OnRenderedFrame(meta);
1567     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1568   }
1569   // Extra last frame.
1570   statistics_proxy_->OnDecodedFrame(frame, kHighQp, 0, content_type_);
1571   statistics_proxy_->OnRenderedFrame(MetaData(frame));
1572 
1573   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1574   const int kExpectedTimeInHdPercents = 66;
1575   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1576     EXPECT_METRIC_EQ(
1577         kExpectedTimeInHdPercents,
1578         metrics::MinSample(
1579             "WebRTC.Video.Screenshare.TimeInBlockyVideoPercentage"));
1580   } else {
1581     EXPECT_METRIC_EQ(
1582         kExpectedTimeInHdPercents,
1583         metrics::MinSample("WebRTC.Video.TimeInBlockyVideoPercentage"));
1584   }
1585 }
1586 
TEST_P(ReceiveStatisticsProxy2TestWithContent,DownscalesReported)1587 TEST_P(ReceiveStatisticsProxy2TestWithContent, DownscalesReported) {
1588   const int kInterFrameDelayMs = 2000;  // To ensure long enough call duration.
1589 
1590   webrtc::VideoFrame frame_hd = CreateFrame(1280, 720);
1591   webrtc::VideoFrame frame_sd = CreateFrame(640, 360);
1592   webrtc::VideoFrame frame_ld = CreateFrame(320, 180);
1593 
1594   // Call once to pass content type.
1595   statistics_proxy_->OnDecodedFrame(frame_hd, absl::nullopt, 0, content_type_);
1596 
1597   loop_.Flush();
1598   statistics_proxy_->OnRenderedFrame(MetaData(frame_hd));
1599   fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1600 
1601   // Downscale.
1602   statistics_proxy_->OnRenderedFrame(MetaData(frame_sd));
1603   fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1604 
1605   // Downscale.
1606   statistics_proxy_->OnRenderedFrame(MetaData(frame_ld));
1607   fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1608 
1609   statistics_proxy_->UpdateHistograms(absl::nullopt, StreamDataCounters(),
1610                                       nullptr);
1611   const int kExpectedDownscales = 30;  // 2 per 4 seconds = 30 per minute.
1612   if (videocontenttypehelpers::IsScreenshare(content_type_)) {
1613     EXPECT_METRIC_EQ(
1614         kExpectedDownscales,
1615         metrics::MinSample("WebRTC.Video.Screenshare."
1616                            "NumberResolutionDownswitchesPerMinute"));
1617   } else {
1618     EXPECT_METRIC_EQ(kExpectedDownscales,
1619                      metrics::MinSample(
1620                          "WebRTC.Video.NumberResolutionDownswitchesPerMinute"));
1621   }
1622 }
1623 
TEST_P(ReceiveStatisticsProxy2TestWithContent,DecodeTimeReported)1624 TEST_P(ReceiveStatisticsProxy2TestWithContent, DecodeTimeReported) {
1625   const int kInterFrameDelayMs = 20;
1626   const int kLowQp = 30;
1627   const int kDecodeMs = 7;
1628 
1629   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1630 
1631   for (int i = 0; i < kMinRequiredSamples; ++i) {
1632     statistics_proxy_->OnDecodedFrame(frame, kLowQp, kDecodeMs, content_type_);
1633     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
1634   }
1635   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1636   EXPECT_METRIC_EQ(
1637       1, metrics::NumEvents("WebRTC.Video.DecodeTimeInMs", kDecodeMs));
1638 }
1639 
TEST_P(ReceiveStatisticsProxy2TestWithContent,StatsAreSlicedOnSimulcastAndExperiment)1640 TEST_P(ReceiveStatisticsProxy2TestWithContent,
1641        StatsAreSlicedOnSimulcastAndExperiment) {
1642   const uint8_t experiment_id = 1;
1643   webrtc::VideoContentType content_type = content_type_;
1644   videocontenttypehelpers::SetExperimentId(&content_type, experiment_id);
1645   const int kInterFrameDelayMs1 = 30;
1646   const int kInterFrameDelayMs2 = 50;
1647   webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
1648 
1649   videocontenttypehelpers::SetSimulcastId(&content_type, 1);
1650   for (int i = 0; i <= kMinRequiredSamples; ++i) {
1651     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs1);
1652     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type);
1653   }
1654 
1655   videocontenttypehelpers::SetSimulcastId(&content_type, 2);
1656   for (int i = 0; i <= kMinRequiredSamples; ++i) {
1657     fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs2);
1658     statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, 0, content_type);
1659   }
1660   FlushAndUpdateHistograms(absl::nullopt, StreamDataCounters(), nullptr);
1661 
1662   if (videocontenttypehelpers::IsScreenshare(content_type)) {
1663     EXPECT_METRIC_EQ(
1664         1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1665     EXPECT_METRIC_EQ(1, metrics::NumSamples(
1666                             "WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1667     EXPECT_METRIC_EQ(1, metrics::NumSamples(
1668                             "WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1669     EXPECT_METRIC_EQ(1,
1670                      metrics::NumSamples(
1671                          "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S0"));
1672     EXPECT_METRIC_EQ(1, metrics::NumSamples(
1673                             "WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1674     EXPECT_METRIC_EQ(1,
1675                      metrics::NumSamples(
1676                          "WebRTC.Video.Screenshare.InterframeDelayMaxInMs.S1"));
1677     EXPECT_METRIC_EQ(
1678         1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayInMs"
1679                                ".ExperimentGroup0"));
1680     EXPECT_METRIC_EQ(
1681         1, metrics::NumSamples("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"
1682                                ".ExperimentGroup0"));
1683     EXPECT_METRIC_EQ(
1684         kInterFrameDelayMs1,
1685         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S0"));
1686     EXPECT_METRIC_EQ(
1687         kInterFrameDelayMs2,
1688         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs.S1"));
1689     EXPECT_METRIC_EQ(
1690         (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1691         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayInMs"));
1692     EXPECT_METRIC_EQ(
1693         kInterFrameDelayMs2,
1694         metrics::MinSample("WebRTC.Video.Screenshare.InterframeDelayMaxInMs"));
1695     EXPECT_METRIC_EQ(
1696         (kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1697         metrics::MinSample(
1698             "WebRTC.Video.Screenshare.InterframeDelayInMs.ExperimentGroup0"));
1699   } else {
1700     EXPECT_METRIC_EQ(1,
1701                      metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"));
1702     EXPECT_METRIC_EQ(
1703         1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"));
1704     EXPECT_METRIC_EQ(
1705         1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S0"));
1706     EXPECT_METRIC_EQ(
1707         1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S0"));
1708     EXPECT_METRIC_EQ(
1709         1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs.S1"));
1710     EXPECT_METRIC_EQ(
1711         1, metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs.S1"));
1712     EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.InterframeDelayInMs"
1713                                             ".ExperimentGroup0"));
1714     EXPECT_METRIC_EQ(1,
1715                      metrics::NumSamples("WebRTC.Video.InterframeDelayMaxInMs"
1716                                          ".ExperimentGroup0"));
1717     EXPECT_METRIC_EQ(kInterFrameDelayMs1,
1718                      metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S0"));
1719     EXPECT_METRIC_EQ(kInterFrameDelayMs2,
1720                      metrics::MinSample("WebRTC.Video.InterframeDelayInMs.S1"));
1721     EXPECT_METRIC_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1722                      metrics::MinSample("WebRTC.Video.InterframeDelayInMs"));
1723     EXPECT_METRIC_EQ(kInterFrameDelayMs2,
1724                      metrics::MinSample("WebRTC.Video.InterframeDelayMaxInMs"));
1725     EXPECT_METRIC_EQ((kInterFrameDelayMs1 + kInterFrameDelayMs2) / 2,
1726                      metrics::MinSample(
1727                          "WebRTC.Video.InterframeDelayInMs.ExperimentGroup0"));
1728   }
1729 }
1730 
1731 class DecodeTimeHistogramsKillswitch {
1732  public:
DecodeTimeHistogramsKillswitch(bool disable_histograms)1733   explicit DecodeTimeHistogramsKillswitch(bool disable_histograms)
1734       : field_trial_(disable_histograms
1735                          ? "WebRTC-DecodeTimeHistogramsKillSwitch/Enabled/"
1736                          : "") {}
1737 
1738  private:
1739   webrtc::test::ScopedFieldTrials field_trial_;
1740 };
1741 
1742 class ReceiveStatisticsProxy2TestWithDecodeTimeHistograms
1743     : public DecodeTimeHistogramsKillswitch,
1744       public ::testing::WithParamInterface<
1745           std::tuple<bool, int, int, int, VideoCodecType, std::string>>,
1746       public ReceiveStatisticsProxy2Test {
1747  public:
ReceiveStatisticsProxy2TestWithDecodeTimeHistograms()1748   ReceiveStatisticsProxy2TestWithDecodeTimeHistograms()
1749       : DecodeTimeHistogramsKillswitch(std::get<0>(GetParam())) {}
1750 
1751  protected:
1752   const std::string kUmaPrefix = "WebRTC.Video.DecodeTimePerFrameInMs.";
1753   const int expected_number_of_samples_ = {std::get<1>(GetParam())};
1754   const int width_ = {std::get<2>(GetParam())};
1755   const int height_ = {std::get<3>(GetParam())};
1756   const VideoCodecType codec_type_ = {std::get<4>(GetParam())};
1757   const std::string implementation_name_ = {std::get<5>(GetParam())};
1758   const std::string uma_histogram_name_ =
1759       kUmaPrefix + (codec_type_ == kVideoCodecVP9 ? "Vp9." : "H264.") +
1760       (height_ == 2160 ? "4k." : "Hd.") +
1761       (implementation_name_.compare("ExternalDecoder") == 0 ? "Hw" : "Sw");
1762 };
1763 
TEST_P(ReceiveStatisticsProxy2TestWithDecodeTimeHistograms,DecodeTimeHistogramsUpdated)1764 TEST_P(ReceiveStatisticsProxy2TestWithDecodeTimeHistograms,
1765        DecodeTimeHistogramsUpdated) {
1766   constexpr int kNumberOfFrames = 10;
1767   constexpr int kDecodeTimeMs = 7;
1768   constexpr int kFrameDurationMs = 1000 / 60;
1769 
1770   webrtc::VideoFrame frame = CreateFrame(width_, height_);
1771 
1772   statistics_proxy_->OnDecoderImplementationName(implementation_name_.c_str());
1773   statistics_proxy_->OnPreDecode(codec_type_, /*qp=*/0);
1774 
1775   for (int i = 0; i < kNumberOfFrames; ++i) {
1776     statistics_proxy_->OnDecodedFrame(frame, /*qp=*/absl::nullopt,
1777                                       kDecodeTimeMs,
1778                                       VideoContentType::UNSPECIFIED);
1779     fake_clock_.AdvanceTimeMilliseconds(kFrameDurationMs);
1780   }
1781 
1782   loop_.Flush();
1783 
1784   EXPECT_METRIC_EQ(expected_number_of_samples_,
1785                    metrics::NumSamples(uma_histogram_name_));
1786   EXPECT_METRIC_EQ(expected_number_of_samples_,
1787                    metrics::NumEvents(uma_histogram_name_, kDecodeTimeMs));
1788 }
1789 
1790 const auto kVp94kHw = std::make_tuple(/*killswitch=*/false,
1791                                       /*expected_number_of_samples=*/10,
1792                                       /*width=*/3840,
1793                                       /*height=*/2160,
1794                                       kVideoCodecVP9,
1795                                       /*implementation=*/"ExternalDecoder");
1796 const auto kVp94kSw = std::make_tuple(/*killswitch=*/false,
1797                                       /*expected_number_of_samples=*/10,
1798                                       /*width=*/3840,
1799                                       /*height=*/2160,
1800                                       kVideoCodecVP9,
1801                                       /*implementation=*/"libvpx");
1802 const auto kVp9HdHw = std::make_tuple(/*killswitch=*/false,
1803                                       /*expected_number_of_samples=*/10,
1804                                       /*width=*/1920,
1805                                       /*height=*/1080,
1806                                       kVideoCodecVP9,
1807                                       /*implementation=*/"ExternalDecoder");
1808 const auto kVp9HdSw = std::make_tuple(/*killswitch=*/false,
1809                                       /*expected_number_of_samples=*/10,
1810                                       /*width=*/1920,
1811                                       /*height=*/1080,
1812                                       kVideoCodecVP9,
1813                                       /*implementation=*/"libvpx");
1814 const auto kH2644kHw = std::make_tuple(/*killswitch=*/false,
1815                                        /*expected_number_of_samples=*/10,
1816                                        /*width=*/3840,
1817                                        /*height=*/2160,
1818                                        kVideoCodecH264,
1819                                        /*implementation=*/"ExternalDecoder");
1820 const auto kH2644kSw = std::make_tuple(/*killswitch=*/false,
1821                                        /*expected_number_of_samples=*/10,
1822                                        /*width=*/3840,
1823                                        /*height=*/2160,
1824                                        kVideoCodecH264,
1825                                        /*implementation=*/"FFmpeg");
1826 const auto kH264HdHw = std::make_tuple(/*killswitch=*/false,
1827                                        /*expected_number_of_samples=*/10,
1828                                        /*width=*/1920,
1829                                        /*height=*/1080,
1830                                        kVideoCodecH264,
1831                                        /*implementation=*/"ExternalDecoder");
1832 const auto kH264HdSw = std::make_tuple(/*killswitch=*/false,
1833                                        /*expected_number_of_samples=*/10,
1834                                        /*width=*/1920,
1835                                        /*height=*/1080,
1836                                        kVideoCodecH264,
1837                                        /*implementation=*/"FFmpeg");
1838 
1839 INSTANTIATE_TEST_SUITE_P(AllHistogramsPopulated,
1840                          ReceiveStatisticsProxy2TestWithDecodeTimeHistograms,
1841                          ::testing::Values(kVp94kHw,
1842                                            kVp94kSw,
1843                                            kVp9HdHw,
1844                                            kVp9HdSw,
1845                                            kH2644kHw,
1846                                            kH2644kSw,
1847                                            kH264HdHw,
1848                                            kH264HdSw));
1849 
1850 const auto kKillswitchDisabled =
1851     std::make_tuple(/*killswitch=*/false,
1852                     /*expected_number_of_samples=*/10,
1853                     /*width=*/1920,
1854                     /*height=*/1080,
1855                     kVideoCodecVP9,
1856                     /*implementation=*/"libvpx");
1857 const auto kKillswitchEnabled =
1858     std::make_tuple(/*killswitch=*/true,
1859                     /*expected_number_of_samples=*/0,
1860                     /*width=*/1920,
1861                     /*height=*/1080,
1862                     kVideoCodecVP9,
1863                     /*implementation=*/"libvpx");
1864 
1865 INSTANTIATE_TEST_SUITE_P(KillswitchEffective,
1866                          ReceiveStatisticsProxy2TestWithDecodeTimeHistograms,
1867                          ::testing::Values(kKillswitchDisabled,
1868                                            kKillswitchEnabled));
1869 
1870 }  // namespace internal
1871 }  // namespace webrtc
1872