Index: remoting/host/audio_pump.cc |
diff --git a/remoting/host/audio_pump.cc b/remoting/host/audio_pump.cc |
index 832f9e8b8a0d7a4f846190e61deacb2409c6e91e..3b6b36c38c72cf3394dd1940df91541895f5baa3 100644 |
--- a/remoting/host/audio_pump.cc |
+++ b/remoting/host/audio_pump.cc |
@@ -16,6 +16,10 @@ |
namespace remoting { |
+// Maximum number of bytes that can be stored in the send buffer before we start |
+// dropping packets. 5kB is about 0.25s in a stream with 160kb/s bitrate. |
Wez
2015/02/12 02:29:47
Do we run our stream at a fixed bit-rate? If not t
Sergey Ulanov
2015/02/13 21:21:56
Our opus encoder uses this bitrate. See https://co
|
+const int kMaxBufferedBytes = 5000; |
+ |
class AudioPump::Core : public base::NonThreadSafe { |
public: |
Core(base::WeakPtr<AudioPump> pump, |
@@ -26,31 +30,34 @@ class AudioPump::Core : public base::NonThreadSafe { |
void Start(); |
void Pause(bool pause); |
+ void OnPacketSent(int size); |
+ |
private: |
void EncodeAudioPacket(scoped_ptr<AudioPacket> packet); |
base::WeakPtr<AudioPump> pump_; |
- |
scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
- |
scoped_ptr<AudioCapturer> audio_capturer_; |
- |
scoped_ptr<AudioEncoder> audio_encoder_; |
bool enabled_; |
+ // Number of bytes in the queue that have been encoded but haven't been sent |
+ // yet. |
+ int bytes_pending_; |
+ |
DISALLOW_COPY_AND_ASSIGN(Core); |
}; |
-AudioPump::Core::Core( |
- base::WeakPtr<AudioPump> pump, |
- scoped_ptr<AudioCapturer> audio_capturer, |
- scoped_ptr<AudioEncoder> audio_encoder) |
+AudioPump::Core::Core(base::WeakPtr<AudioPump> pump, |
+ scoped_ptr<AudioCapturer> audio_capturer, |
+ scoped_ptr<AudioEncoder> audio_encoder) |
: pump_(pump), |
caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
audio_capturer_(audio_capturer.Pass()), |
audio_encoder_(audio_encoder.Pass()), |
- enabled_(true) { |
+ enabled_(true), |
+ bytes_pending_(0) { |
DetachFromThread(); |
} |
@@ -71,13 +78,21 @@ void AudioPump::Core::Pause(bool pause) { |
enabled_ = !pause; |
} |
+void AudioPump::Core::OnPacketSent(int size) { |
+ DCHECK(CalledOnValidThread()); |
+ |
+ bytes_pending_-= size; |
+ DCHECK_GE(bytes_pending_, 0); |
+} |
+ |
void AudioPump::Core::EncodeAudioPacket(scoped_ptr<AudioPacket> packet) { |
DCHECK(CalledOnValidThread()); |
DCHECK(packet); |
- if (!enabled_) |
+ if (!enabled_ || bytes_pending_ > kMaxBufferedBytes) |
return; |
+ |
scoped_ptr<AudioPacket> encoded_packet = |
audio_encoder_->Encode(packet.Pass()); |
@@ -85,9 +100,12 @@ void AudioPump::Core::EncodeAudioPacket(scoped_ptr<AudioPacket> packet) { |
if (!encoded_packet) |
return; |
- caller_task_runner_->PostTask(FROM_HERE, |
- base::Bind(&AudioPump::SendAudioPacket, pump_, |
- base::Passed(&encoded_packet))); |
+ int packet_size = encoded_packet->ByteSize(); |
+ bytes_pending_ += packet_size; |
+ |
+ caller_task_runner_->PostTask( |
+ FROM_HERE, base::Bind(&AudioPump::SendAudioPacket, pump_, |
+ base::Passed(&encoded_packet), packet_size)); |
} |
AudioPump::AudioPump( |
@@ -121,11 +139,19 @@ void AudioPump::Pause(bool pause) { |
base::Bind(&Core::Pause, base::Unretained(core_.get()), pause)); |
} |
-void AudioPump::SendAudioPacket(scoped_ptr<AudioPacket> packet) { |
+void AudioPump::SendAudioPacket(scoped_ptr<AudioPacket> packet, int size) { |
DCHECK(CalledOnValidThread()); |
DCHECK(packet); |
- audio_stub_->ProcessAudioPacket(packet.Pass(), base::Closure()); |
+ audio_stub_->ProcessAudioPacket( |
+ packet.Pass(), |
+ base::Bind(&AudioPump::OnPacketSent, weak_factory_.GetWeakPtr(), size)); |
+} |
+ |
+void AudioPump::OnPacketSent(int size) { |
+ audio_task_runner_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&Core::OnPacketSent, base::Unretained(core_.get()), size)); |
} |
} // namespace remoting |