Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 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" |
Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 22 | #include "rtc_base/numerics/moving_average.h" |
| 23 | #include "rtc_base/numerics/sample_counter.h" |
| 24 | |
| 25 | namespace webrtc { |
| 26 | namespace internal { |
Tommi | d7e08c8 | 2020-05-10 09:24:43 | [diff] [blame] | 27 | // Declared in video_receive_stream2.h. |
| 28 | struct VideoFrameMetaData; |
Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 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. |
Tommi | 553c869 | 2020-05-05 13:35:45 | [diff] [blame] | 36 | VideoQualityObserver(); |
Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 37 | ~VideoQualityObserver() = default; |
| 38 | |
Tommi | d7e08c8 | 2020-05-10 09:24:43 | [diff] [blame] | 39 | void OnDecodedFrame(uint32_t rtp_frame_timestamp, |
Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 40 | absl::optional<uint8_t> qp, |
| 41 | VideoCodecType codec); |
| 42 | |
Tommi | d7e08c8 | 2020-05-10 09:24:43 | [diff] [blame] | 43 | void OnRenderedFrame(const VideoFrameMetaData& frame_meta); |
Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 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 | |
Artem Titov | ab30d72 | 2021-07-27 14:22:11 | [diff] [blame] | 54 | // Set `screenshare` to true if the last decoded frame was for screenshare. |
Tommi | 553c869 | 2020-05-05 13:35:45 | [diff] [blame] | 55 | void UpdateHistograms(bool screenshare); |
Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 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_; |
Tommi | 74fc574 | 2020-04-27 08:43:06 | [diff] [blame] | 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_ |