Commit 0df892bb authored by xians@chromium.org's avatar xians@chromium.org

reland 260073013: Added automatic mode to FakeInputAudioStream to generate automatic beeps

 
Added automatic mode to FakeInputAudioStream to generate automatic beeps.

This patch is to allow writing audio only tests using the fake input stream, also it changes the name of the fake device from "Default" to "Fake Audio", which I hope it will make things less confusing.

NOTRY=true
TBR=grunell@chromium.org

BUG=358541
TEST=bots existing webrtc tests.

Review URL: https://codereview.chromium.org/301633004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@272964 0039d316-1c4b-4281-b951-d872f2087c98
parent 1d6b5b83
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/common/media_stream_request.h" #include "content/public/common/media_stream_request.h"
#include "media/audio/audio_device_name.h"
#include "media/audio/audio_input_ipc.h" #include "media/audio/audio_input_ipc.h"
#include "media/audio/audio_manager_base.h" #include "media/audio/audio_manager_base.h"
#include "media/audio/audio_parameters.h" #include "media/audio/audio_parameters.h"
...@@ -30,14 +29,6 @@ AudioInputDeviceManager::AudioInputDeviceManager( ...@@ -30,14 +29,6 @@ AudioInputDeviceManager::AudioInputDeviceManager(
next_capture_session_id_(kFirstSessionId), next_capture_session_id_(kFirstSessionId),
use_fake_device_(false), use_fake_device_(false),
audio_manager_(audio_manager) { audio_manager_(audio_manager) {
// TODO(xians): Remove this fake_device after the unittests do not need it.
StreamDeviceInfo fake_device(MEDIA_DEVICE_AUDIO_CAPTURE,
media::AudioManagerBase::kDefaultDeviceName,
media::AudioManagerBase::kDefaultDeviceId,
44100, media::CHANNEL_LAYOUT_STEREO,
0);
fake_device.session_id = kFakeOpenSessionId;
devices_.push_back(fake_device);
} }
AudioInputDeviceManager::~AudioInputDeviceManager() { AudioInputDeviceManager::~AudioInputDeviceManager() {
...@@ -123,19 +114,17 @@ void AudioInputDeviceManager::EnumerateOnDeviceThread( ...@@ -123,19 +114,17 @@ void AudioInputDeviceManager::EnumerateOnDeviceThread(
SCOPED_UMA_HISTOGRAM_TIMER( SCOPED_UMA_HISTOGRAM_TIMER(
"Media.AudioInputDeviceManager.EnumerateOnDeviceThreadTime"); "Media.AudioInputDeviceManager.EnumerateOnDeviceThreadTime");
DCHECK(IsOnDeviceThread()); DCHECK(IsOnDeviceThread());
DCHECK_EQ(MEDIA_DEVICE_AUDIO_CAPTURE, stream_type);
media::AudioDeviceNames device_names; media::AudioDeviceNames device_names;
if (use_fake_device_) {
switch (stream_type) { // Use the fake devices.
case MEDIA_DEVICE_AUDIO_CAPTURE: GetFakeDeviceNames(&device_names);
// AudioManager is guaranteed to outlive MediaStreamManager in } else {
// BrowserMainloop. // Enumerate the devices on the OS.
audio_manager_->GetAudioInputDeviceNames(&device_names); // AudioManager is guaranteed to outlive MediaStreamManager in
break; // BrowserMainloop.
audio_manager_->GetAudioInputDeviceNames(&device_names);
default:
NOTREACHED();
break;
} }
scoped_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray()); scoped_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray());
...@@ -146,14 +135,6 @@ void AudioInputDeviceManager::EnumerateOnDeviceThread( ...@@ -146,14 +135,6 @@ void AudioInputDeviceManager::EnumerateOnDeviceThread(
stream_type, it->device_name, it->unique_id)); stream_type, it->device_name, it->unique_id));
} }
// If the |use_fake_device_| flag is on, inject the fake device if there is
// no available device on the OS.
if (use_fake_device_ && devices->empty()) {
devices->push_back(StreamDeviceInfo(
stream_type, media::AudioManagerBase::kDefaultDeviceName,
media::AudioManagerBase::kDefaultDeviceId));
}
// Return the device list through the listener by posting a task on // Return the device list through the listener by posting a task on
// IO thread since MediaStreamManager handles the callback asynchronously. // IO thread since MediaStreamManager handles the callback asynchronously.
BrowserThread::PostTask( BrowserThread::PostTask(
...@@ -255,4 +236,18 @@ AudioInputDeviceManager::GetDevice(int session_id) { ...@@ -255,4 +236,18 @@ AudioInputDeviceManager::GetDevice(int session_id) {
return devices_.end(); return devices_.end();
} }
void AudioInputDeviceManager::GetFakeDeviceNames(
media::AudioDeviceNames* device_names) {
static const char kFakeDeviceName1[] = "Fake Audio 1";
static const char kFakeDeviceId1[] = "fake_audio_1";
static const char kFakeDeviceName2[] = "Fake Audio 2";
static const char kFakeDeviceId2[] = "fake_audio_2";
DCHECK(device_names->empty());
DCHECK(use_fake_device_);
device_names->push_back(media::AudioDeviceName(kFakeDeviceName1,
kFakeDeviceId1));
device_names->push_back(media::AudioDeviceName(kFakeDeviceName2,
kFakeDeviceId2));
}
} // namespace content } // namespace content
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/common/media/media_stream_options.h" #include "content/common/media/media_stream_options.h"
#include "content/public/common/media_stream_request.h" #include "content/public/common/media_stream_request.h"
#include "media/audio/audio_device_name.h"
namespace media { namespace media {
class AudioManager; class AudioManager;
...@@ -56,6 +57,10 @@ class CONTENT_EXPORT AudioInputDeviceManager : public MediaStreamProvider { ...@@ -56,6 +57,10 @@ class CONTENT_EXPORT AudioInputDeviceManager : public MediaStreamProvider {
bool ShouldUseFakeDevice() const; bool ShouldUseFakeDevice() const;
private: private:
// Used by the unittests to get a list of fake devices.
friend class MediaStreamDispatcherHostTest;
void GetFakeDeviceNames(media::AudioDeviceNames* device_names);
typedef std::vector<StreamDeviceInfo> StreamDeviceList; typedef std::vector<StreamDeviceInfo> StreamDeviceList;
virtual ~AudioInputDeviceManager(); virtual ~AudioInputDeviceManager();
......
...@@ -54,11 +54,6 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test { ...@@ -54,11 +54,6 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
public: public:
MAYBE_AudioInputDeviceManagerTest() {} MAYBE_AudioInputDeviceManagerTest() {}
// Returns true iff machine has an audio input device.
bool CanRunAudioInputDeviceTests() {
return audio_manager_->HasAudioInputDevices();
}
protected: protected:
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
// The test must run on Browser::IO. // The test must run on Browser::IO.
...@@ -73,6 +68,7 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test { ...@@ -73,6 +68,7 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
&base::WaitableEvent::Signal, base::Unretained(&event))); &base::WaitableEvent::Signal, base::Unretained(&event)));
event.Wait(); event.Wait();
manager_ = new AudioInputDeviceManager(audio_manager_.get()); manager_ = new AudioInputDeviceManager(audio_manager_.get());
manager_->UseFakeDevice();
audio_input_listener_.reset(new MockAudioInputDeviceManagerListener()); audio_input_listener_.reset(new MockAudioInputDeviceManagerListener());
manager_->Register(audio_input_listener_.get(), manager_->Register(audio_input_listener_.get(),
message_loop_->message_loop_proxy().get()); message_loop_->message_loop_proxy().get());
...@@ -106,8 +102,6 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test { ...@@ -106,8 +102,6 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
// Opens and closes the devices. // Opens and closes the devices.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenAndCloseDevice) { TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenAndCloseDevice) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty()); ASSERT_FALSE(devices_.empty());
...@@ -137,9 +131,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenAndCloseDevice) { ...@@ -137,9 +131,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenAndCloseDevice) {
// Opens multiple devices at one time and closes them later. // Opens multiple devices at one time and closes them later.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenMultipleDevices) { TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenMultipleDevices) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty()); ASSERT_FALSE(devices_.empty());
InSequence s; InSequence s;
...@@ -183,8 +174,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenMultipleDevices) { ...@@ -183,8 +174,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenMultipleDevices) {
// Opens a non-existing device. // Opens a non-existing device.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenNotExistingDevice) { TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenNotExistingDevice) {
if (!CanRunAudioInputDeviceTests())
return;
InSequence s; InSequence s;
MediaStreamType stream_type = MEDIA_DEVICE_AUDIO_CAPTURE; MediaStreamType stream_type = MEDIA_DEVICE_AUDIO_CAPTURE;
...@@ -206,9 +195,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenNotExistingDevice) { ...@@ -206,9 +195,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenNotExistingDevice) {
// Opens default device twice. // Opens default device twice.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenDeviceTwice) { TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenDeviceTwice) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty()); ASSERT_FALSE(devices_.empty());
InSequence s; InSequence s;
...@@ -242,9 +228,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenDeviceTwice) { ...@@ -242,9 +228,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenDeviceTwice) {
// Accesses then closes the sessions after opening the devices. // Accesses then closes the sessions after opening the devices.
TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessAndCloseSession) { TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessAndCloseSession) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty()); ASSERT_FALSE(devices_.empty());
InSequence s; InSequence s;
...@@ -278,8 +261,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessAndCloseSession) { ...@@ -278,8 +261,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessAndCloseSession) {
// Access an invalid session. // Access an invalid session.
TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessInvalidSession) { TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessInvalidSession) {
if (!CanRunAudioInputDeviceTests())
return;
InSequence s; InSequence s;
// Opens the first device. // Opens the first device.
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "content/browser/browser_thread_impl.h" #include "content/browser/browser_thread_impl.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
#include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h" #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
...@@ -247,7 +248,8 @@ class MediaStreamDispatcherHostTest : public testing::Test { ...@@ -247,7 +248,8 @@ class MediaStreamDispatcherHostTest : public testing::Test {
video_capture_device_factory_->GetDeviceNames(&physical_video_devices_); video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
ASSERT_GT(physical_video_devices_.size(), 0u); ASSERT_GT(physical_video_devices_.size(), 0u);
audio_manager_->GetAudioInputDeviceNames(&physical_audio_devices_); media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
&physical_audio_devices_);
ASSERT_GT(physical_audio_devices_.size(), 0u); ASSERT_GT(physical_audio_devices_.size(), 0u);
} }
......
...@@ -20,10 +20,16 @@ namespace { ...@@ -20,10 +20,16 @@ namespace {
const int kBeepDurationMilliseconds = 20; const int kBeepDurationMilliseconds = 20;
const int kBeepFrequency = 400; const int kBeepFrequency = 400;
// Intervals between two automatic beeps.
const int kAutomaticBeepIntervalInMs = 500;
// Automatic beep will be triggered every |kAutomaticBeepIntervalInMs| unless
// users explicitly call BeepOnce(), which will disable the automatic beep.
struct BeepContext { struct BeepContext {
BeepContext() : beep_once(false) {} BeepContext() : beep_once(false), automatic(true) {}
base::Lock beep_lock; base::Lock beep_lock;
bool beep_once; bool beep_once;
bool automatic;
}; };
static base::LazyInstance<BeepContext> g_beep_context = static base::LazyInstance<BeepContext> g_beep_context =
...@@ -78,14 +84,37 @@ void FakeAudioInputStream::Start(AudioInputCallback* callback) { ...@@ -78,14 +84,37 @@ void FakeAudioInputStream::Start(AudioInputCallback* callback) {
void FakeAudioInputStream::DoCallback() { void FakeAudioInputStream::DoCallback() {
DCHECK(callback_); DCHECK(callback_);
const TimeTicks now = TimeTicks::Now();
base::TimeDelta next_callback_time =
last_callback_time_ + callback_interval_ * 2 - now;
// If we are falling behind, try to catch up as much as we can in the next
// callback.
if (next_callback_time < base::TimeDelta())
next_callback_time = base::TimeDelta();
// Accumulate the time from the last beep.
interval_from_last_beep_ += now - last_callback_time_;
last_callback_time_ = now;
memset(buffer_.get(), 0, buffer_size_); memset(buffer_.get(), 0, buffer_size_);
bool should_beep = false; bool should_beep = false;
{ {
BeepContext* beep_context = g_beep_context.Pointer(); BeepContext* beep_context = g_beep_context.Pointer();
base::AutoLock auto_lock(beep_context->beep_lock); base::AutoLock auto_lock(beep_context->beep_lock);
should_beep = beep_context->beep_once; if (beep_context->automatic) {
beep_context->beep_once = false; base::TimeDelta delta = interval_from_last_beep_ -
TimeDelta::FromMilliseconds(kAutomaticBeepIntervalInMs);
if (delta > base::TimeDelta()) {
should_beep = true;
interval_from_last_beep_ = delta;
}
} else {
should_beep = beep_context->beep_once;
beep_context->beep_once = false;
}
} }
// If this object was instructed to generate a beep or has started to // If this object was instructed to generate a beep or has started to
...@@ -103,7 +132,6 @@ void FakeAudioInputStream::DoCallback() { ...@@ -103,7 +132,6 @@ void FakeAudioInputStream::DoCallback() {
while (position + high_bytes <= buffer_size_) { while (position + high_bytes <= buffer_size_) {
// Write high values first. // Write high values first.
memset(buffer_.get() + position, 128, high_bytes); memset(buffer_.get() + position, 128, high_bytes);
// Then leave low values in the buffer with |high_bytes|. // Then leave low values in the buffer with |high_bytes|.
position += high_bytes * 2; position += high_bytes * 2;
} }
...@@ -116,16 +144,6 @@ void FakeAudioInputStream::DoCallback() { ...@@ -116,16 +144,6 @@ void FakeAudioInputStream::DoCallback() {
callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_, 1.0); callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_, 1.0);
frames_elapsed_ += params_.frames_per_buffer(); frames_elapsed_ += params_.frames_per_buffer();
const TimeTicks now = TimeTicks::Now();
base::TimeDelta next_callback_time =
last_callback_time_ + callback_interval_ * 2 - now;
// If we are falling behind, try to catch up as much as we can in the next
// callback.
if (next_callback_time < base::TimeDelta())
next_callback_time = base::TimeDelta();
last_callback_time_ = now;
thread_.message_loop()->PostDelayedTask( thread_.message_loop()->PostDelayedTask(
FROM_HERE, FROM_HERE,
base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)), base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)),
...@@ -163,6 +181,7 @@ void FakeAudioInputStream::BeepOnce() { ...@@ -163,6 +181,7 @@ void FakeAudioInputStream::BeepOnce() {
BeepContext* beep_context = g_beep_context.Pointer(); BeepContext* beep_context = g_beep_context.Pointer();
base::AutoLock auto_lock(beep_context->beep_lock); base::AutoLock auto_lock(beep_context->beep_lock);
beep_context->beep_once = true; beep_context->beep_once = true;
beep_context->automatic = false;
} }
} // namespace media } // namespace media
...@@ -63,6 +63,7 @@ class MEDIA_EXPORT FakeAudioInputStream ...@@ -63,6 +63,7 @@ class MEDIA_EXPORT FakeAudioInputStream
base::Thread thread_; base::Thread thread_;
base::TimeTicks last_callback_time_; base::TimeTicks last_callback_time_;
base::TimeDelta callback_interval_; base::TimeDelta callback_interval_;
base::TimeDelta interval_from_last_beep_;
int beep_duration_in_buffers_; int beep_duration_in_buffers_;
int beep_generated_in_buffers_; int beep_generated_in_buffers_;
int beep_period_in_frames_; int beep_period_in_frames_;
......
...@@ -34,11 +34,8 @@ void MockAudioManager::ShowAudioInputSettings() { ...@@ -34,11 +34,8 @@ void MockAudioManager::ShowAudioInputSettings() {
void MockAudioManager::GetAudioInputDeviceNames( void MockAudioManager::GetAudioInputDeviceNames(
AudioDeviceNames* device_names) { AudioDeviceNames* device_names) {
DCHECK(device_names->empty()); // Do not inject fake devices here, use
device_names->push_back(media::AudioDeviceName("fake_device_name_1", // AudioInputDeviceManager::GetFakeDeviceNames() instead.
"fake_device_id_1"));
device_names->push_back(media::AudioDeviceName("fake_device_name_2",
"fake_device_id_2"));
} }
void MockAudioManager::GetAudioOutputDeviceNames( void MockAudioManager::GetAudioOutputDeviceNames(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment