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

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

Issue 2704183002: Revert of Revert 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 // TODO(brandtr): Replace |rtx_stats_| with a single instance of 81 // TODO(brandtr): Replace |rtx_stats_| with a single instance of
75 // StreamDataCounters. 82 // StreamDataCounters.
76 if (config_.rtp.rtx_ssrc) { 83 if (config_.rtp.rtx_ssrc) {
77 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters(); 84 rtx_stats_[config_.rtp.rtx_ssrc] = StreamDataCounters();
78 } 85 }
79 } 86 }
80 87
81 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() { 88 ReceiveStatisticsProxy::~ReceiveStatisticsProxy() {
82 UpdateHistograms(); 89 UpdateHistograms();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs", sync_offset_ms); 124 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs", sync_offset_ms);
118 } 125 }
119 AggregatedStats freq_offset_stats = freq_offset_counter_.GetStats(); 126 AggregatedStats freq_offset_stats = freq_offset_counter_.GetStats();
120 if (freq_offset_stats.num_samples > 0) { 127 if (freq_offset_stats.num_samples > 0) {
121 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtpToNtpFreqOffsetInKhz", 128 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtpToNtpFreqOffsetInKhz",
122 freq_offset_stats.average); 129 freq_offset_stats.average);
123 LOG(LS_INFO) << "WebRTC.Video.RtpToNtpFreqOffsetInKhz, " 130 LOG(LS_INFO) << "WebRTC.Video.RtpToNtpFreqOffsetInKhz, "
124 << freq_offset_stats.ToString(); 131 << freq_offset_stats.ToString();
125 } 132 }
126 133
134 if (stats_.frame_counts.key_frames > 0 ||
135 stats_.frame_counts.delta_frames > 0) {
136 float num_key_frames = stats_.frame_counts.key_frames;
137 float num_total_frames =
138 stats_.frame_counts.key_frames + stats_.frame_counts.delta_frames;
139 int key_frames_permille =
140 (num_key_frames * 1000.0f / num_total_frames + 0.5f);
141 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille",
142 key_frames_permille);
143 }
144
127 int qp = qp_counters_.vp8.Avg(kMinRequiredSamples); 145 int qp = qp_counters_.vp8.Avg(kMinRequiredSamples);
128 if (qp != -1) 146 if (qp != -1)
129 RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp); 147 RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp);
130 148
131 // TODO(asapersson): DecoderTiming() is call periodically (each 1000ms) and 149 // TODO(asapersson): DecoderTiming() is call periodically (each 1000ms) and
132 // not per frame. Change decode time to include every frame. 150 // not per frame. Change decode time to include every frame.
133 const int kMinRequiredDecodeSamples = 5; 151 const int kMinRequiredDecodeSamples = 5;
134 int decode_ms = decode_time_counter_.Avg(kMinRequiredDecodeSamples); 152 int decode_ms = decode_time_counter_.Avg(kMinRequiredDecodeSamples);
135 if (decode_ms != -1) 153 if (decode_ms != -1)
136 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms); 154 RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms);
137 155
138 if (field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") != 156 int jb_delay_ms = jitter_buffer_delay_counter_.Avg(kMinRequiredDecodeSamples);
139 "Enabled") { 157 if (jb_delay_ms != -1) {
140 int jb_delay_ms = 158 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs",
141 jitter_buffer_delay_counter_.Avg(kMinRequiredDecodeSamples); 159 jb_delay_ms);
142 if (jb_delay_ms != -1) {
143 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs",
144 jb_delay_ms);
145 }
146 } 160 }
161
147 int target_delay_ms = target_delay_counter_.Avg(kMinRequiredDecodeSamples); 162 int target_delay_ms = target_delay_counter_.Avg(kMinRequiredDecodeSamples);
148 if (target_delay_ms != -1) { 163 if (target_delay_ms != -1) {
149 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms); 164 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms);
150 } 165 }
151 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredDecodeSamples); 166 int current_delay_ms = current_delay_counter_.Avg(kMinRequiredDecodeSamples);
152 if (current_delay_ms != -1) { 167 if (current_delay_ms != -1) {
153 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", 168 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs",
154 current_delay_ms); 169 current_delay_ms);
155 } 170 }
156 int delay_ms = delay_counter_.Avg(kMinRequiredDecodeSamples); 171 int delay_ms = delay_counter_.Avg(kMinRequiredDecodeSamples);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 qp_sample_.Reset(); 308 qp_sample_.Reset();
294 309
295 if (fps_threshold_.IsHigh() || variance_threshold_.IsHigh() || 310 if (fps_threshold_.IsHigh() || variance_threshold_.IsHigh() ||
296 qp_threshold_.IsHigh()) { 311 qp_threshold_.IsHigh()) {
297 if (any_bad) 312 if (any_bad)
298 ++num_bad_states_; 313 ++num_bad_states_;
299 ++num_certain_states_; 314 ++num_certain_states_;
300 } 315 }
301 } 316 }
302 317
318 void ReceiveStatisticsProxy::UpdateFrameAndBitrate(int64_t now_ms) const {
319 int64_t old_frames_ms = now_ms - kRateStatisticsWindowSizeMs;
320 while (!frame_window_.empty() &&
321 frame_window_.begin()->first < old_frames_ms) {
322 frame_window_accumulated_bytes_ -= frame_window_.begin()->second;
323 frame_window_.erase(frame_window_.begin());
324 }
325
326 size_t framerate =
327 (frame_window_.size() * 1000 + 500) / kRateStatisticsWindowSizeMs;
328 size_t bitrate_bps =
329 frame_window_accumulated_bytes_ * 8000 / kRateStatisticsWindowSizeMs;
330 stats_.network_frame_rate = static_cast<int>(framerate);
331 stats_.total_bitrate_bps = static_cast<int>(bitrate_bps);
332 }
333
303 VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { 334 VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const {
304 rtc::CritScope lock(&crit_); 335 rtc::CritScope lock(&crit_);
336 UpdateFrameAndBitrate(clock_->TimeInMilliseconds());
305 return stats_; 337 return stats_;
306 } 338 }
307 339
308 void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) { 340 void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) {
309 rtc::CritScope lock(&crit_); 341 rtc::CritScope lock(&crit_);
310 stats_.current_payload_type = payload_type; 342 stats_.current_payload_type = payload_type;
311 } 343 }
312 344
313 void ReceiveStatisticsProxy::OnDecoderImplementationName( 345 void ReceiveStatisticsProxy::OnDecoderImplementationName(
314 const char* implementation_name) { 346 const char* implementation_name) {
315 rtc::CritScope lock(&crit_); 347 rtc::CritScope lock(&crit_);
316 stats_.decoder_implementation_name = implementation_name; 348 stats_.decoder_implementation_name = implementation_name;
317 } 349 }
318 void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate, 350 void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate,
319 unsigned int bitrate_bps) { 351 unsigned int bitrate_bps) {
320 rtc::CritScope lock(&crit_); 352 rtc::CritScope lock(&crit_);
321 if (stats_.rtp_stats.first_packet_time_ms != -1) 353 if (stats_.rtp_stats.first_packet_time_ms != -1)
322 QualitySample(); 354 QualitySample();
323 stats_.network_frame_rate = framerate;
324 stats_.total_bitrate_bps = bitrate_bps;
325 } 355 }
326 356
327 void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms, 357 void ReceiveStatisticsProxy::OnFrameBufferTimingsUpdated(
328 int max_decode_ms, 358 int decode_ms,
329 int current_delay_ms, 359 int max_decode_ms,
330 int target_delay_ms, 360 int current_delay_ms,
331 int jitter_buffer_ms, 361 int target_delay_ms,
332 int min_playout_delay_ms, 362 int jitter_buffer_ms,
333 int render_delay_ms, 363 int min_playout_delay_ms,
334 int64_t rtt_ms) { 364 int render_delay_ms) {
335 rtc::CritScope lock(&crit_); 365 rtc::CritScope lock(&crit_);
336 stats_.decode_ms = decode_ms; 366 stats_.decode_ms = decode_ms;
337 stats_.max_decode_ms = max_decode_ms; 367 stats_.max_decode_ms = max_decode_ms;
338 stats_.current_delay_ms = current_delay_ms; 368 stats_.current_delay_ms = current_delay_ms;
339 stats_.target_delay_ms = target_delay_ms; 369 stats_.target_delay_ms = target_delay_ms;
340 stats_.jitter_buffer_ms = jitter_buffer_ms; 370 stats_.jitter_buffer_ms = jitter_buffer_ms;
341 stats_.min_playout_delay_ms = min_playout_delay_ms; 371 stats_.min_playout_delay_ms = min_playout_delay_ms;
342 stats_.render_delay_ms = render_delay_ms; 372 stats_.render_delay_ms = render_delay_ms;
343 decode_time_counter_.Add(decode_ms); 373 decode_time_counter_.Add(decode_ms);
344 jitter_buffer_delay_counter_.Add(jitter_buffer_ms); 374 jitter_buffer_delay_counter_.Add(jitter_buffer_ms);
345 target_delay_counter_.Add(target_delay_ms); 375 target_delay_counter_.Add(target_delay_ms);
346 current_delay_counter_.Add(current_delay_ms); 376 current_delay_counter_.Add(current_delay_ms);
347 // Network delay (rtt/2) + target_delay_ms (jitter delay + decode time + 377 // Network delay (rtt/2) + target_delay_ms (jitter delay + decode time +
348 // render delay). 378 // render delay).
349 delay_counter_.Add(target_delay_ms + rtt_ms / 2); 379 delay_counter_.Add(target_delay_ms + avg_rtt_ms_ / 2);
350 } 380 }
351 381
352 void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated( 382 void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated(
353 uint32_t ssrc, 383 uint32_t ssrc,
354 const RtcpPacketTypeCounter& packet_counter) { 384 const RtcpPacketTypeCounter& packet_counter) {
355 rtc::CritScope lock(&crit_); 385 rtc::CritScope lock(&crit_);
356 if (stats_.ssrc != ssrc) 386 if (stats_.ssrc != ssrc)
357 return; 387 return;
358 stats_.rtcp_packet_type_counts = packet_counter; 388 stats_.rtcp_packet_type_counts = packet_counter;
359 } 389 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 if (estimated_freq_khz < kMaxFreqKhz && estimated_freq_khz > 0.0) 489 if (estimated_freq_khz < kMaxFreqKhz && estimated_freq_khz > 0.0)
460 offset_khz = static_cast<int>(std::fabs(estimated_freq_khz - 90.0) + 0.5); 490 offset_khz = static_cast<int>(std::fabs(estimated_freq_khz - 90.0) + 0.5);
461 491
462 freq_offset_counter_.Add(offset_khz); 492 freq_offset_counter_.Add(offset_khz);
463 } 493 }
464 494
465 void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate, 495 void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate,
466 uint32_t frameRate) { 496 uint32_t frameRate) {
467 } 497 }
468 498
499 void ReceiveStatisticsProxy::OnCompleteFrame(bool is_keyframe,
500 size_t size_bytes) {
501 rtc::CritScope lock(&crit_);
502 if (is_keyframe)
503 ++stats_.frame_counts.key_frames;
504 else
505 ++stats_.frame_counts.delta_frames;
506
507 int64_t now_ms = clock_->TimeInMilliseconds();
508 frame_window_accumulated_bytes_ += size_bytes;
509 frame_window_.insert(std::make_pair(now_ms, size_bytes));
510 UpdateFrameAndBitrate(now_ms);
511 }
512
469 void ReceiveStatisticsProxy::OnFrameCountsUpdated( 513 void ReceiveStatisticsProxy::OnFrameCountsUpdated(
470 const FrameCounts& frame_counts) { 514 const FrameCounts& frame_counts) {
471 rtc::CritScope lock(&crit_); 515 rtc::CritScope lock(&crit_);
472 stats_.frame_counts = frame_counts; 516 stats_.frame_counts = frame_counts;
473 } 517 }
474 518
475 void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) { 519 void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) {
476 rtc::CritScope lock(&crit_); 520 rtc::CritScope lock(&crit_);
477 stats_.discarded_packets = discarded_packets; 521 stats_.discarded_packets = discarded_packets;
478 } 522 }
(...skipping 21 matching lines...) Expand all
500 if (num_samples < min_required_samples || num_samples == 0) 544 if (num_samples < min_required_samples || num_samples == 0)
501 return -1; 545 return -1;
502 return static_cast<int>(sum / num_samples); 546 return static_cast<int>(sum / num_samples);
503 } 547 }
504 548
505 void ReceiveStatisticsProxy::SampleCounter::Reset() { 549 void ReceiveStatisticsProxy::SampleCounter::Reset() {
506 num_samples = 0; 550 num_samples = 0;
507 sum = 0; 551 sum = 0;
508 } 552 }
509 553
554 void ReceiveStatisticsProxy::OnRttUpdate(int64_t avg_rtt_ms,
555 int64_t max_rtt_ms) {
556 rtc::CritScope lock(&crit_);
557 avg_rtt_ms_ = avg_rtt_ms;
558 }
559
510 } // namespace webrtc 560 } // 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