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