Index: webrtc/modules/pacing/paced_sender.cc |
diff --git a/webrtc/modules/pacing/paced_sender.cc b/webrtc/modules/pacing/paced_sender.cc |
index 4a66581e783fd24b6171d5a70079a5502ac7a839..9de65a4ed7ae6cb7418ddb6ad74fb5d6f18711a3 100644 |
--- a/webrtc/modules/pacing/paced_sender.cc |
+++ b/webrtc/modules/pacing/paced_sender.cc |
@@ -28,6 +28,7 @@ |
namespace { |
// Time limit in milliseconds between packet bursts. |
const int64_t kMinPacketLimitMs = 5; |
+const int64_t kPausedPacketIntervalMs = 500; |
// Upper cap on process interval, in case process has not been called in a long |
// time. |
@@ -278,9 +279,10 @@ void PacedSender::CreateProbeCluster(int bitrate_bps) { |
} |
void PacedSender::Pause() { |
- LOG(LS_INFO) << "PacedSender paused."; |
{ |
rtc::CritScope cs(&critsect_); |
+ if (!paused_) |
+ LOG(LS_INFO) << "PacedSender paused."; |
paused_ = true; |
} |
// Tell the process thread to call our TimeUntilNextProcess() method to get |
@@ -290,9 +292,10 @@ void PacedSender::Pause() { |
} |
void PacedSender::Resume() { |
- LOG(LS_INFO) << "PacedSender resumed."; |
{ |
rtc::CritScope cs(&critsect_); |
+ if (paused_) |
+ LOG(LS_INFO) << "PacedSender resumed."; |
paused_ = false; |
} |
// Tell the process thread to call our TimeUntilNextProcess() method to |
@@ -394,16 +397,18 @@ int64_t PacedSender::AverageQueueTimeMs() { |
int64_t PacedSender::TimeUntilNextProcess() { |
rtc::CritScope cs(&critsect_); |
+ int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_; |
+ int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000; |
+ // When paused we wake up every 500 ms to send a padding packet to ensure |
+ // we won't get stuck in the paused state due to no feedback being received. |
if (paused_) |
- return 1000 * 60 * 60; |
+ return std::max<int64_t>(kPausedPacketIntervalMs - elapsed_time_ms, 0); |
if (prober_->IsProbing()) { |
int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds()); |
if (ret > 0 || (ret == 0 && !probing_send_failure_)) |
return ret; |
} |
- int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_; |
- int64_t elapsed_time_ms = (elapsed_time_us + 500) / 1000; |
return std::max<int64_t>(kMinPacketLimitMs - elapsed_time_ms, 0); |
} |
@@ -411,9 +416,17 @@ void PacedSender::Process() { |
int64_t now_us = clock_->TimeInMicroseconds(); |
rtc::CritScope cs(&critsect_); |
int64_t elapsed_time_ms = (now_us - time_last_update_us_ + 500) / 1000; |
- time_last_update_us_ = now_us; |
int target_bitrate_kbps = pacing_bitrate_kbps_; |
- if (!paused_ && elapsed_time_ms > 0) { |
+ |
+ if (paused_) { |
+ PacedPacketInfo pacing_info; |
+ size_t bytes_sent = SendPadding(1, pacing_info); |
philipel
2017/08/02 15:35:16
Is there a way to completely stop the pacer, not j
stefan-webrtc
2017/08/04 09:50:00
We could, but the problem is that if we lose some
|
+ alr_detector_->OnBytesSent(bytes_sent, now_us / 1000); |
+ time_last_update_us_ = now_us; |
+ return; |
+ } |
+ |
+ if (elapsed_time_ms > 0) { |
size_t queue_size_bytes = packets_->SizeInBytes(); |
if (queue_size_bytes > 0) { |
// Assuming equal size packets and input/output rate, the average packet |
@@ -434,6 +447,8 @@ void PacedSender::Process() { |
UpdateBudgetWithElapsedTime(elapsed_time_ms); |
} |
+ time_last_update_us_ = now_us; |
+ |
bool is_probing = prober_->IsProbing(); |
PacedPacketInfo pacing_info; |
size_t bytes_sent = 0; |
@@ -463,17 +478,12 @@ void PacedSender::Process() { |
} |
} |
- if (packets_->Empty() && !paused_) { |
- // We can not send padding unless a normal packet has first been sent. If we |
- // do, timestamps get messed up. |
- if (packet_counter_ > 0) { |
- int padding_needed = |
- static_cast<int>(is_probing ? (recommended_probe_size - bytes_sent) |
- : padding_budget_->bytes_remaining()); |
- |
- if (padding_needed > 0) |
- bytes_sent += SendPadding(padding_needed, pacing_info); |
- } |
+ if (packets_->Empty()) { |
philipel
2017/08/02 15:35:16
Is this correct?
I assume you want to be able to
stefan-webrtc
2017/08/04 09:50:00
Why would we do that if there are packets in the q
philipel
2017/08/04 14:13:04
Ah, you're right.
|
+ int padding_needed = |
+ static_cast<int>(is_probing ? (recommended_probe_size - bytes_sent) |
+ : padding_budget_->bytes_remaining()); |
+ if (padding_needed > 0) |
+ bytes_sent += SendPadding(padding_needed, pacing_info); |
} |
if (is_probing) { |
probing_send_failure_ = bytes_sent == 0; |
@@ -490,8 +500,6 @@ void PacedSender::ProcessThreadAttached(ProcessThread* process_thread) { |
bool PacedSender::SendPacket(const paced_sender::Packet& packet, |
const PacedPacketInfo& pacing_info) { |
- if (paused_) |
- return false; |
philipel
2017/08/02 15:35:16
Make it into an RTC_DCHECK
stefan-webrtc
2017/08/04 09:50:00
Done.
|
if (media_budget_->bytes_remaining() == 0 && |
pacing_info.probe_cluster_id == PacedPacketInfo::kNotAProbe) { |
return false; |
@@ -517,6 +525,10 @@ bool PacedSender::SendPacket(const paced_sender::Packet& packet, |
size_t PacedSender::SendPadding(size_t padding_needed, |
const PacedPacketInfo& pacing_info) { |
+ // We can not send padding unless a normal packet has first been sent. If we |
+ // do, timestamps get messed up. |
+ if (packet_counter_ == 0) |
philipel
2017/08/02 15:35:16
I think it's somewhat clearer to keep this check w
stefan-webrtc
2017/08/04 09:50:00
Then the code will have to be duplicated since we'
philipel
2017/08/04 14:13:04
I still think that would be preferable.
|
+ return 0; |
critsect_.Leave(); |
size_t bytes_sent = |
packet_sender_->TimeToSendPadding(padding_needed, pacing_info); |