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

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

Issue 2997883002: Video/Screenshare loopback tool.
Patch Set: Rebase Created 3 years, 3 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/probe_bitrate_estimator.h" 11 #include "webrtc/modules/congestion_controller/probe_bitrate_estimator.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <sstream>
14 15
15 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" 16 #include "webrtc/logging/rtc_event_log/rtc_event_log.h"
16 #include "webrtc/rtc_base/checks.h" 17 #include "webrtc/rtc_base/checks.h"
17 #include "webrtc/rtc_base/logging.h" 18 #include "webrtc/rtc_base/logging.h"
19 #include "webrtc/rtc_base/timeutils.h"
18 20
19 namespace { 21 namespace {
20 // The minumum number of probes we need to receive feedback about in percent 22 // The minumum number of probes we need to receive feedback about in percent
21 // in order to have a valid estimate. 23 // in order to have a valid estimate.
22 constexpr int kMinReceivedProbesPercent = 80; 24 constexpr int kMinReceivedProbesPercent = 80;
23 25
24 // The minumum number of bytes we need to receive feedback about in percent 26 // The minumum number of bytes we need to receive feedback about in percent
25 // in order to have a valid estimate. 27 // in order to have a valid estimate.
26 constexpr int kMinReceivedBytesPercent = 80; 28 constexpr int kMinReceivedBytesPercent = 80;
27 29
(...skipping 26 matching lines...) Expand all
54 : event_log_(event_log) {} 56 : event_log_(event_log) {}
55 57
56 ProbeBitrateEstimator::~ProbeBitrateEstimator() = default; 58 ProbeBitrateEstimator::~ProbeBitrateEstimator() = default;
57 59
58 int ProbeBitrateEstimator::HandleProbeAndEstimateBitrate( 60 int ProbeBitrateEstimator::HandleProbeAndEstimateBitrate(
59 const PacketFeedback& packet_feedback) { 61 const PacketFeedback& packet_feedback) {
60 int cluster_id = packet_feedback.pacing_info.probe_cluster_id; 62 int cluster_id = packet_feedback.pacing_info.probe_cluster_id;
61 RTC_DCHECK_NE(cluster_id, PacedPacketInfo::kNotAProbe); 63 RTC_DCHECK_NE(cluster_id, PacedPacketInfo::kNotAProbe);
62 64
63 EraseOldClusters(packet_feedback.arrival_time_ms - kMaxClusterHistoryMs); 65 EraseOldClusters(packet_feedback.arrival_time_ms - kMaxClusterHistoryMs);
66 if (start_ == 0)
67 start_ = packet_feedback.send_time_ms;
68
69 Print("Feedback:%5u id:%3d send:%8ld receive:%8ld size:%4lu",
70 packet_feedback.sequence_number,
71 packet_feedback.pacing_info.probe_cluster_id,
72 packet_feedback.send_time_ms - start_,
73 packet_feedback.arrival_time_ms - start_, packet_feedback.payload_size);
64 74
65 int payload_size_bits = packet_feedback.payload_size * 8; 75 int payload_size_bits = packet_feedback.payload_size * 8;
66 AggregatedCluster* cluster = &clusters_[cluster_id]; 76 AggregatedCluster* cluster = &clusters_[cluster_id];
67 77
68 if (packet_feedback.send_time_ms < cluster->first_send_ms) { 78 if (packet_feedback.send_time_ms < cluster->first_send_ms) {
69 cluster->first_send_ms = packet_feedback.send_time_ms; 79 cluster->first_send_ms = packet_feedback.send_time_ms;
70 } 80 }
71 if (packet_feedback.send_time_ms > cluster->last_send_ms) { 81 if (packet_feedback.send_time_ms > cluster->last_send_ms) {
72 cluster->last_send_ms = packet_feedback.send_time_ms; 82 cluster->last_send_ms = packet_feedback.send_time_ms;
73 cluster->size_last_send = payload_size_bits; 83 cluster->size_last_send = payload_size_bits;
(...skipping 17 matching lines...) Expand all
91 kMinReceivedBytesPercent / 100; 101 kMinReceivedBytesPercent / 100;
92 if (cluster->num_probes < min_probes || cluster->size_total < min_bytes * 8) 102 if (cluster->num_probes < min_probes || cluster->size_total < min_bytes * 8)
93 return -1; 103 return -1;
94 104
95 float send_interval_ms = cluster->last_send_ms - cluster->first_send_ms; 105 float send_interval_ms = cluster->last_send_ms - cluster->first_send_ms;
96 float receive_interval_ms = 106 float receive_interval_ms =
97 cluster->last_receive_ms - cluster->first_receive_ms; 107 cluster->last_receive_ms - cluster->first_receive_ms;
98 108
99 if (send_interval_ms <= 0 || send_interval_ms > kMaxProbeIntervalMs || 109 if (send_interval_ms <= 0 || send_interval_ms > kMaxProbeIntervalMs ||
100 receive_interval_ms <= 0 || receive_interval_ms > kMaxProbeIntervalMs) { 110 receive_interval_ms <= 0 || receive_interval_ms > kMaxProbeIntervalMs) {
111 std::stringstream ss1;
112 ss1 << "Probing unsuccessful, invalid send/receive interval"
113 << " [cluster id: " << cluster_id
114 << "] [send interval: " << send_interval_ms << " ms]"
115 << " [receive interval: " << receive_interval_ms << " ms]";
101 LOG(LS_INFO) << "Probing unsuccessful, invalid send/receive interval" 116 LOG(LS_INFO) << "Probing unsuccessful, invalid send/receive interval"
102 << " [cluster id: " << cluster_id 117 << " [cluster id: " << cluster_id
103 << "] [send interval: " << send_interval_ms << " ms]" 118 << "] [send interval: " << send_interval_ms << " ms]"
104 << " [receive interval: " << receive_interval_ms << " ms]"; 119 << " [receive interval: " << receive_interval_ms << " ms]";
120 Print("%s", ss1.str().c_str());
105 if (event_log_) { 121 if (event_log_) {
106 event_log_->LogProbeResultFailure(cluster_id, 122 event_log_->LogProbeResultFailure(cluster_id,
107 kInvalidSendReceiveInterval); 123 kInvalidSendReceiveInterval);
108 } 124 }
109 return -1; 125 return -1;
110 } 126 }
111 // Since the |send_interval_ms| does not include the time it takes to actually 127 // Since the |send_interval_ms| does not include the time it takes to actually
112 // send the last packet the size of the last sent packet should not be 128 // send the last packet the size of the last sent packet should not be
113 // included when calculating the send bitrate. 129 // included when calculating the send bitrate.
114 RTC_DCHECK_GT(cluster->size_total, cluster->size_last_send); 130 RTC_DCHECK_GT(cluster->size_total, cluster->size_last_send);
115 float send_size = cluster->size_total - cluster->size_last_send; 131 float send_size_bits = cluster->size_total - cluster->size_last_send;
116 float send_bps = send_size / send_interval_ms * 1000; 132 float send_bps = send_size_bits / send_interval_ms * 1000;
117 133
118 // Since the |receive_interval_ms| does not include the time it takes to 134 // Since the |receive_interval_ms| does not include the time it takes to
119 // actually receive the first packet the size of the first received packet 135 // actually receive the first packet the size of the first received packet
120 // should not be included when calculating the receive bitrate. 136 // should not be included when calculating the receive bitrate.
121 RTC_DCHECK_GT(cluster->size_total, cluster->size_first_receive); 137 RTC_DCHECK_GT(cluster->size_total, cluster->size_first_receive);
122 float receive_size = cluster->size_total - cluster->size_first_receive; 138 float receive_size_bits = cluster->size_total - cluster->size_first_receive;
123 float receive_bps = receive_size / receive_interval_ms * 1000; 139 float receive_bps = receive_size_bits / receive_interval_ms * 1000;
124 140
125 float ratio = receive_bps / send_bps; 141 float ratio = receive_bps / send_bps;
126 if (ratio > kMaxValidRatio) { 142 if (ratio > kMaxValidRatio) {
143 std::stringstream ss2;
144 ss2 << "Probing unsuccessful, receive/send ratio too high"
145 << " [cluster id: " << cluster_id << "] [send: " << send_size_bits / 8
146 << " bytes / " << send_interval_ms << " ms = " << send_bps / 1000
147 << " kb/s]"
148 << " [receive: " << receive_size_bits / 8 << " bytes / "
149 << receive_interval_ms << " ms = " << receive_bps / 1000 << " kb/s]"
150 << " [ratio: " << receive_bps / 1000 << " / " << send_bps / 1000
151 << " = " << ratio << " > kMaxValidRatio (" << kMaxValidRatio << ")]";
152 Print("%s", ss2.str().c_str());
127 LOG(LS_INFO) << "Probing unsuccessful, receive/send ratio too high" 153 LOG(LS_INFO) << "Probing unsuccessful, receive/send ratio too high"
128 << " [cluster id: " << cluster_id << "] [send: " << send_size 154 << " [cluster id: " << cluster_id
129 << " bytes / " << send_interval_ms 155 << "] [send: " << send_size_bits / 8 << " bytes / "
130 << " ms = " << send_bps / 1000 << " kb/s]" 156 << send_interval_ms << " ms = " << send_bps / 1000 << " kb/s]"
131 << " [receive: " << receive_size << " bytes / " 157 << " [receive: " << receive_size_bits / 8 << " bytes / "
132 << receive_interval_ms << " ms = " << receive_bps / 1000 158 << receive_interval_ms << " ms = " << receive_bps / 1000
133 << " kb/s]" 159 << " kb/s]"
134 << " [ratio: " << receive_bps / 1000 << " / " 160 << " [ratio: " << receive_bps / 1000 << " / "
135 << send_bps / 1000 << " = " << ratio << " > kMaxValidRatio (" 161 << send_bps / 1000 << " = " << ratio << " > kMaxValidRatio ("
136 << kMaxValidRatio << ")]"; 162 << kMaxValidRatio << ")]";
137 if (event_log_) 163 if (event_log_)
138 event_log_->LogProbeResultFailure(cluster_id, kInvalidSendReceiveRatio); 164 event_log_->LogProbeResultFailure(cluster_id, kInvalidSendReceiveRatio);
139 return -1; 165 return -1;
140 } 166 }
167 std::stringstream ss3;
168 ss3 << "Probing successful"
169 << " [cluster id: " << cluster_id << "] [send: " << send_size_bits / 8
170 << " bytes / " << send_interval_ms << " ms = " << send_bps / 1000
171 << " kb/s]"
172 << " [receive: " << receive_size_bits / 8 << " bytes / "
173 << receive_interval_ms << " ms = " << receive_bps / 1000 << " kb/s]";
141 LOG(LS_INFO) << "Probing successful" 174 LOG(LS_INFO) << "Probing successful"
142 << " [cluster id: " << cluster_id << "] [send: " << send_size 175 << " [cluster id: " << cluster_id
143 << " bytes / " << send_interval_ms << " ms = " << send_bps / 1000 176 << "] [send: " << send_size_bits / 8 << " bytes / "
144 << " kb/s]" 177 << send_interval_ms << " ms = " << send_bps / 1000 << " kb/s]"
145 << " [receive: " << receive_size << " bytes / " 178 << " [receive: " << receive_size_bits / 8 << " bytes / "
146 << receive_interval_ms << " ms = " << receive_bps / 1000 179 << receive_interval_ms << " ms = " << receive_bps / 1000
147 << " kb/s]"; 180 << " kb/s]";
148 181
149 float res = std::min(send_bps, receive_bps); 182 float res = std::min(send_bps, receive_bps);
150 // If we're receiving at significantly lower bitrate than we were sending at, 183 // If we're receiving at significantly lower bitrate than we were sending at,
151 // it suggests that we've found the true capacity of the link. In this case, 184 // it suggests that we've found the true capacity of the link. In this case,
152 // set the target bitrate slightly lower to not immediately overuse. 185 // set the target bitrate slightly lower to not immediately overuse.
153 if (receive_bps < kMinRatioForUnsaturatedLink * send_bps) { 186 if (receive_bps < kMinRatioForUnsaturatedLink * send_bps) {
154 RTC_DCHECK_GT(send_bps, receive_bps); 187 RTC_DCHECK_GT(send_bps, receive_bps);
155 res = kTargetUtilizationFraction * receive_bps; 188 res = kTargetUtilizationFraction * receive_bps;
156 } 189 }
157 if (event_log_)
158 event_log_->LogProbeResultSuccess(cluster_id, res);
159 estimated_bitrate_bps_ = rtc::Optional<int>(res); 190 estimated_bitrate_bps_ = rtc::Optional<int>(res);
191 last_estimate_update_ms_ = rtc::TimeMillis();
192 cluster_id_ = cluster_id;
193 Print("%s, estimated kbps: %d", ss3.str().c_str(),
194 *estimated_bitrate_bps_ / 1000);
160 return *estimated_bitrate_bps_; 195 return *estimated_bitrate_bps_;
161 } 196 }
162 197
163 rtc::Optional<int> 198 rtc::Optional<int> ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrateBps(
164 ProbeBitrateEstimator::FetchAndResetLastEstimatedBitrateBps() { 199 int64_t timeout) {
200 int64_t now_ms = rtc::TimeMillis();
165 rtc::Optional<int> estimated_bitrate_bps = estimated_bitrate_bps_; 201 rtc::Optional<int> estimated_bitrate_bps = estimated_bitrate_bps_;
202
203 if (!estimated_bitrate_bps || now_ms < last_estimate_update_ms_ + timeout)
204 return rtc::Optional<int>();
205
206 Print("Probe result %d kbps", *estimated_bitrate_bps / 1000);
207
208 if (event_log_)
209 event_log_->LogProbeResultSuccess(cluster_id_, *estimated_bitrate_bps);
210
166 estimated_bitrate_bps_.reset(); 211 estimated_bitrate_bps_.reset();
167 return estimated_bitrate_bps; 212 return estimated_bitrate_bps;
168 } 213 }
169 214
170 void ProbeBitrateEstimator::EraseOldClusters(int64_t timestamp_ms) { 215 void ProbeBitrateEstimator::EraseOldClusters(int64_t timestamp_ms) {
171 for (auto it = clusters_.begin(); it != clusters_.end();) { 216 for (auto it = clusters_.begin(); it != clusters_.end();) {
172 if (it->second.last_receive_ms < timestamp_ms) { 217 if (it->second.last_receive_ms < timestamp_ms) {
173 it = clusters_.erase(it); 218 it = clusters_.erase(it);
174 } else { 219 } else {
175 ++it; 220 ++it;
176 } 221 }
177 } 222 }
178 } 223 }
179 } // namespace webrtc 224 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698