summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorhenrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-21 11:33:34 +0000
committerhenrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-21 11:33:34 +0000
commitf45b162b2d1866a61b008bfe835808b7b003031a (patch)
tree6134a0f7cee9b69e3319cf4d22cdd0dc9d185321 /content
parent221f23a8fae1ae0ff9b0697071460531cc1e2ff9 (diff)
downloadchromium_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.gypi2
-rw-r--r--content/renderer/media/media_stream_impl.cc2
-rw-r--r--content/renderer/media/webrtc_audio_device_impl.cc578
-rw-r--r--content/renderer/media/webrtc_audio_device_impl.h172
-rw-r--r--content/renderer/media/webrtc_audio_device_not_impl.cc277
-rw-r--r--content/renderer/media/webrtc_audio_device_not_impl.h120
-rw-r--r--content/renderer/media/webrtc_audio_device_unittest.cc6
-rw-r--r--content/renderer/media/webrtc_audio_renderer.cc2
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;