1 /*
2  *  Copyright (c) 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 #ifndef VIDEO_VIDEO_QUALITY_OBSERVER2_H_
12 #define VIDEO_VIDEO_QUALITY_OBSERVER2_H_
13 
14 #include <stdint.h>
15 
16 #include <set>
17 #include <vector>
18 
19 #include "absl/types/optional.h"
20 #include "api/video/video_codec_type.h"
21 #include "api/video/video_content_type.h"
22 #include "rtc_base/numerics/moving_average.h"
23 #include "rtc_base/numerics/sample_counter.h"
24 
25 namespace webrtc {
26 namespace internal {
27 // Declared in video_receive_stream2.h.
28 struct VideoFrameMetaData;
29 
30 // Calculates spatial and temporal quality metrics and reports them to UMA
31 // stats.
32 class VideoQualityObserver {
33  public:
34   // Use either VideoQualityObserver::kBlockyQpThresholdVp8 or
35   // VideoQualityObserver::kBlockyQpThresholdVp9.
36   VideoQualityObserver();
37   ~VideoQualityObserver() = default;
38 
39   void OnDecodedFrame(uint32_t rtp_frame_timestamp,
40                       absl::optional<uint8_t> qp,
41                       VideoCodecType codec);
42 
43   void OnRenderedFrame(const VideoFrameMetaData& frame_meta);
44 
45   void OnStreamInactive();
46 
47   uint32_t NumFreezes() const;
48   uint32_t NumPauses() const;
49   uint32_t TotalFreezesDurationMs() const;
50   uint32_t TotalPausesDurationMs() const;
51   uint32_t TotalFramesDurationMs() const;
52   double SumSquaredFrameDurationsSec() const;
53 
54   // Set |screenshare| to true if the last decoded frame was for screenshare.
55   void UpdateHistograms(bool screenshare);
56 
57   static const uint32_t kMinFrameSamplesToDetectFreeze;
58   static const uint32_t kMinIncreaseForFreezeMs;
59   static const uint32_t kAvgInterframeDelaysWindowSizeFrames;
60 
61  private:
62   enum Resolution {
63     Low = 0,
64     Medium = 1,
65     High = 2,
66   };
67 
68   int64_t last_frame_rendered_ms_;
69   int64_t num_frames_rendered_;
70   int64_t first_frame_rendered_ms_;
71   int64_t last_frame_pixels_;
72   bool is_last_frame_blocky_;
73   // Decoded timestamp of the last delayed frame.
74   int64_t last_unfreeze_time_ms_;
75   rtc::MovingAverage render_interframe_delays_;
76   double sum_squared_interframe_delays_secs_;
77   // An inter-frame delay is counted as a freeze if it's significantly longer
78   // than average inter-frame delay.
79   rtc::SampleCounter freezes_durations_;
80   rtc::SampleCounter pauses_durations_;
81   // Time between freezes.
82   rtc::SampleCounter smooth_playback_durations_;
83   // Counters for time spent in different resolutions. Time between each two
84   // Consecutive frames is counted to bin corresponding to the first frame
85   // resolution.
86   std::vector<int64_t> time_in_resolution_ms_;
87   // Resolution of the last decoded frame. Resolution enum is used as an index.
88   Resolution current_resolution_;
89   int num_resolution_downgrades_;
90   // Similar to resolution, time spent in high-QP video.
91   int64_t time_in_blocky_video_ms_;
92   bool is_paused_;
93 
94   // Set of decoded frames with high QP value.
95   std::set<int64_t> blocky_frames_;
96 };
97 
98 }  // namespace internal
99 }  // namespace webrtc
100 
101 #endif  // VIDEO_VIDEO_QUALITY_OBSERVER2_H_
102