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