| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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/paced_sender.h" | 11 #include "webrtc/modules/pacing/paced_sender.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <map> | 14 #include <map> |
| 15 #include <queue> | 15 #include <queue> |
| 16 #include <set> | 16 #include <set> |
| 17 #include <vector> | 17 #include <vector> |
| 18 | 18 |
| 19 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 21 #include "webrtc/modules/include/module_common_types.h" | 21 #include "webrtc/modules/include/module_common_types.h" |
| 22 #include "webrtc/modules/pacing/alr_detector.h" |
| 22 #include "webrtc/modules/pacing/bitrate_prober.h" | 23 #include "webrtc/modules/pacing/bitrate_prober.h" |
| 23 #include "webrtc/system_wrappers/include/clock.h" | 24 #include "webrtc/system_wrappers/include/clock.h" |
| 24 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 25 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
| 25 #include "webrtc/system_wrappers/include/field_trial.h" | 26 #include "webrtc/system_wrappers/include/field_trial.h" |
| 26 | 27 |
| 27 namespace { | 28 namespace { |
| 28 // Time limit in milliseconds between packet bursts. | 29 // Time limit in milliseconds between packet bursts. |
| 29 const int64_t kMinPacketLimitMs = 5; | 30 const int64_t kMinPacketLimitMs = 5; |
| 30 | 31 |
| 31 // Upper cap on process interval, in case process has not been called in a long | 32 // Upper cap on process interval, in case process has not been called in a long |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 int bytes_remaining_; | 242 int bytes_remaining_; |
| 242 }; | 243 }; |
| 243 } // namespace paced_sender | 244 } // namespace paced_sender |
| 244 | 245 |
| 245 const int64_t PacedSender::kMaxQueueLengthMs = 2000; | 246 const int64_t PacedSender::kMaxQueueLengthMs = 2000; |
| 246 const float PacedSender::kDefaultPaceMultiplier = 2.5f; | 247 const float PacedSender::kDefaultPaceMultiplier = 2.5f; |
| 247 | 248 |
| 248 PacedSender::PacedSender(Clock* clock, PacketSender* packet_sender) | 249 PacedSender::PacedSender(Clock* clock, PacketSender* packet_sender) |
| 249 : clock_(clock), | 250 : clock_(clock), |
| 250 packet_sender_(packet_sender), | 251 packet_sender_(packet_sender), |
| 252 alr_detector_(new AlrDetector()), |
| 251 critsect_(CriticalSectionWrapper::CreateCriticalSection()), | 253 critsect_(CriticalSectionWrapper::CreateCriticalSection()), |
| 252 paused_(false), | 254 paused_(false), |
| 253 media_budget_(new paced_sender::IntervalBudget(0)), | 255 media_budget_(new paced_sender::IntervalBudget(0)), |
| 254 padding_budget_(new paced_sender::IntervalBudget(0)), | 256 padding_budget_(new paced_sender::IntervalBudget(0)), |
| 255 prober_(new BitrateProber()), | 257 prober_(new BitrateProber()), |
| 256 estimated_bitrate_bps_(0), | 258 estimated_bitrate_bps_(0), |
| 257 min_send_bitrate_kbps_(0u), | 259 min_send_bitrate_kbps_(0u), |
| 258 max_padding_bitrate_kbps_(0u), | 260 max_padding_bitrate_kbps_(0u), |
| 259 pacing_bitrate_kbps_(0), | 261 pacing_bitrate_kbps_(0), |
| 260 time_last_update_us_(clock->TimeInMicroseconds()), | 262 time_last_update_us_(clock->TimeInMicroseconds()), |
| 261 packets_(new paced_sender::PacketQueue(clock)), | 263 packets_(new paced_sender::PacketQueue(clock)), |
| 262 packet_counter_(0) { | 264 packet_counter_(0) { |
| 263 UpdateBytesPerInterval(kMinPacketLimitMs); | 265 UpdateBudgetWithElapsedTime(kMinPacketLimitMs); |
| 264 } | 266 } |
| 265 | 267 |
| 266 PacedSender::~PacedSender() {} | 268 PacedSender::~PacedSender() {} |
| 267 | 269 |
| 268 void PacedSender::CreateProbeCluster(int bitrate_bps, int num_packets) { | 270 void PacedSender::CreateProbeCluster(int bitrate_bps, int num_packets) { |
| 269 CriticalSectionScoped cs(critsect_.get()); | 271 CriticalSectionScoped cs(critsect_.get()); |
| 270 prober_->CreateProbeCluster(bitrate_bps, num_packets); | 272 prober_->CreateProbeCluster(bitrate_bps, num_packets); |
| 271 } | 273 } |
| 272 | 274 |
| 273 void PacedSender::Pause() { | 275 void PacedSender::Pause() { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 291 void PacedSender::SetEstimatedBitrate(uint32_t bitrate_bps) { | 293 void PacedSender::SetEstimatedBitrate(uint32_t bitrate_bps) { |
| 292 if (bitrate_bps == 0) | 294 if (bitrate_bps == 0) |
| 293 LOG(LS_ERROR) << "PacedSender is not designed to handle 0 bitrate."; | 295 LOG(LS_ERROR) << "PacedSender is not designed to handle 0 bitrate."; |
| 294 CriticalSectionScoped cs(critsect_.get()); | 296 CriticalSectionScoped cs(critsect_.get()); |
| 295 estimated_bitrate_bps_ = bitrate_bps; | 297 estimated_bitrate_bps_ = bitrate_bps; |
| 296 padding_budget_->set_target_rate_kbps( | 298 padding_budget_->set_target_rate_kbps( |
| 297 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); | 299 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); |
| 298 pacing_bitrate_kbps_ = | 300 pacing_bitrate_kbps_ = |
| 299 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * | 301 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * |
| 300 kDefaultPaceMultiplier; | 302 kDefaultPaceMultiplier; |
| 303 alr_detector_->SetEstimatedBitrate(bitrate_bps); |
| 301 } | 304 } |
| 302 | 305 |
| 303 void PacedSender::SetSendBitrateLimits(int min_send_bitrate_bps, | 306 void PacedSender::SetSendBitrateLimits(int min_send_bitrate_bps, |
| 304 int padding_bitrate) { | 307 int padding_bitrate) { |
| 305 CriticalSectionScoped cs(critsect_.get()); | 308 CriticalSectionScoped cs(critsect_.get()); |
| 306 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; | 309 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; |
| 307 pacing_bitrate_kbps_ = | 310 pacing_bitrate_kbps_ = |
| 308 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * | 311 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * |
| 309 kDefaultPaceMultiplier; | 312 kDefaultPaceMultiplier; |
| 310 max_padding_bitrate_kbps_ = padding_bitrate / 1000; | 313 max_padding_bitrate_kbps_ = padding_bitrate / 1000; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 int64_t avg_time_left_ms = std::max<int64_t>( | 393 int64_t avg_time_left_ms = std::max<int64_t>( |
| 391 1, kMaxQueueLengthMs - packets_->AverageQueueTimeMs()); | 394 1, kMaxQueueLengthMs - packets_->AverageQueueTimeMs()); |
| 392 int min_bitrate_needed_kbps = | 395 int min_bitrate_needed_kbps = |
| 393 static_cast<int>(queue_size_bytes * 8 / avg_time_left_ms); | 396 static_cast<int>(queue_size_bytes * 8 / avg_time_left_ms); |
| 394 if (min_bitrate_needed_kbps > target_bitrate_kbps) | 397 if (min_bitrate_needed_kbps > target_bitrate_kbps) |
| 395 target_bitrate_kbps = min_bitrate_needed_kbps; | 398 target_bitrate_kbps = min_bitrate_needed_kbps; |
| 396 } | 399 } |
| 397 | 400 |
| 398 media_budget_->set_target_rate_kbps(target_bitrate_kbps); | 401 media_budget_->set_target_rate_kbps(target_bitrate_kbps); |
| 399 | 402 |
| 400 int64_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms); | 403 elapsed_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms); |
| 401 UpdateBytesPerInterval(delta_time_ms); | 404 UpdateBudgetWithElapsedTime(elapsed_time_ms); |
| 402 } | 405 } |
| 403 | 406 |
| 404 bool is_probing = prober_->IsProbing(); | 407 bool is_probing = prober_->IsProbing(); |
| 405 int probe_cluster_id = PacketInfo::kNotAProbe; | 408 int probe_cluster_id = PacketInfo::kNotAProbe; |
| 406 size_t bytes_sent = 0; | 409 size_t bytes_sent = 0; |
| 407 size_t recommended_probe_size = 0; | 410 size_t recommended_probe_size = 0; |
| 408 if (is_probing) { | 411 if (is_probing) { |
| 409 probe_cluster_id = prober_->CurrentClusterId(); | 412 probe_cluster_id = prober_->CurrentClusterId(); |
| 410 recommended_probe_size = prober_->RecommendedMinProbeSize(); | 413 recommended_probe_size = prober_->RecommendedMinProbeSize(); |
| 411 } | 414 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 436 int padding_needed = | 439 int padding_needed = |
| 437 static_cast<int>(is_probing ? (recommended_probe_size - bytes_sent) | 440 static_cast<int>(is_probing ? (recommended_probe_size - bytes_sent) |
| 438 : padding_budget_->bytes_remaining()); | 441 : padding_budget_->bytes_remaining()); |
| 439 | 442 |
| 440 if (padding_needed > 0) | 443 if (padding_needed > 0) |
| 441 bytes_sent += SendPadding(padding_needed, probe_cluster_id); | 444 bytes_sent += SendPadding(padding_needed, probe_cluster_id); |
| 442 } | 445 } |
| 443 } | 446 } |
| 444 if (is_probing && bytes_sent > 0) | 447 if (is_probing && bytes_sent > 0) |
| 445 prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); | 448 prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); |
| 449 alr_detector_->OnBytesSent(bytes_sent, elapsed_time_ms); |
| 446 } | 450 } |
| 447 | 451 |
| 448 bool PacedSender::SendPacket(const paced_sender::Packet& packet, | 452 bool PacedSender::SendPacket(const paced_sender::Packet& packet, |
| 449 int probe_cluster_id) { | 453 int probe_cluster_id) { |
| 450 // TODO(holmer): Because of this bug issue 5307 we have to send audio | 454 // TODO(holmer): Because of this bug issue 5307 we have to send audio |
| 451 // packets even when the pacer is paused. Here we assume audio packets are | 455 // packets even when the pacer is paused. Here we assume audio packets are |
| 452 // always high priority and that they are the only high priority packets. | 456 // always high priority and that they are the only high priority packets. |
| 453 if (packet.priority != kHighPriority) { | 457 if (packet.priority != kHighPriority) { |
| 454 if (paused_) | 458 if (paused_) |
| 455 return false; | 459 return false; |
| 456 if (media_budget_->bytes_remaining() == 0 && | 460 if (media_budget_->bytes_remaining() == 0 && |
| 457 probe_cluster_id == PacketInfo::kNotAProbe) { | 461 probe_cluster_id == PacketInfo::kNotAProbe) { |
| 458 return false; | 462 return false; |
| 459 } | 463 } |
| 460 } | 464 } |
| 461 critsect_->Leave(); | 465 critsect_->Leave(); |
| 462 const bool success = packet_sender_->TimeToSendPacket( | 466 const bool success = packet_sender_->TimeToSendPacket( |
| 463 packet.ssrc, packet.sequence_number, packet.capture_time_ms, | 467 packet.ssrc, packet.sequence_number, packet.capture_time_ms, |
| 464 packet.retransmission, probe_cluster_id); | 468 packet.retransmission, probe_cluster_id); |
| 465 critsect_->Enter(); | 469 critsect_->Enter(); |
| 466 | 470 |
| 467 if (success) { | 471 if (success) { |
| 468 // TODO(holmer): High priority packets should only be accounted for if we | 472 // TODO(holmer): High priority packets should only be accounted for if we |
| 469 // are allocating bandwidth for audio. | 473 // are allocating bandwidth for audio. |
| 470 if (packet.priority != kHighPriority) { | 474 if (packet.priority != kHighPriority) { |
| 471 // Update media bytes sent. | 475 // Update media bytes sent. |
| 472 media_budget_->UseBudget(packet.bytes); | 476 UpdateBudgetWithBytesSent(packet.bytes); |
| 473 padding_budget_->UseBudget(packet.bytes); | |
| 474 } | 477 } |
| 475 } | 478 } |
| 476 | 479 |
| 477 return success; | 480 return success; |
| 478 } | 481 } |
| 479 | 482 |
| 480 size_t PacedSender::SendPadding(size_t padding_needed, int probe_cluster_id) { | 483 size_t PacedSender::SendPadding(size_t padding_needed, int probe_cluster_id) { |
| 481 critsect_->Leave(); | 484 critsect_->Leave(); |
| 482 size_t bytes_sent = | 485 size_t bytes_sent = |
| 483 packet_sender_->TimeToSendPadding(padding_needed, probe_cluster_id); | 486 packet_sender_->TimeToSendPadding(padding_needed, probe_cluster_id); |
| 484 critsect_->Enter(); | 487 critsect_->Enter(); |
| 485 | 488 |
| 486 if (bytes_sent > 0) { | 489 if (bytes_sent > 0) { |
| 487 media_budget_->UseBudget(bytes_sent); | 490 UpdateBudgetWithBytesSent(bytes_sent); |
| 488 padding_budget_->UseBudget(bytes_sent); | |
| 489 } | 491 } |
| 490 return bytes_sent; | 492 return bytes_sent; |
| 491 } | 493 } |
| 492 | 494 |
| 493 void PacedSender::UpdateBytesPerInterval(int64_t delta_time_ms) { | 495 void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) { |
| 494 media_budget_->IncreaseBudget(delta_time_ms); | 496 media_budget_->IncreaseBudget(delta_time_ms); |
| 495 padding_budget_->IncreaseBudget(delta_time_ms); | 497 padding_budget_->IncreaseBudget(delta_time_ms); |
| 496 } | 498 } |
| 499 |
| 500 void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) { |
| 501 media_budget_->UseBudget(bytes_sent); |
| 502 padding_budget_->UseBudget(bytes_sent); |
| 503 } |
| 497 } // namespace webrtc | 504 } // namespace webrtc |
| OLD | NEW |