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

Side by Side Diff: webrtc/modules/pacing/bitrate_prober.cc

Issue 2347023002: BitrateProber: Support higher probing bitrates (Closed)
Patch Set: Rebased 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) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 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/pacing/bitrate_prober.h" 11 #include "webrtc/modules/pacing/bitrate_prober.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 14
15 #include "webrtc/base/checks.h" 15 #include "webrtc/base/checks.h"
16 #include "webrtc/base/logging.h" 16 #include "webrtc/base/logging.h"
17 #include "webrtc/modules/pacing/paced_sender.h" 17 #include "webrtc/modules/pacing/paced_sender.h"
18 18
19 namespace webrtc { 19 namespace webrtc {
20 20
21 namespace { 21 namespace {
22 22
23 // Inactivity threshold above which probing is restarted. 23 // Inactivity threshold above which probing is restarted.
24 constexpr int kInactivityThresholdMs = 5000; 24 constexpr int kInactivityThresholdMs = 5000;
25 25
26 int ComputeDeltaFromBitrate(size_t packet_size, uint32_t bitrate_bps) { 26 // A minimum interval between probes to allow scheduling to be feasible.
27 constexpr int kMinProbeDeltaMs = 1;
28
29 int ComputeDeltaFromBitrate(size_t probe_size, uint32_t bitrate_bps) {
27 RTC_CHECK_GT(bitrate_bps, 0u); 30 RTC_CHECK_GT(bitrate_bps, 0u);
28 // Compute the time delta needed to send packet_size bytes at bitrate_bps 31 // Compute the time delta needed to send probe_size bytes at bitrate_bps
29 // bps. Result is in milliseconds. 32 // bps. Result is in milliseconds.
30 return static_cast<int>((1000ll * packet_size * 8) / bitrate_bps); 33 return static_cast<int>((1000ll * probe_size * 8) / bitrate_bps);
31 } 34 }
32 } // namespace 35 } // namespace
33 36
34 BitrateProber::BitrateProber() 37 BitrateProber::BitrateProber()
35 : probing_state_(ProbingState::kDisabled), 38 : probing_state_(ProbingState::kDisabled),
36 packet_size_last_sent_(0), 39 probe_size_last_sent_(0),
37 time_last_probe_sent_ms_(-1), 40 time_last_probe_sent_ms_(-1),
38 next_cluster_id_(0) { 41 next_cluster_id_(0) {
39 SetEnabled(true); 42 SetEnabled(true);
40 } 43 }
41 44
42 void BitrateProber::SetEnabled(bool enable) { 45 void BitrateProber::SetEnabled(bool enable) {
43 if (enable) { 46 if (enable) {
44 if (probing_state_ == ProbingState::kDisabled) { 47 if (probing_state_ == ProbingState::kDisabled) {
45 probing_state_ = ProbingState::kInactive; 48 probing_state_ = ProbingState::kInactive;
46 LOG(LS_INFO) << "Bandwidth probing enabled, set to inactive"; 49 LOG(LS_INFO) << "Bandwidth probing enabled, set to inactive";
(...skipping 11 matching lines...) Expand all
58 void BitrateProber::OnIncomingPacket(size_t packet_size) { 61 void BitrateProber::OnIncomingPacket(size_t packet_size) {
59 // Don't initialize probing unless we have something large enough to start 62 // Don't initialize probing unless we have something large enough to start
60 // probing. 63 // probing.
61 if (probing_state_ == ProbingState::kInactive && 64 if (probing_state_ == ProbingState::kInactive &&
62 !clusters_.empty() && 65 !clusters_.empty() &&
63 packet_size >= PacedSender::kMinProbePacketSize) { 66 packet_size >= PacedSender::kMinProbePacketSize) {
64 probing_state_ = ProbingState::kActive; 67 probing_state_ = ProbingState::kActive;
65 } 68 }
66 } 69 }
67 70
68 void BitrateProber::CreateProbeCluster(int bitrate_bps, int num_packets) { 71 void BitrateProber::CreateProbeCluster(int bitrate_bps, int num_probes) {
69 RTC_DCHECK(probing_state_ != ProbingState::kDisabled); 72 RTC_DCHECK(probing_state_ != ProbingState::kDisabled);
70 ProbeCluster cluster; 73 ProbeCluster cluster;
71 cluster.max_probe_packets = num_packets; 74 cluster.max_probes = num_probes;
72 cluster.probe_bitrate_bps = bitrate_bps; 75 cluster.probe_bitrate_bps = bitrate_bps;
73 cluster.id = next_cluster_id_++; 76 cluster.id = next_cluster_id_++;
74 clusters_.push(cluster); 77 clusters_.push(cluster);
75 LOG(LS_INFO) << "Probe cluster (bitrate:packets): (" 78 LOG(LS_INFO) << "Probe cluster (bitrate:probes): ("
76 << cluster.probe_bitrate_bps << ":" << cluster.max_probe_packets 79 << cluster.probe_bitrate_bps << ":" << cluster.max_probes
77 << ") "; 80 << ") ";
78 if (probing_state_ != ProbingState::kActive) 81 if (probing_state_ != ProbingState::kActive)
79 probing_state_ = ProbingState::kInactive; 82 probing_state_ = ProbingState::kInactive;
80 } 83 }
81 84
82 void BitrateProber::ResetState() { 85 void BitrateProber::ResetState() {
83 time_last_probe_sent_ms_ = -1; 86 time_last_probe_sent_ms_ = -1;
84 packet_size_last_sent_ = 0; 87 probe_size_last_sent_ = 0;
85 88
86 // Recreate all probing clusters. 89 // Recreate all probing clusters.
87 std::queue<ProbeCluster> clusters; 90 std::queue<ProbeCluster> clusters;
88 clusters.swap(clusters_); 91 clusters.swap(clusters_);
89 while (!clusters.empty()) { 92 while (!clusters.empty()) {
90 CreateProbeCluster(clusters.front().probe_bitrate_bps, 93 CreateProbeCluster(clusters.front().probe_bitrate_bps,
91 clusters.front().max_probe_packets); 94 clusters.front().max_probes);
92 clusters.pop(); 95 clusters.pop();
93 } 96 }
94 // If its enabled, reset to inactive. 97 // If its enabled, reset to inactive.
95 if (probing_state_ != ProbingState::kDisabled) 98 if (probing_state_ != ProbingState::kDisabled)
96 probing_state_ = ProbingState::kInactive; 99 probing_state_ = ProbingState::kInactive;
97 } 100 }
98 101
99 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) { 102 int BitrateProber::TimeUntilNextProbe(int64_t now_ms) {
100 // Probing is not active or probing is already complete. 103 // Probing is not active or probing is already complete.
101 if (probing_state_ != ProbingState::kActive || clusters_.empty()) 104 if (probing_state_ != ProbingState::kActive || clusters_.empty())
102 return -1; 105 return -1;
103 // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent. 106 // time_last_probe_sent_ms_ of -1 indicates no probes have yet been sent.
104 int64_t elapsed_time_ms; 107 int64_t elapsed_time_ms;
105 if (time_last_probe_sent_ms_ == -1) { 108 if (time_last_probe_sent_ms_ == -1) {
106 elapsed_time_ms = 0; 109 elapsed_time_ms = 0;
107 } else { 110 } else {
108 elapsed_time_ms = now_ms - time_last_probe_sent_ms_; 111 elapsed_time_ms = now_ms - time_last_probe_sent_ms_;
109 } 112 }
110 // If no probes have been sent for a while, abort current probing and 113 // If no probes have been sent for a while, abort current probing and
111 // reset. 114 // reset.
112 if (elapsed_time_ms > kInactivityThresholdMs) { 115 if (elapsed_time_ms > kInactivityThresholdMs) {
113 ResetState(); 116 ResetState();
114 return -1; 117 return -1;
115 } 118 }
116 // We will send the first probe packet immediately if no packet has been 119 // We will send the first probe packet immediately if no packet has been
117 // sent before. 120 // sent before.
118 int time_until_probe_ms = 0; 121 int time_until_probe_ms = 0;
119 if (packet_size_last_sent_ != 0 && probing_state_ == ProbingState::kActive) { 122 if (probe_size_last_sent_ != 0 && probing_state_ == ProbingState::kActive) {
120 int next_delta_ms = ComputeDeltaFromBitrate( 123 int next_delta_ms = ComputeDeltaFromBitrate(
121 packet_size_last_sent_, clusters_.front().probe_bitrate_bps); 124 probe_size_last_sent_, clusters_.front().probe_bitrate_bps);
122 time_until_probe_ms = next_delta_ms - elapsed_time_ms; 125 time_until_probe_ms = next_delta_ms - elapsed_time_ms;
123 // There is no point in trying to probe with less than 1 ms between packets
124 // as it essentially means trying to probe at infinite bandwidth.
125 const int kMinProbeDeltaMs = 1;
126 // If we have waited more than 3 ms for a new packet to probe with we will 126 // If we have waited more than 3 ms for a new packet to probe with we will
127 // consider this probing session over. 127 // consider this probing session over.
128 const int kMaxProbeDelayMs = 3; 128 const int kMaxProbeDelayMs = 3;
129 if (next_delta_ms < kMinProbeDeltaMs || 129 if (next_delta_ms < kMinProbeDeltaMs ||
130 time_until_probe_ms < -kMaxProbeDelayMs) { 130 time_until_probe_ms < -kMaxProbeDelayMs) {
131 probing_state_ = ProbingState::kSuspended; 131 probing_state_ = ProbingState::kSuspended;
132 LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend"; 132 LOG(LS_INFO) << "Delta too small or missed probing accurately, suspend";
133 time_until_probe_ms = 0; 133 time_until_probe_ms = 0;
134 } 134 }
135 } 135 }
136 return std::max(time_until_probe_ms, 0); 136 return std::max(time_until_probe_ms, 0);
137 } 137 }
138 138
139 int BitrateProber::CurrentClusterId() const { 139 int BitrateProber::CurrentClusterId() const {
140 RTC_DCHECK(!clusters_.empty()); 140 RTC_DCHECK(!clusters_.empty());
141 RTC_DCHECK(ProbingState::kActive == probing_state_); 141 RTC_DCHECK(ProbingState::kActive == probing_state_);
142 return clusters_.front().id; 142 return clusters_.front().id;
143 } 143 }
144 144
145 size_t BitrateProber::RecommendedPacketSize() const { 145 // Probe size is recommended based on the probe bitrate required. We choose
146 return packet_size_last_sent_; 146 // a minimum of twice |kMinProbeDeltaMs| interval to allow scheduling to be
147 // feasible.
148 size_t BitrateProber::RecommendedMinProbeSize() const {
149 RTC_DCHECK(!clusters_.empty());
150 return clusters_.front().probe_bitrate_bps * 2 * kMinProbeDeltaMs /
151 (8 * 1000);
147 } 152 }
148 153
149 void BitrateProber::PacketSent(int64_t now_ms, size_t packet_size) { 154 void BitrateProber::ProbeSent(int64_t now_ms, size_t bytes) {
150 assert(packet_size > 0); 155 RTC_DCHECK(probing_state_ == ProbingState::kActive);
151 if (packet_size < PacedSender::kMinProbePacketSize) 156 RTC_DCHECK_GT(bytes, 0u);
152 return; 157 probe_size_last_sent_ = bytes;
153 packet_size_last_sent_ = packet_size;
154 if (probing_state_ != ProbingState::kActive)
155 return;
156 time_last_probe_sent_ms_ = now_ms; 158 time_last_probe_sent_ms_ = now_ms;
157 if (!clusters_.empty()) { 159 if (!clusters_.empty()) {
158 ProbeCluster* cluster = &clusters_.front(); 160 ProbeCluster* cluster = &clusters_.front();
159 ++cluster->sent_probe_packets; 161 ++cluster->sent_probes;
160 if (cluster->sent_probe_packets == cluster->max_probe_packets) 162 if (cluster->sent_probes == cluster->max_probes)
161 clusters_.pop(); 163 clusters_.pop();
162 if (clusters_.empty()) 164 if (clusters_.empty())
163 probing_state_ = ProbingState::kSuspended; 165 probing_state_ = ProbingState::kSuspended;
164 } 166 }
165 } 167 }
166 } // namespace webrtc 168 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/pacing/bitrate_prober.h ('k') | webrtc/modules/pacing/bitrate_prober_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698