diff options
author | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-01 18:58:58 +0000 |
---|---|---|
committer | hshi@chromium.org <hshi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-01 18:58:58 +0000 |
commit | f75204bedc56872cc0b76626fd53c34dd2d42c75 (patch) | |
tree | 490c4ba5f0cf09a82ac0755d2cea2f21926cde06 /media | |
parent | 0eb936f3cdcded92a08f9a720e76bb847f6ded9c (diff) | |
download | chromium_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.cc | 7 | ||||
-rw-r--r-- | media/audio/cras/audio_manager_cras.h | 4 | ||||
-rw-r--r-- | media/audio/cras/cras_input.cc | 10 | ||||
-rw-r--r-- | media/audio/cras/cras_input.h | 10 | ||||
-rw-r--r-- | media/audio/cras/cras_input_unittest.cc | 20 |
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 ¶ms, 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(); } |