Chromium Code Reviews| Index: media/audio/audio_input_device.cc |
| =================================================================== |
| --- media/audio/audio_input_device.cc (revision 185810) |
| +++ media/audio/audio_input_device.cc (working copy) |
| @@ -11,6 +11,10 @@ |
| #include "media/audio/audio_manager_base.h" |
| #include "media/base/audio_bus.h" |
| +namespace { |
| +int kRequestdSharedMemoryCount = 10; |
|
henrika (OOO until Aug 14)
2013/03/04 13:12:51
Why not "requested"? Also, rather central constant
wjia(left Chromium)
2013/03/05 02:40:13
That's a typo. It should be Requested. Thanks for
|
| +} |
| + |
| namespace media { |
| // Takes care of invoking the capture callback on the audio thread. |
| @@ -20,7 +24,7 @@ |
| : public AudioDeviceThread::Callback { |
| public: |
| AudioThreadCallback(const AudioParameters& audio_parameters, |
| - base::SharedMemoryHandle memory, |
| + SharedMemoryHandleVector memory, |
| int memory_length, |
| CaptureCallback* capture_callback); |
| virtual ~AudioThreadCallback(); |
| @@ -28,7 +32,7 @@ |
| virtual void MapSharedMemory() OVERRIDE; |
| // Called whenever we receive notifications about pending data. |
| - virtual void Process(int pending_data) OVERRIDE; |
| + virtual void Process(int pending_data, int index) OVERRIDE; |
|
henrika (OOO until Aug 14)
2013/03/04 13:12:51
Comment |index|.
wjia(left Chromium)
2013/03/05 02:40:13
Done.
|
| private: |
| CaptureCallback* capture_callback_; |
| @@ -43,10 +47,13 @@ |
| callback_(NULL), |
| event_handler_(NULL), |
| ipc_(ipc), |
| + socket_handle_(base::SyncSocket::kInvalidHandle), |
| + received_shared_memory_count_(0), |
| stream_id_(0), |
| session_id_(0), |
| pending_device_ready_(false), |
| - agc_is_enabled_(false) { |
| + agc_is_enabled_(false), |
| + audio_thread_(true) { |
| CHECK(ipc_); |
| } |
| @@ -102,22 +109,40 @@ |
| } |
| void AudioInputDevice::OnStreamCreated( |
| - base::SharedMemoryHandle handle, |
| base::SyncSocket::Handle socket_handle, |
| - int length) { |
| + int total_handles) { |
| DCHECK(message_loop()->BelongsToCurrentThread()); |
| -#if defined(OS_WIN) |
| - DCHECK(handle); |
| - DCHECK(socket_handle); |
| -#else |
| - DCHECK_GE(handle.fd, 0); |
| - DCHECK_GE(socket_handle, 0); |
| -#endif |
| + DCHECK_NE(socket_handle, base::SyncSocket::kInvalidHandle); |
| + DVLOG(1) << "OnStreamCreated (stream_id=" << stream_id_ << ")"; |
| + |
| + // We should only get this callback if stream_id_ is valid. If it is not, |
| + // the IPC layer should have closed the socket handle for us and not invoked |
| + // the callback. The basic assertion is that when |
| + // stream_id_ is 0 the AudioInputDevice instance is not registered as a |
| + // delegate and hence it should not receive callbacks. |
| + DCHECK(stream_id_); |
| + DCHECK_GT(total_handles, 0); |
| + DCHECK_EQ(shared_memory_handles_.size(), 0u); |
| + |
| + base::AutoLock auto_lock(audio_thread_lock_); |
| + DCHECK(audio_thread_.IsStopped()); |
| + |
| + socket_handle_ = socket_handle; |
| + shared_memory_handles_.resize(total_handles, base::SharedMemory().handle()); |
| +} |
| + |
| +void AudioInputDevice::OnSharedMemoryCreated( |
| + base::SharedMemoryHandle handle, |
| + int length, |
| + int index) { |
| + DCHECK(message_loop()->BelongsToCurrentThread()); |
| + DCHECK_NE(socket_handle_, base::SyncSocket::kInvalidHandle); |
| + DCHECK(base::SharedMemory::IsHandleValid(handle)); |
| DCHECK(length); |
| DVLOG(1) << "OnStreamCreated (stream_id=" << stream_id_ << ")"; |
| // We should only get this callback if stream_id_ is valid. If it is not, |
| - // the IPC layer should have closed the shared memory and socket handles |
| + // the IPC layer should have closed the shared memory socket handle |
| // for us and not invoked the callback. The basic assertion is that when |
| // stream_id_ is 0 the AudioInputDevice instance is not registered as a |
| // delegate and hence it should not receive callbacks. |
| @@ -126,13 +151,22 @@ |
| base::AutoLock auto_lock(audio_thread_lock_); |
| DCHECK(audio_thread_.IsStopped()); |
| - audio_callback_.reset( |
| - new AudioInputDevice::AudioThreadCallback(audio_parameters_, handle, |
| - length, callback_)); |
| - audio_thread_.Start(audio_callback_.get(), socket_handle, "AudioInputDevice"); |
| - MessageLoop::current()->PostTask(FROM_HERE, |
| - base::Bind(&AudioInputDevice::StartOnIOThread, this)); |
| + int total_handles = static_cast<int>(shared_memory_handles_.size()); |
| + DCHECK_LT(index, total_handles); |
| + DCHECK(!base::SharedMemory::IsHandleValid(shared_memory_handles_[index])); |
| + shared_memory_handles_[index] = handle; |
| + received_shared_memory_count_++; |
| + if (received_shared_memory_count_ == total_handles) { |
| + audio_callback_.reset( |
| + new AudioInputDevice::AudioThreadCallback( |
| + audio_parameters_, shared_memory_handles_, length, callback_)); |
| + audio_thread_.Start(audio_callback_.get(), socket_handle_, |
| + "AudioInputDevice"); |
| + |
| + MessageLoop::current()->PostTask(FROM_HERE, |
| + base::Bind(&AudioInputDevice::StartOnIOThread, this)); |
| + } |
| } |
| void AudioInputDevice::OnVolume(double volume) { |
| @@ -196,7 +230,7 @@ |
| stream_id_ = 0; |
| } else { |
| ipc_->CreateStream(stream_id_, audio_parameters_, device_id, |
| - agc_is_enabled_); |
| + agc_is_enabled_, kRequestdSharedMemoryCount); |
| } |
| pending_device_ready_ = false; |
| @@ -228,7 +262,8 @@ |
| // and create the stream when getting a OnDeviceReady() callback. |
| if (!session_id_) { |
| ipc_->CreateStream(stream_id_, audio_parameters_, |
| - AudioManagerBase::kDefaultDeviceId, agc_is_enabled_); |
| + AudioManagerBase::kDefaultDeviceId, agc_is_enabled_, |
| + kRequestdSharedMemoryCount); |
| } else { |
| ipc_->StartDevice(stream_id_, session_id_); |
| pending_device_ready_ = true; |
| @@ -300,7 +335,7 @@ |
| // AudioInputDevice::AudioThreadCallback |
| AudioInputDevice::AudioThreadCallback::AudioThreadCallback( |
| const AudioParameters& audio_parameters, |
| - base::SharedMemoryHandle memory, |
| + SharedMemoryHandleVector memory, |
| int memory_length, |
| CaptureCallback* capture_callback) |
| : AudioDeviceThread::Callback(audio_parameters, memory, memory_length), |
| @@ -312,15 +347,18 @@ |
| } |
| void AudioInputDevice::AudioThreadCallback::MapSharedMemory() { |
| - shared_memory_.Map(memory_length_); |
| + for (size_t id = 0; id < shared_memory_.size(); ++id) { |
| + shared_memory_[id]->Map(memory_length_); |
| + } |
| } |
| -void AudioInputDevice::AudioThreadCallback::Process(int pending_data) { |
| +void AudioInputDevice::AudioThreadCallback::Process( |
| + int pending_data, int index) { |
| // The shared memory represents parameters, size of the data buffer and the |
| // actual data buffer containing audio data. Map the memory into this |
| // structure and parse out parameters and the data area. |
| AudioInputBuffer* buffer = |
| - reinterpret_cast<AudioInputBuffer*>(shared_memory_.memory()); |
| + reinterpret_cast<AudioInputBuffer*>(shared_memory_[index]->memory()); |
| DCHECK_EQ(buffer->params.size, |
| memory_length_ - sizeof(AudioInputBufferParameters)); |
| double volume = buffer->params.volume; |