Index: webrtc/video/receive_statistics_proxy.cc |
diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc |
index c847a178e8072c15df945b4653925120a8293f6d..066b7ef68c48a9ecdaec0fe8a00fef2312b4a3f4 100644 |
--- a/webrtc/video/receive_statistics_proxy.cc |
+++ b/webrtc/video/receive_statistics_proxy.cc |
@@ -10,7 +10,9 @@ |
#include "webrtc/video/receive_statistics_proxy.h" |
+#include <algorithm> |
#include <cmath> |
+#include <utility> |
#include "webrtc/base/checks.h" |
#include "webrtc/base/logging.h" |
@@ -40,6 +42,9 @@ const int kLowQpThresholdVp8 = 60; |
const int kHighQpThresholdVp8 = 70; |
const int kLowVarianceThreshold = 1; |
const int kHighVarianceThreshold = 2; |
+ |
+// How large window we use to calculate the framerate/bitrate. |
+const int kRateStatisticsWindowSizeMs = 1000; |
} // namespace |
ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
@@ -69,7 +74,9 @@ ReceiveStatisticsProxy::ReceiveStatisticsProxy( |
render_fps_tracker_(100, 10u), |
render_pixel_tracker_(100, 10u), |
freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs), |
- first_report_block_time_ms_(-1) { |
+ first_report_block_time_ms_(-1), |
+ avg_rtt_ms_(0), |
+ frame_window_accumulated_bytes_(0) { |
stats_.ssrc = config_.rtp.remote_ssrc; |
// TODO(brandtr): Replace |rtx_stats_| with a single instance of |
// StreamDataCounters. |
@@ -124,6 +131,17 @@ void ReceiveStatisticsProxy::UpdateHistograms() { |
<< freq_offset_stats.ToString(); |
} |
+ if (stats_.frame_counts.key_frames > 0 || |
+ stats_.frame_counts.delta_frames > 0) { |
+ float num_key_frames = stats_.frame_counts.key_frames; |
+ float num_total_frames = |
+ stats_.frame_counts.key_frames + stats_.frame_counts.delta_frames; |
+ int key_frames_permille = |
+ (num_key_frames * 1000.0f / num_total_frames + 0.5f); |
+ RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille", |
+ key_frames_permille); |
+ } |
+ |
int qp = qp_counters_.vp8.Avg(kMinRequiredSamples); |
if (qp != -1) |
RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp); |
@@ -135,15 +153,12 @@ void ReceiveStatisticsProxy::UpdateHistograms() { |
if (decode_ms != -1) |
RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms); |
- if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") != |
- "Enabled") { |
- int jb_delay_ms = |
- jitter_buffer_delay_counter_.Avg(kMinRequiredDecodeSamples); |
- if (jb_delay_ms != -1) { |
- RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs", |
- jb_delay_ms); |
- } |
+ int jb_delay_ms = jitter_buffer_delay_counter_.Avg(kMinRequiredDecodeSamples); |
+ if (jb_delay_ms != -1) { |
+ RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs", |
+ jb_delay_ms); |
} |
+ |
int target_delay_ms = target_delay_counter_.Avg(kMinRequiredDecodeSamples); |
if (target_delay_ms != -1) { |
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms); |
@@ -300,8 +315,25 @@ void ReceiveStatisticsProxy::QualitySample() { |
} |
} |
+void ReceiveStatisticsProxy::UpdateFrameAndBitrate(int64_t now_ms) const { |
+ int64_t old_frames_ms = now_ms - kRateStatisticsWindowSizeMs; |
+ while (!frame_window_.empty() && |
+ frame_window_.begin()->first < old_frames_ms) { |
+ frame_window_accumulated_bytes_ -= frame_window_.begin()->second; |
+ frame_window_.erase(frame_window_.begin()); |
+ } |
+ |
+ size_t framerate = |
+ (frame_window_.size() * 1000 + 500) / kRateStatisticsWindowSizeMs; |
+ size_t bitrate_bps = |
+ frame_window_accumulated_bytes_ * 8000 / kRateStatisticsWindowSizeMs; |
+ stats_.network_frame_rate = static_cast<int>(framerate); |
+ stats_.total_bitrate_bps = static_cast<int>(bitrate_bps); |
+} |
+ |
VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { |
rtc::CritScope lock(&crit_); |
+ UpdateFrameAndBitrate(clock_->TimeInMilliseconds()); |
return stats_; |
} |
@@ -320,18 +352,16 @@ void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate, |
rtc::CritScope lock(&crit_); |
if (stats_.rtp_stats.first_packet_time_ms != -1) |
QualitySample(); |
- stats_.network_frame_rate = framerate; |
- stats_.total_bitrate_bps = bitrate_bps; |
} |
-void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms, |
- int max_decode_ms, |
- int current_delay_ms, |
- int target_delay_ms, |
- int jitter_buffer_ms, |
- int min_playout_delay_ms, |
- int render_delay_ms, |
- int64_t rtt_ms) { |
+void ReceiveStatisticsProxy::OnFrameBufferTimingsUpdated( |
+ int decode_ms, |
+ int max_decode_ms, |
+ int current_delay_ms, |
+ int target_delay_ms, |
+ int jitter_buffer_ms, |
+ int min_playout_delay_ms, |
+ int render_delay_ms) { |
rtc::CritScope lock(&crit_); |
stats_.decode_ms = decode_ms; |
stats_.max_decode_ms = max_decode_ms; |
@@ -346,7 +376,7 @@ void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms, |
current_delay_counter_.Add(current_delay_ms); |
// Network delay (rtt/2) + target_delay_ms (jitter delay + decode time + |
// render delay). |
- delay_counter_.Add(target_delay_ms + rtt_ms / 2); |
+ delay_counter_.Add(target_delay_ms + avg_rtt_ms_ / 2); |
} |
void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated( |
@@ -466,6 +496,20 @@ void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate, |
uint32_t frameRate) { |
} |
+void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe, |
+ size_t size_bytes) { |
+ rtc::CritScope lock(&crit_); |
+ if (is_keyframe) |
+ ++stats_.frame_counts.key_frames; |
+ else |
+ ++stats_.frame_counts.delta_frames; |
+ |
+ int64_t now_ms = clock_->TimeInMilliseconds(); |
+ frame_window_accumulated_bytes_ += size_bytes; |
+ frame_window_.insert(std::make_pair(now_ms, size_bytes)); |
+ UpdateFrameAndBitrate(now_ms); |
+} |
+ |
void ReceiveStatisticsProxy::OnFrameCountsUpdated( |
const FrameCounts& frame_counts) { |
rtc::CritScope lock(&crit_); |
@@ -507,4 +551,10 @@ void ReceiveStatisticsProxy::SampleCounter::Reset() { |
sum = 0; |
} |
+void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms, |
+ int64_t max_rtt_ms) { |
+ rtc::CritScope lock(&crit_); |
+ avg_rtt_ms_ = avg_rtt_ms; |
+} |
+ |
} // namespace webrtc |