blob: 11dd241afaa05c41f90133f5917d7eb0476afdc0 [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#include "webrtc/video/send_statistics_proxy.h"
12
asaperssond89920b2015-07-22 06:52:00 -070013#include <algorithm>
Tim Psiakiad13d2f2015-11-10 16:34:50 -080014#include <cmath>
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000015#include <map>
16
pbos@webrtc.org49096de2015-02-24 22:37:52 +000017#include "webrtc/base/checks.h"
Peter Boström415d2cd2015-10-26 11:35:17 +010018#include "webrtc/base/logging.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010019#include "webrtc/system_wrappers/include/metrics.h"
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000020
21namespace webrtc {
asapersson2a0a2a42015-10-27 01:32:00 -070022namespace {
asapersson1aa420b2015-12-07 03:12:22 -080023const float kEncodeTimeWeigthFactor = 0.5f;
24
asapersson2a0a2a42015-10-27 01:32:00 -070025// Used by histograms. Values of entries should not be changed.
26enum HistogramCodecType {
27 kVideoUnknown = 0,
28 kVideoVp8 = 1,
29 kVideoVp9 = 2,
30 kVideoH264 = 3,
31 kVideoMax = 64,
32};
33
asaperssonc2148a52016-02-04 00:33:21 -080034const char* kRealtimePrefix = "WebRTC.Video.";
35const char* kScreenPrefix = "WebRTC.Video.Screenshare.";
36
sprangb4a1ae52015-12-03 08:10:08 -080037const char* GetUmaPrefix(VideoEncoderConfig::ContentType content_type) {
38 switch (content_type) {
39 case VideoEncoderConfig::ContentType::kRealtimeVideo:
asaperssonc2148a52016-02-04 00:33:21 -080040 return kRealtimePrefix;
sprangb4a1ae52015-12-03 08:10:08 -080041 case VideoEncoderConfig::ContentType::kScreen:
asaperssonc2148a52016-02-04 00:33:21 -080042 return kScreenPrefix;
sprangb4a1ae52015-12-03 08:10:08 -080043 }
44 RTC_NOTREACHED();
45 return nullptr;
46}
47
asapersson2a0a2a42015-10-27 01:32:00 -070048HistogramCodecType PayloadNameToHistogramCodecType(
49 const std::string& payload_name) {
50 if (payload_name == "VP8") {
51 return kVideoVp8;
52 } else if (payload_name == "VP9") {
53 return kVideoVp9;
54 } else if (payload_name == "H264") {
55 return kVideoH264;
56 } else {
57 return kVideoUnknown;
58 }
59}
60
61void UpdateCodecTypeHistogram(const std::string& payload_name) {
asapersson28ba9272016-01-25 05:58:23 -080062 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.Encoder.CodecType",
63 PayloadNameToHistogramCodecType(payload_name),
64 kVideoMax);
asapersson2a0a2a42015-10-27 01:32:00 -070065}
66} // namespace
67
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000068
pbos@webrtc.org273a4142014-12-01 15:23:21 +000069const int SendStatisticsProxy::kStatsTimeoutMs = 5000;
70
sprangb4a1ae52015-12-03 08:10:08 -080071SendStatisticsProxy::SendStatisticsProxy(
72 Clock* clock,
73 const VideoSendStream::Config& config,
74 VideoEncoderConfig::ContentType content_type)
asaperssond89920b2015-07-22 06:52:00 -070075 : clock_(clock),
76 config_(config),
sprangb4a1ae52015-12-03 08:10:08 -080077 content_type_(content_type),
asaperssond89920b2015-07-22 06:52:00 -070078 last_sent_frame_timestamp_(0),
asapersson1aa420b2015-12-07 03:12:22 -080079 encode_time_(kEncodeTimeWeigthFactor),
sprangb4a1ae52015-12-03 08:10:08 -080080 uma_container_(new UmaSamplesContainer(GetUmaPrefix(content_type_))) {
asapersson2a0a2a42015-10-27 01:32:00 -070081 UpdateCodecTypeHistogram(config_.encoder_settings.payload_name);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000082}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000083
sprangb4a1ae52015-12-03 08:10:08 -080084SendStatisticsProxy::~SendStatisticsProxy() {}
85
86SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer(
87 const char* prefix)
88 : uma_prefix_(prefix),
89 max_sent_width_per_timestamp_(0),
90 max_sent_height_per_timestamp_(0),
91 input_frame_rate_tracker_(100u, 10u),
sprange2d83d62016-02-19 09:03:26 -080092 sent_frame_rate_tracker_(100u, 10u),
93 first_rtcp_stats_time_ms_(-1) {}
sprangb4a1ae52015-12-03 08:10:08 -080094
95SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {
Åsa Persson24b4eda2015-06-16 10:17:01 +020096 UpdateHistograms();
97}
98
sprangb4a1ae52015-12-03 08:10:08 -080099void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms() {
asaperssonc2148a52016-02-04 00:33:21 -0800100 RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix);
101 const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0;
asapersson6718e972015-07-24 00:20:58 -0700102 const int kMinRequiredSamples = 200;
asaperssond89920b2015-07-22 06:52:00 -0700103 int in_width = input_width_counter_.Avg(kMinRequiredSamples);
104 int in_height = input_height_counter_.Avg(kMinRequiredSamples);
asapersson6f14be82015-11-16 00:40:49 -0800105 int in_fps = round(input_frame_rate_tracker_.ComputeTotalRate());
asaperssond89920b2015-07-22 06:52:00 -0700106 if (in_width != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800107 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputWidthInPixels",
108 in_width);
109 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputHeightInPixels",
110 in_height);
111 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "InputFramesPerSecond",
112 in_fps);
asaperssond89920b2015-07-22 06:52:00 -0700113 }
114 int sent_width = sent_width_counter_.Avg(kMinRequiredSamples);
115 int sent_height = sent_height_counter_.Avg(kMinRequiredSamples);
asapersson6f14be82015-11-16 00:40:49 -0800116 int sent_fps = round(sent_frame_rate_tracker_.ComputeTotalRate());
asaperssond89920b2015-07-22 06:52:00 -0700117 if (sent_width != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800118 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentWidthInPixels",
119 sent_width);
120 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentHeightInPixels",
121 sent_height);
122 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "SentFramesPerSecond",
123 sent_fps);
asaperssond89920b2015-07-22 06:52:00 -0700124 }
asapersson6718e972015-07-24 00:20:58 -0700125 int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples);
asaperssonc2148a52016-02-04 00:33:21 -0800126 if (encode_ms != -1) {
127 RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "EncodeTimeInMs",
128 encode_ms);
129 }
asaperssondec5ebf2015-10-05 02:36:17 -0700130 int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples);
131 if (key_frames_permille != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800132 RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "KeyFramesSentInPermille",
133 key_frames_permille);
asaperssondec5ebf2015-10-05 02:36:17 -0700134 }
asapersson4306fc72015-10-19 00:35:21 -0700135 int quality_limited =
136 quality_limited_frame_counter_.Percent(kMinRequiredSamples);
137 if (quality_limited != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800138 RTC_HISTOGRAMS_PERCENTAGE(kIndex,
139 uma_prefix_ + "QualityLimitedResolutionInPercent",
140 quality_limited);
asapersson4306fc72015-10-19 00:35:21 -0700141 }
142 int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples);
143 if (downscales != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800144 RTC_HISTOGRAMS_ENUMERATION(
145 kIndex, uma_prefix_ + "QualityLimitedResolutionDownscales", downscales,
146 20);
asapersson4306fc72015-10-19 00:35:21 -0700147 }
asaperssonda535c42015-10-19 23:32:41 -0700148 int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples);
149 if (bw_limited != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800150 RTC_HISTOGRAMS_PERCENTAGE(
151 kIndex, uma_prefix_ + "BandwidthLimitedResolutionInPercent",
152 bw_limited);
asaperssonda535c42015-10-19 23:32:41 -0700153 }
154 int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples);
155 if (num_disabled != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800156 RTC_HISTOGRAMS_ENUMERATION(
157 kIndex, uma_prefix_ + "BandwidthLimitedResolutionsDisabled",
158 num_disabled, 10);
asaperssonda535c42015-10-19 23:32:41 -0700159 }
asaperssonf040b232015-11-04 00:59:03 -0800160 int delay_ms = delay_counter_.Avg(kMinRequiredSamples);
161 if (delay_ms != -1)
asaperssonc2148a52016-02-04 00:33:21 -0800162 RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayInMs",
163 delay_ms);
asaperssonf040b232015-11-04 00:59:03 -0800164
165 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples);
166 if (max_delay_ms != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800167 RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayMaxInMs",
168 max_delay_ms);
sprangb4a1ae52015-12-03 08:10:08 -0800169 }
sprange2d83d62016-02-19 09:03:26 -0800170 int fraction_lost = report_block_stats_.FractionLostInPercent();
171 if (first_rtcp_stats_time_ms_ != -1) {
172 int64_t elapsed_time_ms = Clock::GetRealTimeClock()->TimeInMilliseconds() -
173 first_rtcp_stats_time_ms_;
174 if (elapsed_time_ms / 1000 >= metrics::kMinRunTimeInSeconds &&
175 fraction_lost != -1) {
176 RTC_HISTOGRAMS_PERCENTAGE(
177 kIndex, uma_prefix_ + "SentPacketsLostInPercent", fraction_lost);
178 }
179 }
sprangb4a1ae52015-12-03 08:10:08 -0800180}
181
182void SendStatisticsProxy::SetContentType(
183 VideoEncoderConfig::ContentType content_type) {
184 rtc::CritScope lock(&crit_);
185 if (content_type_ != content_type) {
sprangb4a1ae52015-12-03 08:10:08 -0800186 uma_container_.reset(new UmaSamplesContainer(GetUmaPrefix(content_type)));
187 content_type_ = content_type;
asaperssonf040b232015-11-04 00:59:03 -0800188 }
Åsa Persson24b4eda2015-06-16 10:17:01 +0200189}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000190
Peter Boströmb7d9a972015-12-18 16:01:11 +0100191void SendStatisticsProxy::OnEncoderImplementationName(
192 const char* implementation_name) {
193 rtc::CritScope lock(&crit_);
194 stats_.encoder_implementation_name = implementation_name;
195}
196
Peter Boström7083e112015-09-22 16:28:51 +0200197void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200198 rtc::CritScope lock(&crit_);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000199 stats_.encode_frame_rate = framerate;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000200 stats_.media_bitrate_bps = bitrate;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000201}
202
Peter Boströme4499152016-02-05 11:13:28 +0100203void SendStatisticsProxy::OnEncodedFrameTimeMeasured(
204 int encode_time_ms,
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000205 const CpuOveruseMetrics& metrics) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200206 rtc::CritScope lock(&crit_);
Peter Boströme4499152016-02-05 11:13:28 +0100207 uma_container_->encode_time_counter_.Add(encode_time_ms);
208 encode_time_.Apply(1.0f, encode_time_ms);
209 stats_.avg_encode_time_ms = round(encode_time_.filtered());
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000210 stats_.encode_usage_percent = metrics.encode_usage_percent;
211}
212
Peter Boström7083e112015-09-22 16:28:51 +0200213void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200214 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000215 stats_.suspended = is_suspended;
216}
217
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000218VideoSendStream::Stats SendStatisticsProxy::GetStats() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200219 rtc::CritScope lock(&crit_);
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000220 PurgeOldStats();
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000221 stats_.input_frame_rate =
sprangb4a1ae52015-12-03 08:10:08 -0800222 round(uma_container_->input_frame_rate_tracker_.ComputeRate());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000223 return stats_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000224}
225
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000226void SendStatisticsProxy::PurgeOldStats() {
Peter Boström20f3f942015-05-15 11:33:39 +0200227 int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000228 for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
229 stats_.substreams.begin();
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000230 it != stats_.substreams.end(); ++it) {
231 uint32_t ssrc = it->first;
Peter Boström20f3f942015-05-15 11:33:39 +0200232 if (update_times_[ssrc].resolution_update_ms <= old_stats_ms) {
233 it->second.width = 0;
234 it->second.height = 0;
235 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000236 }
237}
238
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000239VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
240 uint32_t ssrc) {
241 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
242 stats_.substreams.find(ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000243 if (it != stats_.substreams.end())
244 return &it->second;
245
246 if (std::find(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end(), ssrc) ==
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000247 config_.rtp.ssrcs.end() &&
248 std::find(config_.rtp.rtx.ssrcs.begin(),
249 config_.rtp.rtx.ssrcs.end(),
250 ssrc) == config_.rtp.rtx.ssrcs.end()) {
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000251 return nullptr;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000252 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000253
254 return &stats_.substreams[ssrc]; // Insert new entry and return ptr.
255}
256
Peter Boström20f3f942015-05-15 11:33:39 +0200257void SendStatisticsProxy::OnInactiveSsrc(uint32_t ssrc) {
258 rtc::CritScope lock(&crit_);
259 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
260 if (stats == nullptr)
261 return;
262
263 stats->total_bitrate_bps = 0;
264 stats->retransmit_bitrate_bps = 0;
265 stats->height = 0;
266 stats->width = 0;
267}
268
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000269void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200270 rtc::CritScope lock(&crit_);
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000271 stats_.target_media_bitrate_bps = bitrate_bps;
272}
273
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000274void SendStatisticsProxy::OnSendEncodedImage(
275 const EncodedImage& encoded_image,
276 const RTPVideoHeader* rtp_video_header) {
277 size_t simulcast_idx =
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000278 rtp_video_header != nullptr ? rtp_video_header->simulcastIdx : 0;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000279 if (simulcast_idx >= config_.rtp.ssrcs.size()) {
280 LOG(LS_ERROR) << "Encoded image outside simulcast range (" << simulcast_idx
281 << " >= " << config_.rtp.ssrcs.size() << ").";
282 return;
283 }
284 uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
285
Peter Boströmf2f82832015-05-01 13:00:41 +0200286 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000287 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000288 if (stats == nullptr)
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000289 return;
290
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000291 stats->width = encoded_image._encodedWidth;
292 stats->height = encoded_image._encodedHeight;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000293 update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
asaperssond89920b2015-07-22 06:52:00 -0700294
sprangb4a1ae52015-12-03 08:10:08 -0800295 uma_container_->key_frame_counter_.Add(encoded_image._frameType ==
296 kVideoFrameKey);
asaperssondec5ebf2015-10-05 02:36:17 -0700297
asapersson17821db2015-12-14 02:08:12 -0800298 stats_.bw_limited_resolution =
299 encoded_image.adapt_reason_.quality_resolution_downscales > 0 ||
300 encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
301
asapersson4306fc72015-10-19 00:35:21 -0700302 if (encoded_image.adapt_reason_.quality_resolution_downscales != -1) {
303 bool downscaled =
304 encoded_image.adapt_reason_.quality_resolution_downscales > 0;
sprangb4a1ae52015-12-03 08:10:08 -0800305 uma_container_->quality_limited_frame_counter_.Add(downscaled);
asapersson4306fc72015-10-19 00:35:21 -0700306 if (downscaled) {
sprangb4a1ae52015-12-03 08:10:08 -0800307 uma_container_->quality_downscales_counter_.Add(
asapersson4306fc72015-10-19 00:35:21 -0700308 encoded_image.adapt_reason_.quality_resolution_downscales);
309 }
310 }
asaperssonda535c42015-10-19 23:32:41 -0700311 if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) {
312 bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
sprangb4a1ae52015-12-03 08:10:08 -0800313 uma_container_->bw_limited_frame_counter_.Add(bw_limited);
asaperssonda535c42015-10-19 23:32:41 -0700314 if (bw_limited) {
sprangb4a1ae52015-12-03 08:10:08 -0800315 uma_container_->bw_resolutions_disabled_counter_.Add(
316 encoded_image.adapt_reason_.bw_resolutions_disabled);
asaperssonda535c42015-10-19 23:32:41 -0700317 }
318 }
asapersson4306fc72015-10-19 00:35:21 -0700319
asaperssond89920b2015-07-22 06:52:00 -0700320 // TODO(asapersson): This is incorrect if simulcast layers are encoded on
321 // different threads and there is no guarantee that one frame of all layers
322 // are encoded before the next start.
323 if (last_sent_frame_timestamp_ > 0 &&
324 encoded_image._timeStamp != last_sent_frame_timestamp_) {
sprangb4a1ae52015-12-03 08:10:08 -0800325 uma_container_->sent_frame_rate_tracker_.AddSamples(1);
326 uma_container_->sent_width_counter_.Add(
327 uma_container_->max_sent_width_per_timestamp_);
328 uma_container_->sent_height_counter_.Add(
329 uma_container_->max_sent_height_per_timestamp_);
330 uma_container_->max_sent_width_per_timestamp_ = 0;
331 uma_container_->max_sent_height_per_timestamp_ = 0;
Åsa Persson24b4eda2015-06-16 10:17:01 +0200332 }
asaperssond89920b2015-07-22 06:52:00 -0700333 last_sent_frame_timestamp_ = encoded_image._timeStamp;
sprangb4a1ae52015-12-03 08:10:08 -0800334 uma_container_->max_sent_width_per_timestamp_ =
335 std::max(uma_container_->max_sent_width_per_timestamp_,
asaperssond89920b2015-07-22 06:52:00 -0700336 static_cast<int>(encoded_image._encodedWidth));
sprangb4a1ae52015-12-03 08:10:08 -0800337 uma_container_->max_sent_height_per_timestamp_ =
338 std::max(uma_container_->max_sent_height_per_timestamp_,
asaperssond89920b2015-07-22 06:52:00 -0700339 static_cast<int>(encoded_image._encodedHeight));
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000340}
341
asaperssond89920b2015-07-22 06:52:00 -0700342void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200343 rtc::CritScope lock(&crit_);
sprangb4a1ae52015-12-03 08:10:08 -0800344 uma_container_->input_frame_rate_tracker_.AddSamples(1);
345 uma_container_->input_width_counter_.Add(width);
346 uma_container_->input_height_counter_.Add(height);
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000347}
348
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000349void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
350 uint32_t ssrc,
351 const RtcpPacketTypeCounter& packet_counter) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200352 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000353 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000354 if (stats == nullptr)
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000355 return;
356
357 stats->rtcp_packet_type_counts = packet_counter;
358}
359
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000360void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
361 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200362 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000363 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000364 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000365 return;
366
367 stats->rtcp_stats = statistics;
sprange2d83d62016-02-19 09:03:26 -0800368 uma_container_->report_block_stats_.Store(statistics, 0, ssrc);
369 if (uma_container_->first_rtcp_stats_time_ms_ == -1)
370 uma_container_->first_rtcp_stats_time_ms_ = clock_->TimeInMilliseconds();
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000371}
372
Peter Boströmd1d66ba2016-02-08 14:07:14 +0100373void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {}
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000374
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000375void SendStatisticsProxy::DataCountersUpdated(
376 const StreamDataCounters& counters,
377 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200378 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000379 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
henrikg91d6ede2015-09-17 00:24:34 -0700380 RTC_DCHECK(stats != nullptr)
381 << "DataCountersUpdated reported for unknown ssrc: " << ssrc;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000382
383 stats->rtp_stats = counters;
384}
385
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000386void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
387 const BitrateStatistics& retransmit_stats,
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000388 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200389 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000390 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000391 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000392 return;
393
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000394 stats->total_bitrate_bps = total_stats.bitrate_bps;
395 stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000396}
397
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000398void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
399 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200400 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000401 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000402 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000403 return;
404
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000405 stats->frame_counts = frame_counts;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000406}
407
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000408void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
409 int max_delay_ms,
410 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200411 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000412 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000413 if (stats == nullptr)
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000414 return;
415 stats->avg_delay_ms = avg_delay_ms;
416 stats->max_delay_ms = max_delay_ms;
asaperssonf040b232015-11-04 00:59:03 -0800417
sprangb4a1ae52015-12-03 08:10:08 -0800418 uma_container_->delay_counter_.Add(avg_delay_ms);
419 uma_container_->max_delay_counter_.Add(max_delay_ms);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000420}
421
asaperssond89920b2015-07-22 06:52:00 -0700422void SendStatisticsProxy::SampleCounter::Add(int sample) {
423 sum += sample;
424 ++num_samples;
425}
426
427int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
428 if (num_samples < min_required_samples || num_samples == 0)
429 return -1;
asaperssonda535c42015-10-19 23:32:41 -0700430 return (sum + (num_samples / 2)) / num_samples;
asaperssond89920b2015-07-22 06:52:00 -0700431}
432
asaperssondec5ebf2015-10-05 02:36:17 -0700433void SendStatisticsProxy::BoolSampleCounter::Add(bool sample) {
434 if (sample)
435 ++sum;
436 ++num_samples;
437}
438
439int SendStatisticsProxy::BoolSampleCounter::Percent(
440 int min_required_samples) const {
441 return Fraction(min_required_samples, 100.0f);
442}
443
444int SendStatisticsProxy::BoolSampleCounter::Permille(
445 int min_required_samples) const {
446 return Fraction(min_required_samples, 1000.0f);
447}
448
449int SendStatisticsProxy::BoolSampleCounter::Fraction(
450 int min_required_samples, float multiplier) const {
451 if (num_samples < min_required_samples || num_samples == 0)
452 return -1;
453 return static_cast<int>((sum * multiplier / num_samples) + 0.5f);
454}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000455} // namespace webrtc