OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 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 |
(...skipping 26 matching lines...) Expand all Loading... |
37 ++it; | 37 ++it; |
38 } | 38 } |
39 } | 39 } |
40 return fb_packets; | 40 return fb_packets; |
41 } | 41 } |
42 | 42 |
43 VideoSender::VideoSender(PacketProcessorListener* listener, | 43 VideoSender::VideoSender(PacketProcessorListener* listener, |
44 VideoSource* source, | 44 VideoSource* source, |
45 BandwidthEstimatorType estimator_type) | 45 BandwidthEstimatorType estimator_type) |
46 : PacketSender(listener, source->flow_id()), | 46 : PacketSender(listener, source->flow_id()), |
| 47 running_(true), |
47 source_(source), | 48 source_(source), |
48 bwe_(CreateBweSender(estimator_type, | 49 bwe_(CreateBweSender(estimator_type, |
49 source_->bits_per_second() / 1000, | 50 source_->bits_per_second() / 1000, |
50 this, | 51 this, |
51 &clock_)) { | 52 &clock_)), |
| 53 previous_sending_bitrate_(0) { |
52 modules_.push_back(bwe_.get()); | 54 modules_.push_back(bwe_.get()); |
53 } | 55 } |
54 | 56 |
55 VideoSender::~VideoSender() { | 57 VideoSender::~VideoSender() { |
56 } | 58 } |
57 | 59 |
58 void VideoSender::RunFor(int64_t time_ms, Packets* in_out) { | 60 void VideoSender::RunFor(int64_t time_ms, Packets* in_out) { |
59 std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets( | 61 std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets( |
60 in_out, clock_.TimeInMilliseconds() + time_ms, source_->flow_id()); | 62 in_out, clock_.TimeInMilliseconds() + time_ms, source_->flow_id()); |
61 ProcessFeedbackAndGeneratePackets(time_ms, &feedbacks, in_out); | 63 ProcessFeedbackAndGeneratePackets(time_ms, &feedbacks, in_out); |
62 } | 64 } |
63 | 65 |
64 void VideoSender::ProcessFeedbackAndGeneratePackets( | 66 void VideoSender::ProcessFeedbackAndGeneratePackets( |
65 int64_t time_ms, | 67 int64_t time_ms, |
66 std::list<FeedbackPacket*>* feedbacks, | 68 std::list<FeedbackPacket*>* feedbacks, |
67 Packets* packets) { | 69 Packets* packets) { |
68 do { | 70 do { |
69 // Make sure to at least run Process() below every 100 ms. | 71 // Make sure to at least run Process() below every 100 ms. |
70 int64_t time_to_run_ms = std::min<int64_t>(time_ms, 100); | 72 int64_t time_to_run_ms = std::min<int64_t>(time_ms, 100); |
71 if (!feedbacks->empty()) { | 73 if (!feedbacks->empty()) { |
72 int64_t time_until_feedback_ms = | 74 int64_t time_until_feedback_ms = |
73 feedbacks->front()->send_time_us() / 1000 - | 75 feedbacks->front()->send_time_ms() - clock_.TimeInMilliseconds(); |
74 clock_.TimeInMilliseconds(); | |
75 time_to_run_ms = | 76 time_to_run_ms = |
76 std::max<int64_t>(std::min(time_ms, time_until_feedback_ms), 0); | 77 std::max<int64_t>(std::min(time_ms, time_until_feedback_ms), 0); |
77 } | 78 } |
| 79 |
| 80 if (!running_) { |
| 81 source_->SetBitrateBps(0); |
| 82 } |
| 83 |
78 Packets generated; | 84 Packets generated; |
79 source_->RunFor(time_to_run_ms, &generated); | 85 source_->RunFor(time_to_run_ms, &generated); |
80 bwe_->OnPacketsSent(generated); | 86 bwe_->OnPacketsSent(generated); |
81 packets->merge(generated, DereferencingComparator<Packet>); | 87 packets->merge(generated, DereferencingComparator<Packet>); |
| 88 |
82 clock_.AdvanceTimeMilliseconds(time_to_run_ms); | 89 clock_.AdvanceTimeMilliseconds(time_to_run_ms); |
| 90 |
83 if (!feedbacks->empty()) { | 91 if (!feedbacks->empty()) { |
84 bwe_->GiveFeedback(*feedbacks->front()); | 92 bwe_->GiveFeedback(*feedbacks->front()); |
85 delete feedbacks->front(); | 93 delete feedbacks->front(); |
86 feedbacks->pop_front(); | 94 feedbacks->pop_front(); |
87 } | 95 } |
| 96 |
88 bwe_->Process(); | 97 bwe_->Process(); |
| 98 |
89 time_ms -= time_to_run_ms; | 99 time_ms -= time_to_run_ms; |
90 } while (time_ms > 0); | 100 } while (time_ms > 0); |
91 assert(feedbacks->empty()); | 101 assert(feedbacks->empty()); |
92 } | 102 } |
93 | 103 |
94 int VideoSender::GetFeedbackIntervalMs() const { | 104 int VideoSender::GetFeedbackIntervalMs() const { |
95 return bwe_->GetFeedbackIntervalMs(); | 105 return bwe_->GetFeedbackIntervalMs(); |
96 } | 106 } |
97 | 107 |
98 void VideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, | 108 void VideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, |
99 uint8_t fraction_lost, | 109 uint8_t fraction_lost, |
100 int64_t rtt) { | 110 int64_t rtt) { |
101 source_->SetBitrateBps(target_bitrate_bps); | 111 source_->SetBitrateBps(target_bitrate_bps); |
102 } | 112 } |
103 | 113 |
| 114 void VideoSender::Pause() { |
| 115 running_ = false; |
| 116 previous_sending_bitrate_ = TargetBitrateKbps(); |
| 117 } |
| 118 |
| 119 void VideoSender::Resume() { |
| 120 running_ = true; |
| 121 source_->SetBitrateBps(previous_sending_bitrate_); |
| 122 } |
| 123 |
| 124 uint32_t VideoSender::TargetBitrateKbps() { |
| 125 return (source_->bits_per_second() + 500) / 1000; |
| 126 } |
| 127 |
104 PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener, | 128 PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener, |
105 VideoSource* source, | 129 VideoSource* source, |
106 BandwidthEstimatorType estimator) | 130 BandwidthEstimatorType estimator) |
107 : VideoSender(listener, source, estimator), | 131 : VideoSender(listener, source, estimator), |
108 pacer_(&clock_, | 132 pacer_(&clock_, |
109 this, | 133 this, |
110 source->bits_per_second() / 1000, | 134 source->bits_per_second() / 1000, |
111 PacedSender::kDefaultPaceMultiplier * source->bits_per_second() / | 135 PacedSender::kDefaultPaceMultiplier * source->bits_per_second() / |
112 1000, | 136 1000, |
113 0) { | 137 0) { |
(...skipping 12 matching lines...) Expand all Loading... |
126 // Run process periodically to allow the packets to be paced out. | 150 // Run process periodically to allow the packets to be paced out. |
127 std::list<FeedbackPacket*> feedbacks = | 151 std::list<FeedbackPacket*> feedbacks = |
128 GetFeedbackPackets(in_out, end_time_ms, source_->flow_id()); | 152 GetFeedbackPackets(in_out, end_time_ms, source_->flow_id()); |
129 int64_t last_run_time_ms = -1; | 153 int64_t last_run_time_ms = -1; |
130 BWE_TEST_LOGGING_CONTEXT("Sender"); | 154 BWE_TEST_LOGGING_CONTEXT("Sender"); |
131 BWE_TEST_LOGGING_CONTEXT(source_->flow_id()); | 155 BWE_TEST_LOGGING_CONTEXT(source_->flow_id()); |
132 do { | 156 do { |
133 int64_t time_until_process_ms = TimeUntilNextProcess(modules_); | 157 int64_t time_until_process_ms = TimeUntilNextProcess(modules_); |
134 int64_t time_until_feedback_ms = time_ms; | 158 int64_t time_until_feedback_ms = time_ms; |
135 if (!feedbacks.empty()) | 159 if (!feedbacks.empty()) |
136 time_until_feedback_ms = | 160 time_until_feedback_ms = std::max<int64_t>( |
137 std::max<int64_t>(feedbacks.front()->send_time_us() / 1000 - | 161 feedbacks.front()->send_time_ms() - clock_.TimeInMilliseconds(), 0); |
138 clock_.TimeInMilliseconds(), | |
139 0); | |
140 | 162 |
141 int64_t time_until_next_event_ms = | 163 int64_t time_until_next_event_ms = |
142 std::min(time_until_feedback_ms, time_until_process_ms); | 164 std::min(time_until_feedback_ms, time_until_process_ms); |
143 | 165 |
144 time_until_next_event_ms = | 166 time_until_next_event_ms = |
145 std::min(source_->GetTimeUntilNextFrameMs(), time_until_next_event_ms); | 167 std::min(source_->GetTimeUntilNextFrameMs(), time_until_next_event_ms); |
146 | 168 |
147 // Never run for longer than we have been asked for. | 169 // Never run for longer than we have been asked for. |
148 if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms) | 170 if (clock_.TimeInMilliseconds() + time_until_next_event_ms > end_time_ms) |
149 time_until_next_event_ms = end_time_ms - clock_.TimeInMilliseconds(); | 171 time_until_next_event_ms = end_time_ms - clock_.TimeInMilliseconds(); |
150 | 172 |
151 // Make sure we don't get stuck if an event doesn't trigger. This typically | 173 // Make sure we don't get stuck if an event doesn't trigger. This typically |
152 // happens if the prober wants to probe, but there's no packet to send. | 174 // happens if the prober wants to probe, but there's no packet to send. |
153 if (time_until_next_event_ms == 0 && last_run_time_ms == 0) | 175 if (time_until_next_event_ms == 0 && last_run_time_ms == 0) |
154 time_until_next_event_ms = 1; | 176 time_until_next_event_ms = 1; |
155 last_run_time_ms = time_until_next_event_ms; | 177 last_run_time_ms = time_until_next_event_ms; |
156 | 178 |
157 Packets generated_packets; | 179 Packets generated_packets; |
158 source_->RunFor(time_until_next_event_ms, &generated_packets); | 180 source_->RunFor(time_until_next_event_ms, &generated_packets); |
159 if (!generated_packets.empty()) { | 181 if (!generated_packets.empty()) { |
160 for (Packet* packet : generated_packets) { | 182 for (Packet* packet : generated_packets) { |
161 MediaPacket* media_packet = static_cast<MediaPacket*>(packet); | 183 MediaPacket* media_packet = static_cast<MediaPacket*>(packet); |
162 pacer_.SendPacket(PacedSender::kNormalPriority, | 184 pacer_.SendPacket( |
163 media_packet->header().ssrc, | 185 PacedSender::kNormalPriority, media_packet->header().ssrc, |
164 media_packet->header().sequenceNumber, | 186 media_packet->header().sequenceNumber, media_packet->send_time_ms(), |
165 (media_packet->send_time_us() + 500) / 1000, | 187 media_packet->payload_size(), false); |
166 media_packet->payload_size(), false); | |
167 pacer_queue_.push_back(packet); | 188 pacer_queue_.push_back(packet); |
168 assert(pacer_queue_.size() < 10000); | 189 assert(pacer_queue_.size() < 10000); |
169 } | 190 } |
170 } | 191 } |
171 | 192 |
172 clock_.AdvanceTimeMilliseconds(time_until_next_event_ms); | 193 clock_.AdvanceTimeMilliseconds(time_until_next_event_ms); |
173 | 194 |
174 if (time_until_next_event_ms == time_until_feedback_ms) { | 195 if (time_until_next_event_ms == time_until_feedback_ms) { |
175 if (!feedbacks.empty()) { | 196 if (!feedbacks.empty()) { |
176 bwe_->GiveFeedback(*feedbacks.front()); | 197 bwe_->GiveFeedback(*feedbacks.front()); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 | 249 |
229 bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc, | 250 bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc, |
230 uint16_t sequence_number, | 251 uint16_t sequence_number, |
231 int64_t capture_time_ms, | 252 int64_t capture_time_ms, |
232 bool retransmission) { | 253 bool retransmission) { |
233 for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end(); | 254 for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end(); |
234 ++it) { | 255 ++it) { |
235 MediaPacket* media_packet = static_cast<MediaPacket*>(*it); | 256 MediaPacket* media_packet = static_cast<MediaPacket*>(*it); |
236 if (media_packet->header().sequenceNumber == sequence_number) { | 257 if (media_packet->header().sequenceNumber == sequence_number) { |
237 int64_t pace_out_time_ms = clock_.TimeInMilliseconds(); | 258 int64_t pace_out_time_ms = clock_.TimeInMilliseconds(); |
| 259 |
238 // Make sure a packet is never paced out earlier than when it was put into | 260 // Make sure a packet is never paced out earlier than when it was put into |
239 // the pacer. | 261 // the pacer. |
240 assert(pace_out_time_ms >= (media_packet->send_time_us() + 500) / 1000); | 262 assert(pace_out_time_ms >= media_packet->send_time_ms()); |
| 263 |
241 media_packet->SetAbsSendTimeMs(pace_out_time_ms); | 264 media_packet->SetAbsSendTimeMs(pace_out_time_ms); |
242 media_packet->set_send_time_us(1000 * pace_out_time_ms); | 265 media_packet->set_send_time_us(1000 * pace_out_time_ms); |
243 media_packet->set_sender_timestamp_us(1000 * pace_out_time_ms); | 266 media_packet->set_sender_timestamp_us(1000 * pace_out_time_ms); |
244 queue_.push_back(media_packet); | 267 queue_.push_back(media_packet); |
245 pacer_queue_.erase(it); | 268 pacer_queue_.erase(it); |
246 return true; | 269 return true; |
247 } | 270 } |
248 } | 271 } |
249 return false; | 272 return false; |
250 } | 273 } |
251 | 274 |
252 size_t PacedVideoSender::TimeToSendPadding(size_t bytes) { | 275 size_t PacedVideoSender::TimeToSendPadding(size_t bytes) { |
253 return 0; | 276 return 0; |
254 } | 277 } |
255 | 278 |
256 void PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, | 279 void PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, |
257 uint8_t fraction_lost, | 280 uint8_t fraction_lost, |
258 int64_t rtt) { | 281 int64_t rtt) { |
259 VideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt); | 282 VideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt); |
260 pacer_.UpdateBitrate( | 283 pacer_.UpdateBitrate( |
261 target_bitrate_bps / 1000, | 284 target_bitrate_bps / 1000, |
262 PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 0); | 285 PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 0); |
263 } | 286 } |
264 | 287 |
| 288 const int kNoLimit = std::numeric_limits<int>::max(); |
| 289 const int kPacketSizeBytes = 1200; |
| 290 |
| 291 TcpSender::TcpSender(PacketProcessorListener* listener, |
| 292 int flow_id, |
| 293 int64_t offset_ms) |
| 294 : TcpSender(listener, flow_id, offset_ms, kNoLimit) { |
| 295 } |
| 296 |
| 297 TcpSender::TcpSender(PacketProcessorListener* listener, |
| 298 int flow_id, |
| 299 int64_t offset_ms, |
| 300 int send_limit_bytes) |
| 301 : PacketSender(listener, flow_id), |
| 302 cwnd_(10), |
| 303 ssthresh_(kNoLimit), |
| 304 ack_received_(false), |
| 305 last_acked_seq_num_(0), |
| 306 next_sequence_number_(0), |
| 307 offset_ms_(offset_ms), |
| 308 last_reduction_time_ms_(-1), |
| 309 last_rtt_ms_(0), |
| 310 total_sent_bytes_(0), |
| 311 send_limit_bytes_(send_limit_bytes), |
| 312 running_(true), |
| 313 last_generated_packets_ms_(0), |
| 314 num_recent_sent_packets_(0), |
| 315 bitrate_kbps_(0) { |
| 316 } |
| 317 |
265 void TcpSender::RunFor(int64_t time_ms, Packets* in_out) { | 318 void TcpSender::RunFor(int64_t time_ms, Packets* in_out) { |
266 if (clock_.TimeInMilliseconds() + time_ms < offset_ms_) { | 319 if (clock_.TimeInMilliseconds() + time_ms < offset_ms_) { |
267 clock_.AdvanceTimeMilliseconds(time_ms); | 320 clock_.AdvanceTimeMilliseconds(time_ms); |
| 321 if (running_) { |
| 322 running_ = false; |
| 323 } |
268 return; | 324 return; |
269 } | 325 } |
| 326 |
| 327 if (!running_) { |
| 328 running_ = true; |
| 329 } |
| 330 |
270 int64_t start_time_ms = clock_.TimeInMilliseconds(); | 331 int64_t start_time_ms = clock_.TimeInMilliseconds(); |
271 BWE_TEST_LOGGING_CONTEXT("Sender"); | 332 BWE_TEST_LOGGING_CONTEXT("Sender"); |
272 BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin()); | 333 BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin()); |
273 | 334 |
274 std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets( | 335 std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets( |
275 in_out, clock_.TimeInMilliseconds() + time_ms, *flow_ids().begin()); | 336 in_out, clock_.TimeInMilliseconds() + time_ms, *flow_ids().begin()); |
276 // The number of packets which are sent in during time_ms depends on the | 337 // The number of packets which are sent in during time_ms depends on the |
277 // number of packets in_flight_ and the max number of packets in flight | 338 // number of packets in_flight_ and the max number of packets in flight |
278 // (cwnd_). Therefore SendPackets() isn't directly dependent on time_ms. | 339 // (cwnd_). Therefore SendPackets() isn't directly dependent on time_ms. |
279 for (FeedbackPacket* fb : feedbacks) { | 340 for (FeedbackPacket* fb : feedbacks) { |
280 clock_.AdvanceTimeMilliseconds(fb->send_time_us() / 1000 - | 341 clock_.AdvanceTimeMilliseconds(fb->send_time_ms() - |
281 clock_.TimeInMilliseconds()); | 342 clock_.TimeInMilliseconds()); |
282 last_rtt_ms_ = fb->send_time_us() / 1000 - fb->latest_send_time_ms(); | 343 last_rtt_ms_ = fb->send_time_ms() - fb->latest_send_time_ms(); |
283 UpdateCongestionControl(fb); | 344 UpdateCongestionControl(fb); |
284 SendPackets(in_out); | 345 SendPackets(in_out); |
285 } | 346 } |
286 | 347 |
287 for (auto it = in_flight_.begin(); it != in_flight_.end();) { | 348 for (auto it = in_flight_.begin(); it != in_flight_.end();) { |
288 if (it->time_ms < clock_.TimeInMilliseconds() - 1000) | 349 if (it->time_ms < clock_.TimeInMilliseconds() - 1000) |
289 in_flight_.erase(it++); | 350 in_flight_.erase(it++); |
290 else | 351 else |
291 ++it; | 352 ++it; |
292 } | 353 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 void TcpSender::HandleLoss() { | 413 void TcpSender::HandleLoss() { |
353 if (clock_.TimeInMilliseconds() - last_reduction_time_ms_ < last_rtt_ms_) | 414 if (clock_.TimeInMilliseconds() - last_reduction_time_ms_ < last_rtt_ms_) |
354 return; | 415 return; |
355 last_reduction_time_ms_ = clock_.TimeInMilliseconds(); | 416 last_reduction_time_ms_ = clock_.TimeInMilliseconds(); |
356 ssthresh_ = std::max(static_cast<int>(in_flight_.size() / 2), 2); | 417 ssthresh_ = std::max(static_cast<int>(in_flight_.size() / 2), 2); |
357 cwnd_ = ssthresh_; | 418 cwnd_ = ssthresh_; |
358 } | 419 } |
359 | 420 |
360 Packets TcpSender::GeneratePackets(size_t num_packets) { | 421 Packets TcpSender::GeneratePackets(size_t num_packets) { |
361 Packets generated; | 422 Packets generated; |
| 423 |
| 424 UpdateSendBitrateEstimate(num_packets); |
| 425 |
362 for (size_t i = 0; i < num_packets; ++i) { | 426 for (size_t i = 0; i < num_packets; ++i) { |
363 generated.push_back(new MediaPacket(*flow_ids().begin(), | 427 if ((total_sent_bytes_ + kPacketSizeBytes) > send_limit_bytes_) { |
364 1000 * clock_.TimeInMilliseconds(), | 428 if (running_) { |
365 1200, next_sequence_number_++)); | 429 running_ = false; |
| 430 } |
| 431 break; |
| 432 } |
| 433 generated.push_back( |
| 434 new MediaPacket(*flow_ids().begin(), 1000 * clock_.TimeInMilliseconds(), |
| 435 kPacketSizeBytes, next_sequence_number_++)); |
366 generated.back()->set_sender_timestamp_us( | 436 generated.back()->set_sender_timestamp_us( |
367 1000 * clock_.TimeInMilliseconds()); | 437 1000 * clock_.TimeInMilliseconds()); |
| 438 |
| 439 total_sent_bytes_ += kPacketSizeBytes; |
368 } | 440 } |
| 441 |
369 return generated; | 442 return generated; |
370 } | 443 } |
| 444 |
| 445 void TcpSender::UpdateSendBitrateEstimate(size_t num_packets) { |
| 446 const int kTimeWindowMs = 500; |
| 447 num_recent_sent_packets_ += num_packets; |
| 448 |
| 449 int64_t delta_ms = clock_.TimeInMilliseconds() - last_generated_packets_ms_; |
| 450 if (delta_ms >= kTimeWindowMs) { |
| 451 bitrate_kbps_ = |
| 452 static_cast<uint32_t>(8 * num_recent_sent_packets_ * kPacketSizeBytes) / |
| 453 delta_ms; |
| 454 last_generated_packets_ms_ = clock_.TimeInMilliseconds(); |
| 455 num_recent_sent_packets_ = 0; |
| 456 } |
| 457 } |
| 458 |
| 459 uint32_t TcpSender::TargetBitrateKbps() { |
| 460 return bitrate_kbps_; |
| 461 } |
| 462 |
371 } // namespace bwe | 463 } // namespace bwe |
372 } // namespace testing | 464 } // namespace testing |
373 } // namespace webrtc | 465 } // namespace webrtc |
OLD | NEW |