OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/video/receive_statistics_proxy.h" | 11 #include "webrtc/video/receive_statistics_proxy.h" |
12 | 12 |
| 13 #include <cmath> |
| 14 |
| 15 #include "webrtc/base/checks.h" |
13 #include "webrtc/system_wrappers/interface/clock.h" | 16 #include "webrtc/system_wrappers/interface/clock.h" |
14 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" | 17 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" |
15 #include "webrtc/system_wrappers/interface/metrics.h" | 18 #include "webrtc/system_wrappers/interface/metrics.h" |
16 | 19 |
17 namespace webrtc { | 20 namespace webrtc { |
18 | 21 |
19 ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc, Clock* clock) | 22 ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc, Clock* clock) |
20 : clock_(clock), | 23 : clock_(clock), |
21 // 1000ms window, scale 1000 for ms to s. | 24 // 1000ms window, scale 1000 for ms to s. |
22 decode_fps_estimator_(1000, 1000), | 25 decode_fps_estimator_(1000, 1000), |
23 renders_fps_estimator_(1000, 1000), | 26 renders_fps_estimator_(1000, 1000), |
24 render_fps_tracker_(100u, 10u) { | 27 render_fps_tracker_(100u, 10u), |
| 28 render_pixel_tracker_(100u, 10u) { |
25 stats_.ssrc = ssrc; | 29 stats_.ssrc = ssrc; |
26 } | 30 } |
27 | 31 |
28 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { | 32 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { |
29 UpdateHistograms(); | 33 UpdateHistograms(); |
30 } | 34 } |
31 | 35 |
32 void ReceiveStatisticsProxy::UpdateHistograms() { | 36 void ReceiveStatisticsProxy::UpdateHistograms() { |
33 int fraction_lost = report_block_stats_.FractionLostInPercent(); | 37 int fraction_lost = report_block_stats_.FractionLostInPercent(); |
34 if (fraction_lost != -1) { | 38 if (fraction_lost != -1) { |
35 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", | 39 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", |
36 fraction_lost); | 40 fraction_lost); |
37 } | 41 } |
38 | |
39 int render_fps = static_cast<int>(render_fps_tracker_.ComputeTotalRate()); | |
40 if (render_fps > 0) | |
41 RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", render_fps); | |
42 | |
43 const int kMinRequiredSamples = 200; | 42 const int kMinRequiredSamples = 200; |
| 43 int samples = static_cast<int>(render_fps_tracker_.TotalSampleCount()); |
| 44 if (samples > kMinRequiredSamples) { |
| 45 RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", |
| 46 static_cast<int>(render_fps_tracker_.ComputeTotalRate())); |
| 47 RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.RenderSqrtPixelsPerSecond", |
| 48 static_cast<int>(render_pixel_tracker_.ComputeTotalRate())); |
| 49 } |
44 int width = render_width_counter_.Avg(kMinRequiredSamples); | 50 int width = render_width_counter_.Avg(kMinRequiredSamples); |
45 int height = render_height_counter_.Avg(kMinRequiredSamples); | 51 int height = render_height_counter_.Avg(kMinRequiredSamples); |
46 if (width != -1) { | 52 if (width != -1) { |
47 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedWidthInPixels", width); | 53 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedWidthInPixels", width); |
48 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedHeightInPixels", height); | 54 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedHeightInPixels", height); |
49 } | 55 } |
50 // TODO(asapersson): DecoderTiming() is call periodically (each 1000ms) and | 56 // TODO(asapersson): DecoderTiming() is call periodically (each 1000ms) and |
51 // not per frame. Change decode time to include every frame. | 57 // not per frame. Change decode time to include every frame. |
52 const int kMinRequiredDecodeSamples = 5; | 58 const int kMinRequiredDecodeSamples = 5; |
53 int decode_ms = decode_time_counter_.Avg(kMinRequiredDecodeSamples); | 59 int decode_ms = decode_time_counter_.Avg(kMinRequiredDecodeSamples); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 137 |
132 void ReceiveStatisticsProxy::OnDecodedFrame() { | 138 void ReceiveStatisticsProxy::OnDecodedFrame() { |
133 uint64_t now = clock_->TimeInMilliseconds(); | 139 uint64_t now = clock_->TimeInMilliseconds(); |
134 | 140 |
135 rtc::CritScope lock(&crit_); | 141 rtc::CritScope lock(&crit_); |
136 decode_fps_estimator_.Update(1, now); | 142 decode_fps_estimator_.Update(1, now); |
137 stats_.decode_frame_rate = decode_fps_estimator_.Rate(now); | 143 stats_.decode_frame_rate = decode_fps_estimator_.Rate(now); |
138 } | 144 } |
139 | 145 |
140 void ReceiveStatisticsProxy::OnRenderedFrame(int width, int height) { | 146 void ReceiveStatisticsProxy::OnRenderedFrame(int width, int height) { |
| 147 RTC_DCHECK_GT(width, 0); |
| 148 RTC_DCHECK_GT(height, 0); |
141 uint64_t now = clock_->TimeInMilliseconds(); | 149 uint64_t now = clock_->TimeInMilliseconds(); |
142 | 150 |
143 rtc::CritScope lock(&crit_); | 151 rtc::CritScope lock(&crit_); |
144 renders_fps_estimator_.Update(1, now); | 152 renders_fps_estimator_.Update(1, now); |
145 stats_.render_frame_rate = renders_fps_estimator_.Rate(now); | 153 stats_.render_frame_rate = renders_fps_estimator_.Rate(now); |
146 render_width_counter_.Add(width); | 154 render_width_counter_.Add(width); |
147 render_height_counter_.Add(height); | 155 render_height_counter_.Add(height); |
148 render_fps_tracker_.AddSamples(1); | 156 render_fps_tracker_.AddSamples(1); |
| 157 render_pixel_tracker_.AddSamples(sqrt(width * height)); |
149 } | 158 } |
150 | 159 |
151 void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate, | 160 void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate, |
152 uint32_t frameRate) { | 161 uint32_t frameRate) { |
153 } | 162 } |
154 | 163 |
155 void ReceiveStatisticsProxy::OnFrameCountsUpdated( | 164 void ReceiveStatisticsProxy::OnFrameCountsUpdated( |
156 const FrameCounts& frame_counts) { | 165 const FrameCounts& frame_counts) { |
157 rtc::CritScope lock(&crit_); | 166 rtc::CritScope lock(&crit_); |
158 stats_.frame_counts = frame_counts; | 167 stats_.frame_counts = frame_counts; |
159 } | 168 } |
160 | 169 |
161 void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) { | 170 void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) { |
162 rtc::CritScope lock(&crit_); | 171 rtc::CritScope lock(&crit_); |
163 stats_.discarded_packets = discarded_packets; | 172 stats_.discarded_packets = discarded_packets; |
164 } | 173 } |
165 | 174 |
166 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { | 175 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { |
167 sum += sample; | 176 sum += sample; |
168 ++num_samples; | 177 ++num_samples; |
169 } | 178 } |
170 | 179 |
171 int ReceiveStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { | 180 int ReceiveStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { |
172 if (num_samples < min_required_samples || num_samples == 0) | 181 if (num_samples < min_required_samples || num_samples == 0) |
173 return -1; | 182 return -1; |
174 return sum / num_samples; | 183 return sum / num_samples; |
175 } | 184 } |
176 | 185 |
177 } // namespace webrtc | 186 } // namespace webrtc |
OLD | NEW |