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