Chromium Code Reviews| 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); |