Line data Source code
1 : /*
2 : * Copyright (c) 2013 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 WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
12 : #define WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
13 :
14 : #include <map>
15 : #include <memory>
16 : #include <string>
17 : #include <vector>
18 :
19 : #include "webrtc/base/criticalsection.h"
20 : #include "webrtc/base/numerics/exp_filter.h"
21 : #include "webrtc/base/ratetracker.h"
22 : #include "webrtc/base/thread_annotations.h"
23 : #include "webrtc/common_types.h"
24 : #include "webrtc/modules/video_coding/include/video_codec_interface.h"
25 : #include "webrtc/modules/video_coding/include/video_coding_defines.h"
26 : #include "webrtc/system_wrappers/include/clock.h"
27 : #include "webrtc/video/overuse_frame_detector.h"
28 : #include "webrtc/video/report_block_stats.h"
29 : #include "webrtc/video/stats_counter.h"
30 : #include "webrtc/video/vie_encoder.h"
31 : #include "webrtc/video_send_stream.h"
32 :
33 : namespace webrtc {
34 :
35 : class SendStatisticsProxy : public CpuOveruseMetricsObserver,
36 : public RtcpStatisticsCallback,
37 : public RtcpPacketTypeCounterObserver,
38 : public StreamDataCountersCallback,
39 : public BitrateStatisticsObserver,
40 : public FrameCountObserver,
41 : public SendSideDelayObserver {
42 : public:
43 : static const int kStatsTimeoutMs;
44 : // Number of required samples to be collected before a metric is added
45 : // to a rtc histogram.
46 : static const int kMinRequiredMetricsSamples = 200;
47 :
48 : SendStatisticsProxy(Clock* clock,
49 : const VideoSendStream::Config& config,
50 : VideoEncoderConfig::ContentType content_type);
51 : virtual ~SendStatisticsProxy();
52 :
53 : VideoSendStream::Stats GetStats();
54 :
55 : virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
56 : const CodecSpecificInfo* codec_info);
57 : // Used to update incoming frame rate.
58 : void OnIncomingFrame(int width, int height);
59 :
60 : void OnCpuRestrictedResolutionChanged(bool cpu_restricted_resolution);
61 : void OnQualityRestrictedResolutionChanged(int num_quality_downscales);
62 : void SetResolutionRestrictionStats(bool scaling_enabled,
63 : bool cpu_restricted,
64 : int num_quality_downscales);
65 :
66 : void OnEncoderStatsUpdate(uint32_t framerate, uint32_t bitrate);
67 : void OnSuspendChange(bool is_suspended);
68 : void OnInactiveSsrc(uint32_t ssrc);
69 :
70 : // Used to indicate change in content type, which may require a change in
71 : // how stats are collected and set the configured preferred media bitrate.
72 : void OnEncoderReconfigured(const VideoEncoderConfig& encoder_config,
73 : uint32_t preferred_bitrate_bps);
74 :
75 : // Used to update the encoder target rate.
76 : void OnSetEncoderTargetRate(uint32_t bitrate_bps);
77 :
78 : // Implements CpuOveruseMetricsObserver.
79 : void OnEncodedFrameTimeMeasured(int encode_time_ms,
80 : const CpuOveruseMetrics& metrics) override;
81 :
82 : int GetSendFrameRate() const;
83 :
84 : protected:
85 : // From RtcpStatisticsCallback.
86 : void StatisticsUpdated(const RtcpStatistics& statistics,
87 : uint32_t ssrc) override;
88 : void CNameChanged(const char* cname, uint32_t ssrc) override;
89 : // From RtcpPacketTypeCounterObserver.
90 : void RtcpPacketTypesCounterUpdated(
91 : uint32_t ssrc,
92 : const RtcpPacketTypeCounter& packet_counter) override;
93 : // From StreamDataCountersCallback.
94 : void DataCountersUpdated(const StreamDataCounters& counters,
95 : uint32_t ssrc) override;
96 :
97 : // From BitrateStatisticsObserver.
98 : void Notify(uint32_t total_bitrate_bps,
99 : uint32_t retransmit_bitrate_bps,
100 : uint32_t ssrc) override;
101 :
102 : // From FrameCountObserver.
103 : void FrameCountUpdated(const FrameCounts& frame_counts,
104 : uint32_t ssrc) override;
105 :
106 : void SendSideDelayUpdated(int avg_delay_ms,
107 : int max_delay_ms,
108 : uint32_t ssrc) override;
109 :
110 : private:
111 : class SampleCounter {
112 : public:
113 0 : SampleCounter() : sum(0), num_samples(0) {}
114 0 : ~SampleCounter() {}
115 : void Add(int sample);
116 : int Avg(int64_t min_required_samples) const;
117 :
118 : private:
119 : int64_t sum;
120 : int64_t num_samples;
121 : };
122 : class BoolSampleCounter {
123 : public:
124 0 : BoolSampleCounter() : sum(0), num_samples(0) {}
125 0 : ~BoolSampleCounter() {}
126 : void Add(bool sample);
127 : void Add(bool sample, int64_t count);
128 : int Percent(int64_t min_required_samples) const;
129 : int Permille(int64_t min_required_samples) const;
130 :
131 : private:
132 : int Fraction(int64_t min_required_samples, float multiplier) const;
133 : int64_t sum;
134 : int64_t num_samples;
135 : };
136 : struct StatsUpdateTimes {
137 0 : StatsUpdateTimes() : resolution_update_ms(0), bitrate_update_ms(0) {}
138 : int64_t resolution_update_ms;
139 : int64_t bitrate_update_ms;
140 : };
141 : struct TargetRateUpdates {
142 0 : TargetRateUpdates()
143 0 : : pause_resume_events(0), last_paused_or_resumed(false), last_ms(-1) {}
144 : int pause_resume_events;
145 : bool last_paused_or_resumed;
146 : int64_t last_ms;
147 : };
148 0 : struct QpCounters {
149 : SampleCounter vp8; // QP range: 0-127
150 : SampleCounter vp9; // QP range: 0-255
151 : SampleCounter h264; // QP range: 0-51
152 : };
153 : void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
154 : VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
155 : EXCLUSIVE_LOCKS_REQUIRED(crit_);
156 :
157 : Clock* const clock_;
158 : const std::string payload_name_;
159 : const VideoSendStream::Config::Rtp rtp_config_;
160 : rtc::CriticalSection crit_;
161 : VideoEncoderConfig::ContentType content_type_ GUARDED_BY(crit_);
162 : const int64_t start_ms_;
163 : VideoSendStream::Stats stats_ GUARDED_BY(crit_);
164 : uint32_t last_sent_frame_timestamp_ GUARDED_BY(crit_);
165 : std::map<uint32_t, StatsUpdateTimes> update_times_ GUARDED_BY(crit_);
166 : rtc::ExpFilter encode_time_ GUARDED_BY(crit_);
167 : int quality_downscales_ GUARDED_BY(crit_) = 0;
168 :
169 : // Contains stats used for UMA histograms. These stats will be reset if
170 : // content type changes between real-time video and screenshare, since these
171 : // will be reported separately.
172 : struct UmaSamplesContainer {
173 : UmaSamplesContainer(const char* prefix,
174 : const VideoSendStream::Stats& start_stats,
175 : Clock* clock);
176 : ~UmaSamplesContainer();
177 :
178 : void UpdateHistograms(const VideoSendStream::Config::Rtp& rtp_config,
179 : const VideoSendStream::Stats& current_stats);
180 :
181 : const std::string uma_prefix_;
182 : Clock* const clock_;
183 : int max_sent_width_per_timestamp_;
184 : int max_sent_height_per_timestamp_;
185 : SampleCounter input_width_counter_;
186 : SampleCounter input_height_counter_;
187 : SampleCounter sent_width_counter_;
188 : SampleCounter sent_height_counter_;
189 : SampleCounter encode_time_counter_;
190 : BoolSampleCounter key_frame_counter_;
191 : BoolSampleCounter quality_limited_frame_counter_;
192 : SampleCounter quality_downscales_counter_;
193 : BoolSampleCounter cpu_limited_frame_counter_;
194 : BoolSampleCounter bw_limited_frame_counter_;
195 : SampleCounter bw_resolutions_disabled_counter_;
196 : SampleCounter delay_counter_;
197 : SampleCounter max_delay_counter_;
198 : rtc::RateTracker input_frame_rate_tracker_;
199 : RateCounter input_fps_counter_;
200 : RateCounter sent_fps_counter_;
201 : int64_t first_rtcp_stats_time_ms_;
202 : int64_t first_rtp_stats_time_ms_;
203 : BoolSampleCounter paused_time_counter_;
204 : TargetRateUpdates target_rate_updates_;
205 : ReportBlockStats report_block_stats_;
206 : const VideoSendStream::Stats start_stats_;
207 : std::map<int, QpCounters>
208 : qp_counters_; // QP counters mapped by spatial idx.
209 : };
210 :
211 : std::unique_ptr<UmaSamplesContainer> uma_container_ GUARDED_BY(crit_);
212 : };
213 :
214 : } // namespace webrtc
215 : #endif // WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_
|