Index: webrtc/video/receive_statistics_proxy.cc |
diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc |
index d4a0df371d1902114cf703c068a892ad927a184f..96293f3db10ea4d42017c32c6cdedb19ed82f3cd 100644 |
--- a/webrtc/video/receive_statistics_proxy.cc |
+++ b/webrtc/video/receive_statistics_proxy.cc |
@@ -13,12 +13,20 @@ |
#include <cmath> |
#include "webrtc/base/checks.h" |
+#include "webrtc/base/logging.h" |
#include "webrtc/modules/video_coding/include/video_codec_interface.h" |
#include "webrtc/system_wrappers/include/clock.h" |
#include "webrtc/system_wrappers/include/metrics.h" |
namespace webrtc { |
+const int kNumMeasurements = 10; |
+const float kBadFraction = 0.8f; |
+const int kFpsThreshold = 13; |
+const int kDefaultFps = 15; |
+const int kQpThreshold = 60; |
+const int kDefaultQp = 20; |
+ |
ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
const VideoReceiveStream::Config* config, |
Clock* clock) |
@@ -26,6 +34,12 @@ ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
config_(*config), |
start_ms_(clock->TimeInMilliseconds()), |
// 1000ms window, scale 1000 for ms to s. |
+ last_sample_time_(clock->TimeInMilliseconds()), |
+ fps_threshold_(kFpsThreshold, |
+ kDefaultFps, |
+ kBadFraction, |
+ kNumMeasurements), |
+ qp_threshold_(kQpThreshold, kDefaultQp, kBadFraction, kNumMeasurements), |
decode_fps_estimator_(1000, 1000), |
renders_fps_estimator_(1000, 1000), |
render_fps_tracker_(100, 10u), |
@@ -150,6 +164,82 @@ void ReceiveStatisticsProxy::UpdateHistograms() { |
} |
} |
+void ReceiveStatisticsProxy::BadCallSample() { |
+ uint64_t now = clock_->TimeInMilliseconds(); |
+ |
+ double fps = |
+ render_fps_tracker_.ComputeRateForInterval(now - last_sample_time_); |
+ int qp = qp_sample_.Avg(1); |
+ |
+ BadCallThreshold::BadCallState fps_state = fps_threshold_.AddMeasurement(fps); |
+ BadCallThreshold::BadCallState qp_state = qp_threshold_.AddMeasurement(qp); |
+ |
+ switch (fps_state) { |
+ case BadCallThreshold::NEWLY_HIGH: |
+ LOG(LS_WARNING) << "Bad call (fps) end"; |
+ break; |
+ case BadCallThreshold::NEWLY_LOW: |
+ LOG(LS_WARNING) << "Bad call (fps) start"; |
+ break; |
+ default: |
+ break; |
+ } |
+ |
+ switch (qp_state) { |
+ case BadCallThreshold::NEWLY_HIGH: |
+ LOG(LS_WARNING) << "Bad call (qp) start"; |
+ break; |
+ case BadCallThreshold::NEWLY_LOW: |
+ LOG(LS_WARNING) << "Bad call (qp) end"; |
+ break; |
+ default: |
+ break; |
+ } |
+ |
+ std::string fpsBad; |
+ switch (fps_state) { |
+ case BadCallThreshold::NEWLY_LOW: |
+ fpsBad = "NEWLY_LOW"; |
+ break; |
+ case BadCallThreshold::STILL_LOW: |
+ fpsBad = "STILL_LOW"; |
+ break; |
+ case BadCallThreshold::NEWLY_HIGH: |
+ fpsBad = "NEWLY_HIGH"; |
+ break; |
+ case BadCallThreshold::STILL_HIGH: |
+ fpsBad = "STILL_HIGH"; |
+ break; |
+ default: |
+ fpsBad = "WAT"; |
+ } |
+ |
+ std::string qpBad; |
+ switch (qp_state) { |
+ case BadCallThreshold::NEWLY_LOW: |
+ qpBad = "NEWLY_LOW"; |
+ break; |
+ case BadCallThreshold::STILL_LOW: |
+ qpBad = "STILL_LOW"; |
+ break; |
+ case BadCallThreshold::NEWLY_HIGH: |
+ qpBad = "NEWLY_HIGH"; |
+ break; |
+ case BadCallThreshold::STILL_HIGH: |
+ qpBad = "STILL_HIGH"; |
+ break; |
+ default: |
+ qpBad = "WAT"; |
+ } |
+ |
+ LOG(LS_INFO) << "SAMPLE: sample_length: " << (now - last_sample_time_) |
+ << " fps: " << fps << " fpsBad: " << fpsBad << " qp: " << qp |
+ << " qpBad: " << qpBad; |
+ |
+ last_sample_time_ = now; |
+ qp_sample_.Reset(); |
+} |
+ |
VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { |
rtc::CritScope lock(&crit_); |
return stats_; |
@@ -168,6 +258,7 @@ void ReceiveStatisticsProxy::OnDecoderImplementationName( |
void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate, |
unsigned int bitrate_bps) { |
rtc::CritScope lock(&crit_); |
+ BadCallSample(); |
stats_.network_frame_rate = framerate; |
stats_.total_bitrate_bps = bitrate_bps; |
} |
@@ -304,6 +395,8 @@ void ReceiveStatisticsProxy::OnPreDecode( |
} |
if (codec_specific_info->codecType == kVideoCodecVP8) { |
qp_counters_.vp8.Add(encoded_image.qp_); |
+ rtc::CritScope lock(&crit_); |
+ qp_sample_.Add(encoded_image.qp_); |
} |
} |
@@ -318,4 +411,9 @@ int ReceiveStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { |
return sum / num_samples; |
} |
+void ReceiveStatisticsProxy::SampleCounter::Reset() { |
+ num_samples = 0; |
+ sum = 0; |
+} |
+ |
} // namespace webrtc |