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