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 @@
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_thread.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_manager_base.h"
#include "media/audio/audio_parameters.h"
......@@ -30,14 +29,6 @@ AudioInputDeviceManager::AudioInputDeviceManager(
next_capture_session_id_(kFirstSessionId),
use_fake_device_(false),
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() {
......@@ -123,19 +114,17 @@ void AudioInputDeviceManager::EnumerateOnDeviceThread(
SCOPED_UMA_HISTOGRAM_TIMER(
"Media.AudioInputDeviceManager.EnumerateOnDeviceThreadTime");
DCHECK(IsOnDeviceThread());
DCHECK_EQ(MEDIA_DEVICE_AUDIO_CAPTURE, stream_type);
media::AudioDeviceNames device_names;
switch (stream_type) {
case MEDIA_DEVICE_AUDIO_CAPTURE:
// AudioManager is guaranteed to outlive MediaStreamManager in
// BrowserMainloop.
audio_manager_->GetAudioInputDeviceNames(&device_names);
break;
default:
NOTREACHED();
break;
if (use_fake_device_) {
// Use the fake devices.
GetFakeDeviceNames(&device_names);
} else {
// Enumerate the devices on the OS.
// AudioManager is guaranteed to outlive MediaStreamManager in
// BrowserMainloop.
audio_manager_->GetAudioInputDeviceNames(&device_names);
}
scoped_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray());
......@@ -146,14 +135,6 @@ void AudioInputDeviceManager::EnumerateOnDeviceThread(
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
// IO thread since MediaStreamManager handles the callback asynchronously.
BrowserThread::PostTask(
......@@ -255,4 +236,18 @@ AudioInputDeviceManager::GetDevice(int session_id) {
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
......@@ -22,6 +22,7 @@
#include "content/common/content_export.h"
#include "content/common/media/media_stream_options.h"
#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_device_name.h"
namespace media {
class AudioManager;
......@@ -56,6 +57,10 @@ class CONTENT_EXPORT AudioInputDeviceManager : public MediaStreamProvider {
bool ShouldUseFakeDevice() const;
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;
virtual ~AudioInputDeviceManager();
......
......@@ -54,11 +54,6 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
public:
MAYBE_AudioInputDeviceManagerTest() {}
// Returns true iff machine has an audio input device.
bool CanRunAudioInputDeviceTests() {
return audio_manager_->HasAudioInputDevices();
}
protected:
virtual void SetUp() OVERRIDE {
// The test must run on Browser::IO.
......@@ -73,6 +68,7 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
&base::WaitableEvent::Signal, base::Unretained(&event)));
event.Wait();
manager_ = new AudioInputDeviceManager(audio_manager_.get());
manager_->UseFakeDevice();
audio_input_listener_.reset(new MockAudioInputDeviceManagerListener());
manager_->Register(audio_input_listener_.get(),
message_loop_->message_loop_proxy().get());
......@@ -106,8 +102,6 @@ class MAYBE_AudioInputDeviceManagerTest : public testing::Test {
// Opens and closes the devices.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenAndCloseDevice) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty());
......@@ -137,9 +131,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenAndCloseDevice) {
// Opens multiple devices at one time and closes them later.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenMultipleDevices) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty());
InSequence s;
......@@ -183,8 +174,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenMultipleDevices) {
// Opens a non-existing device.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenNotExistingDevice) {
if (!CanRunAudioInputDeviceTests())
return;
InSequence s;
MediaStreamType stream_type = MEDIA_DEVICE_AUDIO_CAPTURE;
......@@ -206,9 +195,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenNotExistingDevice) {
// Opens default device twice.
TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenDeviceTwice) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty());
InSequence s;
......@@ -242,9 +228,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, OpenDeviceTwice) {
// Accesses then closes the sessions after opening the devices.
TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessAndCloseSession) {
if (!CanRunAudioInputDeviceTests())
return;
ASSERT_FALSE(devices_.empty());
InSequence s;
......@@ -278,8 +261,6 @@ TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessAndCloseSession) {
// Access an invalid session.
TEST_F(MAYBE_AudioInputDeviceManagerTest, AccessInvalidSession) {
if (!CanRunAudioInputDeviceTests())
return;
InSequence s;
// Opens the first device.
......
......@@ -11,6 +11,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.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_manager.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
......@@ -247,7 +248,8 @@ class MediaStreamDispatcherHostTest : public testing::Test {
video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
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);
}
......
......@@ -20,10 +20,16 @@ namespace {
const int kBeepDurationMilliseconds = 20;
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 {
BeepContext() : beep_once(false) {}
BeepContext() : beep_once(false), automatic(true) {}
base::Lock beep_lock;
bool beep_once;
bool automatic;
};
static base::LazyInstance<BeepContext> g_beep_context =
......@@ -78,14 +84,37 @@ void FakeAudioInputStream::Start(AudioInputCallback* callback) {
void FakeAudioInputStream::DoCallback() {
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_);
bool should_beep = false;
{
BeepContext* beep_context = g_beep_context.Pointer();
base::AutoLock auto_lock(beep_context->beep_lock);
should_beep = beep_context->beep_once;
beep_context->beep_once = false;
if (beep_context->automatic) {
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
......@@ -103,7 +132,6 @@ void FakeAudioInputStream::DoCallback() {
while (position + high_bytes <= buffer_size_) {
// Write high values first.
memset(buffer_.get() + position, 128, high_bytes);
// Then leave low values in the buffer with |high_bytes|.
position += high_bytes * 2;
}
......@@ -116,16 +144,6 @@ void FakeAudioInputStream::DoCallback() {
callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_, 1.0);
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(
FROM_HERE,
base::Bind(&FakeAudioInputStream::DoCallback, base::Unretained(this)),
......@@ -163,6 +181,7 @@ void FakeAudioInputStream::BeepOnce() {
BeepContext* beep_context = g_beep_context.Pointer();
base::AutoLock auto_lock(beep_context->beep_lock);
beep_context->beep_once = true;
beep_context->automatic = false;
}
} // namespace media
......@@ -63,6 +63,7 @@ class MEDIA_EXPORT FakeAudioInputStream
base::Thread thread_;
base::TimeTicks last_callback_time_;
base::TimeDelta callback_interval_;
base::TimeDelta interval_from_last_beep_;
int beep_duration_in_buffers_;
int beep_generated_in_buffers_;
int beep_period_in_frames_;
......
......@@ -34,11 +34,8 @@ void MockAudioManager::ShowAudioInputSettings() {
void MockAudioManager::GetAudioInputDeviceNames(
AudioDeviceNames* device_names) {
DCHECK(device_names->empty());
device_names->push_back(media::AudioDeviceName("fake_device_name_1",
"fake_device_id_1"));
device_names->push_back(media::AudioDeviceName("fake_device_name_2",
"fake_device_id_2"));
// Do not inject fake devices here, use
// AudioInputDeviceManager::GetFakeDeviceNames() instead.
}
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