blob: bd0d5186e1d4baf87e361b2bf70636aed8330c36 [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),
92 sent_frame_rate_tracker_(100u, 10u) {}
93
94SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {
Åsa Persson24b4eda2015-06-16 10:17:01 +020095 UpdateHistograms();
96}
97
sprangb4a1ae52015-12-03 08:10:08 -080098void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms() {
asaperssonc2148a52016-02-04 00:33:21 -080099 RTC_DCHECK(uma_prefix_ == kRealtimePrefix || uma_prefix_ == kScreenPrefix);
100 const int kIndex = uma_prefix_ == kScreenPrefix ? 1 : 0;
asapersson6718e972015-07-24 00:20:58 -0700101 const int kMinRequiredSamples = 200;
asaperssond89920b2015-07-22 06:52:00 -0700102 int in_width = input_width_counter_.Avg(kMinRequiredSamples);
103 int in_height = input_height_counter_.Avg(kMinRequiredSamples);
asapersson6f14be82015-11-16 00:40:49 -0800104 int in_fps = round(input_frame_rate_tracker_.ComputeTotalRate());
asaperssond89920b2015-07-22 06:52:00 -0700105 if (in_width != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800106 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputWidthInPixels",
107 in_width);
108 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputHeightInPixels",
109 in_height);
110 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "InputFramesPerSecond",
111 in_fps);
asaperssond89920b2015-07-22 06:52:00 -0700112 }
113 int sent_width = sent_width_counter_.Avg(kMinRequiredSamples);
114 int sent_height = sent_height_counter_.Avg(kMinRequiredSamples);
asapersson6f14be82015-11-16 00:40:49 -0800115 int sent_fps = round(sent_frame_rate_tracker_.ComputeTotalRate());
asaperssond89920b2015-07-22 06:52:00 -0700116 if (sent_width != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800117 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentWidthInPixels",
118 sent_width);
119 RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentHeightInPixels",
120 sent_height);
121 RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "SentFramesPerSecond",
122 sent_fps);
asaperssond89920b2015-07-22 06:52:00 -0700123 }
asapersson6718e972015-07-24 00:20:58 -0700124 int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples);
asaperssonc2148a52016-02-04 00:33:21 -0800125 if (encode_ms != -1) {
126 RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "EncodeTimeInMs",
127 encode_ms);
128 }
asaperssondec5ebf2015-10-05 02:36:17 -0700129 int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples);
130 if (key_frames_permille != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800131 RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "KeyFramesSentInPermille",
132 key_frames_permille);
asaperssondec5ebf2015-10-05 02:36:17 -0700133 }
asapersson4306fc72015-10-19 00:35:21 -0700134 int quality_limited =
135 quality_limited_frame_counter_.Percent(kMinRequiredSamples);
136 if (quality_limited != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800137 RTC_HISTOGRAMS_PERCENTAGE(kIndex,
138 uma_prefix_ + "QualityLimitedResolutionInPercent",
139 quality_limited);
asapersson4306fc72015-10-19 00:35:21 -0700140 }
141 int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples);
142 if (downscales != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800143 RTC_HISTOGRAMS_ENUMERATION(
144 kIndex, uma_prefix_ + "QualityLimitedResolutionDownscales", downscales,
145 20);
asapersson4306fc72015-10-19 00:35:21 -0700146 }
asaperssonda535c42015-10-19 23:32:41 -0700147 int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples);
148 if (bw_limited != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800149 RTC_HISTOGRAMS_PERCENTAGE(
150 kIndex, uma_prefix_ + "BandwidthLimitedResolutionInPercent",
151 bw_limited);
asaperssonda535c42015-10-19 23:32:41 -0700152 }
153 int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples);
154 if (num_disabled != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800155 RTC_HISTOGRAMS_ENUMERATION(
156 kIndex, uma_prefix_ + "BandwidthLimitedResolutionsDisabled",
157 num_disabled, 10);
asaperssonda535c42015-10-19 23:32:41 -0700158 }
asaperssonf040b232015-11-04 00:59:03 -0800159 int delay_ms = delay_counter_.Avg(kMinRequiredSamples);
160 if (delay_ms != -1)
asaperssonc2148a52016-02-04 00:33:21 -0800161 RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayInMs",
162 delay_ms);
asaperssonf040b232015-11-04 00:59:03 -0800163
164 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples);
165 if (max_delay_ms != -1) {
asaperssonc2148a52016-02-04 00:33:21 -0800166 RTC_HISTOGRAMS_COUNTS_100000(kIndex, uma_prefix_ + "SendSideDelayMaxInMs",
167 max_delay_ms);
sprangb4a1ae52015-12-03 08:10:08 -0800168 }
169}
170
171void SendStatisticsProxy::SetContentType(
172 VideoEncoderConfig::ContentType content_type) {
173 rtc::CritScope lock(&crit_);
174 if (content_type_ != content_type) {
sprangb4a1ae52015-12-03 08:10:08 -0800175 uma_container_.reset(new UmaSamplesContainer(GetUmaPrefix(content_type)));
176 content_type_ = content_type;
asaperssonf040b232015-11-04 00:59:03 -0800177 }
Åsa Persson24b4eda2015-06-16 10:17:01 +0200178}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000179
Peter Boströmb7d9a972015-12-18 16:01:11 +0100180void SendStatisticsProxy::OnEncoderImplementationName(
181 const char* implementation_name) {
182 rtc::CritScope lock(&crit_);
183 stats_.encoder_implementation_name = implementation_name;
184}
185
Peter Boström7083e112015-09-22 16:28:51 +0200186void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200187 rtc::CritScope lock(&crit_);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000188 stats_.encode_frame_rate = framerate;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000189 stats_.media_bitrate_bps = bitrate;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000190}
191
Peter Boströme4499152016-02-05 11:13:28 +0100192void SendStatisticsProxy::OnEncodedFrameTimeMeasured(
193 int encode_time_ms,
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000194 const CpuOveruseMetrics& metrics) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200195 rtc::CritScope lock(&crit_);
Peter Boströme4499152016-02-05 11:13:28 +0100196 uma_container_->encode_time_counter_.Add(encode_time_ms);
197 encode_time_.Apply(1.0f, encode_time_ms);
198 stats_.avg_encode_time_ms = round(encode_time_.filtered());
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000199 stats_.encode_usage_percent = metrics.encode_usage_percent;
200}
201
Peter Boström7083e112015-09-22 16:28:51 +0200202void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200203 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000204 stats_.suspended = is_suspended;
205}
206
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000207VideoSendStream::Stats SendStatisticsProxy::GetStats() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200208 rtc::CritScope lock(&crit_);
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000209 PurgeOldStats();
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000210 stats_.input_frame_rate =
sprangb4a1ae52015-12-03 08:10:08 -0800211 round(uma_container_->input_frame_rate_tracker_.ComputeRate());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000212 return stats_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000213}
214
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000215void SendStatisticsProxy::PurgeOldStats() {
Peter Boström20f3f942015-05-15 11:33:39 +0200216 int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000217 for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
218 stats_.substreams.begin();
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000219 it != stats_.substreams.end(); ++it) {
220 uint32_t ssrc = it->first;
Peter Boström20f3f942015-05-15 11:33:39 +0200221 if (update_times_[ssrc].resolution_update_ms <= old_stats_ms) {
222 it->second.width = 0;
223 it->second.height = 0;
224 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000225 }
226}
227
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000228VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
229 uint32_t ssrc) {
230 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
231 stats_.substreams.find(ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000232 if (it != stats_.substreams.end())
233 return &it->second;
234
235 if (std::find(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end(), ssrc) ==
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000236 config_.rtp.ssrcs.end() &&
237 std::find(config_.rtp.rtx.ssrcs.begin(),
238 config_.rtp.rtx.ssrcs.end(),
239 ssrc) == config_.rtp.rtx.ssrcs.end()) {
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000240 return nullptr;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000241 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000242
243 return &stats_.substreams[ssrc]; // Insert new entry and return ptr.
244}
245
Peter Boström20f3f942015-05-15 11:33:39 +0200246void SendStatisticsProxy::OnInactiveSsrc(uint32_t ssrc) {
247 rtc::CritScope lock(&crit_);
248 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
249 if (stats == nullptr)
250 return;
251
252 stats->total_bitrate_bps = 0;
253 stats->retransmit_bitrate_bps = 0;
254 stats->height = 0;
255 stats->width = 0;
256}
257
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000258void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200259 rtc::CritScope lock(&crit_);
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000260 stats_.target_media_bitrate_bps = bitrate_bps;
261}
262
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000263void SendStatisticsProxy::OnSendEncodedImage(
264 const EncodedImage& encoded_image,
265 const RTPVideoHeader* rtp_video_header) {
266 size_t simulcast_idx =
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000267 rtp_video_header != nullptr ? rtp_video_header->simulcastIdx : 0;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000268 if (simulcast_idx >= config_.rtp.ssrcs.size()) {
269 LOG(LS_ERROR) << "Encoded image outside simulcast range (" << simulcast_idx
270 << " >= " << config_.rtp.ssrcs.size() << ").";
271 return;
272 }
273 uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
274
Peter Boströmf2f82832015-05-01 13:00:41 +0200275 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000276 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000277 if (stats == nullptr)
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000278 return;
279
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000280 stats->width = encoded_image._encodedWidth;
281 stats->height = encoded_image._encodedHeight;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000282 update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
asaperssond89920b2015-07-22 06:52:00 -0700283
sprangb4a1ae52015-12-03 08:10:08 -0800284 uma_container_->key_frame_counter_.Add(encoded_image._frameType ==
285 kVideoFrameKey);
asaperssondec5ebf2015-10-05 02:36:17 -0700286
asapersson17821db2015-12-14 02:08:12 -0800287 stats_.bw_limited_resolution =
288 encoded_image.adapt_reason_.quality_resolution_downscales > 0 ||
289 encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
290
asapersson4306fc72015-10-19 00:35:21 -0700291 if (encoded_image.adapt_reason_.quality_resolution_downscales != -1) {
292 bool downscaled =
293 encoded_image.adapt_reason_.quality_resolution_downscales > 0;
sprangb4a1ae52015-12-03 08:10:08 -0800294 uma_container_->quality_limited_frame_counter_.Add(downscaled);
asapersson4306fc72015-10-19 00:35:21 -0700295 if (downscaled) {
sprangb4a1ae52015-12-03 08:10:08 -0800296 uma_container_->quality_downscales_counter_.Add(
asapersson4306fc72015-10-19 00:35:21 -0700297 encoded_image.adapt_reason_.quality_resolution_downscales);
298 }
299 }
asaperssonda535c42015-10-19 23:32:41 -0700300 if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) {
301 bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
sprangb4a1ae52015-12-03 08:10:08 -0800302 uma_container_->bw_limited_frame_counter_.Add(bw_limited);
asaperssonda535c42015-10-19 23:32:41 -0700303 if (bw_limited) {
sprangb4a1ae52015-12-03 08:10:08 -0800304 uma_container_->bw_resolutions_disabled_counter_.Add(
305 encoded_image.adapt_reason_.bw_resolutions_disabled);
asaperssonda535c42015-10-19 23:32:41 -0700306 }
307 }
asapersson4306fc72015-10-19 00:35:21 -0700308
asaperssond89920b2015-07-22 06:52:00 -0700309 // TODO(asapersson): This is incorrect if simulcast layers are encoded on
310 // different threads and there is no guarantee that one frame of all layers
311 // are encoded before the next start.
312 if (last_sent_frame_timestamp_ > 0 &&
313 encoded_image._timeStamp != last_sent_frame_timestamp_) {
sprangb4a1ae52015-12-03 08:10:08 -0800314 uma_container_->sent_frame_rate_tracker_.AddSamples(1);
315 uma_container_->sent_width_counter_.Add(
316 uma_container_->max_sent_width_per_timestamp_);
317 uma_container_->sent_height_counter_.Add(
318 uma_container_->max_sent_height_per_timestamp_);
319 uma_container_->max_sent_width_per_timestamp_ = 0;
320 uma_container_->max_sent_height_per_timestamp_ = 0;
Åsa Persson24b4eda2015-06-16 10:17:01 +0200321 }
asaperssond89920b2015-07-22 06:52:00 -0700322 last_sent_frame_timestamp_ = encoded_image._timeStamp;
sprangb4a1ae52015-12-03 08:10:08 -0800323 uma_container_->max_sent_width_per_timestamp_ =
324 std::max(uma_container_->max_sent_width_per_timestamp_,
asaperssond89920b2015-07-22 06:52:00 -0700325 static_cast<int>(encoded_image._encodedWidth));
sprangb4a1ae52015-12-03 08:10:08 -0800326 uma_container_->max_sent_height_per_timestamp_ =
327 std::max(uma_container_->max_sent_height_per_timestamp_,
asaperssond89920b2015-07-22 06:52:00 -0700328 static_cast<int>(encoded_image._encodedHeight));
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000329}
330
asaperssond89920b2015-07-22 06:52:00 -0700331void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200332 rtc::CritScope lock(&crit_);
sprangb4a1ae52015-12-03 08:10:08 -0800333 uma_container_->input_frame_rate_tracker_.AddSamples(1);
334 uma_container_->input_width_counter_.Add(width);
335 uma_container_->input_height_counter_.Add(height);
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000336}
337
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000338void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
339 uint32_t ssrc,
340 const RtcpPacketTypeCounter& packet_counter) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200341 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000342 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000343 if (stats == nullptr)
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000344 return;
345
346 stats->rtcp_packet_type_counts = packet_counter;
347}
348
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000349void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
350 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200351 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000352 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000353 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000354 return;
355
356 stats->rtcp_stats = statistics;
357}
358
Peter Boströmd1d66ba2016-02-08 14:07:14 +0100359void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {}
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000360
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000361void SendStatisticsProxy::DataCountersUpdated(
362 const StreamDataCounters& counters,
363 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200364 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000365 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
henrikg91d6ede2015-09-17 00:24:34 -0700366 RTC_DCHECK(stats != nullptr)
367 << "DataCountersUpdated reported for unknown ssrc: " << ssrc;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000368
369 stats->rtp_stats = counters;
370}
371
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000372void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
373 const BitrateStatistics& retransmit_stats,
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000374 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200375 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000376 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000377 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000378 return;
379
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000380 stats->total_bitrate_bps = total_stats.bitrate_bps;
381 stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000382}
383
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000384void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
385 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200386 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000387 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000388 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000389 return;
390
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000391 stats->frame_counts = frame_counts;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000392}
393
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000394void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
395 int max_delay_ms,
396 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200397 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000398 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000399 if (stats == nullptr)
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000400 return;
401 stats->avg_delay_ms = avg_delay_ms;
402 stats->max_delay_ms = max_delay_ms;
asaperssonf040b232015-11-04 00:59:03 -0800403
sprangb4a1ae52015-12-03 08:10:08 -0800404 uma_container_->delay_counter_.Add(avg_delay_ms);
405 uma_container_->max_delay_counter_.Add(max_delay_ms);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000406}
407
asaperssond89920b2015-07-22 06:52:00 -0700408void SendStatisticsProxy::SampleCounter::Add(int sample) {
409 sum += sample;
410 ++num_samples;
411}
412
413int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
414 if (num_samples < min_required_samples || num_samples == 0)
415 return -1;
asaperssonda535c42015-10-19 23:32:41 -0700416 return (sum + (num_samples / 2)) / num_samples;
asaperssond89920b2015-07-22 06:52:00 -0700417}
418
asaperssondec5ebf2015-10-05 02:36:17 -0700419void SendStatisticsProxy::BoolSampleCounter::Add(bool sample) {
420 if (sample)
421 ++sum;
422 ++num_samples;
423}
424
425int SendStatisticsProxy::BoolSampleCounter::Percent(
426 int min_required_samples) const {
427 return Fraction(min_required_samples, 100.0f);
428}
429
430int SendStatisticsProxy::BoolSampleCounter::Permille(
431 int min_required_samples) const {
432 return Fraction(min_required_samples, 1000.0f);
433}
434
435int SendStatisticsProxy::BoolSampleCounter::Fraction(
436 int min_required_samples, float multiplier) const {
437 if (num_samples < min_required_samples || num_samples == 0)
438 return -1;
439 return static_cast<int>((sum * multiplier / num_samples) + 0.5f);
440}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000441} // namespace webrtc