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

Side by Side Diff: webrtc/modules/congestion_controller/delay_based_bwe.cc

Issue 2366333003: Fix race / crash in OnNetworkRouteChanged(). (Closed)
Patch Set: . Created 4 years, 2 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) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 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/modules/congestion_controller/delay_based_bwe.h" 11 #include "webrtc/modules/congestion_controller/delay_based_bwe.h"
12 12
13 #include <math.h> 13 #include <math.h>
14 14
15 #include <algorithm> 15 #include <algorithm>
16 16
17 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/constructormagic.h" 18 #include "webrtc/base/constructormagic.h"
19 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
20 #include "webrtc/base/thread_annotations.h" 20 #include "webrtc/base/thread_annotations.h"
21 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" 21 #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
22 #include "webrtc/modules/pacing/paced_sender.h" 22 #include "webrtc/modules/pacing/paced_sender.h"
23 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h" 23 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h"
24 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
25 #include "webrtc/system_wrappers/include/metrics.h" 24 #include "webrtc/system_wrappers/include/metrics.h"
26 #include "webrtc/typedefs.h" 25 #include "webrtc/typedefs.h"
27 26
28 namespace { 27 namespace {
29 constexpr int kTimestampGroupLengthMs = 5; 28 constexpr int kTimestampGroupLengthMs = 5;
30 constexpr int kAbsSendTimeFraction = 18; 29 constexpr int kAbsSendTimeFraction = 18;
31 constexpr int kAbsSendTimeInterArrivalUpshift = 8; 30 constexpr int kAbsSendTimeInterArrivalUpshift = 8;
32 constexpr int kInterArrivalShift = 31 constexpr int kInterArrivalShift =
33 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; 32 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift;
34 constexpr double kTimestampToMs = 33 constexpr double kTimestampToMs =
35 1000.0 / static_cast<double>(1 << kInterArrivalShift); 34 1000.0 / static_cast<double>(1 << kInterArrivalShift);
36 // This ssrc is used to fulfill the current API but will be removed 35 // This ssrc is used to fulfill the current API but will be removed
37 // after the API has been changed. 36 // after the API has been changed.
38 constexpr uint32_t kFixedSsrc = 0; 37 constexpr uint32_t kFixedSsrc = 0;
39 } // namespace 38 } // namespace
40 39
41 namespace webrtc { 40 namespace webrtc {
42 41
43 DelayBasedBwe::DelayBasedBwe(RemoteBitrateObserver* observer, Clock* clock) 42 DelayBasedBwe::DelayBasedBwe(Clock* clock)
44 : clock_(clock), 43 : clock_(clock),
45 observer_(observer),
46 inter_arrival_(), 44 inter_arrival_(),
47 estimator_(), 45 estimator_(),
48 detector_(OverUseDetectorOptions()), 46 detector_(OverUseDetectorOptions()),
49 incoming_bitrate_(kBitrateWindowMs, 8000), 47 incoming_bitrate_(kBitrateWindowMs, 8000),
50 last_update_ms_(-1), 48 last_update_ms_(-1),
51 last_seen_packet_ms_(-1), 49 last_seen_packet_ms_(-1),
52 uma_recorded_(false) { 50 uma_recorded_(false) {
53 RTC_DCHECK(observer_);
54 network_thread_.DetachFromThread(); 51 network_thread_.DetachFromThread();
55 } 52 }
56 53
57 void DelayBasedBwe::IncomingPacketFeedbackVector( 54 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
58 const std::vector<PacketInfo>& packet_feedback_vector) { 55 const std::vector<PacketInfo>& packet_feedback_vector) {
59 RTC_DCHECK(network_thread_.CalledOnValidThread()); 56 RTC_DCHECK(network_thread_.CalledOnValidThread());
60 if (!uma_recorded_) { 57 if (!uma_recorded_) {
61 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, 58 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
62 BweNames::kSendSideTransportSeqNum, 59 BweNames::kSendSideTransportSeqNum,
63 BweNames::kBweNamesMax); 60 BweNames::kBweNamesMax);
64 uma_recorded_ = true; 61 uma_recorded_ = true;
65 } 62 }
63 Result aggregated_result;
66 for (const auto& packet_info : packet_feedback_vector) { 64 for (const auto& packet_info : packet_feedback_vector) {
67 IncomingPacketInfo(packet_info); 65 Result result = IncomingPacketInfo(packet_info);
66 if (result.updated)
67 aggregated_result = result;
68 } 68 }
69 return aggregated_result;
69 } 70 }
70 71
71 void DelayBasedBwe::IncomingPacketInfo(const PacketInfo& info) { 72 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo(
73 const PacketInfo& info) {
74 // printf("Acked: %ld\n", info.payload_size);
72 int64_t now_ms = clock_->TimeInMilliseconds(); 75 int64_t now_ms = clock_->TimeInMilliseconds();
73 76
74 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms); 77 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms);
75 bool delay_based_bwe_changed = false; 78 Result result;
76 uint32_t target_bitrate_bps = 0; 79 // Reset if the stream has timed out.
77 { 80 if (last_seen_packet_ms_ == -1 ||
78 rtc::CritScope lock(&crit_); 81 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) {
82 inter_arrival_.reset(new InterArrival(
83 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
84 kTimestampToMs, true));
85 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions()));
86 }
87 last_seen_packet_ms_ = now_ms;
79 88
80 // Reset if the stream has timed out. 89 uint32_t send_time_24bits =
81 if (last_seen_packet_ms_ == -1 || 90 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms)
82 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { 91 << kAbsSendTimeFraction) +
83 inter_arrival_.reset(new InterArrival( 92 500) /
84 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000, 93 1000) &
85 kTimestampToMs, true)); 94 0x00FFFFFF;
86 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); 95 // Shift up send time to use the full 32 bits that inter_arrival works with,
87 } 96 // so wrapping works properly.
88 last_seen_packet_ms_ = now_ms; 97 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
89 98
90 uint32_t send_time_24bits = 99 uint32_t ts_delta = 0;
91 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms) 100 int64_t t_delta = 0;
92 << kAbsSendTimeFraction) + 101 int size_delta = 0;
93 500) / 102 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms,
94 1000) & 103 info.payload_size, &ts_delta, &t_delta,
95 0x00FFFFFF; 104 &size_delta)) {
96 // Shift up send time to use the full 32 bits that inter_arrival works with, 105 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
97 // so wrapping works properly. 106 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State(),
98 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; 107 info.arrival_time_ms);
99 108 detector_.Detect(estimator_->offset(), ts_delta_ms,
100 uint32_t ts_delta = 0; 109 estimator_->num_of_deltas(), info.arrival_time_ms);
101 int64_t t_delta = 0;
102 int size_delta = 0;
103 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms,
104 info.payload_size, &ts_delta, &t_delta,
105 &size_delta)) {
106 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
107 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State(),
108 info.arrival_time_ms);
109 detector_.Detect(estimator_->offset(), ts_delta_ms,
110 estimator_->num_of_deltas(), info.arrival_time_ms);
111 }
112
113 int probing_bps = 0;
114 if (info.probe_cluster_id != PacketInfo::kNotAProbe) {
115 probing_bps =
116 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info);
117 }
118
119 // Currently overusing the bandwidth.
120 if (detector_.State() == kBwOverusing) {
121 rtc::Optional<uint32_t> incoming_rate =
122 incoming_bitrate_.Rate(info.arrival_time_ms);
123 if (incoming_rate &&
124 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) {
125 delay_based_bwe_changed =
126 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
127 }
128 } else if (probing_bps > 0) {
129 // No overuse, but probing measured a bitrate.
130 remote_rate_.SetEstimate(probing_bps, info.arrival_time_ms);
131 observer_->OnProbeBitrate(probing_bps);
132 delay_based_bwe_changed =
133 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
134 }
135 if (!delay_based_bwe_changed &&
136 (last_update_ms_ == -1 ||
137 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval())) {
138 delay_based_bwe_changed =
139 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps);
140 }
141 } 110 }
142 111
143 if (delay_based_bwe_changed) { 112 int probing_bps = 0;
113 if (info.probe_cluster_id != PacketInfo::kNotAProbe) {
114 probing_bps =
115 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info);
116 }
117
118 // Currently overusing the bandwidth.
119 if (detector_.State() == kBwOverusing) {
120 rtc::Optional<uint32_t> incoming_rate =
121 incoming_bitrate_.Rate(info.arrival_time_ms);
122 if (incoming_rate &&
123 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) {
124 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms,
125 &result.target_bitrate_bps);
126 }
127 } else if (probing_bps > 0) {
128 // No overuse, but probing measured a bitrate.
129 remote_rate_.SetEstimate(probing_bps, info.arrival_time_ms);
130 result.probe = true;
131 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms,
132 &result.target_bitrate_bps);
133 }
134 rtc::Optional<uint32_t> incoming_rate =
135 incoming_bitrate_.Rate(info.arrival_time_ms);
136 if (!result.updated &&
137 (last_update_ms_ == -1 ||
138 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval())) {
139 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms,
140 &result.target_bitrate_bps);
141 }
142 if (result.updated)
144 last_update_ms_ = now_ms; 143 last_update_ms_ = now_ms;
145 observer_->OnReceiveBitrateChanged({kFixedSsrc}, target_bitrate_bps); 144
146 } 145 return result;
147 } 146 }
148 147
149 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, 148 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms,
150 int64_t now_ms, 149 int64_t now_ms,
151 uint32_t* target_bitrate_bps) { 150 uint32_t* target_bitrate_bps) {
152 // The first overuse should immediately trigger a new estimate. 151 // The first overuse should immediately trigger a new estimate.
153 // We also have to update the estimate immediately if we are overusing 152 // We also have to update the estimate immediately if we are overusing
154 // and the target bitrate is too high compared to what we are receiving. 153 // and the target bitrate is too high compared to what we are receiving.
155 const RateControlInput input(detector_.State(), 154 const RateControlInput input(detector_.State(),
156 incoming_bitrate_.Rate(arrival_time_ms), 155 incoming_bitrate_.Rate(arrival_time_ms),
157 estimator_->var_noise()); 156 estimator_->var_noise());
158 remote_rate_.Update(&input, now_ms); 157 remote_rate_.Update(&input, now_ms);
159 *target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms); 158 *target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms);
160 return remote_rate_.ValidEstimate(); 159 return remote_rate_.ValidEstimate();
161 } 160 }
162 161
163 void DelayBasedBwe::Process() {}
164
165 int64_t DelayBasedBwe::TimeUntilNextProcess() {
166 const int64_t kDisabledModuleTime = 1000;
167 return kDisabledModuleTime;
168 }
169
170 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { 162 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
171 rtc::CritScope lock(&crit_);
172 remote_rate_.SetRtt(avg_rtt_ms); 163 remote_rate_.SetRtt(avg_rtt_ms);
173 } 164 }
174 165
175 void DelayBasedBwe::RemoveStream(uint32_t ssrc) {}
176
177 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, 166 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
178 uint32_t* bitrate_bps) const { 167 uint32_t* bitrate_bps) const {
179 // Currently accessed from both the process thread (see 168 // Currently accessed from both the process thread (see
180 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see 169 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see
181 // Call::GetStats()). Should in the future only be accessed from a single 170 // Call::GetStats()). Should in the future only be accessed from a single
182 // thread. 171 // thread.
183 RTC_DCHECK(ssrcs); 172 RTC_DCHECK(ssrcs);
184 RTC_DCHECK(bitrate_bps); 173 RTC_DCHECK(bitrate_bps);
185 rtc::CritScope lock(&crit_);
186 if (!remote_rate_.ValidEstimate()) 174 if (!remote_rate_.ValidEstimate())
187 return false; 175 return false;
188 176
189 *ssrcs = {kFixedSsrc}; 177 *ssrcs = {kFixedSsrc};
190 *bitrate_bps = remote_rate_.LatestEstimate(); 178 *bitrate_bps = remote_rate_.LatestEstimate();
191 return true; 179 return true;
192 } 180 }
193 181
194 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { 182 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
195 // Called from both the configuration thread and the network thread. Shouldn't 183 // Called from both the configuration thread and the network thread. Shouldn't
196 // be called from the network thread in the future. 184 // be called from the network thread in the future.
197 rtc::CritScope lock(&crit_);
198 remote_rate_.SetMinBitrate(min_bitrate_bps); 185 remote_rate_.SetMinBitrate(min_bitrate_bps);
199 } 186 }
200 } // namespace webrtc 187 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698