blob: 6494a6f43c354241a2290403de85f1210836dfb6 [file] [log] [blame]
Ilya Nikolaevskiy94150ee2018-05-23 09:53:191/*
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 Olssona4d87372019-07-05 17:08:3315
Sergey Silkin278f8252019-01-09 13:37:4016#include <set>
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1917#include <vector>
18
Danil Chapovalovb9b146c2018-06-15 10:28:0719#include "absl/types/optional.h"
Niels Möller22b70ff2018-11-20 10:06:5820#include "api/video/video_codec_type.h"
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1921#include "api/video/video_content_type.h"
Sergey Silkin278f8252019-01-09 13:37:4022#include "api/video/video_frame.h"
Sergey Silkin02371062019-01-31 15:45:4223#include "rtc_base/numerics/moving_average.h"
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1924#include "rtc_base/numerics/sample_counter.h"
25
26namespace webrtc {
27
28// Calculates spatial and temporal quality metrics and reports them to UMA
29// stats.
30class VideoQualityObserver {
31 public:
32 // Use either VideoQualityObserver::kBlockyQpThresholdVp8 or
33 // VideoQualityObserver::kBlockyQpThresholdVp9.
34 explicit VideoQualityObserver(VideoContentType content_type);
Niels Möller9a9f18a2019-08-02 11:52:3735 ~VideoQualityObserver() = default;
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1936
Sergey Silkin278f8252019-01-09 13:37:4037 void OnDecodedFrame(const VideoFrame& frame,
38 absl::optional<uint8_t> qp,
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1939 VideoCodecType codec);
Sergey Silkin278f8252019-01-09 13:37:4040
41 void OnRenderedFrame(const VideoFrame& frame, int64_t now_ms);
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1942
43 void OnStreamInactive();
44
Elad Alon58e06572019-05-08 13:34:2445 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 Silkin02371062019-01-31 15:45:4251
Niels Möller9a9f18a2019-08-02 11:52:3752 void UpdateHistograms();
53
Sergey Silkin02371062019-01-31 15:45:4254 static const uint32_t kMinFrameSamplesToDetectFreeze;
55 static const uint32_t kMinIncreaseForFreezeMs;
56 static const uint32_t kAvgInterframeDelaysWindowSizeFrames;
57
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1958 private:
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1959 enum Resolution {
60 Low = 0,
61 Medium = 1,
62 High = 2,
63 };
64
Ilya Nikolaevskiycdc959f2018-10-10 11:15:0965 int64_t last_frame_rendered_ms_;
Ilya Nikolaevskiycdc959f2018-10-10 11:15:0966 int64_t num_frames_rendered_;
Sergey Silkin278f8252019-01-09 13:37:4067 int64_t first_frame_rendered_ms_;
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1968 int64_t last_frame_pixels_;
Sergey Silkin278f8252019-01-09 13:37:4069 bool is_last_frame_blocky_;
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1970 // Decoded timestamp of the last delayed frame.
Sergey Silkin02371062019-01-31 15:45:4271 int64_t last_unfreeze_time_ms_;
72 rtc::MovingAverage render_interframe_delays_;
Sergey Silkin50e77452019-01-16 12:41:4673 double sum_squared_interframe_delays_secs_;
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1974 // 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 Silkin02371062019-01-31 15:45:4277 rtc::SampleCounter pauses_durations_;
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1978 // 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 Silkin278f8252019-01-09 13:37:4092
93 // Set of decoded frames with high QP value.
94 std::set<int64_t> blocky_frames_;
Ilya Nikolaevskiy94150ee2018-05-23 09:53:1995};
96
97} // namespace webrtc
98
99#endif // VIDEO_VIDEO_QUALITY_OBSERVER_H_