blob: f5e7e3d0243fd16f2ad0cd0d1db898143372e711 [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/critical_section_wrapper.h"
20#include "webrtc/system_wrappers/include/metrics.h"
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000021
22namespace webrtc {
asapersson2a0a2a42015-10-27 01:32:00 -070023namespace {
asapersson1aa420b2015-12-07 03:12:22 -080024const float kEncodeTimeWeigthFactor = 0.5f;
25
asapersson2a0a2a42015-10-27 01:32:00 -070026// Used by histograms. Values of entries should not be changed.
27enum HistogramCodecType {
28 kVideoUnknown = 0,
29 kVideoVp8 = 1,
30 kVideoVp9 = 2,
31 kVideoH264 = 3,
32 kVideoMax = 64,
33};
34
sprangb4a1ae52015-12-03 08:10:08 -080035const char* GetUmaPrefix(VideoEncoderConfig::ContentType content_type) {
36 switch (content_type) {
37 case VideoEncoderConfig::ContentType::kRealtimeVideo:
38 return "WebRTC.Video.";
39 case VideoEncoderConfig::ContentType::kScreen:
40 return "WebRTC.Video.Screenshare.";
41 }
42 RTC_NOTREACHED();
43 return nullptr;
44}
45
asapersson2a0a2a42015-10-27 01:32:00 -070046HistogramCodecType PayloadNameToHistogramCodecType(
47 const std::string& payload_name) {
48 if (payload_name == "VP8") {
49 return kVideoVp8;
50 } else if (payload_name == "VP9") {
51 return kVideoVp9;
52 } else if (payload_name == "H264") {
53 return kVideoH264;
54 } else {
55 return kVideoUnknown;
56 }
57}
58
59void UpdateCodecTypeHistogram(const std::string& payload_name) {
60 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.Encoder.CodecType",
61 PayloadNameToHistogramCodecType(payload_name), kVideoMax);
62}
63} // namespace
64
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000065
pbos@webrtc.org273a4142014-12-01 15:23:21 +000066const int SendStatisticsProxy::kStatsTimeoutMs = 5000;
67
sprangb4a1ae52015-12-03 08:10:08 -080068SendStatisticsProxy::SendStatisticsProxy(
69 Clock* clock,
70 const VideoSendStream::Config& config,
71 VideoEncoderConfig::ContentType content_type)
asaperssond89920b2015-07-22 06:52:00 -070072 : clock_(clock),
73 config_(config),
sprangb4a1ae52015-12-03 08:10:08 -080074 content_type_(content_type),
asaperssond89920b2015-07-22 06:52:00 -070075 last_sent_frame_timestamp_(0),
asapersson1aa420b2015-12-07 03:12:22 -080076 encode_time_(kEncodeTimeWeigthFactor),
sprangb4a1ae52015-12-03 08:10:08 -080077 uma_container_(new UmaSamplesContainer(GetUmaPrefix(content_type_))) {
asapersson2a0a2a42015-10-27 01:32:00 -070078 UpdateCodecTypeHistogram(config_.encoder_settings.payload_name);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000079}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000080
sprangb4a1ae52015-12-03 08:10:08 -080081SendStatisticsProxy::~SendStatisticsProxy() {}
82
83SendStatisticsProxy::UmaSamplesContainer::UmaSamplesContainer(
84 const char* prefix)
85 : uma_prefix_(prefix),
86 max_sent_width_per_timestamp_(0),
87 max_sent_height_per_timestamp_(0),
88 input_frame_rate_tracker_(100u, 10u),
89 sent_frame_rate_tracker_(100u, 10u) {}
90
91SendStatisticsProxy::UmaSamplesContainer::~UmaSamplesContainer() {
Åsa Persson24b4eda2015-06-16 10:17:01 +020092 UpdateHistograms();
93}
94
sprangb4a1ae52015-12-03 08:10:08 -080095void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms() {
asapersson6718e972015-07-24 00:20:58 -070096 const int kMinRequiredSamples = 200;
asaperssond89920b2015-07-22 06:52:00 -070097 int in_width = input_width_counter_.Avg(kMinRequiredSamples);
98 int in_height = input_height_counter_.Avg(kMinRequiredSamples);
asapersson6f14be82015-11-16 00:40:49 -080099 int in_fps = round(input_frame_rate_tracker_.ComputeTotalRate());
asaperssond89920b2015-07-22 06:52:00 -0700100 if (in_width != -1) {
sprangb4a1ae52015-12-03 08:10:08 -0800101 RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "InputWidthInPixels", in_width);
102 RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "InputHeightInPixels", in_height);
103 RTC_HISTOGRAM_COUNTS_100(uma_prefix_ + "InputFramesPerSecond", in_fps);
asaperssond89920b2015-07-22 06:52:00 -0700104 }
105 int sent_width = sent_width_counter_.Avg(kMinRequiredSamples);
106 int sent_height = sent_height_counter_.Avg(kMinRequiredSamples);
asapersson6f14be82015-11-16 00:40:49 -0800107 int sent_fps = round(sent_frame_rate_tracker_.ComputeTotalRate());
asaperssond89920b2015-07-22 06:52:00 -0700108 if (sent_width != -1) {
sprangb4a1ae52015-12-03 08:10:08 -0800109 RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "SentWidthInPixels", sent_width);
110 RTC_HISTOGRAM_COUNTS_10000(uma_prefix_ + "SentHeightInPixels", sent_height);
111 RTC_HISTOGRAM_COUNTS_100(uma_prefix_ + "SentFramesPerSecond", sent_fps);
asaperssond89920b2015-07-22 06:52:00 -0700112 }
asapersson6718e972015-07-24 00:20:58 -0700113 int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples);
114 if (encode_ms != -1)
sprangb4a1ae52015-12-03 08:10:08 -0800115 RTC_HISTOGRAM_COUNTS_1000(uma_prefix_ + "EncodeTimeInMs", encode_ms);
asaperssondec5ebf2015-10-05 02:36:17 -0700116
117 int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples);
118 if (key_frames_permille != -1) {
sprangb4a1ae52015-12-03 08:10:08 -0800119 RTC_HISTOGRAM_COUNTS_1000(uma_prefix_ + "KeyFramesSentInPermille",
120 key_frames_permille);
asaperssondec5ebf2015-10-05 02:36:17 -0700121 }
asapersson4306fc72015-10-19 00:35:21 -0700122 int quality_limited =
123 quality_limited_frame_counter_.Percent(kMinRequiredSamples);
124 if (quality_limited != -1) {
sprangb4a1ae52015-12-03 08:10:08 -0800125 RTC_HISTOGRAM_PERCENTAGE(uma_prefix_ + "QualityLimitedResolutionInPercent",
asapersson4306fc72015-10-19 00:35:21 -0700126 quality_limited);
127 }
128 int downscales = quality_downscales_counter_.Avg(kMinRequiredSamples);
129 if (downscales != -1) {
sprangb4a1ae52015-12-03 08:10:08 -0800130 RTC_HISTOGRAM_ENUMERATION(
131 uma_prefix_ + "QualityLimitedResolutionDownscales", downscales, 20);
asapersson4306fc72015-10-19 00:35:21 -0700132 }
asaperssonda535c42015-10-19 23:32:41 -0700133 int bw_limited = bw_limited_frame_counter_.Percent(kMinRequiredSamples);
134 if (bw_limited != -1) {
sprangb4a1ae52015-12-03 08:10:08 -0800135 RTC_HISTOGRAM_PERCENTAGE(
136 uma_prefix_ + "BandwidthLimitedResolutionInPercent", bw_limited);
asaperssonda535c42015-10-19 23:32:41 -0700137 }
138 int num_disabled = bw_resolutions_disabled_counter_.Avg(kMinRequiredSamples);
139 if (num_disabled != -1) {
140 RTC_HISTOGRAM_ENUMERATION(
sprangb4a1ae52015-12-03 08:10:08 -0800141 uma_prefix_ + "BandwidthLimitedResolutionsDisabled", num_disabled, 10);
asaperssonda535c42015-10-19 23:32:41 -0700142 }
asaperssonf040b232015-11-04 00:59:03 -0800143 int delay_ms = delay_counter_.Avg(kMinRequiredSamples);
144 if (delay_ms != -1)
sprangb4a1ae52015-12-03 08:10:08 -0800145 RTC_HISTOGRAM_COUNTS_100000(uma_prefix_ + "SendSideDelayInMs", delay_ms);
asaperssonf040b232015-11-04 00:59:03 -0800146
147 int max_delay_ms = max_delay_counter_.Avg(kMinRequiredSamples);
148 if (max_delay_ms != -1) {
sprangb4a1ae52015-12-03 08:10:08 -0800149 RTC_HISTOGRAM_COUNTS_100000(uma_prefix_ + "SendSideDelayMaxInMs",
150 max_delay_ms);
151 }
152}
153
154void SendStatisticsProxy::SetContentType(
155 VideoEncoderConfig::ContentType content_type) {
156 rtc::CritScope lock(&crit_);
157 if (content_type_ != content_type) {
158 uma_container_->UpdateHistograms();
159 uma_container_.reset(new UmaSamplesContainer(GetUmaPrefix(content_type)));
160 content_type_ = content_type;
asaperssonf040b232015-11-04 00:59:03 -0800161 }
Åsa Persson24b4eda2015-06-16 10:17:01 +0200162}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000163
Peter Boström7083e112015-09-22 16:28:51 +0200164void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200165 rtc::CritScope lock(&crit_);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000166 stats_.encode_frame_rate = framerate;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000167 stats_.media_bitrate_bps = bitrate;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000168}
169
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000170void SendStatisticsProxy::CpuOveruseMetricsUpdated(
171 const CpuOveruseMetrics& metrics) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200172 rtc::CritScope lock(&crit_);
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000173 stats_.encode_usage_percent = metrics.encode_usage_percent;
174}
175
Peter Boström7083e112015-09-22 16:28:51 +0200176void SendStatisticsProxy::OnSuspendChange(bool is_suspended) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200177 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000178 stats_.suspended = is_suspended;
179}
180
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000181VideoSendStream::Stats SendStatisticsProxy::GetStats() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200182 rtc::CritScope lock(&crit_);
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000183 PurgeOldStats();
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000184 stats_.input_frame_rate =
sprangb4a1ae52015-12-03 08:10:08 -0800185 round(uma_container_->input_frame_rate_tracker_.ComputeRate());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000186 return stats_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000187}
188
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000189void SendStatisticsProxy::PurgeOldStats() {
Peter Boström20f3f942015-05-15 11:33:39 +0200190 int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000191 for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
192 stats_.substreams.begin();
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000193 it != stats_.substreams.end(); ++it) {
194 uint32_t ssrc = it->first;
Peter Boström20f3f942015-05-15 11:33:39 +0200195 if (update_times_[ssrc].resolution_update_ms <= old_stats_ms) {
196 it->second.width = 0;
197 it->second.height = 0;
198 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000199 }
200}
201
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000202VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
203 uint32_t ssrc) {
204 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
205 stats_.substreams.find(ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000206 if (it != stats_.substreams.end())
207 return &it->second;
208
209 if (std::find(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end(), ssrc) ==
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000210 config_.rtp.ssrcs.end() &&
211 std::find(config_.rtp.rtx.ssrcs.begin(),
212 config_.rtp.rtx.ssrcs.end(),
213 ssrc) == config_.rtp.rtx.ssrcs.end()) {
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000214 return nullptr;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +0000215 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000216
217 return &stats_.substreams[ssrc]; // Insert new entry and return ptr.
218}
219
Peter Boström20f3f942015-05-15 11:33:39 +0200220void SendStatisticsProxy::OnInactiveSsrc(uint32_t ssrc) {
221 rtc::CritScope lock(&crit_);
222 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
223 if (stats == nullptr)
224 return;
225
226 stats->total_bitrate_bps = 0;
227 stats->retransmit_bitrate_bps = 0;
228 stats->height = 0;
229 stats->width = 0;
230}
231
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000232void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200233 rtc::CritScope lock(&crit_);
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000234 stats_.target_media_bitrate_bps = bitrate_bps;
235}
236
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000237void SendStatisticsProxy::OnSendEncodedImage(
238 const EncodedImage& encoded_image,
239 const RTPVideoHeader* rtp_video_header) {
240 size_t simulcast_idx =
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000241 rtp_video_header != nullptr ? rtp_video_header->simulcastIdx : 0;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000242 if (simulcast_idx >= config_.rtp.ssrcs.size()) {
243 LOG(LS_ERROR) << "Encoded image outside simulcast range (" << simulcast_idx
244 << " >= " << config_.rtp.ssrcs.size() << ").";
245 return;
246 }
247 uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
248
Peter Boströmf2f82832015-05-01 13:00:41 +0200249 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000250 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000251 if (stats == nullptr)
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000252 return;
253
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000254 stats->width = encoded_image._encodedWidth;
255 stats->height = encoded_image._encodedHeight;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000256 update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
asaperssond89920b2015-07-22 06:52:00 -0700257
sprangb4a1ae52015-12-03 08:10:08 -0800258 uma_container_->key_frame_counter_.Add(encoded_image._frameType ==
259 kVideoFrameKey);
asaperssondec5ebf2015-10-05 02:36:17 -0700260
asapersson17821db2015-12-14 02:08:12 -0800261 stats_.bw_limited_resolution =
262 encoded_image.adapt_reason_.quality_resolution_downscales > 0 ||
263 encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
264
asapersson4306fc72015-10-19 00:35:21 -0700265 if (encoded_image.adapt_reason_.quality_resolution_downscales != -1) {
266 bool downscaled =
267 encoded_image.adapt_reason_.quality_resolution_downscales > 0;
sprangb4a1ae52015-12-03 08:10:08 -0800268 uma_container_->quality_limited_frame_counter_.Add(downscaled);
asapersson4306fc72015-10-19 00:35:21 -0700269 if (downscaled) {
sprangb4a1ae52015-12-03 08:10:08 -0800270 uma_container_->quality_downscales_counter_.Add(
asapersson4306fc72015-10-19 00:35:21 -0700271 encoded_image.adapt_reason_.quality_resolution_downscales);
272 }
273 }
asaperssonda535c42015-10-19 23:32:41 -0700274 if (encoded_image.adapt_reason_.bw_resolutions_disabled != -1) {
275 bool bw_limited = encoded_image.adapt_reason_.bw_resolutions_disabled > 0;
sprangb4a1ae52015-12-03 08:10:08 -0800276 uma_container_->bw_limited_frame_counter_.Add(bw_limited);
asaperssonda535c42015-10-19 23:32:41 -0700277 if (bw_limited) {
sprangb4a1ae52015-12-03 08:10:08 -0800278 uma_container_->bw_resolutions_disabled_counter_.Add(
279 encoded_image.adapt_reason_.bw_resolutions_disabled);
asaperssonda535c42015-10-19 23:32:41 -0700280 }
281 }
asapersson4306fc72015-10-19 00:35:21 -0700282
asaperssond89920b2015-07-22 06:52:00 -0700283 // TODO(asapersson): This is incorrect if simulcast layers are encoded on
284 // different threads and there is no guarantee that one frame of all layers
285 // are encoded before the next start.
286 if (last_sent_frame_timestamp_ > 0 &&
287 encoded_image._timeStamp != last_sent_frame_timestamp_) {
sprangb4a1ae52015-12-03 08:10:08 -0800288 uma_container_->sent_frame_rate_tracker_.AddSamples(1);
289 uma_container_->sent_width_counter_.Add(
290 uma_container_->max_sent_width_per_timestamp_);
291 uma_container_->sent_height_counter_.Add(
292 uma_container_->max_sent_height_per_timestamp_);
293 uma_container_->max_sent_width_per_timestamp_ = 0;
294 uma_container_->max_sent_height_per_timestamp_ = 0;
Åsa Persson24b4eda2015-06-16 10:17:01 +0200295 }
asaperssond89920b2015-07-22 06:52:00 -0700296 last_sent_frame_timestamp_ = encoded_image._timeStamp;
sprangb4a1ae52015-12-03 08:10:08 -0800297 uma_container_->max_sent_width_per_timestamp_ =
298 std::max(uma_container_->max_sent_width_per_timestamp_,
asaperssond89920b2015-07-22 06:52:00 -0700299 static_cast<int>(encoded_image._encodedWidth));
sprangb4a1ae52015-12-03 08:10:08 -0800300 uma_container_->max_sent_height_per_timestamp_ =
301 std::max(uma_container_->max_sent_height_per_timestamp_,
asaperssond89920b2015-07-22 06:52:00 -0700302 static_cast<int>(encoded_image._encodedHeight));
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000303}
304
asaperssond89920b2015-07-22 06:52:00 -0700305void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200306 rtc::CritScope lock(&crit_);
sprangb4a1ae52015-12-03 08:10:08 -0800307 uma_container_->input_frame_rate_tracker_.AddSamples(1);
308 uma_container_->input_width_counter_.Add(width);
309 uma_container_->input_height_counter_.Add(height);
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000310}
311
asapersson6718e972015-07-24 00:20:58 -0700312void SendStatisticsProxy::OnEncodedFrame(int encode_time_ms) {
313 rtc::CritScope lock(&crit_);
sprangb4a1ae52015-12-03 08:10:08 -0800314 uma_container_->encode_time_counter_.Add(encode_time_ms);
asapersson1aa420b2015-12-07 03:12:22 -0800315 encode_time_.Apply(1.0f, encode_time_ms);
316 stats_.avg_encode_time_ms = round(encode_time_.filtered());
asapersson6718e972015-07-24 00:20:58 -0700317}
318
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000319void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
320 uint32_t ssrc,
321 const RtcpPacketTypeCounter& packet_counter) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200322 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000323 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000324 if (stats == nullptr)
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000325 return;
326
327 stats->rtcp_packet_type_counts = packet_counter;
328}
329
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000330void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
331 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200332 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000333 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000334 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000335 return;
336
337 stats->rtcp_stats = statistics;
338}
339
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000340void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {
341}
342
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000343void SendStatisticsProxy::DataCountersUpdated(
344 const StreamDataCounters& counters,
345 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200346 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000347 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
henrikg91d6ede2015-09-17 00:24:34 -0700348 RTC_DCHECK(stats != nullptr)
349 << "DataCountersUpdated reported for unknown ssrc: " << ssrc;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000350
351 stats->rtp_stats = counters;
352}
353
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000354void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
355 const BitrateStatistics& retransmit_stats,
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000356 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200357 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000358 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000359 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000360 return;
361
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000362 stats->total_bitrate_bps = total_stats.bitrate_bps;
363 stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000364}
365
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000366void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
367 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200368 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000369 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000370 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000371 return;
372
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000373 stats->frame_counts = frame_counts;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000374}
375
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000376void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
377 int max_delay_ms,
378 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200379 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000380 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000381 if (stats == nullptr)
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000382 return;
383 stats->avg_delay_ms = avg_delay_ms;
384 stats->max_delay_ms = max_delay_ms;
asaperssonf040b232015-11-04 00:59:03 -0800385
sprangb4a1ae52015-12-03 08:10:08 -0800386 uma_container_->delay_counter_.Add(avg_delay_ms);
387 uma_container_->max_delay_counter_.Add(max_delay_ms);
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000388}
389
asaperssond89920b2015-07-22 06:52:00 -0700390void SendStatisticsProxy::SampleCounter::Add(int sample) {
391 sum += sample;
392 ++num_samples;
393}
394
395int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
396 if (num_samples < min_required_samples || num_samples == 0)
397 return -1;
asaperssonda535c42015-10-19 23:32:41 -0700398 return (sum + (num_samples / 2)) / num_samples;
asaperssond89920b2015-07-22 06:52:00 -0700399}
400
asaperssondec5ebf2015-10-05 02:36:17 -0700401void SendStatisticsProxy::BoolSampleCounter::Add(bool sample) {
402 if (sample)
403 ++sum;
404 ++num_samples;
405}
406
407int SendStatisticsProxy::BoolSampleCounter::Percent(
408 int min_required_samples) const {
409 return Fraction(min_required_samples, 100.0f);
410}
411
412int SendStatisticsProxy::BoolSampleCounter::Permille(
413 int min_required_samples) const {
414 return Fraction(min_required_samples, 1000.0f);
415}
416
417int SendStatisticsProxy::BoolSampleCounter::Fraction(
418 int min_required_samples, float multiplier) const {
419 if (num_samples < min_required_samples || num_samples == 0)
420 return -1;
421 return static_cast<int>((sum * multiplier / num_samples) + 0.5f);
422}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000423} // namespace webrtc