Chromium Code Reviews| 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_us() / 1000 - |
| 74 clock_.TimeInMilliseconds(); | 76 clock_.TimeInMilliseconds(); |
| 75 time_to_run_ms = | 77 time_to_run_ms = |
| 76 std::max<int64_t>(std::min(time_ms, time_until_feedback_ms), 0); | 78 std::max<int64_t>(std::min(time_ms, time_until_feedback_ms), 0); |
| 77 } | 79 } |
| 80 | |
| 81 if (!running_) { | |
| 82 source_->SetBitrateBps(0); | |
| 83 } | |
| 84 | |
| 78 Packets generated; | 85 Packets generated; |
| 79 source_->RunFor(time_to_run_ms, &generated); | 86 source_->RunFor(time_to_run_ms, &generated); |
| 80 bwe_->OnPacketsSent(generated); | 87 bwe_->OnPacketsSent(generated); |
| 81 packets->merge(generated, DereferencingComparator<Packet>); | 88 packets->merge(generated, DereferencingComparator<Packet>); |
| 89 | |
| 82 clock_.AdvanceTimeMilliseconds(time_to_run_ms); | 90 clock_.AdvanceTimeMilliseconds(time_to_run_ms); |
| 91 | |
| 83 if (!feedbacks->empty()) { | 92 if (!feedbacks->empty()) { |
| 84 bwe_->GiveFeedback(*feedbacks->front()); | 93 bwe_->GiveFeedback(*feedbacks->front()); |
| 85 delete feedbacks->front(); | 94 delete feedbacks->front(); |
| 86 feedbacks->pop_front(); | 95 feedbacks->pop_front(); |
| 87 } | 96 } |
| 97 | |
| 88 bwe_->Process(); | 98 bwe_->Process(); |
| 99 | |
| 89 time_ms -= time_to_run_ms; | 100 time_ms -= time_to_run_ms; |
| 90 } while (time_ms > 0); | 101 } while (time_ms > 0); |
| 91 assert(feedbacks->empty()); | 102 assert(feedbacks->empty()); |
| 92 } | 103 } |
| 93 | 104 |
| 94 int VideoSender::GetFeedbackIntervalMs() const { | 105 int VideoSender::GetFeedbackIntervalMs() const { |
| 95 return bwe_->GetFeedbackIntervalMs(); | 106 return bwe_->GetFeedbackIntervalMs(); |
| 96 } | 107 } |
| 97 | 108 |
| 98 void VideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, | 109 void VideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, |
| 99 uint8_t fraction_lost, | 110 uint8_t fraction_lost, |
| 100 int64_t rtt) { | 111 int64_t rtt) { |
| 101 source_->SetBitrateBps(target_bitrate_bps); | 112 source_->SetBitrateBps(target_bitrate_bps); |
| 102 } | 113 } |
| 103 | 114 |
| 115 void VideoSender::Pause() { | |
| 116 running_ = false; | |
| 117 previous_sending_bitrate_ = TargetBitrateKbps(); | |
| 118 } | |
| 119 | |
| 120 void VideoSender::Resume() { | |
| 121 running_ = true; | |
| 122 source_->SetBitrateBps(previous_sending_bitrate_); | |
| 123 } | |
| 124 | |
| 125 uint32_t VideoSender::TargetBitrateKbps() { | |
| 126 return (source_->bits_per_second() + 500) / 1000; | |
| 127 } | |
| 128 | |
| 104 PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener, | 129 PacedVideoSender::PacedVideoSender(PacketProcessorListener* listener, |
| 105 VideoSource* source, | 130 VideoSource* source, |
| 106 BandwidthEstimatorType estimator) | 131 BandwidthEstimatorType estimator) |
| 107 : VideoSender(listener, source, estimator), | 132 : VideoSender(listener, source, estimator), |
| 108 pacer_(&clock_, | 133 pacer_(&clock_, |
| 109 this, | 134 this, |
| 110 source->bits_per_second() / 1000, | 135 source->bits_per_second() / 1000, |
| 111 PacedSender::kDefaultPaceMultiplier * source->bits_per_second() / | 136 PacedSender::kDefaultPaceMultiplier * source->bits_per_second() / |
| 112 1000, | 137 1000, |
| 113 0) { | 138 0) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 | 253 |
| 229 bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc, | 254 bool PacedVideoSender::TimeToSendPacket(uint32_t ssrc, |
| 230 uint16_t sequence_number, | 255 uint16_t sequence_number, |
| 231 int64_t capture_time_ms, | 256 int64_t capture_time_ms, |
| 232 bool retransmission) { | 257 bool retransmission) { |
| 233 for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end(); | 258 for (Packets::iterator it = pacer_queue_.begin(); it != pacer_queue_.end(); |
| 234 ++it) { | 259 ++it) { |
| 235 MediaPacket* media_packet = static_cast<MediaPacket*>(*it); | 260 MediaPacket* media_packet = static_cast<MediaPacket*>(*it); |
| 236 if (media_packet->header().sequenceNumber == sequence_number) { | 261 if (media_packet->header().sequenceNumber == sequence_number) { |
| 237 int64_t pace_out_time_ms = clock_.TimeInMilliseconds(); | 262 int64_t pace_out_time_ms = clock_.TimeInMilliseconds(); |
| 263 | |
| 264 // Due to randomization, packet->send_time_ms can be slightly greater than | |
| 265 // pace_out_time_ms. | |
| 266 assert(pace_out_time_ms >= (media_packet->send_time_us() - 500) / 1000); | |
|
stefan-webrtc
2015/07/14 13:49:04
This should not be needed.
magalhaesc
2015/07/14 17:19:33
Done.
| |
| 238 // Make sure a packet is never paced out earlier than when it was put into | 267 // Make sure a packet is never paced out earlier than when it was put into |
| 239 // the pacer. | 268 // the pacer. |
| 240 assert(pace_out_time_ms >= (media_packet->send_time_us() + 500) / 1000); | 269 if (pace_out_time_ms < (media_packet->send_time_us() + 500) / 1000) { |
| 270 clock_.AdvanceTimeMilliseconds( | |
| 271 (media_packet->send_time_us() + 500) / 1000 - pace_out_time_ms); | |
| 272 pace_out_time_ms = clock_.TimeInMilliseconds(); | |
| 273 } | |
| 241 media_packet->SetAbsSendTimeMs(pace_out_time_ms); | 274 media_packet->SetAbsSendTimeMs(pace_out_time_ms); |
| 242 media_packet->set_send_time_us(1000 * pace_out_time_ms); | 275 media_packet->set_send_time_us(1000 * pace_out_time_ms); |
| 243 media_packet->set_sender_timestamp_us(1000 * pace_out_time_ms); | 276 media_packet->set_sender_timestamp_us(1000 * pace_out_time_ms); |
| 244 queue_.push_back(media_packet); | 277 queue_.push_back(media_packet); |
| 245 pacer_queue_.erase(it); | 278 pacer_queue_.erase(it); |
| 246 return true; | 279 return true; |
| 247 } | 280 } |
| 248 } | 281 } |
| 249 return false; | 282 return false; |
| 250 } | 283 } |
| 251 | 284 |
| 252 size_t PacedVideoSender::TimeToSendPadding(size_t bytes) { | 285 size_t PacedVideoSender::TimeToSendPadding(size_t bytes) { |
| 253 return 0; | 286 return 0; |
| 254 } | 287 } |
| 255 | 288 |
| 256 void PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, | 289 void PacedVideoSender::OnNetworkChanged(uint32_t target_bitrate_bps, |
| 257 uint8_t fraction_lost, | 290 uint8_t fraction_lost, |
| 258 int64_t rtt) { | 291 int64_t rtt) { |
| 259 VideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt); | 292 VideoSender::OnNetworkChanged(target_bitrate_bps, fraction_lost, rtt); |
| 260 pacer_.UpdateBitrate( | 293 pacer_.UpdateBitrate( |
| 261 target_bitrate_bps / 1000, | 294 target_bitrate_bps / 1000, |
| 262 PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 0); | 295 PacedSender::kDefaultPaceMultiplier * target_bitrate_bps / 1000, 0); |
| 263 } | 296 } |
| 264 | 297 |
| 298 const int kNoLimit = std::numeric_limits<int>::max(); | |
| 299 const int kPacketSizeBytes = 1200; | |
| 300 | |
| 301 TcpSender::TcpSender(PacketProcessorListener* listener, | |
| 302 int flow_id, | |
| 303 int64_t offset_ms) | |
| 304 : TcpSender(listener, flow_id, offset_ms, kNoLimit) { | |
| 305 } | |
| 306 | |
| 307 TcpSender::TcpSender(PacketProcessorListener* listener, | |
| 308 int flow_id, | |
| 309 int64_t offset_ms, | |
| 310 int send_limit_bytes) | |
| 311 : PacketSender(listener, flow_id), | |
| 312 cwnd_(10), | |
| 313 ssthresh_(kNoLimit), | |
| 314 ack_received_(false), | |
| 315 last_acked_seq_num_(0), | |
| 316 next_sequence_number_(0), | |
| 317 offset_ms_(offset_ms), | |
| 318 last_reduction_time_ms_(-1), | |
| 319 last_rtt_ms_(0), | |
| 320 total_sent_bytes_(0), | |
| 321 send_limit_bytes_(send_limit_bytes), | |
| 322 running_(true), | |
| 323 last_generated_packets_ms_(0), | |
| 324 num_recent_sent_packets_(0), | |
| 325 bitrate_kbps_(0) { | |
| 326 } | |
| 327 | |
| 265 void TcpSender::RunFor(int64_t time_ms, Packets* in_out) { | 328 void TcpSender::RunFor(int64_t time_ms, Packets* in_out) { |
| 266 if (clock_.TimeInMilliseconds() + time_ms < offset_ms_) { | 329 if (clock_.TimeInMilliseconds() + time_ms < offset_ms_) { |
| 267 clock_.AdvanceTimeMilliseconds(time_ms); | 330 clock_.AdvanceTimeMilliseconds(time_ms); |
| 331 if (running_) { | |
| 332 running_ = false; | |
| 333 } | |
| 268 return; | 334 return; |
| 269 } | 335 } |
| 336 | |
| 337 if (!running_) { | |
| 338 running_ = true; | |
| 339 } | |
| 340 | |
| 270 int64_t start_time_ms = clock_.TimeInMilliseconds(); | 341 int64_t start_time_ms = clock_.TimeInMilliseconds(); |
| 271 BWE_TEST_LOGGING_CONTEXT("Sender"); | 342 BWE_TEST_LOGGING_CONTEXT("Sender"); |
| 272 BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin()); | 343 BWE_TEST_LOGGING_CONTEXT(*flow_ids().begin()); |
| 273 | 344 |
| 274 std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets( | 345 std::list<FeedbackPacket*> feedbacks = GetFeedbackPackets( |
| 275 in_out, clock_.TimeInMilliseconds() + time_ms, *flow_ids().begin()); | 346 in_out, clock_.TimeInMilliseconds() + time_ms, *flow_ids().begin()); |
| 276 // The number of packets which are sent in during time_ms depends on the | 347 // 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 | 348 // number of packets in_flight_ and the max number of packets in flight |
| 278 // (cwnd_). Therefore SendPackets() isn't directly dependent on time_ms. | 349 // (cwnd_). Therefore SendPackets() isn't directly dependent on time_ms. |
| 279 for (FeedbackPacket* fb : feedbacks) { | 350 for (FeedbackPacket* fb : feedbacks) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 void TcpSender::HandleLoss() { | 423 void TcpSender::HandleLoss() { |
| 353 if (clock_.TimeInMilliseconds() - last_reduction_time_ms_ < last_rtt_ms_) | 424 if (clock_.TimeInMilliseconds() - last_reduction_time_ms_ < last_rtt_ms_) |
| 354 return; | 425 return; |
| 355 last_reduction_time_ms_ = clock_.TimeInMilliseconds(); | 426 last_reduction_time_ms_ = clock_.TimeInMilliseconds(); |
| 356 ssthresh_ = std::max(static_cast<int>(in_flight_.size() / 2), 2); | 427 ssthresh_ = std::max(static_cast<int>(in_flight_.size() / 2), 2); |
| 357 cwnd_ = ssthresh_; | 428 cwnd_ = ssthresh_; |
| 358 } | 429 } |
| 359 | 430 |
| 360 Packets TcpSender::GeneratePackets(size_t num_packets) { | 431 Packets TcpSender::GeneratePackets(size_t num_packets) { |
| 361 Packets generated; | 432 Packets generated; |
| 433 | |
| 434 UpdateSendBitrateEstimate(num_packets); | |
| 435 | |
| 362 for (size_t i = 0; i < num_packets; ++i) { | 436 for (size_t i = 0; i < num_packets; ++i) { |
| 363 generated.push_back(new MediaPacket(*flow_ids().begin(), | 437 if ((total_sent_bytes_ + kPacketSizeBytes) > send_limit_bytes_) { |
| 364 1000 * clock_.TimeInMilliseconds(), | 438 if (running_) { |
| 365 1200, next_sequence_number_++)); | 439 running_ = false; |
| 440 } | |
| 441 break; | |
| 442 } | |
| 443 generated.push_back( | |
| 444 new MediaPacket(*flow_ids().begin(), 1000 * clock_.TimeInMilliseconds(), | |
| 445 kPacketSizeBytes, next_sequence_number_++)); | |
| 366 generated.back()->set_sender_timestamp_us( | 446 generated.back()->set_sender_timestamp_us( |
| 367 1000 * clock_.TimeInMilliseconds()); | 447 1000 * clock_.TimeInMilliseconds()); |
| 448 | |
| 449 total_sent_bytes_ += kPacketSizeBytes; | |
| 368 } | 450 } |
| 451 | |
| 369 return generated; | 452 return generated; |
| 370 } | 453 } |
| 454 | |
| 455 void TcpSender::UpdateSendBitrateEstimate(size_t num_packets) { | |
| 456 const int kTimeWindowMs = 500; | |
| 457 num_recent_sent_packets_ += num_packets; | |
| 458 | |
| 459 int64_t delta_ms = clock_.TimeInMilliseconds() - last_generated_packets_ms_; | |
| 460 if (delta_ms >= kTimeWindowMs) { | |
| 461 bitrate_kbps_ = | |
| 462 static_cast<uint32_t>(8 * num_recent_sent_packets_ * kPacketSizeBytes) / | |
| 463 delta_ms; | |
| 464 last_generated_packets_ms_ = clock_.TimeInMilliseconds(); | |
| 465 num_recent_sent_packets_ = 0; | |
| 466 } | |
| 467 } | |
| 468 | |
| 469 uint32_t TcpSender::TargetBitrateKbps() { | |
| 470 return bitrate_kbps_; | |
| 471 } | |
| 472 | |
| 371 } // namespace bwe | 473 } // namespace bwe |
| 372 } // namespace testing | 474 } // namespace testing |
| 373 } // namespace webrtc | 475 } // namespace webrtc |
| OLD | NEW |