Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 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> |
Jonas Olsson | a4d8737 | 2019-07-05 17:08:33 | [diff] [blame] | 15 | |
Sergey Silkin | 278f825 | 2019-01-09 13:37:40 | [diff] [blame] | 16 | #include <set> |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 17 | #include <vector> |
| 18 | |
Danil Chapovalov | b9b146c | 2018-06-15 10:28:07 | [diff] [blame] | 19 | #include "absl/types/optional.h" |
Niels Möller | 22b70ff | 2018-11-20 10:06:58 | [diff] [blame] | 20 | #include "api/video/video_codec_type.h" |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 21 | #include "api/video/video_content_type.h" |
Sergey Silkin | 278f825 | 2019-01-09 13:37:40 | [diff] [blame] | 22 | #include "api/video/video_frame.h" |
Sergey Silkin | 0237106 | 2019-01-31 15:45:42 | [diff] [blame] | 23 | #include "rtc_base/numerics/moving_average.h" |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 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); |
Niels Möller | 9a9f18a | 2019-08-02 11:52:37 | [diff] [blame] | 35 | ~VideoQualityObserver() = default; |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 36 | |
Sergey Silkin | 278f825 | 2019-01-09 13:37:40 | [diff] [blame] | 37 | void OnDecodedFrame(const VideoFrame& frame, |
| 38 | absl::optional<uint8_t> qp, |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 39 | VideoCodecType codec); |
Sergey Silkin | 278f825 | 2019-01-09 13:37:40 | [diff] [blame] | 40 | |
| 41 | void OnRenderedFrame(const VideoFrame& frame, int64_t now_ms); |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 42 | |
| 43 | void OnStreamInactive(); |
| 44 | |
Elad Alon | 58e0657 | 2019-05-08 13:34:24 | [diff] [blame] | 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; |
Sergey Silkin | 0237106 | 2019-01-31 15:45:42 | [diff] [blame] | 51 | |
Niels Möller | 9a9f18a | 2019-08-02 11:52:37 | [diff] [blame] | 52 | void UpdateHistograms(); |
| 53 | |
Sergey Silkin | 0237106 | 2019-01-31 15:45:42 | [diff] [blame] | 54 | static const uint32_t kMinFrameSamplesToDetectFreeze; |
| 55 | static const uint32_t kMinIncreaseForFreezeMs; |
| 56 | static const uint32_t kAvgInterframeDelaysWindowSizeFrames; |
| 57 | |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 58 | private: |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 59 | enum Resolution { |
| 60 | Low = 0, |
| 61 | Medium = 1, |
| 62 | High = 2, |
| 63 | }; |
| 64 | |
Ilya Nikolaevskiy | cdc959f | 2018-10-10 11:15:09 | [diff] [blame] | 65 | int64_t last_frame_rendered_ms_; |
Ilya Nikolaevskiy | cdc959f | 2018-10-10 11:15:09 | [diff] [blame] | 66 | int64_t num_frames_rendered_; |
Sergey Silkin | 278f825 | 2019-01-09 13:37:40 | [diff] [blame] | 67 | int64_t first_frame_rendered_ms_; |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 68 | int64_t last_frame_pixels_; |
Sergey Silkin | 278f825 | 2019-01-09 13:37:40 | [diff] [blame] | 69 | bool is_last_frame_blocky_; |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 70 | // Decoded timestamp of the last delayed frame. |
Sergey Silkin | 0237106 | 2019-01-31 15:45:42 | [diff] [blame] | 71 | int64_t last_unfreeze_time_ms_; |
| 72 | rtc::MovingAverage render_interframe_delays_; |
Sergey Silkin | 50e7745 | 2019-01-16 12:41:46 | [diff] [blame] | 73 | double sum_squared_interframe_delays_secs_; |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 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_; |
Sergey Silkin | 0237106 | 2019-01-31 15:45:42 | [diff] [blame] | 77 | rtc::SampleCounter pauses_durations_; |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 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_; |
Sergey Silkin | 278f825 | 2019-01-09 13:37:40 | [diff] [blame] | 92 | |
| 93 | // Set of decoded frames with high QP value. |
| 94 | std::set<int64_t> blocky_frames_; |
Ilya Nikolaevskiy | 94150ee | 2018-05-23 09:53:19 | [diff] [blame] | 95 | }; |
| 96 | |
| 97 | } // namespace webrtc |
| 98 | |
| 99 | #endif // VIDEO_VIDEO_QUALITY_OBSERVER_H_ |