blob: 312186a1f9e63bce2a8e7d099a593edcf99699e8 [file] [log] [blame]
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001/*
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
mflodmand1590b22015-12-09 07:07:59 -080014#include <map>
kwiberg27f982b2016-03-01 11:52:33 -080015#include <memory>
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000016#include <string>
Pera48ddb72016-09-29 11:48:50 +020017#include <vector>
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000018
Peter Boströmf2f82832015-05-01 13:00:41 +020019#include "webrtc/base/criticalsection.h"
tereliusbc5d9212017-01-13 09:14:33 -080020#include "webrtc/base/numerics/exp_filter.h"
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +000021#include "webrtc/base/ratetracker.h"
pbos@webrtc.org38344ed2014-09-24 06:05:00 +000022#include "webrtc/base/thread_annotations.h"
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000023#include "webrtc/common_types.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010024#include "webrtc/modules/video_coding/include/video_codec_interface.h"
25#include "webrtc/modules/video_coding/include/video_coding_defines.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010026#include "webrtc/system_wrappers/include/clock.h"
Peter Boström7623ce42015-12-09 12:13:30 +010027#include "webrtc/video/overuse_frame_detector.h"
sprange2d83d62016-02-19 09:03:26 -080028#include "webrtc/video/report_block_stats.h"
asapersson320e45a2016-11-29 01:40:35 -080029#include "webrtc/video/stats_counter.h"
Peter Boström7623ce42015-12-09 12:13:30 +010030#include "webrtc/video/vie_encoder.h"
pbos@webrtc.org273a4142014-12-01 15:23:21 +000031#include "webrtc/video_send_stream.h"
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000032
33namespace webrtc {
34
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000035class SendStatisticsProxy : public CpuOveruseMetricsObserver,
36 public RtcpStatisticsCallback,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000037 public RtcpPacketTypeCounterObserver,
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000038 public StreamDataCountersCallback,
39 public BitrateStatisticsObserver,
40 public FrameCountObserver,
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000041 public SendSideDelayObserver {
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000042 public:
pbos@webrtc.org273a4142014-12-01 15:23:21 +000043 static const int kStatsTimeoutMs;
perkj803d97f2016-11-01 11:45:46 -070044 // Number of required samples to be collected before a metric is added
45 // to a rtc histogram.
46 static const int kMinRequiredMetricsSamples = 200;
pbos@webrtc.org273a4142014-12-01 15:23:21 +000047
sprangb4a1ae52015-12-03 08:10:08 -080048 SendStatisticsProxy(Clock* clock,
49 const VideoSendStream::Config& config,
50 VideoEncoderConfig::ContentType content_type);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000051 virtual ~SendStatisticsProxy();
52
sprangc5d62e22017-04-02 23:53:04 -070053 virtual VideoSendStream::Stats GetStats();
pbos@webrtc.org273a4142014-12-01 15:23:21 +000054
55 virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
kjellander02b3d272016-04-20 05:05:54 -070056 const CodecSpecificInfo* codec_info);
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +000057 // Used to update incoming frame rate.
asaperssond89920b2015-07-22 06:52:00 -070058 void OnIncomingFrame(int width, int height);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000059
perkj803d97f2016-11-01 11:45:46 -070060 void OnCpuRestrictedResolutionChanged(bool cpu_restricted_resolution);
kthelgason0cd27ba2016-12-19 06:32:16 -080061 void OnQualityRestrictedResolutionChanged(int num_quality_downscales);
asapersson36e9eb42017-03-31 05:29:12 -070062 void SetCpuScalingStats(bool cpu_restricted_resolution);
63 void SetQualityScalingStats(int num_quality_downscales); // -1: disabled.
perkj803d97f2016-11-01 11:45:46 -070064
perkj275afc52016-09-01 00:21:16 -070065 void OnEncoderStatsUpdate(uint32_t framerate, uint32_t bitrate);
Peter Boström7083e112015-09-22 16:28:51 +020066 void OnSuspendChange(bool is_suspended);
Peter Boström20f3f942015-05-15 11:33:39 +020067 void OnInactiveSsrc(uint32_t ssrc);
68
sprangb4a1ae52015-12-03 08:10:08 -080069 // Used to indicate change in content type, which may require a change in
Pera48ddb72016-09-29 11:48:50 +020070 // how stats are collected and set the configured preferred media bitrate.
71 void OnEncoderReconfigured(const VideoEncoderConfig& encoder_config,
72 uint32_t preferred_bitrate_bps);
sprangb4a1ae52015-12-03 08:10:08 -080073
perkjf5b2e512016-07-05 08:34:04 -070074 // Used to update the encoder target rate.
75 void OnSetEncoderTargetRate(uint32_t bitrate_bps);
Peter Boströme4499152016-02-05 11:13:28 +010076
77 // Implements CpuOveruseMetricsObserver.
78 void OnEncodedFrameTimeMeasured(int encode_time_ms,
79 const CpuOveruseMetrics& metrics) override;
80
Per69b332d2016-06-02 15:45:42 +020081 int GetSendFrameRate() const;
82
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000083 protected:
84 // From RtcpStatisticsCallback.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000085 void StatisticsUpdated(const RtcpStatistics& statistics,
86 uint32_t ssrc) override;
87 void CNameChanged(const char* cname, uint32_t ssrc) override;
asaperssond89920b2015-07-22 06:52:00 -070088 // From RtcpPacketTypeCounterObserver.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000089 void RtcpPacketTypesCounterUpdated(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000090 uint32_t ssrc,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000091 const RtcpPacketTypeCounter& packet_counter) override;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000092 // From StreamDataCountersCallback.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000093 void DataCountersUpdated(const StreamDataCounters& counters,
94 uint32_t ssrc) override;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000095
96 // From BitrateStatisticsObserver.
sprangcd349d92016-07-13 09:11:28 -070097 void Notify(uint32_t total_bitrate_bps,
98 uint32_t retransmit_bitrate_bps,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000099 uint32_t ssrc) override;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000100
101 // From FrameCountObserver.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000102 void FrameCountUpdated(const FrameCounts& frame_counts,
103 uint32_t ssrc) override;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000104
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000105 void SendSideDelayUpdated(int avg_delay_ms,
106 int max_delay_ms,
107 uint32_t ssrc) override;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000108
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000109 private:
asaperssonda535c42015-10-19 23:32:41 -0700110 class SampleCounter {
111 public:
asaperssond89920b2015-07-22 06:52:00 -0700112 SampleCounter() : sum(0), num_samples(0) {}
asaperssonda535c42015-10-19 23:32:41 -0700113 ~SampleCounter() {}
asaperssond89920b2015-07-22 06:52:00 -0700114 void Add(int sample);
asapersson66d4b372016-12-19 06:50:53 -0800115 int Avg(int64_t min_required_samples) const;
asaperssond89920b2015-07-22 06:52:00 -0700116
117 private:
asapersson66d4b372016-12-19 06:50:53 -0800118 int64_t sum;
119 int64_t num_samples;
asaperssond89920b2015-07-22 06:52:00 -0700120 };
asaperssonda535c42015-10-19 23:32:41 -0700121 class BoolSampleCounter {
122 public:
asaperssondec5ebf2015-10-05 02:36:17 -0700123 BoolSampleCounter() : sum(0), num_samples(0) {}
asaperssonda535c42015-10-19 23:32:41 -0700124 ~BoolSampleCounter() {}
asaperssondec5ebf2015-10-05 02:36:17 -0700125 void Add(bool sample);
asapersson66d4b372016-12-19 06:50:53 -0800126 void Add(bool sample, int64_t count);
127 int Percent(int64_t min_required_samples) const;
128 int Permille(int64_t min_required_samples) const;
asaperssondec5ebf2015-10-05 02:36:17 -0700129
130 private:
asapersson66d4b372016-12-19 06:50:53 -0800131 int Fraction(int64_t min_required_samples, float multiplier) const;
132 int64_t sum;
133 int64_t num_samples;
asaperssondec5ebf2015-10-05 02:36:17 -0700134 };
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000135 struct StatsUpdateTimes {
sprangb4a1ae52015-12-03 08:10:08 -0800136 StatsUpdateTimes() : resolution_update_ms(0), bitrate_update_ms(0) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000137 int64_t resolution_update_ms;
Peter Boström20f3f942015-05-15 11:33:39 +0200138 int64_t bitrate_update_ms;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000139 };
asapersson66d4b372016-12-19 06:50:53 -0800140 struct TargetRateUpdates {
141 TargetRateUpdates()
142 : pause_resume_events(0), last_paused_or_resumed(false), last_ms(-1) {}
143 int pause_resume_events;
144 bool last_paused_or_resumed;
145 int64_t last_ms;
146 };
asapersson118ef002016-03-31 00:00:19 -0700147 struct QpCounters {
asapersson827cab32016-11-02 09:08:47 -0700148 SampleCounter vp8; // QP range: 0-127
149 SampleCounter vp9; // QP range: 0-255
150 SampleCounter h264; // QP range: 0-51
asapersson118ef002016-03-31 00:00:19 -0700151 };
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000152 void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000153 VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
154 EXCLUSIVE_LOCKS_REQUIRED(crit_);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000155
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000156 Clock* const clock_;
perkj26091b12016-09-01 01:17:40 -0700157 const std::string payload_name_;
158 const VideoSendStream::Config::Rtp rtp_config_;
pbos5ad935c2016-01-25 03:52:44 -0800159 rtc::CriticalSection crit_;
sprangb4a1ae52015-12-03 08:10:08 -0800160 VideoEncoderConfig::ContentType content_type_ GUARDED_BY(crit_);
asapersson4374a092016-07-27 00:39:09 -0700161 const int64_t start_ms_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000162 VideoSendStream::Stats stats_ GUARDED_BY(crit_);
Åsa Persson24b4eda2015-06-16 10:17:01 +0200163 uint32_t last_sent_frame_timestamp_ GUARDED_BY(crit_);
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000164 std::map<uint32_t, StatsUpdateTimes> update_times_ GUARDED_BY(crit_);
asapersson1aa420b2015-12-07 03:12:22 -0800165 rtc::ExpFilter encode_time_ GUARDED_BY(crit_);
kthelgason0cd27ba2016-12-19 06:32:16 -0800166 int quality_downscales_ GUARDED_BY(crit_) = 0;
asaperssond89920b2015-07-22 06:52:00 -0700167
sprangb4a1ae52015-12-03 08:10:08 -0800168 // Contains stats used for UMA histograms. These stats will be reset if
169 // content type changes between real-time video and screenshare, since these
170 // will be reported separately.
171 struct UmaSamplesContainer {
sprang07fb9be2016-02-24 07:55:00 -0800172 UmaSamplesContainer(const char* prefix,
173 const VideoSendStream::Stats& start_stats,
174 Clock* clock);
sprangb4a1ae52015-12-03 08:10:08 -0800175 ~UmaSamplesContainer();
176
perkj26091b12016-09-01 01:17:40 -0700177 void UpdateHistograms(const VideoSendStream::Config::Rtp& rtp_config,
sprang07fb9be2016-02-24 07:55:00 -0800178 const VideoSendStream::Stats& current_stats);
sprangb4a1ae52015-12-03 08:10:08 -0800179
asapersson93e1e232017-02-06 05:18:35 -0800180 void InitializeBitrateCounters(const VideoSendStream::Stats& stats);
181
sprangb4a1ae52015-12-03 08:10:08 -0800182 const std::string uma_prefix_;
sprang07fb9be2016-02-24 07:55:00 -0800183 Clock* const clock_;
sprangb4a1ae52015-12-03 08:10:08 -0800184 int max_sent_width_per_timestamp_;
185 int max_sent_height_per_timestamp_;
186 SampleCounter input_width_counter_;
187 SampleCounter input_height_counter_;
188 SampleCounter sent_width_counter_;
189 SampleCounter sent_height_counter_;
190 SampleCounter encode_time_counter_;
191 BoolSampleCounter key_frame_counter_;
192 BoolSampleCounter quality_limited_frame_counter_;
193 SampleCounter quality_downscales_counter_;
perkj803d97f2016-11-01 11:45:46 -0700194 BoolSampleCounter cpu_limited_frame_counter_;
sprangb4a1ae52015-12-03 08:10:08 -0800195 BoolSampleCounter bw_limited_frame_counter_;
196 SampleCounter bw_resolutions_disabled_counter_;
197 SampleCounter delay_counter_;
198 SampleCounter max_delay_counter_;
199 rtc::RateTracker input_frame_rate_tracker_;
asapersson320e45a2016-11-29 01:40:35 -0800200 RateCounter input_fps_counter_;
201 RateCounter sent_fps_counter_;
asapersson93e1e232017-02-06 05:18:35 -0800202 RateAccCounter total_byte_counter_;
203 RateAccCounter media_byte_counter_;
204 RateAccCounter rtx_byte_counter_;
205 RateAccCounter padding_byte_counter_;
206 RateAccCounter retransmit_byte_counter_;
207 RateAccCounter fec_byte_counter_;
sprange2d83d62016-02-19 09:03:26 -0800208 int64_t first_rtcp_stats_time_ms_;
Erik Språng22c2b482016-03-01 09:40:42 +0100209 int64_t first_rtp_stats_time_ms_;
asapersson66d4b372016-12-19 06:50:53 -0800210 BoolSampleCounter paused_time_counter_;
211 TargetRateUpdates target_rate_updates_;
sprange2d83d62016-02-19 09:03:26 -0800212 ReportBlockStats report_block_stats_;
sprang07fb9be2016-02-24 07:55:00 -0800213 const VideoSendStream::Stats start_stats_;
sprangc5d62e22017-04-02 23:53:04 -0700214
asapersson118ef002016-03-31 00:00:19 -0700215 std::map<int, QpCounters>
216 qp_counters_; // QP counters mapped by spatial idx.
sprangb4a1ae52015-12-03 08:10:08 -0800217 };
218
kwiberg27f982b2016-03-01 11:52:33 -0800219 std::unique_ptr<UmaSamplesContainer> uma_container_ GUARDED_BY(crit_);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000220};
221
222} // namespace webrtc
223#endif // WEBRTC_VIDEO_SEND_STATISTICS_PROXY_H_