1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef VIDEO_VIDEO_QUALITY_OBSERVER2_H_ 12*d9f75844SAndroid Build Coastguard Worker #define VIDEO_VIDEO_QUALITY_OBSERVER2_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 15*d9f75844SAndroid Build Coastguard Worker 16*d9f75844SAndroid Build Coastguard Worker #include <set> 17*d9f75844SAndroid Build Coastguard Worker #include <vector> 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 20*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_codec_type.h" 21*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_content_type.h" 22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/moving_average.h" 23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/sample_counter.h" 24*d9f75844SAndroid Build Coastguard Worker 25*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 26*d9f75844SAndroid Build Coastguard Worker namespace internal { 27*d9f75844SAndroid Build Coastguard Worker // Declared in video_receive_stream2.h. 28*d9f75844SAndroid Build Coastguard Worker struct VideoFrameMetaData; 29*d9f75844SAndroid Build Coastguard Worker 30*d9f75844SAndroid Build Coastguard Worker // Calculates spatial and temporal quality metrics and reports them to UMA 31*d9f75844SAndroid Build Coastguard Worker // stats. 32*d9f75844SAndroid Build Coastguard Worker class VideoQualityObserver { 33*d9f75844SAndroid Build Coastguard Worker public: 34*d9f75844SAndroid Build Coastguard Worker // Use either VideoQualityObserver::kBlockyQpThresholdVp8 or 35*d9f75844SAndroid Build Coastguard Worker // VideoQualityObserver::kBlockyQpThresholdVp9. 36*d9f75844SAndroid Build Coastguard Worker VideoQualityObserver(); 37*d9f75844SAndroid Build Coastguard Worker ~VideoQualityObserver() = default; 38*d9f75844SAndroid Build Coastguard Worker 39*d9f75844SAndroid Build Coastguard Worker void OnDecodedFrame(uint32_t rtp_frame_timestamp, 40*d9f75844SAndroid Build Coastguard Worker absl::optional<uint8_t> qp, 41*d9f75844SAndroid Build Coastguard Worker VideoCodecType codec); 42*d9f75844SAndroid Build Coastguard Worker 43*d9f75844SAndroid Build Coastguard Worker void OnRenderedFrame(const VideoFrameMetaData& frame_meta); 44*d9f75844SAndroid Build Coastguard Worker 45*d9f75844SAndroid Build Coastguard Worker void OnStreamInactive(); 46*d9f75844SAndroid Build Coastguard Worker 47*d9f75844SAndroid Build Coastguard Worker uint32_t NumFreezes() const; 48*d9f75844SAndroid Build Coastguard Worker uint32_t NumPauses() const; 49*d9f75844SAndroid Build Coastguard Worker uint32_t TotalFreezesDurationMs() const; 50*d9f75844SAndroid Build Coastguard Worker uint32_t TotalPausesDurationMs() const; 51*d9f75844SAndroid Build Coastguard Worker uint32_t TotalFramesDurationMs() const; 52*d9f75844SAndroid Build Coastguard Worker double SumSquaredFrameDurationsSec() const; 53*d9f75844SAndroid Build Coastguard Worker 54*d9f75844SAndroid Build Coastguard Worker // Set `screenshare` to true if the last decoded frame was for screenshare. 55*d9f75844SAndroid Build Coastguard Worker void UpdateHistograms(bool screenshare); 56*d9f75844SAndroid Build Coastguard Worker 57*d9f75844SAndroid Build Coastguard Worker static const uint32_t kMinFrameSamplesToDetectFreeze; 58*d9f75844SAndroid Build Coastguard Worker static const uint32_t kMinIncreaseForFreezeMs; 59*d9f75844SAndroid Build Coastguard Worker static const uint32_t kAvgInterframeDelaysWindowSizeFrames; 60*d9f75844SAndroid Build Coastguard Worker 61*d9f75844SAndroid Build Coastguard Worker private: 62*d9f75844SAndroid Build Coastguard Worker enum Resolution { 63*d9f75844SAndroid Build Coastguard Worker Low = 0, 64*d9f75844SAndroid Build Coastguard Worker Medium = 1, 65*d9f75844SAndroid Build Coastguard Worker High = 2, 66*d9f75844SAndroid Build Coastguard Worker }; 67*d9f75844SAndroid Build Coastguard Worker 68*d9f75844SAndroid Build Coastguard Worker int64_t last_frame_rendered_ms_; 69*d9f75844SAndroid Build Coastguard Worker int64_t num_frames_rendered_; 70*d9f75844SAndroid Build Coastguard Worker int64_t first_frame_rendered_ms_; 71*d9f75844SAndroid Build Coastguard Worker int64_t last_frame_pixels_; 72*d9f75844SAndroid Build Coastguard Worker bool is_last_frame_blocky_; 73*d9f75844SAndroid Build Coastguard Worker // Decoded timestamp of the last delayed frame. 74*d9f75844SAndroid Build Coastguard Worker int64_t last_unfreeze_time_ms_; 75*d9f75844SAndroid Build Coastguard Worker rtc::MovingAverage render_interframe_delays_; 76*d9f75844SAndroid Build Coastguard Worker double sum_squared_interframe_delays_secs_; 77*d9f75844SAndroid Build Coastguard Worker // An inter-frame delay is counted as a freeze if it's significantly longer 78*d9f75844SAndroid Build Coastguard Worker // than average inter-frame delay. 79*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter freezes_durations_; 80*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter pauses_durations_; 81*d9f75844SAndroid Build Coastguard Worker // Time between freezes. 82*d9f75844SAndroid Build Coastguard Worker rtc::SampleCounter smooth_playback_durations_; 83*d9f75844SAndroid Build Coastguard Worker // Counters for time spent in different resolutions. Time between each two 84*d9f75844SAndroid Build Coastguard Worker // Consecutive frames is counted to bin corresponding to the first frame 85*d9f75844SAndroid Build Coastguard Worker // resolution. 86*d9f75844SAndroid Build Coastguard Worker std::vector<int64_t> time_in_resolution_ms_; 87*d9f75844SAndroid Build Coastguard Worker // Resolution of the last decoded frame. Resolution enum is used as an index. 88*d9f75844SAndroid Build Coastguard Worker Resolution current_resolution_; 89*d9f75844SAndroid Build Coastguard Worker int num_resolution_downgrades_; 90*d9f75844SAndroid Build Coastguard Worker // Similar to resolution, time spent in high-QP video. 91*d9f75844SAndroid Build Coastguard Worker int64_t time_in_blocky_video_ms_; 92*d9f75844SAndroid Build Coastguard Worker bool is_paused_; 93*d9f75844SAndroid Build Coastguard Worker 94*d9f75844SAndroid Build Coastguard Worker // Set of decoded frames with high QP value. 95*d9f75844SAndroid Build Coastguard Worker std::set<int64_t> blocky_frames_; 96*d9f75844SAndroid Build Coastguard Worker }; 97*d9f75844SAndroid Build Coastguard Worker 98*d9f75844SAndroid Build Coastguard Worker } // namespace internal 99*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 100*d9f75844SAndroid Build Coastguard Worker 101*d9f75844SAndroid Build Coastguard Worker #endif // VIDEO_VIDEO_QUALITY_OBSERVER2_H_ 102