summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorhshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-01 18:58:58 +0000
committerhshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-01 18:58:58 +0000
commitf75204bedc56872cc0b76626fd53c34dd2d42c75 (patch)
tree490c4ba5f0cf09a82ac0755d2cea2f21926cde06 /media
parent0eb936f3cdcded92a08f9a720e76bb847f6ded9c (diff)
downloadchromium_src-f75204bedc56872cc0b76626fd53c34dd2d42c75.zip
chromium_src-f75204bedc56872cc0b76626fd53c34dd2d42c75.tar.gz
chromium_src-f75204bedc56872cc0b76626fd53c34dd2d42c75.tar.bz2
Enable audio desktop mirroring.
Define getUserMedia mandatory constraint {chromeMediaSource:"system"} to indicate audio loopback (post-mix system audio). Add plumbing in MediaCaptureDevicesDispatcher, AudioManagerCras and CrasInputStream classes to support the loopback path. BUG=261383 TEST=manually verify audio mirroring with a modified extension R=dalecurtis@chromium.org, miu@chromium.org, piman@chromium.org, xians@chromium.org Review URL: https://codereview.chromium.org/20847002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215077 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/cras/audio_manager_cras.cc7
-rw-r--r--media/audio/cras/audio_manager_cras.h4
-rw-r--r--media/audio/cras/cras_input.cc10
-rw-r--r--media/audio/cras/cras_input.h10
-rw-r--r--media/audio/cras/cras_input_unittest.cc20
5 files changed, 34 insertions, 17 deletions
diff --git a/media/audio/cras/audio_manager_cras.cc b/media/audio/cras/audio_manager_cras.cc
index 73d689a..165d642 100644
--- a/media/audio/cras/audio_manager_cras.cc
+++ b/media/audio/cras/audio_manager_cras.cc
@@ -22,6 +22,8 @@ static const int kMaxOutputStreams = 50;
// Default sample rate for input and output streams.
static const int kDefaultSampleRate = 48000;
+const char AudioManagerCras::kLoopbackDeviceId[] = "loopback";
+
bool AudioManagerCras::HasAudioOutputDevices() {
return true;
}
@@ -52,7 +54,8 @@ void AudioManagerCras::GetAudioInputDeviceNames(
AudioParameters AudioManagerCras::GetInputStreamParameters(
const std::string& device_id) {
static const int kDefaultInputBufferSize = 1024;
-
+ // TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal
+ // parameters for the loopback stream may differ from the default.
return AudioParameters(
AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
kDefaultSampleRate, 16, kDefaultInputBufferSize);
@@ -124,7 +127,7 @@ AudioOutputStream* AudioManagerCras::MakeOutputStream(
AudioInputStream* AudioManagerCras::MakeInputStream(
const AudioParameters& params, const std::string& device_id) {
- return new CrasInputStream(params, this);
+ return new CrasInputStream(params, this, device_id);
}
} // namespace media
diff --git a/media/audio/cras/audio_manager_cras.h b/media/audio/cras/audio_manager_cras.h
index 4e69c8f..fdc5b02 100644
--- a/media/audio/cras/audio_manager_cras.h
+++ b/media/audio/cras/audio_manager_cras.h
@@ -15,6 +15,10 @@ namespace media {
class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase {
public:
+ // Unique ID of the "loopback" input device. This device captures post-mix,
+ // pre-DSP system audio.
+ static const char kLoopbackDeviceId[];
+
AudioManagerCras();
// AudioManager implementation.
diff --git a/media/audio/cras/cras_input.cc b/media/audio/cras/cras_input.cc
index dec96b8..a82fe28 100644
--- a/media/audio/cras/cras_input.cc
+++ b/media/audio/cras/cras_input.cc
@@ -17,14 +17,18 @@
namespace media {
CrasInputStream::CrasInputStream(const AudioParameters& params,
- AudioManagerCras* manager)
+ AudioManagerCras* manager,
+ const std::string& device_id)
: audio_manager_(manager),
bytes_per_frame_(0),
callback_(NULL),
client_(NULL),
params_(params),
started_(false),
- stream_id_(0) {
+ stream_id_(0),
+ stream_direction_(device_id == AudioManagerCras::kLoopbackDeviceId
+ ? CRAS_STREAM_POST_MIX_PRE_DSP
+ : CRAS_STREAM_INPUT) {
DCHECK(audio_manager_);
}
@@ -127,7 +131,7 @@ void CrasInputStream::Start(AudioInputCallback* callback) {
unsigned int frames_per_packet = params_.frames_per_buffer();
cras_stream_params* stream_params = cras_client_stream_params_create(
- CRAS_STREAM_INPUT,
+ stream_direction_,
frames_per_packet, // Total latency.
frames_per_packet, // Call back when this many ready.
frames_per_packet, // Minimum Callback level ignored for capture streams.
diff --git a/media/audio/cras/cras_input.h b/media/audio/cras/cras_input.h
index 1b2a611..dd2cb54 100644
--- a/media/audio/cras/cras_input.h
+++ b/media/audio/cras/cras_input.h
@@ -27,7 +27,8 @@ class CrasInputStream : public AgcAudioStream<AudioInputStream> {
public:
// The ctor takes all the usual parameters, plus |manager| which is the
// audio manager who is creating this object.
- CrasInputStream(const AudioParameters& params, AudioManagerCras* manager);
+ CrasInputStream(const AudioParameters& params, AudioManagerCras* manager,
+ const std::string& device_id);
// The dtor is typically called by the AudioManager only and it is usually
// triggered by calling AudioOutputStream::Close().
@@ -76,7 +77,7 @@ class CrasInputStream : public AgcAudioStream<AudioInputStream> {
// want circular references. Additionally, stream objects live on the audio
// thread, which is owned by the audio manager and we don't want to addref
// the manager from that thread.
- AudioManagerCras* audio_manager_;
+ AudioManagerCras* const audio_manager_;
// Size of frame in bytes.
uint32 bytes_per_frame_;
@@ -88,7 +89,7 @@ class CrasInputStream : public AgcAudioStream<AudioInputStream> {
cras_client* client_;
// PCM parameters for the stream.
- AudioParameters params_;
+ const AudioParameters params_;
// True if the stream has been started.
bool started_;
@@ -96,6 +97,9 @@ class CrasInputStream : public AgcAudioStream<AudioInputStream> {
// ID of the playing stream.
cras_stream_id_t stream_id_;
+ // Direction of the stream.
+ const CRAS_STREAM_DIRECTION stream_direction_;
+
DISALLOW_COPY_AND_ASSIGN(CrasInputStream);
};
diff --git a/media/audio/cras/cras_input_unittest.cc b/media/audio/cras/cras_input_unittest.cc
index aba89f3..27ea985 100644
--- a/media/audio/cras/cras_input_unittest.cc
+++ b/media/audio/cras/cras_input_unittest.cc
@@ -62,13 +62,14 @@ class CrasInputStreamTest : public testing::Test {
kTestSampleRate,
kTestBitsPerSample,
samples_per_packet);
- return new CrasInputStream(params, mock_manager_.get());
+ return new CrasInputStream(params, mock_manager_.get(),
+ AudioManagerBase::kDefaultDeviceId);
}
void CaptureSomeFrames(const AudioParameters &params,
unsigned int duration_ms) {
- CrasInputStream* test_stream = new CrasInputStream(params,
- mock_manager_.get());
+ CrasInputStream* test_stream = new CrasInputStream(
+ params, mock_manager_.get(), AudioManagerBase::kDefaultDeviceId);
ASSERT_TRUE(test_stream->Open());
@@ -137,8 +138,8 @@ TEST_F(CrasInputStreamTest, BadBitsPerSample) {
kTestSampleRate,
kTestBitsPerSample - 1,
kTestFramesPerPacket);
- CrasInputStream* test_stream =
- new CrasInputStream(bad_bps_params, mock_manager_.get());
+ CrasInputStream* test_stream = new CrasInputStream(
+ bad_bps_params, mock_manager_.get(), AudioManagerBase::kDefaultDeviceId);
EXPECT_FALSE(test_stream->Open());
test_stream->Close();
}
@@ -149,8 +150,9 @@ TEST_F(CrasInputStreamTest, BadFormat) {
kTestSampleRate,
kTestBitsPerSample,
kTestFramesPerPacket);
- CrasInputStream* test_stream =
- new CrasInputStream(bad_format_params, mock_manager_.get());
+ CrasInputStream* test_stream = new CrasInputStream(
+ bad_format_params, mock_manager_.get(),
+ AudioManagerBase::kDefaultDeviceId);
EXPECT_FALSE(test_stream->Open());
test_stream->Close();
}
@@ -161,8 +163,8 @@ TEST_F(CrasInputStreamTest, BadSampleRate) {
0,
kTestBitsPerSample,
kTestFramesPerPacket);
- CrasInputStream* test_stream =
- new CrasInputStream(bad_rate_params, mock_manager_.get());
+ CrasInputStream* test_stream = new CrasInputStream(
+ bad_rate_params, mock_manager_.get(), AudioManagerBase::kDefaultDeviceId);
EXPECT_FALSE(test_stream->Open());
test_stream->Close();
}