| 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/alr_detector.h" |
| 23 #include "webrtc/modules/pacing/bitrate_prober.h" | 23 #include "webrtc/modules/pacing/bitrate_prober.h" |
| 24 #include "webrtc/modules/utility/include/process_thread.h" | 24 #include "webrtc/modules/utility/include/process_thread.h" |
| 25 #include "webrtc/system_wrappers/include/clock.h" | 25 #include "webrtc/system_wrappers/include/clock.h" |
| 26 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
| 27 #include "webrtc/system_wrappers/include/field_trial.h" | 26 #include "webrtc/system_wrappers/include/field_trial.h" |
| 28 | 27 |
| 29 namespace { | 28 namespace { |
| 30 // Time limit in milliseconds between packet bursts. | 29 // Time limit in milliseconds between packet bursts. |
| 31 const int64_t kMinPacketLimitMs = 5; | 30 const int64_t kMinPacketLimitMs = 5; |
| 32 | 31 |
| 33 // 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 |
| 34 // time. | 33 // time. |
| 35 const int64_t kMaxIntervalTimeMs = 30; | 34 const int64_t kMaxIntervalTimeMs = 30; |
| 36 | 35 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 | 245 |
| 247 const int64_t PacedSender::kMaxQueueLengthMs = 2000; | 246 const int64_t PacedSender::kMaxQueueLengthMs = 2000; |
| 248 const float PacedSender::kDefaultPaceMultiplier = 2.5f; | 247 const float PacedSender::kDefaultPaceMultiplier = 2.5f; |
| 249 | 248 |
| 250 PacedSender::PacedSender(const Clock* clock, | 249 PacedSender::PacedSender(const Clock* clock, |
| 251 PacketSender* packet_sender, | 250 PacketSender* packet_sender, |
| 252 RtcEventLog* event_log) | 251 RtcEventLog* event_log) |
| 253 : clock_(clock), | 252 : clock_(clock), |
| 254 packet_sender_(packet_sender), | 253 packet_sender_(packet_sender), |
| 255 alr_detector_(new AlrDetector()), | 254 alr_detector_(new AlrDetector()), |
| 256 critsect_(CriticalSectionWrapper::CreateCriticalSection()), | |
| 257 paused_(false), | 255 paused_(false), |
| 258 media_budget_(new paced_sender::IntervalBudget(0)), | 256 media_budget_(new paced_sender::IntervalBudget(0)), |
| 259 padding_budget_(new paced_sender::IntervalBudget(0)), | 257 padding_budget_(new paced_sender::IntervalBudget(0)), |
| 260 prober_(new BitrateProber(event_log)), | 258 prober_(new BitrateProber(event_log)), |
| 261 probing_send_failure_(false), | 259 probing_send_failure_(false), |
| 262 estimated_bitrate_bps_(0), | 260 estimated_bitrate_bps_(0), |
| 263 min_send_bitrate_kbps_(0u), | 261 min_send_bitrate_kbps_(0u), |
| 264 max_padding_bitrate_kbps_(0u), | 262 max_padding_bitrate_kbps_(0u), |
| 265 pacing_bitrate_kbps_(0), | 263 pacing_bitrate_kbps_(0), |
| 266 time_last_update_us_(clock->TimeInMicroseconds()), | 264 time_last_update_us_(clock->TimeInMicroseconds()), |
| 267 packets_(new paced_sender::PacketQueue(clock)), | 265 packets_(new paced_sender::PacketQueue(clock)), |
| 268 packet_counter_(0) { | 266 packet_counter_(0) { |
| 269 UpdateBudgetWithElapsedTime(kMinPacketLimitMs); | 267 UpdateBudgetWithElapsedTime(kMinPacketLimitMs); |
| 270 } | 268 } |
| 271 | 269 |
| 272 PacedSender::~PacedSender() {} | 270 PacedSender::~PacedSender() {} |
| 273 | 271 |
| 274 void PacedSender::CreateProbeCluster(int bitrate_bps) { | 272 void PacedSender::CreateProbeCluster(int bitrate_bps) { |
| 275 CriticalSectionScoped cs(critsect_.get()); | 273 rtc::CritScope cs(&critsect_); |
| 276 prober_->CreateProbeCluster(bitrate_bps, clock_->TimeInMilliseconds()); | 274 prober_->CreateProbeCluster(bitrate_bps, clock_->TimeInMilliseconds()); |
| 277 } | 275 } |
| 278 | 276 |
| 279 void PacedSender::Pause() { | 277 void PacedSender::Pause() { |
| 280 LOG(LS_INFO) << "PacedSender paused."; | 278 LOG(LS_INFO) << "PacedSender paused."; |
| 281 { | 279 { |
| 282 CriticalSectionScoped cs(critsect_.get()); | 280 rtc::CritScope cs(&critsect_); |
| 283 paused_ = true; | 281 paused_ = true; |
| 284 } | 282 } |
| 285 // Tell the process thread to call our TimeUntilNextProcess() method to get | 283 // Tell the process thread to call our TimeUntilNextProcess() method to get |
| 286 // a new (longer) estimate for when to call Process(). | 284 // a new (longer) estimate for when to call Process(). |
| 287 if (process_thread_) | 285 if (process_thread_) |
| 288 process_thread_->WakeUp(this); | 286 process_thread_->WakeUp(this); |
| 289 } | 287 } |
| 290 | 288 |
| 291 void PacedSender::Resume() { | 289 void PacedSender::Resume() { |
| 292 LOG(LS_INFO) << "PacedSender resumed."; | 290 LOG(LS_INFO) << "PacedSender resumed."; |
| 293 { | 291 { |
| 294 CriticalSectionScoped cs(critsect_.get()); | 292 rtc::CritScope cs(&critsect_); |
| 295 paused_ = false; | 293 paused_ = false; |
| 296 } | 294 } |
| 297 // Tell the process thread to call our TimeUntilNextProcess() method to | 295 // Tell the process thread to call our TimeUntilNextProcess() method to |
| 298 // refresh the estimate for when to call Process(). | 296 // refresh the estimate for when to call Process(). |
| 299 if (process_thread_) | 297 if (process_thread_) |
| 300 process_thread_->WakeUp(this); | 298 process_thread_->WakeUp(this); |
| 301 } | 299 } |
| 302 | 300 |
| 303 void PacedSender::SetProbingEnabled(bool enabled) { | 301 void PacedSender::SetProbingEnabled(bool enabled) { |
| 304 RTC_CHECK_EQ(0, packet_counter_); | 302 RTC_CHECK_EQ(0, packet_counter_); |
| 305 CriticalSectionScoped cs(critsect_.get()); | 303 rtc::CritScope cs(&critsect_); |
| 306 prober_->SetEnabled(enabled); | 304 prober_->SetEnabled(enabled); |
| 307 } | 305 } |
| 308 | 306 |
| 309 void PacedSender::SetEstimatedBitrate(uint32_t bitrate_bps) { | 307 void PacedSender::SetEstimatedBitrate(uint32_t bitrate_bps) { |
| 310 if (bitrate_bps == 0) | 308 if (bitrate_bps == 0) |
| 311 LOG(LS_ERROR) << "PacedSender is not designed to handle 0 bitrate."; | 309 LOG(LS_ERROR) << "PacedSender is not designed to handle 0 bitrate."; |
| 312 CriticalSectionScoped cs(critsect_.get()); | 310 rtc::CritScope cs(&critsect_); |
| 313 estimated_bitrate_bps_ = bitrate_bps; | 311 estimated_bitrate_bps_ = bitrate_bps; |
| 314 padding_budget_->set_target_rate_kbps( | 312 padding_budget_->set_target_rate_kbps( |
| 315 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); | 313 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); |
| 316 pacing_bitrate_kbps_ = | 314 pacing_bitrate_kbps_ = |
| 317 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * | 315 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * |
| 318 kDefaultPaceMultiplier; | 316 kDefaultPaceMultiplier; |
| 319 alr_detector_->SetEstimatedBitrate(bitrate_bps); | 317 alr_detector_->SetEstimatedBitrate(bitrate_bps); |
| 320 } | 318 } |
| 321 | 319 |
| 322 void PacedSender::SetSendBitrateLimits(int min_send_bitrate_bps, | 320 void PacedSender::SetSendBitrateLimits(int min_send_bitrate_bps, |
| 323 int padding_bitrate) { | 321 int padding_bitrate) { |
| 324 CriticalSectionScoped cs(critsect_.get()); | 322 rtc::CritScope cs(&critsect_); |
| 325 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; | 323 min_send_bitrate_kbps_ = min_send_bitrate_bps / 1000; |
| 326 pacing_bitrate_kbps_ = | 324 pacing_bitrate_kbps_ = |
| 327 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * | 325 std::max(min_send_bitrate_kbps_, estimated_bitrate_bps_ / 1000) * |
| 328 kDefaultPaceMultiplier; | 326 kDefaultPaceMultiplier; |
| 329 max_padding_bitrate_kbps_ = padding_bitrate / 1000; | 327 max_padding_bitrate_kbps_ = padding_bitrate / 1000; |
| 330 padding_budget_->set_target_rate_kbps( | 328 padding_budget_->set_target_rate_kbps( |
| 331 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); | 329 std::min(estimated_bitrate_bps_ / 1000, max_padding_bitrate_kbps_)); |
| 332 } | 330 } |
| 333 | 331 |
| 334 void PacedSender::InsertPacket(RtpPacketSender::Priority priority, | 332 void PacedSender::InsertPacket(RtpPacketSender::Priority priority, |
| 335 uint32_t ssrc, | 333 uint32_t ssrc, |
| 336 uint16_t sequence_number, | 334 uint16_t sequence_number, |
| 337 int64_t capture_time_ms, | 335 int64_t capture_time_ms, |
| 338 size_t bytes, | 336 size_t bytes, |
| 339 bool retransmission) { | 337 bool retransmission) { |
| 340 CriticalSectionScoped cs(critsect_.get()); | 338 rtc::CritScope cs(&critsect_); |
| 341 RTC_DCHECK(estimated_bitrate_bps_ > 0) | 339 RTC_DCHECK(estimated_bitrate_bps_ > 0) |
| 342 << "SetEstimatedBitrate must be called before InsertPacket."; | 340 << "SetEstimatedBitrate must be called before InsertPacket."; |
| 343 | 341 |
| 344 int64_t now_ms = clock_->TimeInMilliseconds(); | 342 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 345 prober_->OnIncomingPacket(bytes); | 343 prober_->OnIncomingPacket(bytes); |
| 346 | 344 |
| 347 if (capture_time_ms < 0) | 345 if (capture_time_ms < 0) |
| 348 capture_time_ms = now_ms; | 346 capture_time_ms = now_ms; |
| 349 | 347 |
| 350 packets_->Push(paced_sender::Packet(priority, ssrc, sequence_number, | 348 packets_->Push(paced_sender::Packet(priority, ssrc, sequence_number, |
| 351 capture_time_ms, now_ms, bytes, | 349 capture_time_ms, now_ms, bytes, |
| 352 retransmission, packet_counter_++)); | 350 retransmission, packet_counter_++)); |
| 353 } | 351 } |
| 354 | 352 |
| 355 int64_t PacedSender::ExpectedQueueTimeMs() const { | 353 int64_t PacedSender::ExpectedQueueTimeMs() const { |
| 356 CriticalSectionScoped cs(critsect_.get()); | 354 rtc::CritScope cs(&critsect_); |
| 357 RTC_DCHECK_GT(pacing_bitrate_kbps_, 0); | 355 RTC_DCHECK_GT(pacing_bitrate_kbps_, 0); |
| 358 return static_cast<int64_t>(packets_->SizeInBytes() * 8 / | 356 return static_cast<int64_t>(packets_->SizeInBytes() * 8 / |
| 359 pacing_bitrate_kbps_); | 357 pacing_bitrate_kbps_); |
| 360 } | 358 } |
| 361 | 359 |
| 362 rtc::Optional<int64_t> PacedSender::GetApplicationLimitedRegionStartTime() | 360 rtc::Optional<int64_t> PacedSender::GetApplicationLimitedRegionStartTime() |
| 363 const { | 361 const { |
| 364 CriticalSectionScoped cs(critsect_.get()); | 362 rtc::CritScope cs(&critsect_); |
| 365 return alr_detector_->GetApplicationLimitedRegionStartTime(); | 363 return alr_detector_->GetApplicationLimitedRegionStartTime(); |
| 366 } | 364 } |
| 367 | 365 |
| 368 size_t PacedSender::QueueSizePackets() const { | 366 size_t PacedSender::QueueSizePackets() const { |
| 369 CriticalSectionScoped cs(critsect_.get()); | 367 rtc::CritScope cs(&critsect_); |
| 370 return packets_->SizeInPackets(); | 368 return packets_->SizeInPackets(); |
| 371 } | 369 } |
| 372 | 370 |
| 373 int64_t PacedSender::QueueInMs() const { | 371 int64_t PacedSender::QueueInMs() const { |
| 374 CriticalSectionScoped cs(critsect_.get()); | 372 rtc::CritScope cs(&critsect_); |
| 375 | 373 |
| 376 int64_t oldest_packet = packets_->OldestEnqueueTimeMs(); | 374 int64_t oldest_packet = packets_->OldestEnqueueTimeMs(); |
| 377 if (oldest_packet == 0) | 375 if (oldest_packet == 0) |
| 378 return 0; | 376 return 0; |
| 379 | 377 |
| 380 return clock_->TimeInMilliseconds() - oldest_packet; | 378 return clock_->TimeInMilliseconds() - oldest_packet; |
| 381 } | 379 } |
| 382 | 380 |
| 383 int64_t PacedSender::AverageQueueTimeMs() { | 381 int64_t PacedSender::AverageQueueTimeMs() { |
| 384 CriticalSectionScoped cs(critsect_.get()); | 382 rtc::CritScope cs(&critsect_); |
| 385 packets_->UpdateQueueTime(clock_->TimeInMilliseconds()); | 383 packets_->UpdateQueueTime(clock_->TimeInMilliseconds()); |
| 386 return packets_->AverageQueueTimeMs(); | 384 return packets_->AverageQueueTimeMs(); |
| 387 } | 385 } |
| 388 | 386 |
| 389 int64_t PacedSender::TimeUntilNextProcess() { | 387 int64_t PacedSender::TimeUntilNextProcess() { |
| 390 CriticalSectionScoped cs(critsect_.get()); | 388 rtc::CritScope cs(&critsect_); |
| 391 if (paused_) | 389 if (paused_) |
| 392 return 1000 * 60 * 60; | 390 return 1000 * 60 * 60; |
| 393 | 391 |
| 394 if (prober_->IsProbing()) { | 392 if (prober_->IsProbing()) { |
| 395 int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds()); | 393 int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds()); |
| 396 if (ret > 0 || (ret == 0 && !probing_send_failure_)) | 394 if (ret > 0 || (ret == 0 && !probing_send_failure_)) |
| 397 return ret; | 395 return ret; |
| 398 } | 396 } |
| 399 int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_; | 397 int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_; |
| 400 int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000; | 398 int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000; |
| 401 return std::max<int64_t>(kMinPacketLimitMs - elapsed_time_ms, 0); | 399 return std::max<int64_t>(kMinPacketLimitMs - elapsed_time_ms, 0); |
| 402 } | 400 } |
| 403 | 401 |
| 404 void PacedSender::Process() { | 402 void PacedSender::Process() { |
| 405 int64_t now_us = clock_->TimeInMicroseconds(); | 403 int64_t now_us = clock_->TimeInMicroseconds(); |
| 406 CriticalSectionScoped cs(critsect_.get()); | 404 rtc::CritScope cs(&critsect_); |
| 407 int64_t elapsed_time_ms = (now_us - time_last_update_us_ + 500) / 1000; | 405 int64_t elapsed_time_ms = (now_us - time_last_update_us_ + 500) / 1000; |
| 408 time_last_update_us_ = now_us; | 406 time_last_update_us_ = now_us; |
| 409 int target_bitrate_kbps = pacing_bitrate_kbps_; | 407 int target_bitrate_kbps = pacing_bitrate_kbps_; |
| 410 if (!paused_ && elapsed_time_ms > 0) { | 408 if (!paused_ && elapsed_time_ms > 0) { |
| 411 size_t queue_size_bytes = packets_->SizeInBytes(); | 409 size_t queue_size_bytes = packets_->SizeInBytes(); |
| 412 if (queue_size_bytes > 0) { | 410 if (queue_size_bytes > 0) { |
| 413 // Assuming equal size packets and input/output rate, the average packet | 411 // Assuming equal size packets and input/output rate, the average packet |
| 414 // has avg_time_left_ms left to get queue_size_bytes out of the queue, if | 412 // has avg_time_left_ms left to get queue_size_bytes out of the queue, if |
| 415 // time constraint shall be met. Determine bitrate needed for that. | 413 // time constraint shall be met. Determine bitrate needed for that. |
| 416 packets_->UpdateQueueTime(clock_->TimeInMilliseconds()); | 414 packets_->UpdateQueueTime(clock_->TimeInMilliseconds()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 | 480 |
| 483 bool PacedSender::SendPacket(const paced_sender::Packet& packet, | 481 bool PacedSender::SendPacket(const paced_sender::Packet& packet, |
| 484 const PacedPacketInfo& pacing_info) { | 482 const PacedPacketInfo& pacing_info) { |
| 485 if (paused_) | 483 if (paused_) |
| 486 return false; | 484 return false; |
| 487 if (media_budget_->bytes_remaining() == 0 && | 485 if (media_budget_->bytes_remaining() == 0 && |
| 488 pacing_info.probe_cluster_id == PacedPacketInfo::kNotAProbe) { | 486 pacing_info.probe_cluster_id == PacedPacketInfo::kNotAProbe) { |
| 489 return false; | 487 return false; |
| 490 } | 488 } |
| 491 | 489 |
| 492 critsect_->Leave(); | 490 critsect_.Leave(); |
| 493 const bool success = packet_sender_->TimeToSendPacket( | 491 const bool success = packet_sender_->TimeToSendPacket( |
| 494 packet.ssrc, packet.sequence_number, packet.capture_time_ms, | 492 packet.ssrc, packet.sequence_number, packet.capture_time_ms, |
| 495 packet.retransmission, pacing_info); | 493 packet.retransmission, pacing_info); |
| 496 critsect_->Enter(); | 494 critsect_.Enter(); |
| 497 | 495 |
| 498 if (success) { | 496 if (success) { |
| 499 // TODO(holmer): High priority packets should only be accounted for if we | 497 // TODO(holmer): High priority packets should only be accounted for if we |
| 500 // are allocating bandwidth for audio. | 498 // are allocating bandwidth for audio. |
| 501 if (packet.priority != kHighPriority) { | 499 if (packet.priority != kHighPriority) { |
| 502 // Update media bytes sent. | 500 // Update media bytes sent. |
| 503 UpdateBudgetWithBytesSent(packet.bytes); | 501 UpdateBudgetWithBytesSent(packet.bytes); |
| 504 } | 502 } |
| 505 } | 503 } |
| 506 | 504 |
| 507 return success; | 505 return success; |
| 508 } | 506 } |
| 509 | 507 |
| 510 size_t PacedSender::SendPadding(size_t padding_needed, | 508 size_t PacedSender::SendPadding(size_t padding_needed, |
| 511 const PacedPacketInfo& pacing_info) { | 509 const PacedPacketInfo& pacing_info) { |
| 512 critsect_->Leave(); | 510 critsect_.Leave(); |
| 513 size_t bytes_sent = | 511 size_t bytes_sent = |
| 514 packet_sender_->TimeToSendPadding(padding_needed, pacing_info); | 512 packet_sender_->TimeToSendPadding(padding_needed, pacing_info); |
| 515 critsect_->Enter(); | 513 critsect_.Enter(); |
| 516 | 514 |
| 517 if (bytes_sent > 0) { | 515 if (bytes_sent > 0) { |
| 518 UpdateBudgetWithBytesSent(bytes_sent); | 516 UpdateBudgetWithBytesSent(bytes_sent); |
| 519 } | 517 } |
| 520 return bytes_sent; | 518 return bytes_sent; |
| 521 } | 519 } |
| 522 | 520 |
| 523 void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) { | 521 void PacedSender::UpdateBudgetWithElapsedTime(int64_t delta_time_ms) { |
| 524 media_budget_->IncreaseBudget(delta_time_ms); | 522 media_budget_->IncreaseBudget(delta_time_ms); |
| 525 padding_budget_->IncreaseBudget(delta_time_ms); | 523 padding_budget_->IncreaseBudget(delta_time_ms); |
| 526 } | 524 } |
| 527 | 525 |
| 528 void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) { | 526 void PacedSender::UpdateBudgetWithBytesSent(size_t bytes_sent) { |
| 529 media_budget_->UseBudget(bytes_sent); | 527 media_budget_->UseBudget(bytes_sent); |
| 530 padding_budget_->UseBudget(bytes_sent); | 528 padding_budget_->UseBudget(bytes_sent); |
| 531 } | 529 } |
| 532 } // namespace webrtc | 530 } // namespace webrtc |
| OLD | NEW |