diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-11 03:07:19 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-11 03:07:19 +0000 |
commit | 9ade381f46175dead00a1cc9ffc3328230e8c982 (patch) | |
tree | 64c6caf04643408b2e25bce192f03c9b7b93eaa2 /media | |
parent | adc19c0eeac9f3caaae4e35bd64e79e6b6e72a0f (diff) | |
download | chromium_src-9ade381f46175dead00a1cc9ffc3328230e8c982.zip chromium_src-9ade381f46175dead00a1cc9ffc3328230e8c982.tar.gz chromium_src-9ade381f46175dead00a1cc9ffc3328230e8c982.tar.bz2 |
Simplified AudioOutputStream interface.
1. Removed packet_size parameter from Open().
2. Removed OnClose() from the callback. Now the callback is guaranteed to be called only between Start() and Stop().
3. Added samples_per_packet in the AudioParameters struct.
BUG=39825
TEST=Unittests
Review URL: http://codereview.chromium.org/4661001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65766 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
46 files changed, 324 insertions, 404 deletions
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc index 45ab2c4..b5c9df2b 100644 --- a/media/audio/audio_input_controller.cc +++ b/media/audio/audio_input_controller.cc @@ -8,7 +8,6 @@ namespace { const int kMaxInputChannels = 2; -const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate; } // namespace @@ -31,15 +30,12 @@ AudioInputController::~AudioInputController() { // static scoped_refptr<AudioInputController> AudioInputController::Create( EventHandler* event_handler, - AudioParameters params, - int samples_per_packet) { - if (!params.IsValid() || - (params.channels > kMaxInputChannels) || - (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) + AudioParameters params) { + if (!params.IsValid() || (params.channels > kMaxInputChannels)) return NULL; if (factory_) { - return factory_->Create(event_handler, params, samples_per_packet); + return factory_->Create(event_handler, params); } scoped_refptr<AudioInputController> controller(new AudioInputController( @@ -50,7 +46,7 @@ scoped_refptr<AudioInputController> AudioInputController::Create( controller->thread_.message_loop()->PostTask( FROM_HERE, NewRunnableMethod(controller.get(), &AudioInputController::DoCreate, - params, samples_per_packet)); + params)); return controller; } @@ -75,10 +71,8 @@ void AudioInputController::Close() { thread_.Stop(); } -void AudioInputController::DoCreate(AudioParameters params, - uint32 samples_per_packet) { - stream_ = AudioManager::GetAudioManager()->MakeAudioInputStream( - params, samples_per_packet); +void AudioInputController::DoCreate(AudioParameters params) { + stream_ = AudioManager::GetAudioManager()->MakeAudioInputStream(params); if (!stream_) { // TODO(satish): Define error types. diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h index f6e8d1e..cfba450b3 100644 --- a/media/audio/audio_input_controller.h +++ b/media/audio/audio_input_controller.h @@ -55,8 +55,7 @@ class AudioInputController : class Factory { public: virtual AudioInputController* Create(EventHandler* event_handler, - AudioParameters params, - int samples_per_packet) = 0; + AudioParameters params) = 0; protected: virtual ~Factory() {} @@ -70,8 +69,7 @@ class AudioInputController : // handler will receive a OnCreated() call. static scoped_refptr<AudioInputController> Create( EventHandler* event_handler, - AudioParameters params, - int samples_per_packet); // Size of the hardware buffer. + AudioParameters params); // Sets the factory used by the static method Create. AudioInputController // does not take ownership of |factory|. A value of NULL results in an @@ -110,8 +108,7 @@ class AudioInputController : AudioInputController(EventHandler* handler); // The following methods are executed on the audio controller thread. - void DoCreate(AudioParameters params, - uint32 samples_per_packet); + void DoCreate(AudioParameters params); void DoRecord(); void DoClose(); void DoReportError(int code); diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc index 03219f8..ac57d2a 100644 --- a/media/audio/audio_input_controller_unittest.cc +++ b/media/audio/audio_input_controller_unittest.cc @@ -55,9 +55,9 @@ TEST(AudioInputControllerTest, CreateAndClose) { .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioInputController> controller = - AudioInputController::Create(&event_handler, params, kSamplesPerPacket); + AudioInputController::Create(&event_handler, params); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. @@ -86,9 +86,9 @@ TEST(AudioInputControllerTest, RecordAndClose) { .WillRepeatedly(CheckCountAndSignalEvent(&count, 10, &event)); AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioInputController> controller = - AudioInputController::Create(&event_handler, params, kSamplesPerPacket); + AudioInputController::Create(&event_handler, params); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. @@ -108,9 +108,9 @@ TEST(AudioInputControllerTest, SamplesPerPacketTooLarge) { MockAudioInputControllerEventHandler event_handler; AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket * 1000); scoped_refptr<AudioInputController> controller = AudioInputController::Create( - &event_handler, params, kSamplesPerPacket * 1000); + &event_handler, params); ASSERT_FALSE(controller); } @@ -119,9 +119,9 @@ TEST(AudioInputControllerTest, CloseTwice) { MockAudioInputControllerEventHandler event_handler; EXPECT_CALL(event_handler, OnCreated(NotNull())); AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioInputController> controller = - AudioInputController::Create(&event_handler, params, kSamplesPerPacket); + AudioInputController::Create(&event_handler, params); ASSERT_TRUE(controller.get()); controller->Close(); diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc index 6a67f0c..82cb887 100644 --- a/media/audio/audio_input_unittest.cc +++ b/media/audio/audio_input_unittest.cc @@ -104,8 +104,8 @@ bool CanRunAudioTests() { AudioInputStream* CreateTestAudioInputStream() { AudioManager* audio_man = AudioManager::GetAudioManager(); AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16), - kSamplesPerPacket); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, + 16, kSamplesPerPacket)); EXPECT_TRUE(NULL != ais); return ais; } @@ -119,21 +119,21 @@ TEST(AudioInputTest, SanityOnMakeParams) { AudioManager* audio_man = AudioManager::GetAudioManager(); AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR; EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, 8, 8000, 16), 0)); + AudioParameters(fmt, 8, 8000, 16, kSamplesPerPacket))); EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, 1, 1024 * 1024, 16), 0)); + AudioParameters(fmt, 1, 1024 * 1024, 16, kSamplesPerPacket))); EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, 2, 8000, 80), 0)); + AudioParameters(fmt, 2, 8000, 80, kSamplesPerPacket))); EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, 2, 8000, 80), 1024 * 4096)); + AudioParameters(fmt, 2, 8000, 80, 1000 * kSamplesPerPacket))); EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, -2, 8000, 16), 0)); + AudioParameters(fmt, -2, 8000, 16, kSamplesPerPacket))); EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, 2, -8000, 16), 0)); + AudioParameters(fmt, 2, -8000, 16, kSamplesPerPacket))); EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, 2, 8000, -16), 0)); + AudioParameters(fmt, 2, 8000, -16, kSamplesPerPacket))); EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( - AudioParameters(fmt, 2, 8000, 16), -1024)); + AudioParameters(fmt, 2, 8000, 16, -1024))); } // Test create and close of an AudioInputStream without recording audio. diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h index 3aa22cf..cadc5d3 100644 --- a/media/audio/audio_io.h +++ b/media/audio/audio_io.h @@ -40,6 +40,11 @@ // Models an audio stream that gets rendered to the audio hardware output. // Because we support more audio streams than physically available channels // a given AudioOutputStream might or might not talk directly to hardware. +// An audio stream allocates several buffers for audio data and calls +// AudioSourceCallback::OnModeData() periodically to fill these buffers, +// as the data is written to the audio device. Size of each packet is determined +// by |samples_per_packet| specified in AudioParameters when the stream is +// created. class AudioOutputStream { public: // Audio sources must implement AudioSourceCallback. This interface will be @@ -51,19 +56,16 @@ class AudioOutputStream { virtual ~AudioSourceCallback() {} // Provide more data by filling |dest| up to |max_size| bytes. The provided - // buffer size is usually what is specified in Open(). The source - // will return the number of bytes it filled. The expected structure of - // |dest| is platform and format specific. - // |pending_bytes| is the number of bytes will be played before the - // requested data is played. + // buffer size is determined by the |samples_per_packet| specified in + // AudioParameters when the stream is created. The source will return + // the number of bytes it filled. The expected structure of |dest| is + // platform and format specific. + // |buffers_state| contains current state of the buffers, and can be used + // by the source to calculate delay. virtual uint32 OnMoreData( AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState buffers_state) = 0; - // The stream is done with this callback. After this call the audio source - // can go away or be destroyed. - virtual void OnClose(AudioOutputStream* stream) = 0; - // There was an error while playing a buffer. Audio source cannot be // destroyed yet. No direct action needed by the AudioStream, but it is // a good place to stop accumulating sound data since is is likely that @@ -72,17 +74,8 @@ class AudioOutputStream { virtual void OnError(AudioOutputStream* stream, int code) = 0; }; - // Open the stream. |packet_size| is the requested buffer allocation which - // the audio source thinks it can usually fill without blocking. Internally - // two or three buffers of |packet_size| size are created, one will be - // locked for playback and one will be ready to be filled in the call to - // AudioSourceCallback::OnMoreData(). - // The number of buffers is controlled by AUDIO_PCM_LOW_LATENCY. See more - // information below. - // - // TODO(ajwong): Streams are not reusable, so try to move packet_size into the - // constructor. - virtual bool Open(uint32 packet_size) = 0; + // Open the stream. false is returned if the stream cannot be opened. + virtual bool Open() = 0; // Starts playing audio and generating AudioSourceCallback::OnMoreData(). // Since implementor of AudioOutputStream may have internal buffers, right diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h index 805db89..26f0acf 100644 --- a/media/audio/audio_manager.h +++ b/media/audio/audio_manager.h @@ -12,6 +12,9 @@ class AudioInputStream; class AudioOutputStream; class MessageLoop; +// TODO(sergeyu): In this interface and some other places AudioParameters struct +// is passed by value. It is better to change it to const reference. + // Manages all audio resources. In particular it owns the AudioOutputStream // objects. Provides some convenience functions that avoid the need to provide // iterators over the existing streams. @@ -26,14 +29,19 @@ class AudioManager { // sample rates. virtual bool HasAudioInputDevices() = 0; - // Factory for all the supported stream formats. The |channels| can be 1 to 5. - // The |sample_rate| is in hertz and can be any value supported by the - // platform. For some future formats the |sample_rate| and |bits_per_sample| - // can take special values. + // Factory for all the supported stream formats. |params| defines parameters + // of the audio stream to be created. + // + // |params.sample_per_packet| is the requested buffer allocation which the + // audio source thinks it can usually fill without blocking. Internally two + // or three buffers are created, one will be locked for playback and one will + // be ready to be filled in the call to AudioSourceCallback::OnMoreData(). + // // Returns NULL if the combination of the parameters is not supported, or if // we have reached some other platform specific limit. // - // AUDIO_PCM_LOW_LATENCY can be passed to this method and it has two effects: + // |params.format| can be set to AUDIO_PCM_LOW_LATENCY and that has two + // effects: // 1- Instead of triple buffered the audio will be double buffered. // 2- A low latency driver or alternative audio subsystem will be used when // available. @@ -53,8 +61,7 @@ class AudioManager { // // Do not free the returned AudioInputStream. It is owned by AudioManager. // When you are done with it, call |Stop()| and |Close()| to release it. - virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - int samples_per_packet) = 0; + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params) = 0; // Muting continues playback but effectively the volume is set to zero. // Un-muting returns the volume to the previous level. diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc index 4ba0f3e..033d4c5 100644 --- a/media/audio/audio_output_controller.cc +++ b/media/audio/audio_output_controller.cc @@ -6,23 +6,15 @@ #include "base/message_loop.h" -// The following parameters limit the request buffer and packet size from the -// renderer to avoid renderer from requesting too much memory. -static const uint32 kMegabytes = 1024 * 1024; -static const uint32 kMaxHardwareBufferSize = 2 * kMegabytes; // Signal a pause in low-latency mode. static const int kPauseMark = -1; namespace { // Return true if the parameters for creating an audio stream is valid. // Return false otherwise. -static bool CheckParameters(AudioParameters params, - uint32 hardware_buffer_size) { +static bool CheckParameters(AudioParameters params) { if (!params.IsValid()) return false; - if (hardware_buffer_size <= 0 || - hardware_buffer_size > kMaxHardwareBufferSize) - return false; return true; } @@ -51,10 +43,9 @@ AudioOutputController::~AudioOutputController() { scoped_refptr<AudioOutputController> AudioOutputController::Create( EventHandler* event_handler, AudioParameters params, - uint32 hardware_buffer_size, uint32 buffer_capacity) { - if (!CheckParameters(params, hardware_buffer_size)) + if (!CheckParameters(params)) return NULL; // Starts the audio controller thread. @@ -66,7 +57,7 @@ scoped_refptr<AudioOutputController> AudioOutputController::Create( controller->message_loop_->PostTask( FROM_HERE, NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate, - params, hardware_buffer_size)); + params)); return controller; } @@ -74,12 +65,11 @@ scoped_refptr<AudioOutputController> AudioOutputController::Create( scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency( EventHandler* event_handler, AudioParameters params, - uint32 hardware_buffer_size, SyncReader* sync_reader) { DCHECK(sync_reader); - if (!CheckParameters(params, hardware_buffer_size)) + if (!CheckParameters(params)) return NULL; // Starts the audio controller thread. @@ -91,7 +81,7 @@ scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency( controller->message_loop_->PostTask( FROM_HERE, NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate, - params, hardware_buffer_size)); + params)); return controller; } @@ -144,8 +134,7 @@ void AudioOutputController::EnqueueData(const uint8* data, uint32 size) { } } -void AudioOutputController::DoCreate(AudioParameters params, - uint32 hardware_buffer_size) { +void AudioOutputController::DoCreate(AudioParameters params) { DCHECK_EQ(message_loop_, MessageLoop::current()); // Close() can be called before DoCreate() is executed. @@ -160,7 +149,7 @@ void AudioOutputController::DoCreate(AudioParameters params, return; } - if (!stream_->Open(hardware_buffer_size)) { + if (!stream_->Open()) { stream_->Close(); stream_ = NULL; @@ -168,6 +157,7 @@ void AudioOutputController::DoCreate(AudioParameters params, handler_->OnError(this, 0); return; } + // We have successfully opened the stream. Set the initial volume. stream_->SetVolume(volume_); @@ -246,6 +236,10 @@ void AudioOutputController::DoClose(Task* closed_task) { stream_ = NULL; } + if (LowLatencyMode()) { + sync_reader_->Close(); + } + state_ = kClosed; } @@ -299,15 +293,6 @@ uint32 AudioOutputController::OnMoreData( return size; } -void AudioOutputController::OnClose(AudioOutputStream* stream) { - DCHECK_EQ(message_loop_, MessageLoop::current()); - - // Push source doesn't need to know the stream so just pass in NULL. - if (LowLatencyMode()) { - sync_reader_->Close(); - } -} - void AudioOutputController::OnError(AudioOutputStream* stream, int code) { // Handle error on the audio controller thread. message_loop_->PostTask( diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h index 6c1ba89..0a191e3 100644 --- a/media/audio/audio_output_controller.h +++ b/media/audio/audio_output_controller.h @@ -108,8 +108,6 @@ class AudioOutputController static scoped_refptr<AudioOutputController> Create( EventHandler* event_handler, AudioParameters params, - uint32 hardware_buffer_size, // Size of the hardware buffer. - // Soft limit for buffer capacity in this controller. This parameter // is used only in regular latency mode. uint32 buffer_capacity); @@ -118,8 +116,6 @@ class AudioOutputController static scoped_refptr<AudioOutputController> CreateLowLatency( EventHandler* event_handler, AudioParameters params, - uint32 hardware_buffer_size, // Size of the hardware buffer. - // External synchronous reader for audio controller. SyncReader* sync_reader); @@ -158,7 +154,6 @@ class AudioOutputController // AudioSourceCallback methods. virtual uint32 OnMoreData(AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState buffers_state); - virtual void OnClose(AudioOutputStream* stream); virtual void OnError(AudioOutputStream* stream, int code); private: @@ -166,7 +161,7 @@ class AudioOutputController uint32 capacity, SyncReader* sync_reader); // The following methods are executed on the audio controller thread. - void DoCreate(AudioParameters params, uint32 hardware_buffer_size); + void DoCreate(AudioParameters params); void DoPlay(); void DoPause(); void DoFlush(); diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc index 6997016..d70aed1 100644 --- a/media/audio/audio_output_controller_unittest.cc +++ b/media/audio/audio_output_controller_unittest.cc @@ -21,8 +21,9 @@ using ::testing::Return; static const int kSampleRate = AudioParameters::kAudioCDSampleRate; static const int kBitsPerSample = 16; static const int kChannels = 2; -static const int kHardwareBufferSize = kSampleRate * kBitsPerSample * - kChannels / 8; +static const int kSamplesPerPacket = kSampleRate / 10; +static const int kHardwareBufferSize = kSamplesPerPacket * kChannels * + kBitsPerSample / 8; static const int kBufferCapacity = 3 * kHardwareBufferSize; namespace media { @@ -97,10 +98,9 @@ TEST(AudioOutputControllerTest, CreateAndClose) { EXPECT_CALL(event_handler, OnMoreData(NotNull(), _)); AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, params, - kHardwareBufferSize, kBufferCapacity); + AudioOutputController::Create(&event_handler, params, kBufferCapacity); ASSERT_TRUE(controller.get()); // Close the controller immediately. @@ -128,10 +128,9 @@ TEST(AudioOutputControllerTest, PlayAndClose) { .WillRepeatedly(SignalEvent(&event)); AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, params, - kHardwareBufferSize, kBufferCapacity); + AudioOutputController::Create(&event_handler, params, kBufferCapacity); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. @@ -178,10 +177,9 @@ TEST(AudioOutputControllerTest, PlayPauseClose) { .WillOnce(InvokeWithoutArgs(&pause_event, &base::WaitableEvent::Signal)); AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, params, - kHardwareBufferSize, kBufferCapacity); + AudioOutputController::Create(&event_handler, params, kBufferCapacity); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. @@ -239,10 +237,9 @@ TEST(AudioOutputControllerTest, PlayPausePlay) { .RetiresOnSaturation(); AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, params, - kHardwareBufferSize, kBufferCapacity); + AudioOutputController::Create(&event_handler, params, kBufferCapacity); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. @@ -283,10 +280,10 @@ TEST(AudioOutputControllerTest, HardwareBufferTooLarge) { // Create an audio device with a very large hardware buffer size. MockAudioOutputControllerEventHandler event_handler; AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, + kSamplesPerPacket * 1000); scoped_refptr<AudioOutputController> controller = AudioOutputController::Create(&event_handler, params, - kHardwareBufferSize * 1000, kBufferCapacity); // Use assert because we don't stop the device and assume we can't @@ -311,10 +308,9 @@ TEST(AudioOutputControllerTest, CloseTwice) { .WillRepeatedly(SignalEvent(&event)); AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels, - kSampleRate, kBitsPerSample); + kSampleRate, kBitsPerSample, kSamplesPerPacket); scoped_refptr<AudioOutputController> controller = - AudioOutputController::Create(&event_handler, params, - kHardwareBufferSize, kBufferCapacity); + AudioOutputController::Create(&event_handler, params, kBufferCapacity); ASSERT_TRUE(controller.get()); // Wait for OnCreated() to be called. diff --git a/media/audio/audio_parameters.cc b/media/audio/audio_parameters.cc index ca12452..b0a691b 100644 --- a/media/audio/audio_parameters.cc +++ b/media/audio/audio_parameters.cc @@ -10,15 +10,18 @@ AudioParameters::AudioParameters() : format(AUDIO_PCM_LINEAR), channels(0), sample_rate(0), - bits_per_sample(0) { + bits_per_sample(0), + samples_per_packet(0) { } AudioParameters::AudioParameters(Format format, int channels, - int sample_rate, int bits_per_sample) + int sample_rate, int bits_per_sample, + int samples_per_packet) : format(format), channels(channels), sample_rate(sample_rate), - bits_per_sample(bits_per_sample) { + bits_per_sample(bits_per_sample), + samples_per_packet(samples_per_packet) { } bool AudioParameters::IsValid() const { @@ -26,5 +29,11 @@ bool AudioParameters::IsValid() const { (channels > 0) && (channels <= media::Limits::kMaxChannels) && (sample_rate > 0) && (sample_rate <= media::Limits::kMaxSampleRate) && (bits_per_sample > 0) && - (bits_per_sample <= media::Limits::kMaxBitsPerSample); + (bits_per_sample <= media::Limits::kMaxBitsPerSample) && + (samples_per_packet > 0) && + (samples_per_packet <= media::Limits::kMaxSamplesPerPacket); +} + +int AudioParameters::GetPacketSize() const { + return samples_per_packet * channels * bits_per_sample / 8; } diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h index b7b8ae5..9172d74 100644 --- a/media/audio/audio_parameters.h +++ b/media/audio/audio_parameters.h @@ -24,15 +24,21 @@ struct AudioParameters { AudioParameters(); - AudioParameters(Format format, int channels, - int sample_rate, int bits_per_sample); + AudioParameters(Format format, int channels, int sample_rate, + int bits_per_sample, int samples_per_packet); + // Checks that all values are in the expected range. All limits are specified + // in media::Limits. bool IsValid() const; - Format format; // Format of the stream. - int channels; // Number of channels. - int sample_rate; // Sampling frequency/rate. - int bits_per_sample; // Number of bits per sample. + // Returns size of audio packets in bytes. + int GetPacketSize() const; + + Format format; // Format of the stream. + int channels; // Number of channels. + int sample_rate; // Sampling frequency/rate. + int bits_per_sample; // Number of bits per sample. + int samples_per_packet; // Size of a packet in frames. }; #endif // MEDIA_AUDIO_AUDIO_PARAMETERS_H_ diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc index a60446a..dacea2f 100644 --- a/media/audio/fake_audio_input_stream.cc +++ b/media/audio/fake_audio_input_stream.cc @@ -7,18 +7,17 @@ using base::Time; using base::TimeDelta; -AudioInputStream* FakeAudioInputStream::MakeFakeStream(AudioParameters params, - int samples_per_packet) { - return new FakeAudioInputStream(params, samples_per_packet); +AudioInputStream* FakeAudioInputStream::MakeFakeStream(AudioParameters params) { + return new FakeAudioInputStream(params); } -FakeAudioInputStream::FakeAudioInputStream(AudioParameters params, - int samples_per_packet) +FakeAudioInputStream::FakeAudioInputStream(AudioParameters params) : callback_(NULL), buffer_size_((params.channels * params.bits_per_sample * - samples_per_packet) / 8), + params.samples_per_packet) / 8), thread_("FakeAudioRecordingThread"), - callback_interval_ms_((samples_per_packet * 1000) / params.sample_rate) { + callback_interval_ms_((params.samples_per_packet * 1000) / + params.sample_rate) { // This object is ref counted (so that it can be used with Thread, PostTask) // but the caller expects a plain pointer. So we take a reference here and // will Release() ourselves in Close(). diff --git a/media/audio/fake_audio_input_stream.h b/media/audio/fake_audio_input_stream.h index d1e3260..62ab504 100644 --- a/media/audio/fake_audio_input_stream.h +++ b/media/audio/fake_audio_input_stream.h @@ -20,8 +20,7 @@ class FakeAudioInputStream : public AudioInputStream, public base::RefCountedThreadSafe<FakeAudioInputStream> { public: - static AudioInputStream* MakeFakeStream(AudioParameters params, - int samples_per_packet); + static AudioInputStream* MakeFakeStream(AudioParameters params); virtual bool Open(); virtual void Start(AudioInputCallback* callback); @@ -32,7 +31,7 @@ class FakeAudioInputStream : // Give RefCountedThreadSafe access our destructor. friend class base::RefCountedThreadSafe<FakeAudioInputStream>; - FakeAudioInputStream(AudioParameters params, int samples_per_packet); + FakeAudioInputStream(AudioParameters params); virtual ~FakeAudioInputStream(); void DoCallback(); diff --git a/media/audio/fake_audio_input_stream_unittest.cc b/media/audio/fake_audio_input_stream_unittest.cc index eee8c92..1e37359 100644 --- a/media/audio/fake_audio_input_stream_unittest.cc +++ b/media/audio/fake_audio_input_stream_unittest.cc @@ -41,7 +41,7 @@ TEST(FakeAudioInputTest, BasicCallbacks) { ASSERT_TRUE(NULL != audio_man); // Ask for one recorded packet every 50ms. AudioInputStream* stream = audio_man->MakeAudioInputStream( - AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8), 400); + AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8, 400)); ASSERT_TRUE(NULL != stream); EXPECT_TRUE(stream->Open()); stream->Start(&callback); diff --git a/media/audio/fake_audio_output_stream.cc b/media/audio/fake_audio_output_stream.cc index d69e80a..1530227 100644 --- a/media/audio/fake_audio_output_stream.cc +++ b/media/audio/fake_audio_output_stream.cc @@ -11,12 +11,13 @@ bool FakeAudioOutputStream::has_created_fake_stream_ = false; FakeAudioOutputStream* FakeAudioOutputStream::last_fake_stream_ = NULL; // static -AudioOutputStream* FakeAudioOutputStream::MakeFakeStream() { +AudioOutputStream* FakeAudioOutputStream::MakeFakeStream( + AudioParameters params) { if (!has_created_fake_stream_) base::AtExitManager::RegisterCallback(&DestroyLastFakeStream, NULL); has_created_fake_stream_ = true; - FakeAudioOutputStream* new_stream = new FakeAudioOutputStream(); + FakeAudioOutputStream* new_stream = new FakeAudioOutputStream(params); if (last_fake_stream_) { DCHECK(last_fake_stream_->closed_); @@ -32,10 +33,9 @@ FakeAudioOutputStream* FakeAudioOutputStream::GetLastFakeStream() { return last_fake_stream_; } -bool FakeAudioOutputStream::Open(uint32 packet_size) { - if (packet_size < sizeof(int16)) +bool FakeAudioOutputStream::Open() { + if (packet_size_ < sizeof(int16)) return false; - packet_size_ = packet_size; buffer_.reset(new uint8[packet_size_]); return true; } @@ -48,6 +48,7 @@ void FakeAudioOutputStream::Start(AudioSourceCallback* callback) { } void FakeAudioOutputStream::Stop() { + callback_ = NULL; } void FakeAudioOutputStream::SetVolume(double volume) { @@ -59,19 +60,13 @@ void FakeAudioOutputStream::GetVolume(double* volume) { } void FakeAudioOutputStream::Close() { - // Calls |callback_| only if it is valid. We don't have |callback_| if - // we have not yet started. - if (callback_) { - callback_->OnClose(this); - callback_ = NULL; - } closed_ = true; } -FakeAudioOutputStream::FakeAudioOutputStream() +FakeAudioOutputStream::FakeAudioOutputStream(AudioParameters params) : volume_(0), callback_(NULL), - packet_size_(0), + packet_size_(params.GetPacketSize()), closed_(false) { } diff --git a/media/audio/fake_audio_output_stream.h b/media/audio/fake_audio_output_stream.h index 35aed2a..5d80a8e 100644 --- a/media/audio/fake_audio_output_stream.h +++ b/media/audio/fake_audio_output_stream.h @@ -13,13 +13,14 @@ #include "base/scoped_ptr.h" #include "media/audio/audio_io.h" +#include "media/audio/audio_parameters.h" class FakeAudioOutputStream : public AudioOutputStream { public: - static AudioOutputStream* MakeFakeStream(); + static AudioOutputStream* MakeFakeStream(AudioParameters params); static FakeAudioOutputStream* GetLastFakeStream(); - virtual bool Open(uint32 packet_size); + virtual bool Open(); virtual void Start(AudioSourceCallback* callback); virtual void Stop(); virtual void SetVolume(double volume); @@ -30,7 +31,7 @@ class FakeAudioOutputStream : public AudioOutputStream { double volume() { return volume_; } private: - FakeAudioOutputStream(); + explicit FakeAudioOutputStream(AudioParameters params); virtual ~FakeAudioOutputStream(); static void DestroyLastFakeStream(void* param); diff --git a/media/audio/linux/alsa_input.cc b/media/audio/linux/alsa_input.cc index 800be6f..13aea5b4 100644 --- a/media/audio/linux/alsa_input.cc +++ b/media/audio/linux/alsa_input.cc @@ -28,16 +28,14 @@ const char* AlsaPcmInputStream::kAutoSelectDevice = ""; AlsaPcmInputStream::AlsaPcmInputStream(const std::string& device_name, const AudioParameters& params, - int samples_per_packet, AlsaWrapper* wrapper) : device_name_(device_name), params_(params), - samples_per_packet_(samples_per_packet), - bytes_per_packet_(samples_per_packet_ * + bytes_per_packet_(params.samples_per_packet * (params.channels * params.bits_per_sample) / 8), wrapper_(wrapper), packet_duration_ms_( - (samples_per_packet_ * base::Time::kMillisecondsPerSecond) / + (params.samples_per_packet * base::Time::kMillisecondsPerSecond) / params.sample_rate), callback_(NULL), device_handle_(NULL), @@ -147,7 +145,7 @@ void AlsaPcmInputStream::ReadAudio() { Recover(frames); } - if (frames < samples_per_packet_) { + if (frames < params_.samples_per_packet) { // Not enough data yet or error happened. In both cases wait for a very // small duration before checking again. MessageLoop::current()->PostDelayedTask( @@ -157,15 +155,15 @@ void AlsaPcmInputStream::ReadAudio() { return; } - int num_packets = frames / samples_per_packet_; + int num_packets = frames / params_.samples_per_packet; while (num_packets--) { int frames_read = wrapper_->PcmReadi(device_handle_, audio_packet_.get(), - samples_per_packet_); - if (frames_read == samples_per_packet_) { + params_.samples_per_packet); + if (frames_read == params_.samples_per_packet) { callback_->OnData(this, audio_packet_.get(), bytes_per_packet_); } else { LOG(WARNING) << "PcmReadi returning less than expected frames: " - << frames_read << " vs. " << samples_per_packet_ + << frames_read << " vs. " << params_.samples_per_packet << ". Dropping this packet."; } } @@ -213,4 +211,3 @@ void AlsaPcmInputStream::HandleError(const char* method, int error) { LOG(WARNING) << method << ": " << wrapper_->StrError(error); callback_->OnError(this, error); } - diff --git a/media/audio/linux/alsa_input.h b/media/audio/linux/alsa_input.h index d0ed07d..94af7df 100644 --- a/media/audio/linux/alsa_input.h +++ b/media/audio/linux/alsa_input.h @@ -30,7 +30,6 @@ class AlsaPcmInputStream : public AudioInputStream { // |kAutoSelectDevice|. AlsaPcmInputStream(const std::string& device_name, const AudioParameters& params, - int samples_per_packet, AlsaWrapper* wrapper); virtual ~AlsaPcmInputStream(); @@ -53,7 +52,6 @@ class AlsaPcmInputStream : public AudioInputStream { std::string device_name_; AudioParameters params_; - int samples_per_packet_; int bytes_per_packet_; AlsaWrapper* wrapper_; int packet_duration_ms_; // Length of each recorded packet in milliseconds. diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc index 410ed15f..6df30b4 100644 --- a/media/audio/linux/alsa_output.cc +++ b/media/audio/linux/alsa_output.cc @@ -232,15 +232,18 @@ AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, bytes_per_sample_(params.bits_per_sample / 8), bytes_per_frame_(channels_ * params.bits_per_sample / 8), should_downmix_(false), - latency_micros_(0), - micros_per_packet_(0), + packet_size_(params.GetPacketSize()), + micros_per_packet_(FramesToMicros( + params.samples_per_packet, sample_rate_)), + latency_micros_(std::max(AlsaPcmOutputStream::kMinLatencyMicros, + micros_per_packet_ * 2)), bytes_per_output_frame_(bytes_per_frame_), alsa_buffer_frames_(0), stop_stream_(false), wrapper_(wrapper), manager_(manager), playback_handle_(NULL), - frames_per_packet_(0), + frames_per_packet_(packet_size_ / bytes_per_frame_), client_thread_loop_(MessageLoop::current()), message_loop_(message_loop) { @@ -271,13 +274,9 @@ AlsaPcmOutputStream::~AlsaPcmOutputStream() { // where the stream is not always stopped and closed, causing this to fail. } -bool AlsaPcmOutputStream::Open(uint32 packet_size) { +bool AlsaPcmOutputStream::Open() { DCHECK_EQ(MessageLoop::current(), client_thread_loop_); - DCHECK_EQ(0U, packet_size % bytes_per_frame_) - << "Buffers should end on a frame boundary. Frame size: " - << bytes_per_frame_; - if (shared_data_.state() == kInError) { return false; } @@ -294,7 +293,7 @@ bool AlsaPcmOutputStream::Open(uint32 packet_size) { shared_data_.TransitionTo(kIsOpened); message_loop_->PostTask( FROM_HERE, - NewRunnableMethod(this, &AlsaPcmOutputStream::OpenTask, packet_size)); + NewRunnableMethod(this, &AlsaPcmOutputStream::OpenTask)); return true; } @@ -308,10 +307,6 @@ void AlsaPcmOutputStream::Close() { NOTREACHED() << "Unable to transition Closed."; } - // Signal our successful close, and disassociate the source callback. - shared_data_.OnClose(this); - shared_data_.set_source_callback(NULL); - message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &AlsaPcmOutputStream::CloseTask)); @@ -340,6 +335,9 @@ void AlsaPcmOutputStream::Start(AudioSourceCallback* callback) { void AlsaPcmOutputStream::Stop() { DCHECK_EQ(MessageLoop::current(), client_thread_loop_); + // Reset the callback, so that it is not called anymore. + shared_data_.set_source_callback(NULL); + shared_data_.TransitionTo(kIsStopped); } @@ -355,18 +353,10 @@ void AlsaPcmOutputStream::GetVolume(double* volume) { *volume = shared_data_.volume(); } -void AlsaPcmOutputStream::OpenTask(uint32 packet_size) { +void AlsaPcmOutputStream::OpenTask() { DCHECK_EQ(message_loop_, MessageLoop::current()); - // Initialize the configuration variables. - packet_size_ = packet_size; - frames_per_packet_ = packet_size_ / bytes_per_frame_; - // Try to open the device. - micros_per_packet_ = - FramesToMicros(packet_size / bytes_per_frame_, sample_rate_); - latency_micros_ = std::max(AlsaPcmOutputStream::kMinLatencyMicros, - micros_per_packet_ * 2); if (requested_device_name_ == kAutoSelectDevice) { playback_handle_ = AutoSelectDevice(latency_micros_); if (playback_handle_) @@ -920,13 +910,6 @@ uint32 AlsaPcmOutputStream::SharedData::OnMoreData( return 0; } -void AlsaPcmOutputStream::SharedData::OnClose(AudioOutputStream* stream) { - AutoLock l(lock_); - if (source_callback_) { - source_callback_->OnClose(stream); - } -} - void AlsaPcmOutputStream::SharedData::OnError(AudioOutputStream* stream, int code) { AutoLock l(lock_); diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h index bd1ecb9..25ff055 100644 --- a/media/audio/linux/alsa_output.h +++ b/media/audio/linux/alsa_output.h @@ -24,6 +24,13 @@ // threading assumptions at the top of the implementation file to avoid // introducing race conditions between tasks posted to the internal // message_loop, and the thread calling the public APIs. +// +// TODO(sergeyu): AlsaPcmOutputStream is always created and used from the +// audio thread (i.e. |client_thread_loop_| and |message_loop_| always point +// to the same thread), so it doesn't need to be thread-safe anymore. +// +// TODO(sergeyu): Remove refcounter from AlsaPcmOutputStream and use +// ScopedRunnableMethodFactory to create tasks. #ifndef MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ #define MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ @@ -79,7 +86,7 @@ class AlsaPcmOutputStream : MessageLoop* message_loop); // Implementation of AudioOutputStream. - virtual bool Open(uint32 packet_size); + virtual bool Open(); virtual void Close(); virtual void Start(AudioSourceCallback* callback); virtual void Stop(); @@ -127,7 +134,7 @@ class AlsaPcmOutputStream : friend std::ostream& operator<<(std::ostream& os, InternalState); // Various tasks that complete actions started in the public API. - void OpenTask(uint32 packet_size); + void OpenTask(); void StartTask(); void CloseTask(); @@ -179,7 +186,6 @@ class AlsaPcmOutputStream : // using a deleted callback. uint32 OnMoreData(AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState buffers_state); - void OnClose(AudioOutputStream* stream); void OnError(AudioOutputStream* stream, int code); // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to @@ -211,9 +217,9 @@ class AlsaPcmOutputStream : // Device configuration data. Populated after OpenTask() completes. std::string device_name_; bool should_downmix_; - uint32 latency_micros_; uint32 packet_size_; uint32 micros_per_packet_; + uint32 latency_micros_; uint32 bytes_per_output_frame_; uint32 alsa_buffer_frames_; diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc index cd50919..83c0eff 100644 --- a/media/audio/linux/alsa_output_unittest.cc +++ b/media/audio/linux/alsa_output_unittest.cc @@ -70,7 +70,6 @@ class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState buffers_state)); - MOCK_METHOD1(OnClose, void(AudioOutputStream* stream)); MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); }; @@ -96,16 +95,20 @@ class MockAudioManagerLinux : public AudioManagerLinux { class AlsaPcmOutputStreamTest : public testing::Test { protected: AlsaPcmOutputStreamTest() { - test_stream_ = CreateStreamWithChannels(kTestChannels); + test_stream_ = CreateStream(kTestChannels); } virtual ~AlsaPcmOutputStreamTest() { test_stream_ = NULL; } - AlsaPcmOutputStream* CreateStreamWithChannels(int channels) { + AlsaPcmOutputStream* CreateStream(int channels) { + return CreateStream(channels, kTestFramesPerPacket); + } + + AlsaPcmOutputStream* CreateStream(int channels, int32 samples_per_packet) { AudioParameters params(kTestFormat, channels, kTestSampleRate, - kTestBitsPerSample); + kTestBitsPerSample, samples_per_packet); return new AlsaPcmOutputStream(kTestDeviceName, params, &mock_alsa_wrapper_, @@ -197,18 +200,19 @@ TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { test_stream_->shared_data_.state()); // Should support mono. - test_stream_ = CreateStreamWithChannels(1); + test_stream_ = CreateStream(1); EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->shared_data_.state()); // Should support multi-channel. - test_stream_ = CreateStreamWithChannels(3); + test_stream_ = CreateStream(3); EXPECT_EQ(AlsaPcmOutputStream::kCreated, test_stream_->shared_data_.state()); // Bad bits per sample. AudioParameters bad_bps_params(kTestFormat, kTestChannels, - kTestSampleRate, kTestBitsPerSample - 1); + kTestSampleRate, kTestBitsPerSample - 1, + kTestFramesPerPacket); test_stream_ = new AlsaPcmOutputStream(kTestDeviceName, bad_bps_params, &mock_alsa_wrapper_, @@ -220,7 +224,7 @@ TEST_F(AlsaPcmOutputStreamTest, ConstructedState) { // Bad format. AudioParameters bad_format_params( AudioParameters::AUDIO_LAST_FORMAT, kTestChannels, - kTestSampleRate, kTestBitsPerSample); + kTestSampleRate, kTestBitsPerSample, kTestFramesPerPacket); test_stream_ = new AlsaPcmOutputStream(kTestDeviceName, bad_format_params, &mock_alsa_wrapper_, @@ -235,8 +239,6 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { static_cast<double>(1000000) / kTestSampleRate; const double kPacketFramesInMinLatency = AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0; - const int kMinLatencyPacketSize = - static_cast<int>(kPacketFramesInMinLatency * kTestBytesPerFrame); // Test that packets which would cause a latency under less than // AlsaPcmOutputStream::kMinLatencyMicros will get clipped to @@ -253,7 +255,8 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); - ASSERT_TRUE(test_stream_->Open(kMinLatencyPacketSize)); + test_stream_ = CreateStream(kTestChannels, kPacketFramesInMinLatency); + ASSERT_TRUE(test_stream_->Open()); message_loop_.RunAllPending(); // Now close it and test that everything was released. @@ -268,15 +271,9 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { Mock::VerifyAndClear(&mock_manager_); // Test that having more packets ends up with a latency based on packet size. - const int kOverMinLatencyPacketSize = - (kPacketFramesInMinLatency + 1) * kTestBytesPerFrame; - int64 expected_micros = 2 * - AlsaPcmOutputStream::FramesToMicros( - kOverMinLatencyPacketSize / kTestBytesPerFrame, - kTestSampleRate); - - // Recreate the stream to reset the state. - test_stream_ = CreateStreamWithChannels(kTestChannels); + const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1; + int64 expected_micros = 2 * AlsaPcmOutputStream::FramesToMicros( + kOverMinLatencyPacketSize, kTestSampleRate); EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _)) .WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0))); @@ -288,7 +285,8 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { SetArgumentPointee<2>(kTestFramesPerPacket / 2), Return(0))); - ASSERT_TRUE(test_stream_->Open(kOverMinLatencyPacketSize)); + test_stream_ = CreateStream(kTestChannels, kOverMinLatencyPacketSize); + ASSERT_TRUE(test_stream_->Open()); message_loop_.RunAllPending(); // Now close it and test that everything was released. @@ -332,7 +330,7 @@ TEST_F(AlsaPcmOutputStreamTest, OpenClose) { Return(0))); // Open the stream. - ASSERT_TRUE(test_stream_->Open(kTestPacketSize)); + ASSERT_TRUE(test_stream_->Open()); message_loop_.RunAllPending(); EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, @@ -363,7 +361,7 @@ TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { .WillOnce(Return(kDummyMessage)); // Open still succeeds since PcmOpen is delegated to another thread. - ASSERT_TRUE(test_stream_->Open(kTestPacketSize)); + ASSERT_TRUE(test_stream_->Open()); ASSERT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->shared_data_.state()); ASSERT_FALSE(test_stream_->stop_stream_); @@ -397,7 +395,7 @@ TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { // If open fails, the stream stays in kCreated because it has effectively had // no changes. - ASSERT_TRUE(test_stream_->Open(kTestPacketSize)); + ASSERT_TRUE(test_stream_->Open()); EXPECT_EQ(AlsaPcmOutputStream::kIsOpened, test_stream_->shared_data_.state()); ASSERT_FALSE(test_stream_->stop_stream_); @@ -431,7 +429,7 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) { Return(0))); // Open the stream. - ASSERT_TRUE(test_stream_->Open(kTestPacketSize)); + ASSERT_TRUE(test_stream_->Open()); message_loop_.RunAllPending(); // Expect Device setup. @@ -469,7 +467,6 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) { message_loop_.RunAllPending(); EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get())); - EXPECT_CALL(mock_callback, OnClose(test_stream_.get())); EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle)) .WillOnce(Return(0)); EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle)) @@ -684,7 +681,7 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { .WillRepeatedly(Invoke(EchoHint)); - test_stream_ = CreateStreamWithChannels(i); + test_stream_ = CreateStream(i); EXPECT_TRUE(test_stream_->AutoSelectDevice(i)); EXPECT_EQ(kExpectedDownmix[i], test_stream_->should_downmix_); @@ -734,7 +731,7 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_FallbackDevices) { EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(fourth_try.c_str()), _, _)) .WillOnce(Return(kTestFailedErrno)); - test_stream_ = CreateStreamWithChannels(5); + test_stream_ = CreateStream(5); EXPECT_FALSE(test_stream_->AutoSelectDevice(5)); } @@ -752,7 +749,7 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) .WillOnce(Return(kDummyMessage)); - test_stream_ = CreateStreamWithChannels(5); + test_stream_ = CreateStream(5); EXPECT_TRUE(test_stream_->AutoSelectDevice(5)); EXPECT_TRUE(test_stream_->should_downmix_); } diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc index b22ec44..fdf8044 100644 --- a/media/audio/linux/audio_manager_linux.cc +++ b/media/audio/linux/audio_manager_linux.cc @@ -17,7 +17,6 @@ namespace { const int kMaxInputChannels = 2; -const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate; } // namespace @@ -37,7 +36,7 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( // Early return for testing hook. Do this before checking for // |initialized_|. if (params.format == AudioParameters::AUDIO_MOCK) { - return FakeAudioOutputStream::MakeFakeStream(); + return FakeAudioOutputStream::MakeFakeStream(params); } if (!initialized()) { @@ -60,13 +59,12 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( } AudioInputStream* AudioManagerLinux::MakeAudioInputStream( - AudioParameters params, int samples_per_packet) { - if (!params.IsValid() || params.channels > kMaxInputChannels || - samples_per_packet < 0 || samples_per_packet > kMaxSamplesPerPacket) + AudioParameters params) { + if (!params.IsValid() || params.channels > kMaxInputChannels) return NULL; if (params.format == AudioParameters::AUDIO_MOCK) { - return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); + return FakeAudioInputStream::MakeFakeStream(params); } else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) { return NULL; } @@ -81,7 +79,7 @@ AudioInputStream* AudioManagerLinux::MakeAudioInputStream( } AlsaPcmInputStream* stream = new AlsaPcmInputStream( - device_name, params, samples_per_packet, wrapper_.get()); + device_name, params, wrapper_.get()); return stream; } diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h index afa60af..a5ba17cf 100644 --- a/media/audio/linux/audio_manager_linux.h +++ b/media/audio/linux/audio_manager_linux.h @@ -27,8 +27,7 @@ class AudioManagerLinux : public AudioManagerBase { virtual bool HasAudioOutputDevices(); virtual bool HasAudioInputDevices(); virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); - virtual AudioInputStream* MakeAudioInputStream( - AudioParameters params, int samples_per_packet); + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc index 88db2db..7e0c933 100644 --- a/media/audio/mac/audio_input_mac.cc +++ b/media/audio/mac/audio_input_mac.cc @@ -17,9 +17,7 @@ enum { #endif PCMQueueInAudioInputStream::PCMQueueInAudioInputStream( - AudioManagerMac* manager, - AudioParameters params, - int samples_per_buffer) + AudioManagerMac* manager, AudioParameters params) : manager_(manager), callback_(NULL), audio_queue_(NULL), @@ -39,7 +37,7 @@ PCMQueueInAudioInputStream::PCMQueueInAudioInputStream( format_.mBytesPerPacket = (params.bits_per_sample * params.channels) / 8; format_.mBytesPerFrame = format_.mBytesPerPacket; - buffer_size_bytes_ = format_.mBytesPerFrame * samples_per_buffer; + buffer_size_bytes_ = params.GetPacketSize(); } PCMQueueInAudioInputStream::~PCMQueueInAudioInputStream() { diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h index 8b049f7..078d4da 100644 --- a/media/audio/mac/audio_input_mac.h +++ b/media/audio/mac/audio_input_mac.h @@ -19,8 +19,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream { public: // Parameters as per AudioManager::MakeAudioInputStream. PCMQueueInAudioInputStream(AudioManagerMac* manager, - AudioParameters params, - int samples_per_packet); + AudioParameters params); virtual ~PCMQueueInAudioInputStream(); // Implementation of AudioInputStream. diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc index 1eb9398..4565bba 100644 --- a/media/audio/mac/audio_manager_mac.cc +++ b/media/audio/mac/audio_manager_mac.cc @@ -13,7 +13,6 @@ namespace { const int kMaxInputChannels = 2; -const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate; bool HasAudioHardware(AudioObjectPropertySelector selector) { AudioDeviceID output_device_id = kAudioObjectUnknown; @@ -45,22 +44,21 @@ bool AudioManagerMac::HasAudioInputDevices() { AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( AudioParameters params) { if (params.format == AudioParameters::AUDIO_MOCK) - return FakeAudioOutputStream::MakeFakeStream(); + return FakeAudioOutputStream::MakeFakeStream(params); else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) return NULL; return new PCMQueueOutAudioOutputStream(this, params); } AudioInputStream* AudioManagerMac::MakeAudioInputStream( - AudioParameters params, int samples_per_packet) { - if (!params.IsValid() || (params.channels > kMaxInputChannels) || - (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) + AudioParameters params) { + if (!params.IsValid() || (params.channels > kMaxInputChannels)) return NULL; if (params.format == AudioParameters::AUDIO_MOCK) { - return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); + return FakeAudioInputStream::MakeFakeStream(params); } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { - return new PCMQueueInAudioInputStream(this, params, samples_per_packet); + return new PCMQueueInAudioInputStream(this, params); } return NULL; } diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h index 3abfab1..31f6de2 100644 --- a/media/audio/mac/audio_manager_mac.h +++ b/media/audio/mac/audio_manager_mac.h @@ -22,8 +22,7 @@ class AudioManagerMac : public AudioManagerBase { virtual bool HasAudioOutputDevices(); virtual bool HasAudioInputDevices(); virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); - virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - int samples_per_packet); + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/mac/audio_output_mac.cc b/media/audio/mac/audio_output_mac.cc index 8d68b27..615fa5e 100644 --- a/media/audio/mac/audio_output_mac.cc +++ b/media/audio/mac/audio_output_mac.cc @@ -45,14 +45,14 @@ enum { PCMQueueOutAudioOutputStream::PCMQueueOutAudioOutputStream( AudioManagerMac* manager, AudioParameters params) - : format_(), - audio_queue_(NULL), - buffer_(), - source_(NULL), - manager_(manager), - silence_bytes_(0), - volume_(1), - pending_bytes_(0) { + : format_(), + audio_queue_(NULL), + buffer_(), + source_(NULL), + manager_(manager), + silence_bytes_(0), + volume_(1), + pending_bytes_(0) { // We must have a manager. DCHECK(manager_); // A frame is one sample across all channels. In interleaved audio the per @@ -68,6 +68,8 @@ PCMQueueOutAudioOutputStream::PCMQueueOutAudioOutputStream( format_.mBytesPerPacket = (format_.mBitsPerChannel * params.channels) / 8; format_.mBytesPerFrame = format_.mBytesPerPacket; + packet_size_ = params.GetPacketSize(); + // Silence buffer has a duration of 6ms to simulate the behavior of Windows. // This value is choosen by experiments and macs cannot keep up with // anything less than 6ms. @@ -87,11 +89,7 @@ void PCMQueueOutAudioOutputStream::HandleError(OSStatus err) { NOTREACHED() << "error code " << err; } -bool PCMQueueOutAudioOutputStream::Open(uint32 packet_size) { - if (0 == packet_size) { - // TODO(cpu) : Impelement default buffer computation. - return false; - } +bool PCMQueueOutAudioOutputStream::Open() { // Create the actual queue object and let the OS use its own thread to // run its CFRunLoop. OSStatus err = AudioQueueNewOutput(&format_, RenderCallback, this, NULL, @@ -102,7 +100,7 @@ bool PCMQueueOutAudioOutputStream::Open(uint32 packet_size) { } // Allocate the hardware-managed buffers. for (uint32 ix = 0; ix != kNumBuffers; ++ix) { - err = AudioQueueAllocateBuffer(audio_queue_, packet_size, &buffer_[ix]); + err = AudioQueueAllocateBuffer(audio_queue_, packet_size_, &buffer_[ix]); if (err != noErr) { HandleError(err); return false; diff --git a/media/audio/mac/audio_output_mac.h b/media/audio/mac/audio_output_mac.h index 60cf2b6..31128bc 100644 --- a/media/audio/mac/audio_output_mac.h +++ b/media/audio/mac/audio_output_mac.h @@ -27,7 +27,7 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream { virtual ~PCMQueueOutAudioOutputStream(); // Implementation of AudioOutputStream. - virtual bool Open(uint32 packet_size); + virtual bool Open(); virtual void Close(); virtual void Start(AudioSourceCallback* callback); virtual void Stop(); @@ -54,6 +54,8 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream { AudioSourceCallback* source_; // Our creator, the audio manager needs to be notified when we close. AudioManagerMac* manager_; + // Packet size in bytes. + uint32 packet_size_; // Number of bytes for making a silence buffer. int silence_bytes_; // Volume level from 0 to 1. diff --git a/media/audio/mac/audio_output_mac_unittest.cc b/media/audio/mac/audio_output_mac_unittest.cc index 061316f..e330e2b 100644 --- a/media/audio/mac/audio_output_mac_unittest.cc +++ b/media/audio/mac/audio_output_mac_unittest.cc @@ -24,7 +24,6 @@ class MockAudioSource : public AudioOutputStream::AudioSourceCallback { MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState buffers_state)); - MOCK_METHOD1(OnClose, void(AudioOutputStream* stream)); MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); }; @@ -58,7 +57,7 @@ TEST(MacAudioTest, PCMWaveStreamGetAndClose) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 1024)); ASSERT_TRUE(NULL != oas); oas->Close(); } @@ -70,9 +69,9 @@ TEST(MacAudioTest, PCMWaveStreamOpenAndClose) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 1024)); ASSERT_TRUE(NULL != oas); - EXPECT_TRUE(oas->Open(1024)); + EXPECT_TRUE(oas->Open()); oas->Close(); } @@ -85,17 +84,15 @@ TEST(MacAudioTest, PCMWaveStreamPlay200HzTone44KssMono) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate, 16)); + AudioParameters::kAudioCDSampleRate, 16, frames_100_ms)); ASSERT_TRUE(NULL != oas); + EXPECT_TRUE(oas->Open()); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, 200.0, AudioParameters::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; - - EXPECT_TRUE(oas->Open(bytes_100_ms)); - oas->SetVolume(0.5); oas->Start(&source); usleep(500000); @@ -118,16 +115,16 @@ TEST(MacAudioTest, PCMWaveStreamPlay200HzTone22KssMono) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate / 2, 16)); + AudioParameters::kAudioCDSampleRate / 2, 16, + frames_100_ms)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, 200.0, AudioParameters::kAudioCDSampleRate/2); - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 20) * 2; - - EXPECT_TRUE(oas->Open(bytes_100_ms)); + EXPECT_TRUE(oas->Open()); oas->Start(&source); usleep(1500000); oas->Stop(); @@ -145,14 +142,17 @@ TEST(MacAudioTest, PCMWaveStreamPendingBytes) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + + uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate, 16)); + AudioParameters::kAudioCDSampleRate, 16, frames_100_ms)); ASSERT_TRUE(NULL != oas); NiceMock<MockAudioSource> source; - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; - EXPECT_TRUE(oas->Open(bytes_100_ms)); + EXPECT_TRUE(oas->Open()); + + uint32 bytes_100_ms = frames_100_ms * 2; // We expect the amount of pending bytes will reaching |bytes_100_ms| // because the audio output stream has a double buffer scheme. diff --git a/media/audio/openbsd/audio_manager_openbsd.cc b/media/audio/openbsd/audio_manager_openbsd.cc index 251a085..b200309 100644 --- a/media/audio/openbsd/audio_manager_openbsd.cc +++ b/media/audio/openbsd/audio_manager_openbsd.cc @@ -28,8 +28,7 @@ AudioOutputStream* AudioManagerOpenBSD::MakeAudioOutputStream( } AudioInputStream* AudioManagerOpenBSD::MakeAudioInputStream( - AudioParameters params, - uint32 samples_per_packet) { + AudioParameters params) { NOTIMPLEMENTED(); return NULL; } diff --git a/media/audio/openbsd/audio_manager_openbsd.h b/media/audio/openbsd/audio_manager_openbsd.h index c643cdd..281ac79 100644 --- a/media/audio/openbsd/audio_manager_openbsd.h +++ b/media/audio/openbsd/audio_manager_openbsd.h @@ -18,8 +18,7 @@ class AudioManagerOpenBSD : public AudioManagerBase { virtual bool HasAudioOutputDevices(); virtual bool HasAudioInputDevices(); virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); - virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - uint32 samples_per_packet); + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/simple_sources.cc b/media/audio/simple_sources.cc index 5445600..df0a730 100644 --- a/media/audio/simple_sources.cc +++ b/media/audio/simple_sources.cc @@ -43,9 +43,6 @@ uint32 SineWaveAudioSource::OnMoreData( return max_size; } -void SineWaveAudioSource::OnClose(AudioOutputStream* stream) { -} - void SineWaveAudioSource::OnError(AudioOutputStream* stream, int code) { NOTREACHED(); } @@ -65,10 +62,6 @@ uint32 PushSource::OnMoreData( return buffer_.Read(dest, max_size); } -void PushSource::OnClose(AudioOutputStream* stream) { - CleanUp(); -} - void PushSource::OnError(AudioOutputStream* stream, int code) { NOTREACHED(); } diff --git a/media/audio/simple_sources.h b/media/audio/simple_sources.h index 4f4dc07..dec839d 100644 --- a/media/audio/simple_sources.h +++ b/media/audio/simple_sources.h @@ -29,7 +29,6 @@ class SineWaveAudioSource : public AudioOutputStream::AudioSourceCallback { virtual uint32 OnMoreData( AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState audio_buffers); - virtual void OnClose(AudioOutputStream* stream); virtual void OnError(AudioOutputStream* stream, int code); protected: @@ -73,7 +72,6 @@ class PushSource : public AudioOutputStream::AudioSourceCallback, // Implementation of AudioSourceCallback. virtual uint32 OnMoreData(AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState buffers_state); - virtual void OnClose(AudioOutputStream* stream); virtual void OnError(AudioOutputStream* stream, int code); // Discard all buffered data and reset to initial state. diff --git a/media/audio/simple_sources_unittest.cc b/media/audio/simple_sources_unittest.cc index bbcbff2..f96ffad 100644 --- a/media/audio/simple_sources_unittest.cc +++ b/media/audio/simple_sources_unittest.cc @@ -58,8 +58,6 @@ TEST(SimpleSourcesTest, PushSourceSmallerWrite) { EXPECT_EQ(0, memcmp(data.get() + i, read_data.get(), size)); } EXPECT_EQ(0u, push_source.UnProcessedBytes()); - - push_source.OnClose(NULL); } // Validate that the SineWaveAudioSource writes the expected values for @@ -78,10 +76,10 @@ TEST(SimpleSources, SineWaveAudio16MonoTest) { ASSERT_TRUE(NULL != audio_man); AudioParameters params( AudioParameters::AUDIO_MOCK, 1, AudioParameters::kTelephoneSampleRate, - bytes_per_sample * 2); + bytes_per_sample * 2, samples); AudioOutputStream* oas = audio_man->MakeAudioOutputStream(params); ASSERT_TRUE(NULL != oas); - EXPECT_TRUE(oas->Open(samples * bytes_per_sample)); + EXPECT_TRUE(oas->Open()); oas->Start(&source); oas->Stop(); diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc index 99980bf..2a2f402 100644 --- a/media/audio/test_audio_input_controller_factory.cc +++ b/media/audio/test_audio_input_controller_factory.cc @@ -25,8 +25,7 @@ TestAudioInputControllerFactory::TestAudioInputControllerFactory() AudioInputController* TestAudioInputControllerFactory::Create( AudioInputController::EventHandler* event_handler, - AudioParameters params, - int samples_per_packet) { + AudioParameters params) { DCHECK(!controller_); // Only one test instance managed at a time. controller_ = new TestAudioInputController(this, event_handler); return controller_; diff --git a/media/audio/test_audio_input_controller_factory.h b/media/audio/test_audio_input_controller_factory.h index 0d14828..382626d 100644 --- a/media/audio/test_audio_input_controller_factory.h +++ b/media/audio/test_audio_input_controller_factory.h @@ -74,8 +74,7 @@ class TestAudioInputControllerFactory : public AudioInputController::Factory { // AudioInputController::Factory methods. AudioInputController* Create( AudioInputController::EventHandler* event_handler, - AudioParameters params, - int samples_per_packet); + AudioParameters params); TestAudioInputController* controller() const { return controller_; } diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc index 3d5c137..a2fbd92 100644 --- a/media/audio/win/audio_manager_win.cc +++ b/media/audio/win/audio_manager_win.cc @@ -23,7 +23,6 @@ namespace { const int kWinMaxChannels = 8; const int kWinMaxInputChannels = 2; -const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate; // We use 3 buffers for recording audio so that if a recording callback takes // some time to return we won't lose audio. More buffers while recording are // ok because they don't introduce any delay in recording, unlike in playback @@ -51,7 +50,7 @@ AudioOutputStream* AudioManagerWin::MakeAudioOutputStream( return NULL; if (params.format == AudioParameters::AUDIO_MOCK) { - return FakeAudioOutputStream::MakeFakeStream(); + return FakeAudioOutputStream::MakeFakeStream(params); } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { return new PCMWaveOutAudioOutputStream(this, params, 3, WAVE_MAPPER); } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) { @@ -63,16 +62,15 @@ AudioOutputStream* AudioManagerWin::MakeAudioOutputStream( // Factory for the implementations of AudioInputStream. AudioInputStream* AudioManagerWin::MakeAudioInputStream( - AudioParameters params, int samples_per_packet) { - if (!params.IsValid() || (params.channels > kWinMaxInputChannels) || - (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) + AudioParameters params) { + if (!params.IsValid() || (params.channels > kWinMaxInputChannels)) return NULL; if (params.format == AudioParameters::AUDIO_MOCK) { - return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); + return FakeAudioInputStream::MakeFakeStream(params); } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers, - samples_per_packet, WAVE_MAPPER); + WAVE_MAPPER); } return NULL; } diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h index 09f0019..2ea4c8f 100644 --- a/media/audio/win/audio_manager_win.h +++ b/media/audio/win/audio_manager_win.h @@ -23,8 +23,7 @@ class AudioManagerWin : public AudioManagerBase { virtual bool HasAudioOutputDevices(); virtual bool HasAudioInputDevices(); virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); - virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - int samples_per_packet); + virtual AudioInputStream* MakeAudioInputStream(AudioParameters params); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc index 2e86450..7665d08 100644 --- a/media/audio/win/audio_output_win_unittest.cc +++ b/media/audio/win/audio_output_win_unittest.cc @@ -36,8 +36,7 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback { public: explicit TestSourceBasic() : callback_count_(0), - had_error_(0), - was_closed_(0) { + had_error_(0) { } // AudioSourceCallback::OnMoreData implementation: virtual uint32 OnMoreData(AudioOutputStream* stream, uint8* dest, @@ -48,10 +47,6 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback { reinterpret_cast<char*>(dest)[0] = 1; return max_size; } - // AudioSourceCallback::OnClose implementation: - virtual void OnClose(AudioOutputStream* stream) { - ++was_closed_; - } // AudioSourceCallback::OnError implementation: virtual void OnError(AudioOutputStream* stream, int code) { ++had_error_; @@ -68,15 +63,10 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback { void set_error(bool error) { had_error_ += error ? 1 : 0; } - // Returns how many times the OnClose callback was called. - int was_closed() const { - return was_closed_; - } private: int callback_count_; int had_error_; - int was_closed_; }; bool IsRunningHeadless() { @@ -153,7 +143,6 @@ class MockAudioSource : public AudioOutputStream::AudioSourceCallback { MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, uint8* dest, uint32 max_size, AudioBuffersState buffers_state)); - MOCK_METHOD1(OnClose, void(AudioOutputStream* stream)); MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); }; @@ -211,16 +200,15 @@ TEST(WinAudioTest, MockStreamBasicCallbacks) { AudioManager* audio_man = AudioManager::GetAudioManager(); ASSERT_TRUE(NULL != audio_man); AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8)); + AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8, 128)); ASSERT_TRUE(NULL != oas); - EXPECT_TRUE(oas->Open(256)); + EXPECT_TRUE(oas->Open()); TestSourceBasic source; oas->Start(&source); EXPECT_GT(source.callback_count(), 0); oas->Stop(); oas->Close(); EXPECT_EQ(0, source.had_error()); - EXPECT_EQ(1, source.was_closed()); } // =========================================================================== @@ -240,7 +228,7 @@ TEST(WinAudioTest, PCMWaveStreamGetAndClose) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 256)); ASSERT_TRUE(NULL != oas); oas->Close(); } @@ -255,17 +243,21 @@ TEST(WinAudioTest, SanityOnMakeParams) { return; AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR; EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( - AudioParameters(fmt, 9, 8000, 16))); + AudioParameters(fmt, 9, 8000, 16, 256))); + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, 1, 1024 * 1024, 16, 256))); + EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( + AudioParameters(fmt, 2, 8000, 80, 256))); EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( - AudioParameters(fmt, 1, 1024 * 1024, 16))); + AudioParameters(fmt, -2, 8000, 16, 256))); EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( - AudioParameters(fmt, 2, 8000, 80))); + AudioParameters(fmt, 2, -8000, 16, 256))); EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( - AudioParameters(fmt, -2, 8000, 16))); + AudioParameters(fmt, 1, 8000, 16, -100))); EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( - AudioParameters(fmt, 2, -8000, 16))); + AudioParameters(fmt, 1, 8000, 16, 0))); EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream( - AudioParameters(fmt, 2, -8000, -16))); + AudioParameters(fmt, 1, 8000, 16, 100000))); } // Test that it can be opened and closed. @@ -277,9 +269,9 @@ TEST(WinAudioTest, PCMWaveStreamOpenAndClose) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 256)); ASSERT_TRUE(NULL != oas); - EXPECT_TRUE(oas->Open(1024)); + EXPECT_TRUE(oas->Open()); oas->Close(); } @@ -292,9 +284,9 @@ TEST(WinAudioTest, PCMWaveStreamOpenLimit) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16)); - ASSERT_TRUE(NULL != oas); - EXPECT_FALSE(oas->Open(1024 * 1024 * 1024)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, + 1024 * 1024 * 1024)); + ASSERT_TRUE(NULL == oas); oas->Close(); } @@ -308,10 +300,10 @@ TEST(WinAudioTest, PCMWaveStreamTripleBuffer) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16, 256)); ASSERT_TRUE(NULL != oas); TestSourceTripleBuffer test_triple_buffer; - EXPECT_TRUE(oas->Open(512)); + EXPECT_TRUE(oas->Open()); oas->Start(&test_triple_buffer); ::Sleep(300); EXPECT_GT(test_triple_buffer.callback_count(), kNumBuffers); @@ -332,10 +324,10 @@ TEST(WinAudioTest, PCMWaveSlowSource) { if (!audio_man->HasAudioOutputDevices()) return; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16, 256)); ASSERT_TRUE(NULL != oas); TestSourceLaggy test_laggy(2, 90); - EXPECT_TRUE(oas->Open(512)); + EXPECT_TRUE(oas->Open()); // The test parameters cause a callback every 32 ms and the source is // sleeping for 90 ms, so it is guaranteed that we run out of ready buffers. oas->Start(&test_laggy); @@ -357,16 +349,16 @@ TEST(WinAudioTest, PCMWaveStreamPlaySlowLoop) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate, 16)); + AudioParameters::kAudioCDSampleRate, 16, samples_100_ms)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, 200.0, AudioParameters::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; - EXPECT_TRUE(oas->Open(bytes_100_ms)); + EXPECT_TRUE(oas->Open()); oas->SetVolume(1.0); for (int ix = 0; ix != 5; ++ix) { @@ -388,16 +380,16 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44Kss) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate, 16)); + AudioParameters::kAudioCDSampleRate, 16, samples_100_ms)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, 200.0, AudioParameters::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; - EXPECT_TRUE(oas->Open(bytes_100_ms)); + EXPECT_TRUE(oas->Open()); oas->SetVolume(1.0); oas->Start(&source); ::Sleep(500); @@ -416,16 +408,17 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone22Kss) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 20; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate / 2, 16)); + AudioParameters::kAudioCDSampleRate / 2, 16, + samples_100_ms)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, 200.0, AudioParameters::kAudioCDSampleRate/2); - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 20) * 2; - EXPECT_TRUE(oas->Open(bytes_100_ms)); + EXPECT_TRUE(oas->Open()); oas->SetVolume(0.5); oas->Start(&source); @@ -462,29 +455,33 @@ TEST(WinAudioTest, PushSourceFile16KHz) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + + // Compute buffer size for 100ms of audio. + const uint32 kSamples100ms = (16000 / 1000) * 100; + const uint32 kSize100ms = kSamples100ms * 2; + AudioOutputStream* oas = audio_man->MakeAudioOutputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16)); + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16, + kSamples100ms)); ASSERT_TRUE(NULL != oas); - // compute buffer size for 100ms of audio. Which is 3200 bytes. - const uint32 kSize50ms = 2 * (16000 / 1000) * 100; - EXPECT_TRUE(oas->Open(kSize50ms)); + EXPECT_TRUE(oas->Open()); uint32 offset = 0; - const uint32 kMaxStartOffset = file_reader.size() - kSize50ms; + const uint32 kMaxStartOffset = file_reader.size() - kSize100ms; // We buffer and play at the same time, buffering happens every ~10ms and the - // consuming of the buffer happens every ~50ms. We do 100 buffers which + // consuming of the buffer happens every ~100ms. We do 100 buffers which // effectively wrap around the file more than once. PushSource push_source; for (uint32 ix = 0; ix != 100; ++ix) { - push_source.Write(file_reader.GetChunkAt(offset), kSize50ms); + push_source.Write(file_reader.GetChunkAt(offset), kSize100ms); if (ix == 2) { // For glitch free, start playing after some buffers are in. oas->Start(&push_source); } ::Sleep(10); - offset += kSize50ms; + offset += kSize100ms; if (offset > kMaxStartOffset) offset = 0; } @@ -506,16 +503,16 @@ TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + + uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate, 16)); + AudioParameters::kAudioCDSampleRate, 16, samples_100_ms)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, 200.0, AudioParameters::kAudioCDSampleRate); - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; - - EXPECT_TRUE(oas->Open(bytes_100_ms)); + EXPECT_TRUE(oas->Open()); oas->SetVolume(1.0); // Play the wave for .5 seconds. @@ -545,17 +542,17 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44KssLowLatency) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + + uint32 samples_50_ms = AudioParameters::kAudioCDSampleRate / 20; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, 1, - AudioParameters::kAudioCDSampleRate, 16)); + AudioParameters::kAudioCDSampleRate, 16, samples_50_ms)); ASSERT_TRUE(NULL != oas); SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1, 200.0, AudioParameters::kAudioCDSampleRate); - uint32 bytes_50_ms = (AudioParameters::kAudioCDSampleRate / 20) * - sizeof(uint16); - EXPECT_TRUE(oas->Open(bytes_50_ms)); + EXPECT_TRUE(oas->Open()); oas->SetVolume(1.0); // Play the wave for .8 seconds. @@ -573,14 +570,17 @@ TEST(WinAudioTest, PCMWaveStreamPendingBytes) { ASSERT_TRUE(NULL != audio_man); if (!audio_man->HasAudioOutputDevices()) return; + + uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, - AudioParameters::kAudioCDSampleRate, 16)); + AudioParameters::kAudioCDSampleRate, 16, samples_100_ms)); ASSERT_TRUE(NULL != oas); NiceMock<MockAudioSource> source; - uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2; - EXPECT_TRUE(oas->Open(bytes_100_ms)); + EXPECT_TRUE(oas->Open()); + + uint32 bytes_100_ms = samples_100_ms * 2; // We expect the amount of pending bytes will reaching 2 times of // |bytes_100_ms| because the audio output stream has a triple buffer scheme. @@ -637,9 +637,6 @@ class SyncSocketSource : public AudioOutputStream::AudioSourceCallback { uint32 got = socket_->Receive(dest, max_size); return got; } - // AudioSourceCallback::OnClose implementation: - virtual void OnClose(AudioOutputStream* stream) { - } // AudioSourceCallback::OnError implementation: virtual void OnError(AudioOutputStream* stream, int code) { } @@ -703,14 +700,14 @@ TEST(WinAudioTest, SyncSocketBasic) { return; int sample_rate = AudioParameters::kAudioCDSampleRate; + const uint32 kSamples20ms = sample_rate / 50; AudioOutputStream* oas = audio_man->MakeAudioOutputStream( AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, 1, - sample_rate, 16)); + sample_rate, 16, kSamples20ms)); ASSERT_TRUE(NULL != oas); // compute buffer size for 20ms of audio, 882 samples (mono). - const uint32 kSamples20ms = sample_rate / 50 * sizeof(uint16); - ASSERT_TRUE(oas->Open(kSamples20ms)); + ASSERT_TRUE(oas->Open()); base::SyncSocket* sockets[2]; ASSERT_TRUE(base::SyncSocket::CreatePair(sockets)); diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc index b328dcd..c02fd52 100644 --- a/media/audio/win/wavein_input_win.cc +++ b/media/audio/win/wavein_input_win.cc @@ -26,7 +26,7 @@ WAVEHDR* GetNextBuffer(WAVEHDR* current) { PCMWaveInAudioInputStream::PCMWaveInAudioInputStream( AudioManagerWin* manager, AudioParameters params, int num_buffers, - uint32 samples_per_packet, UINT device_id) + UINT device_id) : state_(kStateEmpty), manager_(manager), device_id_(device_id), @@ -42,7 +42,7 @@ PCMWaveInAudioInputStream::PCMWaveInAudioInputStream( format_.cbSize = 0; format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8; format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec; - buffer_size_ = samples_per_packet * format_.nBlockAlign; + buffer_size_ = params.samples_per_packet * format_.nBlockAlign; // If we don't have a packet size we use 100ms. if (!buffer_size_) buffer_size_ = format_.nAvgBytesPerSec / 10; diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h index 46aa0b6..7dd4781 100644 --- a/media/audio/win/wavein_input_win.h +++ b/media/audio/win/wavein_input_win.h @@ -21,8 +21,7 @@ class PCMWaveInAudioInputStream : public AudioInputStream { // the audio manager who is creating this object and |device_id| which // is provided by the operating system. PCMWaveInAudioInputStream(AudioManagerWin* manager, AudioParameters params, - int num_buffers, uint32 samples_per_packet, - UINT device_id); + int num_buffers, UINT device_id); virtual ~PCMWaveInAudioInputStream(); // Implementation of AudioInputStream. diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc index 2c3d5c4..9c99634 100644 --- a/media/audio/win/waveout_output_win.cc +++ b/media/audio/win/waveout_output_win.cc @@ -87,10 +87,11 @@ PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream( callback_(NULL), num_buffers_(num_buffers), buffer_(NULL), - buffer_size_(0), + buffer_size_(params.GetPacketSize()), volume_(1), channels_(params.channels), pending_bytes_(0) { + format_.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; format_.Format.nChannels = params.channels; format_.Format.nSamplesPerSec = params.sample_rate; @@ -116,11 +117,9 @@ PCMWaveOutAudioOutputStream::~PCMWaveOutAudioOutputStream() { DCHECK(NULL == waveout_); } -bool PCMWaveOutAudioOutputStream::Open(uint32 buffer_size) { +bool PCMWaveOutAudioOutputStream::Open() { if (state_ != PCMA_BRAND_NEW) return false; - if (buffer_size > kMaxOpenBufferSize) - return false; if (num_buffers_ < 2 || num_buffers_ > 5) return false; // Open the device. We'll be getting callback in WaveCallback function. @@ -132,24 +131,20 @@ bool PCMWaveOutAudioOutputStream::Open(uint32 buffer_size) { CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) return false; - // If we don't have a packet size we use 100ms. - if (!buffer_size) - buffer_size = format_.Format.nAvgBytesPerSec / 10; - SetupBuffers(buffer_size); - buffer_size_ = buffer_size; + SetupBuffers(); state_ = PCMA_READY; return true; } -void PCMWaveOutAudioOutputStream::SetupBuffers(uint32 rq_size) { +void PCMWaveOutAudioOutputStream::SetupBuffers() { WAVEHDR* last = NULL; WAVEHDR* first = NULL; for (int ix = 0; ix != num_buffers_; ++ix) { - uint32 sz = sizeof(WAVEHDR) + rq_size; + uint32 sz = sizeof(WAVEHDR) + buffer_size_; buffer_ = reinterpret_cast<WAVEHDR*>(new char[sz]); buffer_->lpData = reinterpret_cast<char*>(buffer_) + sizeof(WAVEHDR); - buffer_->dwBufferLength = rq_size; + buffer_->dwBufferLength = buffer_size_; buffer_->dwBytesRecorded = 0; buffer_->dwUser = reinterpret_cast<DWORD_PTR>(last); buffer_->dwFlags = WHDR_DONE; @@ -235,6 +230,10 @@ void PCMWaveOutAudioOutputStream::Stop() { HandleError(res); return; } + + // Don't use callback after Stop(). + callback_ = NULL; + state_ = PCMA_READY; } @@ -347,10 +346,5 @@ void PCMWaveOutAudioOutputStream::WaveCallback(HWAVEOUT hwo, UINT msg, obj->pending_bytes_ += buffer->dwBufferLength; - } else if (msg == WOM_CLOSE) { - // We can be closed before calling Start, so it is possible to have a - // null callback at this point. - if (obj->callback_) - obj->callback_->OnClose(obj); } } diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h index 7437416..651c9d2 100644 --- a/media/audio/win/waveout_output_win.h +++ b/media/audio/win/waveout_output_win.h @@ -35,7 +35,7 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream { virtual ~PCMWaveOutAudioOutputStream(); // Implementation of AudioOutputStream. - virtual bool Open(uint32 packet_size); + virtual bool Open(); virtual void Close(); virtual void Start(AudioSourceCallback* callback); virtual void Stop(); @@ -65,7 +65,7 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream { void HandleError(MMRESULT error); // Allocates and prepares the memory that will be used for playback. Only // two buffers are created. - void SetupBuffers(uint32 rq_size); + void SetupBuffers(); // Deallocates the memory allocated in SetupBuffers. void FreeBuffers(); @@ -116,4 +116,3 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream { }; #endif // MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_ - diff --git a/media/base/limits.h b/media/base/limits.h index b8a139f..cef29ec 100644 --- a/media/base/limits.h +++ b/media/base/limits.h @@ -27,6 +27,7 @@ struct Limits { static const int kMaxSampleRate = 192000; static const int kMaxChannels = 32; static const int kMaxBitsPerSample = 64; + static const int kMaxSamplesPerPacket = kMaxSampleRate; // Maximum possible time. static const int64 kMaxTimeInMicroseconds = kint64max; diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc index 5634ab2..3c7ce91 100644 --- a/media/filters/audio_renderer_impl.cc +++ b/media/filters/audio_renderer_impl.cc @@ -79,6 +79,9 @@ bool AudioRendererImpl::OnInitialize(const MediaFormat& media_format) { return false; } + // Set packet size. + params.samples_per_packet = kSamplesPerBuffer; + bytes_per_second_ = params.sample_rate * params.channels * params.bits_per_sample / 8; @@ -87,10 +90,7 @@ bool AudioRendererImpl::OnInitialize(const MediaFormat& media_format) { if (!stream_) return false; - // Calculate buffer size and open the stream. - size_t size = kSamplesPerBuffer * params.channels * - params.bits_per_sample / 8; - if (!stream_->Open(size)) { + if (!stream_->Open()) { stream_->Close(); stream_ = NULL; } |