| 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!
|
| 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() {
|
|
|