Chromium Code Reviews| Index: media/audio/virtual_audio_input_stream.cc |
| diff --git a/media/audio/virtual_audio_input_stream.cc b/media/audio/virtual_audio_input_stream.cc |
| index 4f2f9bd04fb84a4619766597777c75665b5641c6..e3145093be792a79cfed91f3fa715301159a44de 100644 |
| --- a/media/audio/virtual_audio_input_stream.cc |
| +++ b/media/audio/virtual_audio_input_stream.cc |
| @@ -9,6 +9,7 @@ |
| #include "base/bind.h" |
| #include "base/message_loop.h" |
| +#include "base/message_loop_proxy.h" |
| #include "media/audio/virtual_audio_output_stream.h" |
| namespace media { |
| @@ -47,26 +48,20 @@ class LoopbackAudioConverter : public AudioConverter::InputCallback { |
| DISALLOW_COPY_AND_ASSIGN(LoopbackAudioConverter); |
| }; |
| -VirtualAudioInputStream* VirtualAudioInputStream::MakeStream( |
| - AudioManagerBase* manager, const AudioParameters& params, |
| - base::MessageLoopProxy* message_loop) { |
| - return new VirtualAudioInputStream(manager, params, message_loop); |
| -} |
| - |
| VirtualAudioInputStream::VirtualAudioInputStream( |
| - AudioManagerBase* manager, const AudioParameters& params, |
| - base::MessageLoopProxy* message_loop) |
| - : audio_manager_(manager), |
| - message_loop_(message_loop), |
| + const AudioParameters& params, base::MessageLoopProxy* message_loop) |
| + : message_loop_(message_loop), |
| callback_(NULL), |
| - buffer_duration_ms_(base::TimeDelta::FromMilliseconds( |
| - params.frames_per_buffer() * base::Time::kMillisecondsPerSecond / |
| - static_cast<float>(params.sample_rate()))), |
| + buffer_duration_(base::TimeDelta::FromMicroseconds( |
| + params.frames_per_buffer() * base::Time::kMicrosecondsPerSecond / |
| + params.sample_rate())), |
| buffer_(new uint8[params.GetBytesPerBuffer()]), |
| params_(params), |
| audio_bus_(AudioBus::Create(params_)), |
| mixer_(params_, params_, false), |
| - num_attached_outputs_streams_(0) { |
| + num_attached_output_streams_(0) { |
| + DCHECK(params_.IsValid()); |
| + DCHECK(message_loop_); |
| } |
| VirtualAudioInputStream::~VirtualAudioInputStream() { |
| @@ -74,10 +69,16 @@ VirtualAudioInputStream::~VirtualAudioInputStream() { |
| it != converters_.end(); ++it) |
| delete it->second; |
| - DCHECK_EQ(0, num_attached_outputs_streams_); |
| + DCHECK_EQ(0, num_attached_output_streams_); |
| +} |
| + |
| +void VirtualAudioInputStream::RunOnceClosed(const base::Closure& cb) { |
| + DCHECK(on_close_cb_.is_null()); |
| + on_close_cb_ = cb; |
| } |
| bool VirtualAudioInputStream::Open() { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| memset(buffer_.get(), 0, params_.GetBytesPerBuffer()); |
| return true; |
| } |
| @@ -87,8 +88,7 @@ void VirtualAudioInputStream::Start(AudioInputCallback* callback) { |
| callback_ = callback; |
| on_more_data_cb_.Reset(base::Bind(&VirtualAudioInputStream::ReadAudio, |
| base::Unretained(this))); |
| - audio_manager_->GetMessageLoop()->PostTask(FROM_HERE, |
| - on_more_data_cb_.callback()); |
| + message_loop_->PostTask(FROM_HERE, on_more_data_cb_.callback()); |
| } |
| void VirtualAudioInputStream::Stop() { |
| @@ -111,7 +111,7 @@ void VirtualAudioInputStream::AddOutputStream( |
| mixer_.AddInput(converter->second); |
| } |
| converter->second->AddInput(stream); |
| - ++num_attached_outputs_streams_; |
| + ++num_attached_output_streams_; |
| } |
| void VirtualAudioInputStream::RemoveOutputStream( |
| @@ -121,7 +121,8 @@ void VirtualAudioInputStream::RemoveOutputStream( |
| DCHECK(converters_.find(output_params) != converters_.end()); |
| converters_[output_params]->RemoveInput(stream); |
| - --num_attached_outputs_streams_; |
| + --num_attached_output_streams_; |
| + DCHECK_LE(0, num_attached_output_streams_); |
| } |
| void VirtualAudioInputStream::ReadAudio() { |
| @@ -139,9 +140,14 @@ void VirtualAudioInputStream::ReadAudio() { |
| params_.GetBytesPerBuffer(), |
| 1.0); |
| + // TODO(miu): We want ReadAudio() to be called every buffer_duration_ amount |
| + // of time. However, we're not accounting for the time spent doing the |
| + // conversion and data delivery above, which is significant. Therefore, audio |
| + // data is always being delivered at a slower rate than required, and this |
| + // will cause cut-outs! |
|
DaleCurtis
2013/01/15 22:02:18
Justin has a fix out for this?
miu
2013/01/16 03:22:18
Yep (https://codereview.chromium.org/11889041/).
|
| message_loop_->PostDelayedTask(FROM_HERE, |
| on_more_data_cb_.callback(), |
| - buffer_duration_ms_); |
| + buffer_duration_); |
| } |
| void VirtualAudioInputStream::Close() { |
| @@ -151,7 +157,11 @@ void VirtualAudioInputStream::Close() { |
| callback_->OnClose(this); |
| callback_ = NULL; |
| } |
| - audio_manager_->ReleaseInputStream(this); |
| + if (!on_close_cb_.is_null()) { |
| + const base::Closure cb = on_close_cb_; |
| + on_close_cb_.Reset(); |
| + cb.Run(); |
| + } |
| } |
| double VirtualAudioInputStream::GetMaxVolume() { |