diff options
author | henrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-21 11:33:34 +0000 |
---|---|---|
committer | henrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-21 11:33:34 +0000 |
commit | f45b162b2d1866a61b008bfe835808b7b003031a (patch) | |
tree | 6134a0f7cee9b69e3319cf4d22cdd0dc9d185321 /content | |
parent | 221f23a8fae1ae0ff9b0697071460531cc1e2ff9 (diff) | |
download | chromium_src-f45b162b2d1866a61b008bfe835808b7b003031a.zip chromium_src-f45b162b2d1866a61b008bfe835808b7b003031a.tar.gz chromium_src-f45b162b2d1866a61b008bfe835808b7b003031a.tar.bz2 |
Cleaning up the webrtc::AudioDeviceModule implementation.
Main parts of this CL:
- Improved thread handling (using thread check and better documentation).
- Removes usage of message loop proxy.
- Non-implemented methods are all moved to separate class to make main class more readable.
- Adding support for the MicrophoneVolume() API.
- Removed ad-hoc return value strategy.
BUG=none
TEST=Manual WebRTC tests and content_unittests.
Review URL: https://codereview.chromium.org/12918003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@189561 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/content_renderer.gypi | 2 | ||||
-rw-r--r-- | content/renderer/media/media_stream_impl.cc | 2 | ||||
-rw-r--r-- | content/renderer/media/webrtc_audio_device_impl.cc | 578 | ||||
-rw-r--r-- | content/renderer/media/webrtc_audio_device_impl.h | 172 | ||||
-rw-r--r-- | content/renderer/media/webrtc_audio_device_not_impl.cc | 277 | ||||
-rw-r--r-- | content/renderer/media/webrtc_audio_device_not_impl.h | 120 | ||||
-rw-r--r-- | content/renderer/media/webrtc_audio_device_unittest.cc | 6 | ||||
-rw-r--r-- | content/renderer/media/webrtc_audio_renderer.cc | 2 |
8 files changed, 560 insertions, 599 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 67456f6..a129e79 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -372,6 +372,8 @@ 'renderer/media/webrtc_audio_capturer.h', 'renderer/media/webrtc_audio_device_impl.cc', 'renderer/media/webrtc_audio_device_impl.h', + 'renderer/media/webrtc_audio_device_not_impl.cc', + 'renderer/media/webrtc_audio_device_not_impl.h', 'renderer/media/webrtc_audio_renderer.cc', 'renderer/media/webrtc_audio_renderer.h', 'renderer/media/webrtc_local_audio_renderer.cc', diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc index a184fe95..85c8fde 100644 --- a/content/renderer/media/media_stream_impl.cc +++ b/content/renderer/media/media_stream_impl.cc @@ -278,7 +278,7 @@ MediaStreamImpl::GetAudioRenderer(const GURL& url) { if (!renderer) { renderer = CreateRemoteAudioRenderer(extra_data->stream()); - if (renderer && !audio_device->SetRenderer(renderer)) + if (renderer && !audio_device->SetAudioRenderer(renderer)) renderer = NULL; } return renderer; diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc index 63e5293..11091a6 100644 --- a/content/renderer/media/webrtc_audio_device_impl.cc +++ b/content/renderer/media/webrtc_audio_device_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -22,36 +22,36 @@ namespace content { namespace { -const int64 kMillisecondsBetweenProcessCalls = 5000; const double kMaxVolumeLevel = 255.0; } // namespace WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl() : ref_count_(0), - render_loop_(base::MessageLoopProxy::current()), audio_transport_callback_(NULL), input_delay_ms_(0), output_delay_ms_(0), - last_error_(AudioDeviceModule::kAdmErrNone), - last_process_time_(base::TimeTicks::Now()), initialized_(false), playing_(false), recording_(false), - agc_is_enabled_(false) { + agc_is_enabled_(false), + microphone_volume_(0) { DVLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()"; } WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() { DVLOG(1) << "WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl()"; + DCHECK(thread_checker_.CalledOnValidThread()); Terminate(); } int32_t WebRtcAudioDeviceImpl::AddRef() { + DCHECK(thread_checker_.CalledOnValidThread()); return base::subtle::Barrier_AtomicIncrement(&ref_count_, 1); } int32_t WebRtcAudioDeviceImpl::Release() { + DCHECK(thread_checker_.CalledOnValidThread()); int ret = base::subtle::Barrier_AtomicIncrement(&ref_count_, -1); if (ret == 0) { delete this; @@ -59,79 +59,6 @@ int32_t WebRtcAudioDeviceImpl::Release() { return ret; } -void WebRtcAudioDeviceImpl::RenderData(uint8* audio_data, - int number_of_channels, - int number_of_frames, - int audio_delay_milliseconds) { - DCHECK_LE(number_of_frames, output_buffer_size()); - - { - base::AutoLock auto_lock(lock_); - // Store the reported audio delay locally. - output_delay_ms_ = audio_delay_milliseconds; - } - - const int channels = number_of_channels; - DCHECK_LE(channels, output_channels()); - - int samples_per_sec = output_sample_rate(); - if (samples_per_sec == 44100) { - // Even if the hardware runs at 44.1kHz, we use 44.0 internally. - samples_per_sec = 44000; - } - int samples_per_10_msec = (samples_per_sec / 100); - int bytes_per_sample = output_audio_parameters_.bits_per_sample() / 8; - const int bytes_per_10_msec = - channels * samples_per_10_msec * bytes_per_sample; - - uint32_t num_audio_samples = 0; - int accumulated_audio_samples = 0; - - // Get audio samples in blocks of 10 milliseconds from the registered - // webrtc::AudioTransport source. Keep reading until our internal buffer - // is full. - while (accumulated_audio_samples < number_of_frames) { - // Get 10ms and append output to temporary byte buffer. - audio_transport_callback_->NeedMorePlayData(samples_per_10_msec, - bytes_per_sample, - channels, - samples_per_sec, - audio_data, - num_audio_samples); - accumulated_audio_samples += num_audio_samples; - audio_data += bytes_per_10_msec; - } -} - -void WebRtcAudioDeviceImpl::SetRenderFormat(const AudioParameters& params) { - output_audio_parameters_ = params; -} - -void WebRtcAudioDeviceImpl::RemoveRenderer(WebRtcAudioRenderer* renderer) { - DCHECK(renderer); - base::AutoLock auto_lock(lock_); - if (renderer != renderer_) - return; - - renderer_ = NULL; - playing_ = false; -} - -// TODO(xians): Change the name to SetAudioRenderer(). -bool WebRtcAudioDeviceImpl::SetRenderer(WebRtcAudioRenderer* renderer) { - DCHECK(renderer); - - base::AutoLock auto_lock(lock_); - if (renderer_) - return false; - - if (!renderer->Initialize(this)) - return false; - - renderer_ = renderer; - return true; -} - void WebRtcAudioDeviceImpl::CaptureData(const int16* audio_data, int number_of_channels, int number_of_frames, @@ -149,39 +76,42 @@ void WebRtcAudioDeviceImpl::CaptureData(const int16* audio_data, DCHECK_LE(volume, 1.6); #endif + media::AudioParameters input_audio_parameters; int output_delay_ms = 0; { base::AutoLock auto_lock(lock_); if (!recording_) return; + // Take a copy of the input parameters while we are under a lock. + input_audio_parameters = input_audio_parameters_; + // Store the reported audio delay locally. input_delay_ms_ = audio_delay_milliseconds; output_delay_ms = output_delay_ms_; + + // Map internal volume range of [0.0, 1.0] into [0, 255] used by the + // webrtc::VoiceEngine. + microphone_volume_ = static_cast<uint32_t>(volume * kMaxVolumeLevel); } const int channels = number_of_channels; DCHECK_LE(channels, input_channels()); uint32_t new_mic_level = 0; - int samples_per_sec = input_sample_rate(); if (samples_per_sec == 44100) { // Even if the hardware runs at 44.1kHz, we use 44.0 internally. samples_per_sec = 44000; } const int samples_per_10_msec = (samples_per_sec / 100); - int bytes_per_sample = input_audio_parameters_.bits_per_sample() / 8; + int bytes_per_sample = input_audio_parameters.bits_per_sample() / 8; const int bytes_per_10_msec = channels * samples_per_10_msec * bytes_per_sample; int accumulated_audio_samples = 0; const uint8* audio_byte_buffer = reinterpret_cast<const uint8*>(audio_data); - // Map internal volume range of [0.0, 1.0] into [0, 255] used by the - // webrtc::VoiceEngine. - uint32_t current_mic_level = static_cast<uint32_t>(volume * kMaxVolumeLevel); - // Write audio samples in blocks of 10 milliseconds to the registered // webrtc::AudioTransport sink. Keep writing until our internal byte // buffer is empty. @@ -195,7 +125,7 @@ void WebRtcAudioDeviceImpl::CaptureData(const int16* audio_data, samples_per_sec, input_delay_ms_ + output_delay_ms, 0, // TODO(henrika): |clock_drift| parameter is not utilized today. - current_mic_level, + microphone_volume_, new_mic_level); accumulated_audio_samples += samples_per_10_msec; @@ -217,79 +147,80 @@ void WebRtcAudioDeviceImpl::CaptureData(const int16* audio_data, void WebRtcAudioDeviceImpl::SetCaptureFormat( const media::AudioParameters& params) { DVLOG(1) << "WebRtcAudioDeviceImpl::SetCaptureFormat()"; + DCHECK(thread_checker_.CalledOnValidThread()); + base::AutoLock auto_lock(lock_); input_audio_parameters_ = params; } -int32_t WebRtcAudioDeviceImpl::ChangeUniqueId(const int32_t id) { - NOTIMPLEMENTED(); - return -1; -} +void WebRtcAudioDeviceImpl::RenderData(uint8* audio_data, + int number_of_channels, + int number_of_frames, + int audio_delay_milliseconds) { + DCHECK_LE(number_of_frames, output_buffer_size()); + { + base::AutoLock auto_lock(lock_); + // Store the reported audio delay locally. + output_delay_ms_ = audio_delay_milliseconds; + } -int32_t WebRtcAudioDeviceImpl::TimeUntilNextProcess() { - // Calculate the number of milliseconds until this module wants its - // Process method to be called. - base::TimeDelta delta_time = (base::TimeTicks::Now() - last_process_time_); - int64 time_until_next = - kMillisecondsBetweenProcessCalls - delta_time.InMilliseconds(); - return static_cast<int32_t>(time_until_next); -} + const int channels = number_of_channels; + DCHECK_LE(channels, output_channels()); -int32_t WebRtcAudioDeviceImpl::Process() { - // TODO(henrika): it is possible to add functionality in this method, which - // is called periodically. The idea is that we should call one of the methods - // in the registered AudioDeviceObserver to inform the user about warnings - // or error states. Leave it empty for now. - last_process_time_ = base::TimeTicks::Now(); - return 0; -} + int samples_per_sec = output_sample_rate(); + if (samples_per_sec == 44100) { + // Even if the hardware runs at 44.1kHz, we use 44.0 internally. + samples_per_sec = 44000; + } + int samples_per_10_msec = (samples_per_sec / 100); + int bytes_per_sample = output_audio_parameters_.bits_per_sample() / 8; + const int bytes_per_10_msec = + channels * samples_per_10_msec * bytes_per_sample; + + uint32_t num_audio_samples = 0; + int accumulated_audio_samples = 0; -int32_t WebRtcAudioDeviceImpl::ActiveAudioLayer(AudioLayer* audio_layer) const { - NOTIMPLEMENTED(); - return -1; + // Get audio samples in blocks of 10 milliseconds from the registered + // webrtc::AudioTransport source. Keep reading until our internal buffer + // is full. + while (accumulated_audio_samples < number_of_frames) { + // Get 10ms and append output to temporary byte buffer. + audio_transport_callback_->NeedMorePlayData(samples_per_10_msec, + bytes_per_sample, + channels, + samples_per_sec, + audio_data, + num_audio_samples); + accumulated_audio_samples += num_audio_samples; + audio_data += bytes_per_10_msec; + } } -webrtc::AudioDeviceModule::ErrorCode WebRtcAudioDeviceImpl::LastError() const { - return last_error_; +void WebRtcAudioDeviceImpl::SetRenderFormat(const AudioParameters& params) { + DCHECK(thread_checker_.CalledOnValidThread()); + output_audio_parameters_ = params; } -int32_t WebRtcAudioDeviceImpl::RegisterEventObserver( - webrtc::AudioDeviceObserver* event_callback) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::RegisterEventObserver() " - << "NOT IMPLEMENTED"; - return -1; +void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_EQ(renderer, renderer_); + base::AutoLock auto_lock(lock_); + renderer_ = NULL; + playing_ = false; } int32_t WebRtcAudioDeviceImpl::RegisterAudioCallback( webrtc::AudioTransport* audio_callback) { + DVLOG(1) << "WebRtcAudioDeviceImpl::RegisterAudioCallback()"; + DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_EQ(audio_transport_callback_ == NULL, audio_callback != NULL); audio_transport_callback_ = audio_callback; return 0; } int32_t WebRtcAudioDeviceImpl::Init() { - DVLOG(1) << "Init()"; - - // TODO(henrika): Remove the following code if the |capturer_| does not need - // to be initialized in the render thread any more. - if (!render_loop_->BelongsToCurrentThread()) { - int32_t error = 0; - base::WaitableEvent event(false, false); - // Ensure that we call Init() from the main render thread since - // the audio clients can only be created on this thread. - render_loop_->PostTask( - FROM_HERE, - base::Bind(&WebRtcAudioDeviceImpl::InitOnRenderThread, - this, &error, &event)); - event.Wait(); - return error; - } + DVLOG(1) << "WebRtcAudioDeviceImpl::Init()"; + DCHECK(thread_checker_.CalledOnValidThread()); - // Calling Init() multiple times in a row is OK. - // TODO(henrika): Figure out why we need to call Init()/Terminate() for - // multiple times. This feels like a bug on the webrtc side if Init is called - // multiple times. Init() in my mind feels like a constructor, so unless - // Terminate() is called (the equivalent of a dtor), then Init() should not - // be called randomly after it has already been called. if (initialized_) return 0; @@ -300,21 +231,15 @@ int32_t WebRtcAudioDeviceImpl::Init() { // We need to return a success to continue the initialization of WebRtc VoE // because failure on the capturer_ initialization should not prevent WebRTC - // from working. See issue 144421 for details. + // from working. See issue http://crbug.com/144421 for details. initialized_ = true; return 0; } -void WebRtcAudioDeviceImpl::InitOnRenderThread(int32_t* error, - base::WaitableEvent* event) { - DCHECK(render_loop_->BelongsToCurrentThread()); - *error = Init(); - event->Signal(); -} - int32_t WebRtcAudioDeviceImpl::Terminate() { - DVLOG(1) << "Terminate()"; + DVLOG(1) << "WebRtcAudioDeviceImpl::Terminate()"; + DCHECK(thread_checker_.CalledOnValidThread()); // Calling Terminate() multiple times in a row is OK. if (!initialized_) @@ -344,97 +269,33 @@ bool WebRtcAudioDeviceImpl::Initialized() const { return initialized_; } -int16_t WebRtcAudioDeviceImpl::PlayoutDevices() { - NOTIMPLEMENTED(); - return -1; -} - -int16_t WebRtcAudioDeviceImpl::RecordingDevices() { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::PlayoutDeviceName( - uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::RecordingDeviceName( - uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetPlayoutDevice(uint16_t index) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetPlayoutDevice() " - << "NOT IMPLEMENTED"; - return 0; -} - -int32_t WebRtcAudioDeviceImpl::SetPlayoutDevice(WindowsDeviceType device) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetPlayoutDevice() " - << "NOT IMPLEMENTED"; - return 0; -} - -int32_t WebRtcAudioDeviceImpl::SetRecordingDevice(uint16_t index) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetRecordingDevice() " - << "NOT IMPLEMENTED"; - return 0; -} - -int32_t WebRtcAudioDeviceImpl::SetRecordingDevice(WindowsDeviceType device) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetRecordingDevice() " - << "NOT IMPLEMENTED"; - return 0; -} - int32_t WebRtcAudioDeviceImpl::PlayoutIsAvailable(bool* available) { - DVLOG(1) << "PlayoutIsAvailable()"; *available = initialized_; return 0; } -int32_t WebRtcAudioDeviceImpl::InitPlayout() { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::InitPlayout() " - << "NOT IMPLEMENTED"; - return 0; -} - bool WebRtcAudioDeviceImpl::PlayoutIsInitialized() const { - DVLOG(1) << "PlayoutIsInitialized()"; return initialized_; } int32_t WebRtcAudioDeviceImpl::RecordingIsAvailable(bool* available) { - DVLOG(1) << "RecordingIsAvailable()"; *available = (capturer_ != NULL); return 0; } -int32_t WebRtcAudioDeviceImpl::InitRecording() { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::InitRecording() " - << "NOT IMPLEMENTED"; - return 0; -} - bool WebRtcAudioDeviceImpl::RecordingIsInitialized() const { - DVLOG(1) << "RecordingIsInitialized()"; + DVLOG(1) << "WebRtcAudioDeviceImpl::RecordingIsInitialized()"; + DCHECK(thread_checker_.CalledOnValidThread()); return (capturer_ != NULL); } int32_t WebRtcAudioDeviceImpl::StartPlayout() { - DVLOG(1) << "StartPlayout()"; + DVLOG(1) << "WebRtcAudioDeviceImpl::StartPlayout()"; LOG_IF(ERROR, !audio_transport_callback_) << "Audio transport is missing"; { base::AutoLock auto_lock(lock_); if (!audio_transport_callback_) - return -1; + return 0; } if (playing_) { @@ -449,7 +310,7 @@ int32_t WebRtcAudioDeviceImpl::StartPlayout() { } int32_t WebRtcAudioDeviceImpl::StopPlayout() { - DVLOG(1) << "StopPlayout()"; + DVLOG(1) << "WebRtcAudioDeviceImpl::StopPlayout()"; if (!playing_) { // webrtc::VoiceEngine assumes that it is OK to call Stop() just in case. return 0; @@ -471,8 +332,8 @@ bool WebRtcAudioDeviceImpl::Playing() const { } int32_t WebRtcAudioDeviceImpl::StartRecording() { + DVLOG(1) << "WebRtcAudioDeviceImpl::StartRecording()"; DCHECK(initialized_); - DVLOG(1) << "StartRecording()"; LOG_IF(ERROR, !audio_transport_callback_) << "Audio transport is missing"; if (!audio_transport_callback_) { return -1; @@ -487,10 +348,8 @@ int32_t WebRtcAudioDeviceImpl::StartRecording() { } int32_t WebRtcAudioDeviceImpl::StopRecording() { - DVLOG(1) << "StopRecording()"; + DVLOG(1) << "WebRtcAudioDeviceImpl::StopRecording()"; if (!recording_) { - // webrtc::VoiceEngine assumes that it is OK to call Stop() - // more than once. return 0; } @@ -513,8 +372,8 @@ bool WebRtcAudioDeviceImpl::Recording() const { } int32_t WebRtcAudioDeviceImpl::SetAGC(bool enable) { + DVLOG(1) << "WebRtcAudioDeviceImpl::SetAGC(enable=" << enable << ")"; DCHECK(initialized_); - DVLOG(1) << "SetAGC(enable=" << enable << ")"; // Return early if we are not changing the AGC state. if (enable == agc_is_enabled_) @@ -532,100 +391,16 @@ int32_t WebRtcAudioDeviceImpl::SetAGC(bool enable) { } bool WebRtcAudioDeviceImpl::AGC() const { + DVLOG(1) << "WebRtcAudioDeviceImpl::AGC()"; + DCHECK(thread_checker_.CalledOnValidThread()); // To reduce the usage of IPC messages, an internal AGC state is used. // TODO(henrika): investigate if there is a need for a "deeper" getter. return agc_is_enabled_; } -int32_t WebRtcAudioDeviceImpl::SetWaveOutVolume(uint16_t volume_left, - uint16_t volume_right) { - NOTIMPLEMENTED(); - return -1; -} -int32_t WebRtcAudioDeviceImpl::WaveOutVolume( - uint16_t* volume_left, - uint16_t* volume_right) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SpeakerIsAvailable(bool* available) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SpeakerIsAvailable() " - << "NOT IMPLEMENTED"; - *available = true; - return 0; -} - -int32_t WebRtcAudioDeviceImpl::InitSpeaker() { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::InitSpeaker() " - << "NOT IMPLEMENTED"; - return 0; -} - -bool WebRtcAudioDeviceImpl::SpeakerIsInitialized() const { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SpeakerIsInitialized() " - << "NOT IMPLEMENTED"; - return true; -} - -int32_t WebRtcAudioDeviceImpl::MicrophoneIsAvailable(bool* available) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::MicrophoneIsAvailable() " - << "NOT IMPLEMENTED"; - *available = true; - return 0; -} - -int32_t WebRtcAudioDeviceImpl::InitMicrophone() { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::InitMicrophone() " - << "NOT IMPLEMENTED"; - return 0; -} - -bool WebRtcAudioDeviceImpl::MicrophoneIsInitialized() const { - NOTIMPLEMENTED(); - return true; -} - -int32_t WebRtcAudioDeviceImpl::SpeakerVolumeIsAvailable( - bool* available) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetSpeakerVolume(uint32_t volume) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SpeakerVolume(uint32_t* volume) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::MaxSpeakerVolume(uint32_t* max_volume) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::MinSpeakerVolume(uint32_t* min_volume) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SpeakerVolumeStepSize( - uint16_t* step_size) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::MicrophoneVolumeIsAvailable(bool* available) { - NOTIMPLEMENTED(); - return -1; -} - int32_t WebRtcAudioDeviceImpl::SetMicrophoneVolume(uint32_t volume) { + DVLOG(1) << "WebRtcAudioDeviceImpl::SetMicrophoneVolume(" << volume << ")"; DCHECK(initialized_); - DVLOG(1) << "SetMicrophoneVolume(" << volume << ")"; if (!capturer_) return -1; @@ -640,12 +415,18 @@ int32_t WebRtcAudioDeviceImpl::SetMicrophoneVolume(uint32_t volume) { return 0; } +// TODO(henrika): sort out calling thread once we start using this API. int32_t WebRtcAudioDeviceImpl::MicrophoneVolume(uint32_t* volume) const { + DVLOG(1) << "WebRtcAudioDeviceImpl::MicrophoneVolume()"; // The microphone level is fed to this class using the Capture() callback - // and this external API should not be used. Additional IPC messages are - // required if support for this API is ever needed. - NOTREACHED(); - return -1; + // and cached in the same method, i.e. we don't ask the native audio layer + // for the actual micropone level here. + DCHECK(initialized_); + if (!capturer_) + return -1; + base::AutoLock auto_lock(lock_); + *volume = microphone_volume_; + return 0; } int32_t WebRtcAudioDeviceImpl::MaxMicrophoneVolume(uint32_t* max_volume) const { @@ -658,205 +439,58 @@ int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(uint32_t* min_volume) const { return 0; } -int32_t WebRtcAudioDeviceImpl::MicrophoneVolumeStepSize( - uint16_t* step_size) const { - NOTREACHED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SpeakerMuteIsAvailable(bool* available) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetSpeakerMute(bool enable) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SpeakerMute(bool* enabled) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::MicrophoneMuteIsAvailable( - bool* available) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetMicrophoneMute(bool enable) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::MicrophoneMute(bool* enabled) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::MicrophoneBoostIsAvailable(bool* available) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetMicrophoneBoost(bool enable) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::MicrophoneBoost(bool* enabled) const { - NOTIMPLEMENTED(); - return -1; -} - int32_t WebRtcAudioDeviceImpl::StereoPlayoutIsAvailable(bool* available) const { - DCHECK(initialized_) << "Init() must be called first."; - + DCHECK(initialized_); *available = (output_channels() == 2); return 0; } -int32_t WebRtcAudioDeviceImpl::SetStereoPlayout(bool enable) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetStereoPlayout() " - << "NOT IMPLEMENTED"; - return 0; -} - -int32_t WebRtcAudioDeviceImpl::StereoPlayout(bool* enabled) const { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::StereoPlayout() " - << "NOT IMPLEMENTED"; - return 0; -} - int32_t WebRtcAudioDeviceImpl::StereoRecordingIsAvailable( bool* available) const { - DCHECK(initialized_) << "Init() must be called first."; + DCHECK(initialized_); if (!capturer_) return -1; - *available = (input_channels() == 2); return 0; } -int32_t WebRtcAudioDeviceImpl::SetStereoRecording(bool enable) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetStereoRecording() " - << "NOT IMPLEMENTED"; - return -1; -} - -int32_t WebRtcAudioDeviceImpl::StereoRecording(bool* enabled) const { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::StereoRecording() " - << "NOT IMPLEMENTED"; - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetRecordingChannel(const ChannelType channel) { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetRecordingChannel() " - << "NOT IMPLEMENTED"; - return -1; -} - -int32_t WebRtcAudioDeviceImpl::RecordingChannel(ChannelType* channel) const { - DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::RecordingChannel() " - << "NOT IMPLEMENTED"; - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetPlayoutBuffer(const BufferType type, - uint16_t size_ms) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::PlayoutBuffer(BufferType* type, - uint16_t* size_ms) const { - NOTIMPLEMENTED(); - return -1; -} - int32_t WebRtcAudioDeviceImpl::PlayoutDelay(uint16_t* delay_ms) const { - // Report the cached output delay value. base::AutoLock auto_lock(lock_); *delay_ms = static_cast<uint16_t>(output_delay_ms_); return 0; } int32_t WebRtcAudioDeviceImpl::RecordingDelay(uint16_t* delay_ms) const { - // Report the cached output delay value. base::AutoLock auto_lock(lock_); *delay_ms = static_cast<uint16_t>(input_delay_ms_); return 0; } -int32_t WebRtcAudioDeviceImpl::CPULoad(uint16_t* load) const { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::StartRawOutputFileRecording( - const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::StopRawOutputFileRecording() { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::StartRawInputFileRecording( - const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::StopRawInputFileRecording() { - NOTIMPLEMENTED(); - return -1; -} - -int32_t WebRtcAudioDeviceImpl::SetRecordingSampleRate( - const uint32_t samples_per_sec) { - // Sample rate should only be set at construction. - NOTIMPLEMENTED(); - return -1; -} - int32_t WebRtcAudioDeviceImpl::RecordingSampleRate( uint32_t* samples_per_sec) const { - // Returns the sample rate set at construction. *samples_per_sec = static_cast<uint32_t>(input_sample_rate()); return 0; } -int32_t WebRtcAudioDeviceImpl::SetPlayoutSampleRate( - const uint32_t samples_per_sec) { - // Sample rate should only be set at construction. - NOTIMPLEMENTED(); - return -1; -} - int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate( uint32_t* samples_per_sec) const { - // Returns the sample rate set at construction. *samples_per_sec = static_cast<uint32_t>(output_sample_rate()); return 0; } -int32_t WebRtcAudioDeviceImpl::ResetAudioDevice() { - NOTIMPLEMENTED(); - return -1; -} +bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(renderer); -int32_t WebRtcAudioDeviceImpl::SetLoudspeakerStatus(bool enable) { - NOTIMPLEMENTED(); - return -1; -} + base::AutoLock auto_lock(lock_); + if (renderer_) + return false; + + if (!renderer->Initialize(this)) + return false; -int32_t WebRtcAudioDeviceImpl::GetLoudspeakerStatus(bool* enabled) const { - NOTIMPLEMENTED(); - return -1; + renderer_ = renderer; + return true; } } // namespace content diff --git a/content/renderer/media/webrtc_audio_device_impl.h b/content/renderer/media/webrtc_audio_device_impl.h index 7bae27a..e53bd09 100644 --- a/content/renderer/media/webrtc_audio_device_impl.h +++ b/content/renderer/media/webrtc_audio_device_impl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,17 +9,16 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/message_loop_proxy.h" -#include "base/synchronization/waitable_event.h" -#include "base/time.h" +#include "base/threading/thread_checker.h" #include "content/common/content_export.h" #include "content/renderer/media/webrtc_audio_capturer.h" +#include "content/renderer/media/webrtc_audio_device_not_impl.h" #include "content/renderer/media/webrtc_audio_renderer.h" #include "media/base/audio_capturer_source.h" #include "media/base/audio_renderer_sink.h" -#include "third_party/webrtc/modules/audio_device/include/audio_device.h" // A WebRtcAudioDeviceImpl instance implements the abstract interface // webrtc::AudioDeviceModule which makes it possible for a user (e.g. webrtc:: @@ -164,7 +163,11 @@ // // Implementation notes: // -// - This class must be created on the main render thread. +// - This class must be created and destroyed on the main render thread and +// most methods are called on the same thread. However, some methods are +// also called on a Libjingle worker thread. RenderData is called on the +// AudioOutputDevice thread and CaptureData on the AudioInputDevice thread. +// To summarize: this class lives on four different threads. // - The webrtc::AudioDeviceModule is reference counted. // - AGC is only supported in combination with the WASAPI-based audio layer // on Windows, i.e., it is not supported on Windows XP. @@ -194,7 +197,7 @@ class WebRtcAudioRendererSource { virtual void SetRenderFormat(const media::AudioParameters& params) = 0; // Callback to notify the client that the renderer is going away. - virtual void RemoveRenderer(WebRtcAudioRenderer* renderer) = 0; + virtual void RemoveAudioRenderer(WebRtcAudioRenderer* renderer) = 0; protected: virtual ~WebRtcAudioRendererSource() {} @@ -216,47 +219,52 @@ class WebRtcAudioCapturerSink { virtual ~WebRtcAudioCapturerSink() {} }; +// Note that this class inherits from webrtc::AudioDeviceModule but due to +// the high number of non-implemented methods, we move the cruft over to the +// WebRtcAudioDeviceNotImpl. class CONTENT_EXPORT WebRtcAudioDeviceImpl - : NON_EXPORTED_BASE(public webrtc::AudioDeviceModule), + : NON_EXPORTED_BASE(public WebRtcAudioDeviceNotImpl), NON_EXPORTED_BASE(public WebRtcAudioCapturerSink), NON_EXPORTED_BASE(public WebRtcAudioRendererSource) { public: - // Methods called on main render thread. + // Instances of this object are created on the main render thread. WebRtcAudioDeviceImpl(); // webrtc::RefCountedModule implementation. // The creator must call AddRef() after construction and use Release() // to release the reference and delete this object. + // Called on the main render thread. virtual int32_t AddRef() OVERRIDE; virtual int32_t Release() OVERRIDE; - // WebRtcAudioRendererSource implementation. - virtual void RenderData(uint8* audio_data, - int number_of_channels, - int number_of_frames, - int audio_delay_milliseconds) OVERRIDE; - virtual void SetRenderFormat(const media::AudioParameters& params) OVERRIDE; - virtual void RemoveRenderer(WebRtcAudioRenderer* renderer) OVERRIDE; - // WebRtcAudioCapturerSink implementation. + + // Called on the AudioInputDevice worker thread. virtual void CaptureData(const int16* audio_data, int number_of_channels, int number_of_frames, int audio_delay_milliseconds, double volume) OVERRIDE; + + // Called on the main render thread. virtual void SetCaptureFormat(const media::AudioParameters& params) OVERRIDE; - // webrtc::Module implementation. - virtual int32_t ChangeUniqueId(const int32_t id) OVERRIDE; - virtual int32_t TimeUntilNextProcess() OVERRIDE; - virtual int32_t Process() OVERRIDE; + // WebRtcAudioRendererSource implementation. + + // Called on the AudioInputDevice worker thread. + virtual void RenderData(uint8* audio_data, + int number_of_channels, + int number_of_frames, + int audio_delay_milliseconds) OVERRIDE; + + // Called on the main render thread. + virtual void SetRenderFormat(const media::AudioParameters& params) OVERRIDE; + virtual void RemoveAudioRenderer(WebRtcAudioRenderer* renderer) OVERRIDE; // webrtc::AudioDeviceModule implementation. - virtual int32_t ActiveAudioLayer(AudioLayer* audio_layer) const OVERRIDE; - virtual ErrorCode LastError() const OVERRIDE; + // All implemented methods are called on the main render thread unless + // anything else is stated. - virtual int32_t RegisterEventObserver( - webrtc::AudioDeviceObserver* event_callback) OVERRIDE; virtual int32_t RegisterAudioCallback(webrtc::AudioTransport* audio_callback) OVERRIDE; @@ -264,28 +272,12 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl virtual int32_t Terminate() OVERRIDE; virtual bool Initialized() const OVERRIDE; - virtual int16_t PlayoutDevices() OVERRIDE; - virtual int16_t RecordingDevices() OVERRIDE; - virtual int32_t PlayoutDeviceName(uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) - OVERRIDE; - virtual int32_t RecordingDeviceName(uint16_t index, - char name[webrtc::kAdmMaxDeviceNameSize], - char guid[webrtc::kAdmMaxGuidSize]) - OVERRIDE; - virtual int32_t SetPlayoutDevice(uint16_t index) OVERRIDE; - virtual int32_t SetPlayoutDevice(WindowsDeviceType device) OVERRIDE; - virtual int32_t SetRecordingDevice(uint16_t index) OVERRIDE; - virtual int32_t SetRecordingDevice(WindowsDeviceType device) OVERRIDE; - virtual int32_t PlayoutIsAvailable(bool* available) OVERRIDE; - virtual int32_t InitPlayout() OVERRIDE; virtual bool PlayoutIsInitialized() const OVERRIDE; virtual int32_t RecordingIsAvailable(bool* available) OVERRIDE; - virtual int32_t InitRecording() OVERRIDE; virtual bool RecordingIsInitialized() const OVERRIDE; + // All Start/Stop methods are called on a libJingle worker thread. virtual int32_t StartPlayout() OVERRIDE; virtual int32_t StopPlayout() OVERRIDE; virtual bool Playing() const OVERRIDE; @@ -293,94 +285,36 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl virtual int32_t StopRecording() OVERRIDE; virtual bool Recording() const OVERRIDE; + // Called on the main render thread and libJingle worker thread. virtual int32_t SetAGC(bool enable) OVERRIDE; + virtual bool AGC() const OVERRIDE; - virtual int32_t SetWaveOutVolume(uint16_t volume_left, - uint16_t volume_right) OVERRIDE; - virtual int32_t WaveOutVolume(uint16_t* volume_left, - uint16_t* volume_right) const OVERRIDE; - - virtual int32_t SpeakerIsAvailable(bool* available) OVERRIDE; - virtual int32_t InitSpeaker() OVERRIDE; - virtual bool SpeakerIsInitialized() const OVERRIDE; - virtual int32_t MicrophoneIsAvailable(bool* available) OVERRIDE; - virtual int32_t InitMicrophone() OVERRIDE; - virtual bool MicrophoneIsInitialized() const OVERRIDE; - - virtual int32_t SpeakerVolumeIsAvailable(bool* available) OVERRIDE; - virtual int32_t SetSpeakerVolume(uint32_t volume) OVERRIDE; - virtual int32_t SpeakerVolume(uint32_t* volume) const OVERRIDE; - virtual int32_t MaxSpeakerVolume(uint32_t* max_volume) const OVERRIDE; - virtual int32_t MinSpeakerVolume(uint32_t* min_volume) const OVERRIDE; - virtual int32_t SpeakerVolumeStepSize(uint16_t* step_size) const OVERRIDE; - - virtual int32_t MicrophoneVolumeIsAvailable(bool* available) OVERRIDE; + // Called on the AudioInputDevice worker thread. virtual int32_t SetMicrophoneVolume(uint32_t volume) OVERRIDE; + + // TODO(henrika): sort out calling thread once we start using this API. virtual int32_t MicrophoneVolume(uint32_t* volume) const OVERRIDE; + virtual int32_t MaxMicrophoneVolume(uint32_t* max_volume) const OVERRIDE; virtual int32_t MinMicrophoneVolume(uint32_t* min_volume) const OVERRIDE; - virtual int32_t MicrophoneVolumeStepSize(uint16_t* step_size) const OVERRIDE; - - virtual int32_t SpeakerMuteIsAvailable(bool* available) OVERRIDE; - virtual int32_t SetSpeakerMute(bool enable) OVERRIDE; - virtual int32_t SpeakerMute(bool* enabled) const OVERRIDE; - - virtual int32_t MicrophoneMuteIsAvailable(bool* available) OVERRIDE; - virtual int32_t SetMicrophoneMute(bool enable) OVERRIDE; - virtual int32_t MicrophoneMute(bool* enabled) const OVERRIDE; - - virtual int32_t MicrophoneBoostIsAvailable(bool* available) OVERRIDE; - virtual int32_t SetMicrophoneBoost(bool enable) OVERRIDE; - virtual int32_t MicrophoneBoost(bool* enabled) const OVERRIDE; - virtual int32_t StereoPlayoutIsAvailable(bool* available) const OVERRIDE; - virtual int32_t SetStereoPlayout(bool enable) OVERRIDE; - virtual int32_t StereoPlayout(bool* enabled) const OVERRIDE; virtual int32_t StereoRecordingIsAvailable(bool* available) const OVERRIDE; - virtual int32_t SetStereoRecording(bool enable) OVERRIDE; - virtual int32_t StereoRecording(bool* enabled) const OVERRIDE; - virtual int32_t SetRecordingChannel(const ChannelType channel) OVERRIDE; - virtual int32_t RecordingChannel(ChannelType* channel) const OVERRIDE; - - virtual int32_t SetPlayoutBuffer( - const BufferType type, uint16_t size_ms) OVERRIDE; - virtual int32_t PlayoutBuffer( - BufferType* type, uint16_t* size_ms) const OVERRIDE; virtual int32_t PlayoutDelay(uint16_t* delay_ms) const OVERRIDE; virtual int32_t RecordingDelay(uint16_t* delay_ms) const OVERRIDE; - - virtual int32_t CPULoad(uint16_t* load) const OVERRIDE; - - virtual int32_t StartRawOutputFileRecording( - const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) OVERRIDE; - virtual int32_t StopRawOutputFileRecording() OVERRIDE; - virtual int32_t StartRawInputFileRecording( - const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) OVERRIDE; - virtual int32_t StopRawInputFileRecording() OVERRIDE; - - virtual int32_t SetRecordingSampleRate( - const uint32_t samples_per_sec) OVERRIDE; virtual int32_t RecordingSampleRate(uint32_t* samples_per_sec) const OVERRIDE; - virtual int32_t SetPlayoutSampleRate(const uint32_t samples_per_sec) OVERRIDE; virtual int32_t PlayoutSampleRate(uint32_t* samples_per_sec) const OVERRIDE; - virtual int32_t ResetAudioDevice() OVERRIDE; - virtual int32_t SetLoudspeakerStatus(bool enable) OVERRIDE; - virtual int32_t GetLoudspeakerStatus(bool* enabled) const OVERRIDE; - - // Sets the |renderer_|, returns false if |renderer_| has already existed. - bool SetRenderer(WebRtcAudioRenderer* renderer); + // Sets the |renderer_|, returns false if |renderer_| already exists. + // Called on the main renderer thread. + bool SetAudioRenderer(WebRtcAudioRenderer* renderer); const scoped_refptr<WebRtcAudioCapturer>& capturer() const { return capturer_; } - const scoped_refptr<WebRtcAudioRenderer>& renderer() const { return renderer_; } - - // Accessors. int input_buffer_size() const { return input_audio_parameters_.frames_per_buffer(); } @@ -404,17 +338,11 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl // Make destructor private to ensure that we can only be deleted by Release(). virtual ~WebRtcAudioDeviceImpl(); - // Methods called on the main render thread ---------------------------------- - // The following methods are tasks posted on the render thread that needs to - // be executed on that thread. - void InitOnRenderThread(int32_t* error, base::WaitableEvent* event); + // Used to DCHECK that we are called on the correct thread. + base::ThreadChecker thread_checker_; int ref_count_; - // Gives access to the message loop of the render thread on which this - // object is created. - scoped_refptr<base::MessageLoopProxy> render_loop_; - // Provides access to the native audio input layer in the browser process. scoped_refptr<WebRtcAudioCapturer> capturer_; @@ -436,12 +364,8 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl // Cached value of the current audio delay on the output/renderer side. int output_delay_ms_; - webrtc::AudioDeviceModule::ErrorCode last_error_; - - base::TimeTicks last_process_time_; - // Protects |recording_|, |output_delay_ms_|, |input_delay_ms_|, |renderer_| - // and |recording_|. + // |recording_| and |microphone_volume_|. mutable base::Lock lock_; bool initialized_; @@ -455,6 +379,10 @@ class CONTENT_EXPORT WebRtcAudioDeviceImpl base::Time start_capture_time_; base::Time start_render_time_; + // Stores latest microphone volume received in a CaptureData() callback. + // Range is [0, 255]. + uint32_t microphone_volume_; + DISALLOW_COPY_AND_ASSIGN(WebRtcAudioDeviceImpl); }; diff --git a/content/renderer/media/webrtc_audio_device_not_impl.cc b/content/renderer/media/webrtc_audio_device_not_impl.cc new file mode 100644 index 0000000..fd21fcb --- /dev/null +++ b/content/renderer/media/webrtc_audio_device_not_impl.cc @@ -0,0 +1,277 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc_audio_device_not_impl.h" + +namespace { + +const int64 kMillisecondsBetweenProcessCalls = 5000; + +} // namespace + +namespace content { + +WebRtcAudioDeviceNotImpl::WebRtcAudioDeviceNotImpl() + : last_process_time_(base::TimeTicks::Now()) { +} + +int32_t WebRtcAudioDeviceNotImpl::ChangeUniqueId(const int32_t id) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::TimeUntilNextProcess() { + base::TimeDelta delta_time = (base::TimeTicks::Now() - last_process_time_); + int64 time_until_next = + kMillisecondsBetweenProcessCalls - delta_time.InMilliseconds(); + return static_cast<int32_t>(time_until_next); +} + +int32_t WebRtcAudioDeviceNotImpl::Process() { + last_process_time_ = base::TimeTicks::Now(); + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::RegisterEventObserver( + webrtc::AudioDeviceObserver* event_callback) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::ActiveAudioLayer( + AudioLayer* audio_layer) const { + return 0; +} + +webrtc::AudioDeviceModule::ErrorCode +WebRtcAudioDeviceNotImpl::LastError() const { + return AudioDeviceModule::kAdmErrNone; +} + +int16_t WebRtcAudioDeviceNotImpl::PlayoutDevices() { + return 0; +} + +int16_t WebRtcAudioDeviceNotImpl::RecordingDevices() { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::PlayoutDeviceName( + uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::RecordingDeviceName( + uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetPlayoutDevice(uint16_t index) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetPlayoutDevice(WindowsDeviceType device) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetRecordingDevice(uint16_t index) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetRecordingDevice(WindowsDeviceType device) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::InitPlayout() { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::InitRecording() { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetWaveOutVolume(uint16_t volume_left, + uint16_t volume_right) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::WaveOutVolume( + uint16_t* volume_left, uint16_t* volume_right) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SpeakerIsAvailable(bool* available) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::InitSpeaker() { + return 0; +} + +bool WebRtcAudioDeviceNotImpl::SpeakerIsInitialized() const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MicrophoneIsAvailable(bool* available) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::InitMicrophone() { + return 0; +} + +bool WebRtcAudioDeviceNotImpl::MicrophoneIsInitialized() const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SpeakerVolumeIsAvailable(bool* available) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetSpeakerVolume(uint32_t volume) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SpeakerVolume(uint32_t* volume) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MaxSpeakerVolume(uint32_t* max_volume) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MinSpeakerVolume(uint32_t* min_volume) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SpeakerVolumeStepSize( + uint16_t* step_size) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MicrophoneVolumeIsAvailable(bool* available) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MicrophoneVolumeStepSize( + uint16_t* step_size) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SpeakerMuteIsAvailable(bool* available) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetSpeakerMute(bool enable) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SpeakerMute(bool* enabled) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MicrophoneMuteIsAvailable(bool* available) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetMicrophoneMute(bool enable) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MicrophoneMute(bool* enabled) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MicrophoneBoostIsAvailable(bool* available) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetMicrophoneBoost(bool enable) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::MicrophoneBoost(bool* enabled) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetStereoPlayout(bool enable) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::StereoPlayout(bool* enabled) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetStereoRecording(bool enable) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::StereoRecording(bool* enabled) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetRecordingChannel( + const ChannelType channel) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::RecordingChannel(ChannelType* channel) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetPlayoutBuffer(const BufferType type, + uint16_t size_ms) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::PlayoutBuffer(BufferType* type, + uint16_t* size_ms) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::CPULoad(uint16_t* load) const { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::StartRawOutputFileRecording( + const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::StopRawOutputFileRecording() { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::StartRawInputFileRecording( + const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::StopRawInputFileRecording() { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetRecordingSampleRate( + const uint32_t samples_per_sec) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetPlayoutSampleRate( + const uint32_t samples_per_sec) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::ResetAudioDevice() { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::SetLoudspeakerStatus(bool enable) { + return 0; +} + +int32_t WebRtcAudioDeviceNotImpl::GetLoudspeakerStatus(bool* enabled) const { + return 0; +} + +} // namespace content diff --git a/content/renderer/media/webrtc_audio_device_not_impl.h b/content/renderer/media/webrtc_audio_device_not_impl.h new file mode 100644 index 0000000..2ef49de --- /dev/null +++ b/content/renderer/media/webrtc_audio_device_not_impl.h @@ -0,0 +1,120 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_DEVICE_NOT_IMPL_H_ +#define CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_DEVICE_NOT_IMPL_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/time.h" +#include "content/common/content_export.h" +#include "third_party/webrtc/modules/audio_device/include/audio_device.h" + +namespace content { + +// WebRtcAudioDeviceNotImpl contains default implementations of all methods +// in the webrtc::AudioDeviceModule which are currently not supported in Chrome. +// The real implementation is in WebRtcAudioDeviceImpl and it derives from +// this class. The main purpose of breaking out non-implemented methods into +// a separate unit is to make WebRtcAudioDeviceImpl more readable and easier +// to maintain. +class CONTENT_EXPORT WebRtcAudioDeviceNotImpl + : NON_EXPORTED_BASE(public webrtc::AudioDeviceModule) { + public: + WebRtcAudioDeviceNotImpl(); + + // webrtc::Module implementation. + // TODO(henrika): it is possible to add functionality in these methods. + // Only adding very basic support for now without triggering any callback + // in the webrtc::AudioDeviceObserver interface. + virtual int32_t ChangeUniqueId(const int32_t id) OVERRIDE; + virtual int32_t TimeUntilNextProcess() OVERRIDE; + virtual int32_t Process() OVERRIDE; + + // Methods in webrtc::AudioDeviceModule which are not yet implemented. + // The idea is that we can move methods from this class to the real + // implementation in WebRtcAudioDeviceImpl when needed. + + virtual int32_t RegisterEventObserver( + webrtc::AudioDeviceObserver* event_callback) OVERRIDE; + virtual int32_t ActiveAudioLayer(AudioLayer* audio_layer) const OVERRIDE; + virtual webrtc::AudioDeviceModule::ErrorCode LastError() const OVERRIDE; + virtual int16_t PlayoutDevices() OVERRIDE; + virtual int16_t RecordingDevices() OVERRIDE; + virtual int32_t PlayoutDeviceName( + uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) OVERRIDE; + virtual int32_t RecordingDeviceName( + uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], + char guid[webrtc::kAdmMaxGuidSize]) OVERRIDE; + virtual int32_t SetPlayoutDevice(uint16_t index) OVERRIDE; + virtual int32_t SetPlayoutDevice(WindowsDeviceType device) OVERRIDE; + virtual int32_t SetRecordingDevice(uint16_t index) OVERRIDE; + virtual int32_t SetRecordingDevice(WindowsDeviceType device) OVERRIDE; + virtual int32_t InitPlayout() OVERRIDE; + virtual int32_t InitRecording() OVERRIDE; + virtual int32_t SetWaveOutVolume(uint16_t volume_left, + uint16_t volume_right) OVERRIDE; + virtual int32_t WaveOutVolume(uint16_t* volume_left, + uint16_t* volume_right) const OVERRIDE; + virtual int32_t SpeakerIsAvailable(bool* available) OVERRIDE; + virtual int32_t InitSpeaker() OVERRIDE; + virtual bool SpeakerIsInitialized() const OVERRIDE; + virtual int32_t MicrophoneIsAvailable(bool* available) OVERRIDE; + virtual int32_t InitMicrophone() OVERRIDE; + virtual bool MicrophoneIsInitialized() const OVERRIDE; + virtual int32_t SpeakerVolumeIsAvailable(bool* available) OVERRIDE; + virtual int32_t SetSpeakerVolume(uint32_t volume) OVERRIDE; + virtual int32_t SpeakerVolume(uint32_t* volume) const OVERRIDE; + virtual int32_t MaxSpeakerVolume(uint32_t* max_volume) const OVERRIDE; + virtual int32_t MinSpeakerVolume(uint32_t* min_volume) const OVERRIDE; + virtual int32_t SpeakerVolumeStepSize(uint16_t* step_size) const OVERRIDE; + virtual int32_t MicrophoneVolumeIsAvailable(bool* available) OVERRIDE; + virtual int32_t MicrophoneVolumeStepSize( + uint16_t* step_size) const OVERRIDE; + virtual int32_t SpeakerMuteIsAvailable(bool* available) OVERRIDE; + virtual int32_t SetSpeakerMute(bool enable) OVERRIDE; + virtual int32_t SpeakerMute(bool* enabled) const OVERRIDE; + virtual int32_t MicrophoneMuteIsAvailable(bool* available) OVERRIDE; + virtual int32_t SetMicrophoneMute(bool enable) OVERRIDE; + virtual int32_t MicrophoneMute(bool* enabled) const OVERRIDE; + virtual int32_t MicrophoneBoostIsAvailable(bool* available) OVERRIDE; + virtual int32_t SetMicrophoneBoost(bool enable) OVERRIDE; + virtual int32_t MicrophoneBoost(bool* enabled) const OVERRIDE; + virtual int32_t SetStereoPlayout(bool enable) OVERRIDE; + virtual int32_t StereoPlayout(bool* enabled) const OVERRIDE; + virtual int32_t SetStereoRecording(bool enable) OVERRIDE; + virtual int32_t StereoRecording(bool* enabled) const OVERRIDE; + virtual int32_t SetRecordingChannel(const ChannelType channel) OVERRIDE; + virtual int32_t RecordingChannel(ChannelType* channel) const OVERRIDE; + virtual int32_t SetPlayoutBuffer( + const BufferType type, uint16_t size_ms) OVERRIDE; + virtual int32_t PlayoutBuffer( + BufferType* type, uint16_t* size_ms) const OVERRIDE; + virtual int32_t CPULoad(uint16_t* load) const OVERRIDE; + virtual int32_t StartRawOutputFileRecording( + const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) OVERRIDE; + virtual int32_t StopRawOutputFileRecording() OVERRIDE; + virtual int32_t StartRawInputFileRecording( + const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) OVERRIDE; + virtual int32_t StopRawInputFileRecording() OVERRIDE; + virtual int32_t SetRecordingSampleRate( + const uint32_t samples_per_sec) OVERRIDE; + virtual int32_t SetPlayoutSampleRate( + const uint32_t samples_per_sec) OVERRIDE; + virtual int32_t ResetAudioDevice() OVERRIDE; + virtual int32_t SetLoudspeakerStatus(bool enable) OVERRIDE; + virtual int32_t GetLoudspeakerStatus(bool* enabled) const OVERRIDE; + + protected: + virtual ~WebRtcAudioDeviceNotImpl() {}; + + private: + base::TimeTicks last_process_time_; + DISALLOW_COPY_AND_ASSIGN(WebRtcAudioDeviceNotImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_WEBRTC_AUDIO_DEVICE_NOT_IMPL_H_ diff --git a/content/renderer/media/webrtc_audio_device_unittest.cc b/content/renderer/media/webrtc_audio_device_unittest.cc index 2d111e0..73c95fe 100644 --- a/content/renderer/media/webrtc_audio_device_unittest.cc +++ b/content/renderer/media/webrtc_audio_device_unittest.cc @@ -283,7 +283,7 @@ TEST_F(WebRTCAudioDeviceTest, DISABLED_StartPlayout) { new WebRtcAudioRenderer(kRenderViewId); scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); - EXPECT_TRUE(webrtc_audio_device->SetRenderer(renderer)); + EXPECT_TRUE(webrtc_audio_device->SetAudioRenderer(renderer)); WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); ASSERT_TRUE(engine.valid()); @@ -446,7 +446,7 @@ TEST_F(WebRTCAudioDeviceTest, DISABLED_PlayLocalFile) { new WebRtcAudioRenderer(kRenderViewId); scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); - EXPECT_TRUE(webrtc_audio_device->SetRenderer(renderer)); + EXPECT_TRUE(webrtc_audio_device->SetAudioRenderer(renderer)); WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); ASSERT_TRUE(engine.valid()); @@ -524,7 +524,7 @@ TEST_F(WebRTCAudioDeviceTest, MAYBE_FullDuplexAudioWithAGC) { new WebRtcAudioRenderer(kRenderViewId); scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( new WebRtcAudioDeviceImpl()); - EXPECT_TRUE(webrtc_audio_device->SetRenderer(renderer)); + EXPECT_TRUE(webrtc_audio_device->SetAudioRenderer(renderer)); WebRTCAutoDelete<webrtc::VoiceEngine> engine(webrtc::VoiceEngine::Create()); ASSERT_TRUE(engine.valid()); diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc index c30f265..d5591d0 100644 --- a/content/renderer/media/webrtc_audio_renderer.cc +++ b/content/renderer/media/webrtc_audio_renderer.cc @@ -268,7 +268,7 @@ void WebRtcAudioRenderer::Stop() { if (state_ == UNINITIALIZED) return; - source_->RemoveRenderer(this); + source_->RemoveAudioRenderer(this); source_ = NULL; sink_->Stop(); state_ = UNINITIALIZED; |