Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: webrtc/video/receive_statistics_proxy.cc

Issue 2652043005: Reland of Make the new jitter buffer the default jitter buffer. (Closed)
Patch Set: Rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm>
13 #include <cmath> 14 #include <cmath>
15 #include <utility>
14 16
15 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
16 #include "webrtc/base/logging.h" 18 #include "webrtc/base/logging.h"
17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 19 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
18 #include "webrtc/system_wrappers/include/clock.h" 20 #include "webrtc/system_wrappers/include/clock.h"
19 #include "webrtc/system_wrappers/include/field_trial.h" 21 #include "webrtc/system_wrappers/include/field_trial.h"
20 #include "webrtc/system_wrappers/include/metrics.h" 22 #include "webrtc/system_wrappers/include/metrics.h"
21 23
22 namespace webrtc { 24 namespace webrtc {
23 namespace { 25 namespace {
24 // Periodic time interval for processing samples for |freq_offset_counter_|. 26 // Periodic time interval for processing samples for |freq_offset_counter_|.
25 const int64_t kFreqOffsetProcessIntervalMs = 40000; 27 const int64_t kFreqOffsetProcessIntervalMs = 40000;
26 28
27 // Configuration for bad call detection. 29 // Configuration for bad call detection.
28 const int kBadCallMinRequiredSamples = 10; 30 const int kBadCallMinRequiredSamples = 10;
29 const int kMinSampleLengthMs = 990; 31 const int kMinSampleLengthMs = 990;
30 const int kNumMeasurements = 10; 32 const int kNumMeasurements = 10;
31 const int kNumMeasurementsVariance = kNumMeasurements * 1.5; 33 const int kNumMeasurementsVariance = kNumMeasurements * 1.5;
32 const float kBadFraction = 0.8f; 34 const float kBadFraction = 0.8f;
33 // For fps: 35 // For fps:
34 // Low means low enough to be bad, high means high enough to be good 36 // Low means low enough to be bad, high means high enough to be good
35 const int kLowFpsThreshold = 12; 37 const int kLowFpsThreshold = 12;
36 const int kHighFpsThreshold = 14; 38 const int kHighFpsThreshold = 14;
37 // For qp and fps variance: 39 // For qp and fps variance:
38 // Low means low enough to be good, high means high enough to be bad 40 // Low means low enough to be good, high means high enough to be bad
39 const int kLowQpThresholdVp8 = 60; 41 const int kLowQpThresholdVp8 = 60;
40 const int kHighQpThresholdVp8 = 70; 42 const int kHighQpThresholdVp8 = 70;
41 const int kLowVarianceThreshold = 1; 43 const int kLowVarianceThreshold = 1;
42 const int kHighVarianceThreshold = 2; 44 const int kHighVarianceThreshold = 2;
45
46 // How large window we use to calculate the framerate/bitrate.
47 const int kRateStatisticsWindowSizeMs = 1000;
43 } // namespace 48 } // namespace
44 49
45 ReceiveStatisticsProxy::ReceiveStatisticsProxy( 50 ReceiveStatisticsProxy::ReceiveStatisticsProxy(
46 const VideoReceiveStream::Config* config, 51 const VideoReceiveStream::Config* config,
47 Clock* clock) 52 Clock* clock)
48 : clock_(clock), 53 : clock_(clock),
49 config_(*config), 54 config_(*config),
50 start_ms_(clock->TimeInMilliseconds()), 55 start_ms_(clock->TimeInMilliseconds()),
51 last_sample_time_(clock->TimeInMilliseconds()), 56 last_sample_time_(clock->TimeInMilliseconds()),
52 fps_threshold_(kLowFpsThreshold, 57 fps_threshold_(kLowFpsThreshold,
53 kHighFpsThreshold, 58 kHighFpsThreshold,
54 kBadFraction, 59 kBadFraction,
55 kNumMeasurements), 60 kNumMeasurements),
56 qp_threshold_(kLowQpThresholdVp8, 61 qp_threshold_(kLowQpThresholdVp8,
57 kHighQpThresholdVp8, 62 kHighQpThresholdVp8,
58 kBadFraction, 63 kBadFraction,
59 kNumMeasurements), 64 kNumMeasurements),
60 variance_threshold_(kLowVarianceThreshold, 65 variance_threshold_(kLowVarianceThreshold,
61 kHighVarianceThreshold, 66 kHighVarianceThreshold,
62 kBadFraction, 67 kBadFraction,
63 kNumMeasurementsVariance), 68 kNumMeasurementsVariance),
64 num_bad_states_(0), 69 num_bad_states_(0),
65 num_certain_states_(0), 70 num_certain_states_(0),
66 // 1000ms window, scale 1000 for ms to s. 71 // 1000ms window, scale 1000 for ms to s.
67 decode_fps_estimator_(1000, 1000), 72 decode_fps_estimator_(1000, 1000),
68 renders_fps_estimator_(1000, 1000), 73 renders_fps_estimator_(1000, 1000),
69 render_fps_tracker_(100, 10u), 74 render_fps_tracker_(100, 10u),
70 render_pixel_tracker_(100, 10u), 75 render_pixel_tracker_(100, 10u),
71 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs), 76 freq_offset_counter_(clock, nullptr, kFreqOffsetProcessIntervalMs),
72 first_report_block_time_ms_(-1) { 77 first_report_block_time_ms_(-1),
78 avg_rtt_ms_(0),
79 frame_window_accumulated_bytes_(0) {
73 stats_.ssrc = config_.rtp.remote_ssrc; 80 stats_.ssrc = config_.rtp.remote_ssrc;
74 for (auto it : config_.rtp.rtx) 81 for (auto it : config_.rtp.rtx)
75 rtx_stats_[it.second.ssrc] = StreamDataCounters(); 82 rtx_stats_[it.second.ssrc] = StreamDataCounters();
76 } 83 }
77 84
78 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { 85 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() {
79 UpdateHistograms(); 86 UpdateHistograms();
80 } 87 }
81 88
82 void ReceiveStatisticsProxy::UpdateHistograms() { 89 void ReceiveStatisticsProxy::UpdateHistograms() {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs", sync_offset_ms); 121 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs", sync_offset_ms);
115 } 122 }
116 AggregatedStats freq_offset_stats = freq_offset_counter_.GetStats(); 123 AggregatedStats freq_offset_stats = freq_offset_counter_.GetStats();
117 if (freq_offset_stats.num_samples > 0) { 124 if (freq_offset_stats.num_samples > 0) {
118 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 125 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtpToNtpFreqOffsetInKhz",
119 freq_offset_stats.average); 126 freq_offset_stats.average);
120 LOG(LS_INFO) << "WebRTC.Video.RtpToNtpFreqOffsetInKhz, " 127 LOG(LS_INFO) << "WebRTC.Video.RtpToNtpFreqOffsetInKhz, "
121 << freq_offset_stats.ToString(); 128 << freq_offset_stats.ToString();
122 } 129 }
123 130
131 if (stats_.frame_counts.key_frames > 0 ||
132 stats_.frame_counts.delta_frames > 0) {
133 float num_key_frames = stats_.frame_counts.key_frames;
134 float num_total_frames =
135 stats_.frame_counts.key_frames + stats_.frame_counts.delta_frames;
136 int key_frames_permille =
137 (num_key_frames * 1000.0f / num_total_frames + 0.5f);
138 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille",
139 key_frames_permille);
140 }
141
124 int qp = qp_counters_.vp8.Avg(kMinRequiredSamples); 142 int qp = qp_counters_.vp8.Avg(kMinRequiredSamples);
125 if (qp != -1) 143 if (qp != -1)
126 RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp); 144 RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp);
127 145
128 // TODO(asapersson): DecoderTiming() is call periodically (each 1000ms) and 146 // TODO(asapersson): DecoderTiming() is call periodically (each 1000ms) and
129 // not per frame. Change decode time to include every frame. 147 // not per frame. Change decode time to include every frame.
130 const int kMinRequiredDecodeSamples = 5; 148 const int kMinRequiredDecodeSamples = 5;
131 int decode_ms = decode_time_counter_.Avg(kMinRequiredDecodeSamples); 149 int decode_ms = decode_time_counter_.Avg(kMinRequiredDecodeSamples);
132 if (decode_ms != -1) 150 if (decode_ms != -1)
133 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms); 151 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms);
134 152
135 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") != 153 int jb_delay_ms = jitter_buffer_delay_counter_.Avg(kMinRequiredDecodeSamples);
136 "Enabled") { 154 if (jb_delay_ms != -1) {
137 int jb_delay_ms = 155 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs",
138 jitter_buffer_delay_counter_.Avg(kMinRequiredDecodeSamples); 156 jb_delay_ms);
139 if (jb_delay_ms != -1) {
140 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs",
141 jb_delay_ms);
142 }
143 } 157 }
158
144 int target_delay_ms = target_delay_counter_.Avg(kMinRequiredDecodeSamples); 159 int target_delay_ms = target_delay_counter_.Avg(kMinRequiredDecodeSamples);
145 if (target_delay_ms != -1) { 160 if (target_delay_ms != -1) {
146 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms); 161 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms);
147 } 162 }
148 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredDecodeSamples); 163 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredDecodeSamples);
149 if (current_delay_ms != -1) { 164 if (current_delay_ms != -1) {
150 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", 165 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs",
151 current_delay_ms); 166 current_delay_ms);
152 } 167 }
153 int delay_ms = delay_counter_.Avg(kMinRequiredDecodeSamples); 168 int delay_ms = delay_counter_.Avg(kMinRequiredDecodeSamples);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 qp_sample_.Reset(); 305 qp_sample_.Reset();
291 306
292 if (fps_threshold_.IsHigh() || variance_threshold_.IsHigh() || 307 if (fps_threshold_.IsHigh() || variance_threshold_.IsHigh() ||
293 qp_threshold_.IsHigh()) { 308 qp_threshold_.IsHigh()) {
294 if (any_bad) 309 if (any_bad)
295 ++num_bad_states_; 310 ++num_bad_states_;
296 ++num_certain_states_; 311 ++num_certain_states_;
297 } 312 }
298 } 313 }
299 314
315 void ReceiveStatisticsProxy::UpdateFrameAndBitrate(int64_t now_ms) const {
316 int64_t old_frames_ms = now_ms - kRateStatisticsWindowSizeMs;
317 while (!frame_window_.empty() &&
318 frame_window_.begin()->first < old_frames_ms) {
319 frame_window_accumulated_bytes_ -= frame_window_.begin()->second;
320 frame_window_.erase(frame_window_.begin());
321 }
322
323 size_t framerate =
324 (frame_window_.size() * 1000 + 500) / kRateStatisticsWindowSizeMs;
325 size_t bitrate_bps =
326 frame_window_accumulated_bytes_ * 8000 / kRateStatisticsWindowSizeMs;
327 stats_.network_frame_rate = static_cast<int>(framerate);
328 stats_.total_bitrate_bps = static_cast<int>(bitrate_bps);
329 }
330
300 VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { 331 VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const {
301 rtc::CritScope lock(&crit_); 332 rtc::CritScope lock(&crit_);
333 UpdateFrameAndBitrate(clock_->TimeInMilliseconds());
302 return stats_; 334 return stats_;
303 } 335 }
304 336
305 void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) { 337 void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) {
306 rtc::CritScope lock(&crit_); 338 rtc::CritScope lock(&crit_);
307 stats_.current_payload_type = payload_type; 339 stats_.current_payload_type = payload_type;
308 } 340 }
309 341
310 void ReceiveStatisticsProxy::OnDecoderImplementationName( 342 void ReceiveStatisticsProxy::OnDecoderImplementationName(
311 const char* implementation_name) { 343 const char* implementation_name) {
312 rtc::CritScope lock(&crit_); 344 rtc::CritScope lock(&crit_);
313 stats_.decoder_implementation_name = implementation_name; 345 stats_.decoder_implementation_name = implementation_name;
314 } 346 }
315 void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate, 347 void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate,
316 unsigned int bitrate_bps) { 348 unsigned int bitrate_bps) {
317 rtc::CritScope lock(&crit_); 349 rtc::CritScope lock(&crit_);
318 if (stats_.rtp_stats.first_packet_time_ms != -1) 350 if (stats_.rtp_stats.first_packet_time_ms != -1)
319 QualitySample(); 351 QualitySample();
320 stats_.network_frame_rate = framerate;
321 stats_.total_bitrate_bps = bitrate_bps;
322 } 352 }
323 353
324 void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms, 354 void ReceiveStatisticsProxy::OnFrameBufferTimingsUpdated(
325 int max_decode_ms, 355 int decode_ms,
326 int current_delay_ms, 356 int max_decode_ms,
327 int target_delay_ms, 357 int current_delay_ms,
328 int jitter_buffer_ms, 358 int target_delay_ms,
329 int min_playout_delay_ms, 359 int jitter_buffer_ms,
330 int render_delay_ms, 360 int min_playout_delay_ms,
331 int64_t rtt_ms) { 361 int render_delay_ms) {
332 rtc::CritScope lock(&crit_); 362 rtc::CritScope lock(&crit_);
333 stats_.decode_ms = decode_ms; 363 stats_.decode_ms = decode_ms;
334 stats_.max_decode_ms = max_decode_ms; 364 stats_.max_decode_ms = max_decode_ms;
335 stats_.current_delay_ms = current_delay_ms; 365 stats_.current_delay_ms = current_delay_ms;
336 stats_.target_delay_ms = target_delay_ms; 366 stats_.target_delay_ms = target_delay_ms;
337 stats_.jitter_buffer_ms = jitter_buffer_ms; 367 stats_.jitter_buffer_ms = jitter_buffer_ms;
338 stats_.min_playout_delay_ms = min_playout_delay_ms; 368 stats_.min_playout_delay_ms = min_playout_delay_ms;
339 stats_.render_delay_ms = render_delay_ms; 369 stats_.render_delay_ms = render_delay_ms;
340 decode_time_counter_.Add(decode_ms); 370 decode_time_counter_.Add(decode_ms);
341 jitter_buffer_delay_counter_.Add(jitter_buffer_ms); 371 jitter_buffer_delay_counter_.Add(jitter_buffer_ms);
342 target_delay_counter_.Add(target_delay_ms); 372 target_delay_counter_.Add(target_delay_ms);
343 current_delay_counter_.Add(current_delay_ms); 373 current_delay_counter_.Add(current_delay_ms);
344 // Network delay (rtt/2) + target_delay_ms (jitter delay + decode time + 374 // Network delay (rtt/2) + target_delay_ms (jitter delay + decode time +
345 // render delay). 375 // render delay).
346 delay_counter_.Add(target_delay_ms + rtt_ms / 2); 376 delay_counter_.Add(target_delay_ms + avg_rtt_ms_ / 2);
347 } 377 }
348 378
349 void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated( 379 void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated(
350 uint32_t ssrc, 380 uint32_t ssrc,
351 const RtcpPacketTypeCounter& packet_counter) { 381 const RtcpPacketTypeCounter& packet_counter) {
352 rtc::CritScope lock(&crit_); 382 rtc::CritScope lock(&crit_);
353 if (stats_.ssrc != ssrc) 383 if (stats_.ssrc != ssrc)
354 return; 384 return;
355 stats_.rtcp_packet_type_counts = packet_counter; 385 stats_.rtcp_packet_type_counts = packet_counter;
356 } 386 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 if (estimated_freq_khz < kMaxFreqKhz && estimated_freq_khz > 0.0) 471 if (estimated_freq_khz < kMaxFreqKhz && estimated_freq_khz > 0.0)
442 offset_khz = static_cast<int>(std::fabs(estimated_freq_khz - 90.0) + 0.5); 472 offset_khz = static_cast<int>(std::fabs(estimated_freq_khz - 90.0) + 0.5);
443 473
444 freq_offset_counter_.Add(offset_khz); 474 freq_offset_counter_.Add(offset_khz);
445 } 475 }
446 476
447 void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate, 477 void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate,
448 uint32_t frameRate) { 478 uint32_t frameRate) {
449 } 479 }
450 480
481 void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe,
482 size_t size_bytes) {
483 rtc::CritScope lock(&crit_);
484 if (is_keyframe)
485 ++stats_.frame_counts.key_frames;
486 else
487 ++stats_.frame_counts.delta_frames;
488
489 int64_t now_ms = clock_->TimeInMilliseconds();
490 frame_window_accumulated_bytes_ += size_bytes;
491 frame_window_.insert(std::make_pair(now_ms, size_bytes));
492 UpdateFrameAndBitrate(now_ms);
493 }
494
451 void ReceiveStatisticsProxy::OnFrameCountsUpdated( 495 void ReceiveStatisticsProxy::OnFrameCountsUpdated(
452 const FrameCounts& frame_counts) { 496 const FrameCounts& frame_counts) {
453 rtc::CritScope lock(&crit_); 497 rtc::CritScope lock(&crit_);
454 stats_.frame_counts = frame_counts; 498 stats_.frame_counts = frame_counts;
455 } 499 }
456 500
457 void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) { 501 void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) {
458 rtc::CritScope lock(&crit_); 502 rtc::CritScope lock(&crit_);
459 stats_.discarded_packets = discarded_packets; 503 stats_.discarded_packets = discarded_packets;
460 } 504 }
(...skipping 21 matching lines...) Expand all
482 if (num_samples < min_required_samples || num_samples == 0) 526 if (num_samples < min_required_samples || num_samples == 0)
483 return -1; 527 return -1;
484 return static_cast<int>(sum / num_samples); 528 return static_cast<int>(sum / num_samples);
485 } 529 }
486 530
487 void ReceiveStatisticsProxy::SampleCounter::Reset() { 531 void ReceiveStatisticsProxy::SampleCounter::Reset() {
488 num_samples = 0; 532 num_samples = 0;
489 sum = 0; 533 sum = 0;
490 } 534 }
491 535
536 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms,
537 int64_t max_rtt_ms) {
538 rtc::CritScope lock(&crit_);
539 avg_rtt_ms_ = avg_rtt_ms;
540 }
541
492 } // namespace webrtc 542 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/receive_statistics_proxy.h ('k') | webrtc/video/receive_statistics_proxy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698