| 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> | 13 #include <cmath> |
| 14 | 14 |
| 15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
| 16 #include "webrtc/base/logging.h" |
| 16 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
| 17 #include "webrtc/system_wrappers/include/clock.h" | 18 #include "webrtc/system_wrappers/include/clock.h" |
| 18 #include "webrtc/system_wrappers/include/metrics.h" | 19 #include "webrtc/system_wrappers/include/metrics.h" |
| 19 | 20 |
| 20 namespace webrtc { | 21 namespace webrtc { |
| 21 | 22 |
| 23 const int kNumMeasurements = 10; |
| 24 const float kBadFraction = 0.8f; |
| 25 const int kFpsThreshold = 13; |
| 26 const int kDefaultFps = 15; |
| 27 const int kQpThreshold = 60; |
| 28 const int kDefaultQp = 20; |
| 29 |
| 22 ReceiveStatisticsProxy::ReceiveStatisticsProxy( | 30 ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
| 23 const VideoReceiveStream::Config* config, | 31 const VideoReceiveStream::Config* config, |
| 24 Clock* clock) | 32 Clock* clock) |
| 25 : clock_(clock), | 33 : clock_(clock), |
| 26 config_(*config), | 34 config_(*config), |
| 27 start_ms_(clock->TimeInMilliseconds()), | 35 start_ms_(clock->TimeInMilliseconds()), |
| 28 // 1000ms window, scale 1000 for ms to s. | 36 // 1000ms window, scale 1000 for ms to s. |
| 37 last_sample_time_(clock->TimeInMilliseconds()), |
| 38 fps_threshold_(kFpsThreshold, |
| 39 kDefaultFps, |
| 40 kBadFraction, |
| 41 kNumMeasurements), |
| 42 qp_threshold_(kQpThreshold, kDefaultQp, kBadFraction, kNumMeasurements), |
| 29 decode_fps_estimator_(1000, 1000), | 43 decode_fps_estimator_(1000, 1000), |
| 30 renders_fps_estimator_(1000, 1000), | 44 renders_fps_estimator_(1000, 1000), |
| 31 render_fps_tracker_(100, 10u), | 45 render_fps_tracker_(100, 10u), |
| 32 render_pixel_tracker_(100, 10u) { | 46 render_pixel_tracker_(100, 10u) { |
| 33 stats_.ssrc = config_.rtp.remote_ssrc; | 47 stats_.ssrc = config_.rtp.remote_ssrc; |
| 34 for (auto it : config_.rtp.rtx) | 48 for (auto it : config_.rtp.rtx) |
| 35 rtx_stats_[it.second.ssrc] = StreamDataCounters(); | 49 rtx_stats_[it.second.ssrc] = StreamDataCounters(); |
| 36 } | 50 } |
| 37 | 51 |
| 38 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { | 52 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 counters.fir_packets * 60 / elapsed_sec); | 157 counters.fir_packets * 60 / elapsed_sec); |
| 144 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute", | 158 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PliPacketsSentPerMinute", |
| 145 counters.pli_packets * 60 / elapsed_sec); | 159 counters.pli_packets * 60 / elapsed_sec); |
| 146 if (counters.nack_requests > 0) { | 160 if (counters.nack_requests > 0) { |
| 147 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent", | 161 RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.UniqueNackRequestsSentInPercent", |
| 148 counters.UniqueNackRequestsInPercent()); | 162 counters.UniqueNackRequestsInPercent()); |
| 149 } | 163 } |
| 150 } | 164 } |
| 151 } | 165 } |
| 152 | 166 |
| 167 void ReceiveStatisticsProxy::BadCallSample() { |
| 168 uint64_t now = clock_->TimeInMilliseconds(); |
| 169 |
| 170 double fps = |
| 171 render_fps_tracker_.ComputeRateForInterval(now - last_sample_time_); |
| 172 int qp = qp_sample_.Avg(1); |
| 173 |
| 174 BadCallThreshold::BadCallState fps_state = fps_threshold_.AddMeasurement(fps); |
| 175 BadCallThreshold::BadCallState qp_state = qp_threshold_.AddMeasurement(qp); |
| 176 |
| 177 switch (fps_state) { |
| 178 case BadCallThreshold::NEWLY_HIGH: |
| 179 LOG(LS_WARNING) << "Bad call (fps) end"; |
| 180 break; |
| 181 case BadCallThreshold::NEWLY_LOW: |
| 182 LOG(LS_WARNING) << "Bad call (fps) start"; |
| 183 break; |
| 184 default: |
| 185 break; |
| 186 } |
| 187 |
| 188 switch (qp_state) { |
| 189 case BadCallThreshold::NEWLY_HIGH: |
| 190 LOG(LS_WARNING) << "Bad call (qp) start"; |
| 191 break; |
| 192 case BadCallThreshold::NEWLY_LOW: |
| 193 LOG(LS_WARNING) << "Bad call (qp) end"; |
| 194 break; |
| 195 default: |
| 196 break; |
| 197 } |
| 198 |
| 199 std::string fpsBad; |
| 200 switch (fps_state) { |
| 201 case BadCallThreshold::NEWLY_LOW: |
| 202 fpsBad = "NEWLY_LOW"; |
| 203 break; |
| 204 case BadCallThreshold::STILL_LOW: |
| 205 fpsBad = "STILL_LOW"; |
| 206 break; |
| 207 case BadCallThreshold::NEWLY_HIGH: |
| 208 fpsBad = "NEWLY_HIGH"; |
| 209 break; |
| 210 case BadCallThreshold::STILL_HIGH: |
| 211 fpsBad = "STILL_HIGH"; |
| 212 break; |
| 213 default: |
| 214 fpsBad = "WAT"; |
| 215 } |
| 216 |
| 217 std::string qpBad; |
| 218 switch (qp_state) { |
| 219 case BadCallThreshold::NEWLY_LOW: |
| 220 qpBad = "NEWLY_LOW"; |
| 221 break; |
| 222 case BadCallThreshold::STILL_LOW: |
| 223 qpBad = "STILL_LOW"; |
| 224 break; |
| 225 case BadCallThreshold::NEWLY_HIGH: |
| 226 qpBad = "NEWLY_HIGH"; |
| 227 break; |
| 228 case BadCallThreshold::STILL_HIGH: |
| 229 qpBad = "STILL_HIGH"; |
| 230 break; |
| 231 default: |
| 232 qpBad = "WAT"; |
| 233 } |
| 234 |
| 235 LOG(LS_INFO) << "SAMPLE: sample_length: " << (now - last_sample_time_) |
| 236 << " fps: " << fps << " fpsBad: " << fpsBad << " qp: " << qp |
| 237 << " qpBad: " << qpBad; |
| 238 |
| 239 last_sample_time_ = now; |
| 240 qp_sample_.Reset(); |
| 241 } |
| 242 |
| 153 VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { | 243 VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { |
| 154 rtc::CritScope lock(&crit_); | 244 rtc::CritScope lock(&crit_); |
| 155 return stats_; | 245 return stats_; |
| 156 } | 246 } |
| 157 | 247 |
| 158 void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) { | 248 void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) { |
| 159 rtc::CritScope lock(&crit_); | 249 rtc::CritScope lock(&crit_); |
| 160 stats_.current_payload_type = payload_type; | 250 stats_.current_payload_type = payload_type; |
| 161 } | 251 } |
| 162 | 252 |
| 163 void ReceiveStatisticsProxy::OnDecoderImplementationName( | 253 void ReceiveStatisticsProxy::OnDecoderImplementationName( |
| 164 const char* implementation_name) { | 254 const char* implementation_name) { |
| 165 rtc::CritScope lock(&crit_); | 255 rtc::CritScope lock(&crit_); |
| 166 stats_.decoder_implementation_name = implementation_name; | 256 stats_.decoder_implementation_name = implementation_name; |
| 167 } | 257 } |
| 168 void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate, | 258 void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate, |
| 169 unsigned int bitrate_bps) { | 259 unsigned int bitrate_bps) { |
| 170 rtc::CritScope lock(&crit_); | 260 rtc::CritScope lock(&crit_); |
| 261 BadCallSample(); |
| 171 stats_.network_frame_rate = framerate; | 262 stats_.network_frame_rate = framerate; |
| 172 stats_.total_bitrate_bps = bitrate_bps; | 263 stats_.total_bitrate_bps = bitrate_bps; |
| 173 } | 264 } |
| 174 | 265 |
| 175 void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms, | 266 void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms, |
| 176 int max_decode_ms, | 267 int max_decode_ms, |
| 177 int current_delay_ms, | 268 int current_delay_ms, |
| 178 int target_delay_ms, | 269 int target_delay_ms, |
| 179 int jitter_buffer_ms, | 270 int jitter_buffer_ms, |
| 180 int min_playout_delay_ms, | 271 int min_playout_delay_ms, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 } | 388 } |
| 298 | 389 |
| 299 void ReceiveStatisticsProxy::OnPreDecode( | 390 void ReceiveStatisticsProxy::OnPreDecode( |
| 300 const EncodedImage& encoded_image, | 391 const EncodedImage& encoded_image, |
| 301 const CodecSpecificInfo* codec_specific_info) { | 392 const CodecSpecificInfo* codec_specific_info) { |
| 302 if (!codec_specific_info || encoded_image.qp_ == -1) { | 393 if (!codec_specific_info || encoded_image.qp_ == -1) { |
| 303 return; | 394 return; |
| 304 } | 395 } |
| 305 if (codec_specific_info->codecType == kVideoCodecVP8) { | 396 if (codec_specific_info->codecType == kVideoCodecVP8) { |
| 306 qp_counters_.vp8.Add(encoded_image.qp_); | 397 qp_counters_.vp8.Add(encoded_image.qp_); |
| 398 rtc::CritScope lock(&crit_); |
| 399 qp_sample_.Add(encoded_image.qp_); |
| 307 } | 400 } |
| 308 } | 401 } |
| 309 | 402 |
| 310 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { | 403 void ReceiveStatisticsProxy::SampleCounter::Add(int sample) { |
| 311 sum += sample; | 404 sum += sample; |
| 312 ++num_samples; | 405 ++num_samples; |
| 313 } | 406 } |
| 314 | 407 |
| 315 int ReceiveStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { | 408 int ReceiveStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { |
| 316 if (num_samples < min_required_samples || num_samples == 0) | 409 if (num_samples < min_required_samples || num_samples == 0) |
| 317 return -1; | 410 return -1; |
| 318 return sum / num_samples; | 411 return sum / num_samples; |
| 319 } | 412 } |
| 320 | 413 |
| 414 void ReceiveStatisticsProxy::SampleCounter::Reset() { |
| 415 num_samples = 0; |
| 416 sum = 0; |
| 417 } |
| 418 |
| 321 } // namespace webrtc | 419 } // namespace webrtc |
| OLD | NEW |