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