diff options
author | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-18 22:08:24 +0000 |
---|---|---|
committer | acolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-18 22:09:57 +0000 |
commit | 1fdcfb56d3e76afa29cfc4ff795ba9c1353b0f54 (patch) | |
tree | 097d5a5114f0b70be2c2041d9d5be2fc70f23d6c /media | |
parent | 73a643f618a1329425fcecb4d3c9d5ea890b636c (diff) | |
download | chromium_src-1fdcfb56d3e76afa29cfc4ff795ba9c1353b0f54.zip chromium_src-1fdcfb56d3e76afa29cfc4ff795ba9c1353b0f54.tar.gz chromium_src-1fdcfb56d3e76afa29cfc4ff795ba9c1353b0f54.tar.bz2 |
Revert 290359 "Remove AudioBuffersState class."
Broke ChromeOS bots
http://build.chromium.org/p/chromium.chrome/builders/Google%20Chrome%20ChromeOS/builds/70835/steps/compile/logs/stdio#error1
> Remove AudioBuffersState class.
>
> The AudioBuffersState object doesn't appear to be necessary anymore.
> Most code either completely ignores this information or doesn't actually
> care about the difference between pending_bytes and hardware_delay_bytes.
> Also usually only one of the 2 fields was actually being used at a time.
> This change removes the class and simply uses an int that represent the
> total number of delay bytes.
>
> BUG=125685
>
> Review URL: https://codereview.chromium.org/467833002
TBR=acolwell@chromium.org
Review URL: https://codereview.chromium.org/487543002
Cr-Commit-Position: refs/heads/master@{#290376}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290376 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
35 files changed, 177 insertions, 82 deletions
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn index 0f48af0..e6ac957 100644 --- a/media/audio/BUILD.gn +++ b/media/audio/BUILD.gn @@ -36,6 +36,8 @@ if (!linux_link_pulseaudio) { source_set("audio") { sources = [ "agc_audio_stream.h", + "audio_buffers_state.cc", + "audio_buffers_state.h", "audio_device_name.cc", "audio_device_name.h", "audio_device_thread.cc", diff --git a/media/audio/alsa/alsa_output.cc b/media/audio/alsa/alsa_output.cc index bb03825..690d738 100644 --- a/media/audio/alsa/alsa_output.cc +++ b/media/audio/alsa/alsa_output.cc @@ -360,7 +360,7 @@ void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) { scoped_refptr<media::DataBuffer> packet = new media::DataBuffer(packet_size_); int frames_filled = RunDataCallback( - audio_bus_.get(), hardware_delay); + audio_bus_.get(), AudioBuffersState(0, hardware_delay)); size_t packet_size = frames_filled * bytes_per_frame_; DCHECK_LE(packet_size, packet_size_); @@ -740,11 +740,11 @@ bool AlsaPcmOutputStream::IsOnAudioThread() const { } int AlsaPcmOutputStream::RunDataCallback(AudioBus* audio_bus, - int total_bytes_delay) { + AudioBuffersState buffers_state) { TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback"); if (source_callback_) - return source_callback_->OnMoreData(audio_bus, total_bytes_delay); + return source_callback_->OnMoreData(audio_bus, buffers_state); return 0; } diff --git a/media/audio/alsa/alsa_output.h b/media/audio/alsa/alsa_output.h index 6a2817c..1805645 100644 --- a/media/audio/alsa/alsa_output.h +++ b/media/audio/alsa/alsa_output.h @@ -154,7 +154,7 @@ class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { // is passed into the output stream, but ownership is not transfered which // requires a synchronization on access of the |source_callback_| to avoid // using a deleted callback. - int RunDataCallback(AudioBus* audio_bus, int total_bytes_delay); + int RunDataCallback(AudioBus* audio_bus, AudioBuffersState buffers_state); void RunErrorCallback(int code); // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to diff --git a/media/audio/alsa/alsa_output_unittest.cc b/media/audio/alsa/alsa_output_unittest.cc index 3b6592b..8b0aeae 100644 --- a/media/audio/alsa/alsa_output_unittest.cc +++ b/media/audio/alsa/alsa_output_unittest.cc @@ -644,7 +644,10 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { .WillOnce(Return(SND_PCM_STATE_XRUN)); EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) .WillRepeatedly(Return(0)); // Buffer is full. - EXPECT_CALL(mock_callback, OnMoreData(_, 0)) + EXPECT_CALL(mock_callback, + OnMoreData(_, AllOf( + Field(&AudioBuffersState::pending_bytes, 0), + Field(&AudioBuffersState::hardware_delay_bytes, 0)))) .WillOnce(DoAll(ClearBuffer(), Return(kTestFramesPerPacket / 2))); bool source_exhausted; diff --git a/media/audio/android/audio_android_unittest.cc b/media/audio/android/audio_android_unittest.cc index d333237..177953d 100644 --- a/media/audio/android/audio_android_unittest.cc +++ b/media/audio/android/audio_android_unittest.cc @@ -123,7 +123,7 @@ static void CheckDeviceNames(const AudioDeviceNames& device_names) { } // We clear the data bus to ensure that the test does not cause noise. -static int RealOnMoreData(AudioBus* dest, int total_bytes_delay) { +static int RealOnMoreData(AudioBus* dest, AudioBuffersState buffers_state) { dest->Zero(); return dest->frames(); } @@ -178,7 +178,7 @@ class FileAudioSource : public AudioOutputStream::AudioSourceCallback { // Use samples read from a data file and fill up the audio buffer // provided to us in the callback. virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) OVERRIDE { + AudioBuffersState buffers_state) OVERRIDE { bool stop_playing = false; int max_size = audio_bus->frames() * audio_bus->channels() * kBytesPerSample; @@ -354,7 +354,7 @@ class FullDuplexAudioSinkSource // AudioOutputStream::AudioSourceCallback implementation virtual int OnMoreData(AudioBus* dest, - int total_bytes_delay) OVERRIDE { + AudioBuffersState buffers_state) OVERRIDE { const int size_in_bytes = (params_.bits_per_sample() / 8) * dest->frames() * dest->channels(); EXPECT_EQ(size_in_bytes, params_.GetBytesPerBuffer()); diff --git a/media/audio/android/opensles_output.cc b/media/audio/android/opensles_output.cc index 4ac0af2..41c03c7 100644 --- a/media/audio/android/opensles_output.cc +++ b/media/audio/android/opensles_output.cc @@ -326,7 +326,7 @@ void OpenSLESOutputStream::FillBufferQueueNoLock() { // delay estimation. const uint32 hardware_delay = buffer_size_bytes_; int frames_filled = callback_->OnMoreData( - audio_bus_.get(), hardware_delay); + audio_bus_.get(), AudioBuffersState(0, hardware_delay)); if (frames_filled <= 0) { // Audio source is shutting down, or halted on error. return; diff --git a/media/audio/audio_buffers_state.cc b/media/audio/audio_buffers_state.cc new file mode 100644 index 0000000..6c4f950 --- /dev/null +++ b/media/audio/audio_buffers_state.cc @@ -0,0 +1,20 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/audio/audio_buffers_state.h" + +namespace media { + +AudioBuffersState::AudioBuffersState() + : pending_bytes(0), + hardware_delay_bytes(0) { +} + +AudioBuffersState::AudioBuffersState(int pending_bytes, + int hardware_delay_bytes) + : pending_bytes(pending_bytes), + hardware_delay_bytes(hardware_delay_bytes) { +} + +} // namespace media diff --git a/media/audio/audio_buffers_state.h b/media/audio/audio_buffers_state.h new file mode 100644 index 0000000..79244ae --- /dev/null +++ b/media/audio/audio_buffers_state.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_AUDIO_AUDIO_BUFFERS_STATE_H_ +#define MEDIA_AUDIO_AUDIO_BUFFERS_STATE_H_ + +#include "media/base/media_export.h" + +namespace media { + +// AudioBuffersState struct stores current state of audio buffers. +// It is used for audio synchronization. +struct MEDIA_EXPORT AudioBuffersState { + AudioBuffersState(); + AudioBuffersState(int pending_bytes, int hardware_delay_bytes); + + int total_bytes() { + return pending_bytes + hardware_delay_bytes; + } + + // Number of bytes we currently have in our software buffer. + int pending_bytes; + + // Number of bytes that have been written to the device, but haven't + // been played yet. + int hardware_delay_bytes; +}; + +} // namespace media + +#endif // MEDIA_AUDIO_AUDIO_BUFFERS_STATE_H_ diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h index cb0ca59..1e1eba4 100644 --- a/media/audio/audio_io.h +++ b/media/audio/audio_io.h @@ -6,6 +6,7 @@ #define MEDIA_AUDIO_AUDIO_IO_H_ #include "base/basictypes.h" +#include "media/audio/audio_buffers_state.h" #include "media/base/audio_bus.h" // Low-level audio output support. To make sound there are 3 objects involved: @@ -57,10 +58,10 @@ class MEDIA_EXPORT AudioOutputStream { class MEDIA_EXPORT AudioSourceCallback { public: // Provide more data by fully filling |dest|. The source will return - // the number of frames it filled. |total_bytes_delay| contains current - // number of bytes of delay buffered by the AudioOutputStream. + // the number of frames it filled. |buffers_state| contains current state + // of the buffers, and can be used by the source to calculate delay. virtual int OnMoreData(AudioBus* dest, - int total_bytes_delay) = 0; + AudioBuffersState buffers_state) = 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 diff --git a/media/audio/audio_low_latency_input_output_unittest.cc b/media/audio/audio_low_latency_input_output_unittest.cc index 0a572c9..5632896 100644 --- a/media/audio/audio_low_latency_input_output_unittest.cc +++ b/media/audio/audio_low_latency_input_output_unittest.cc @@ -226,14 +226,23 @@ class FullDuplexAudioSinkSource // AudioOutputStream::AudioSourceCallback. virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) OVERRIDE { + AudioBuffersState buffers_state) OVERRIDE { base::AutoLock lock(lock_); // Update one component in the AudioDelayState for the packet // which is about to be played out. if (output_elements_to_write_ < kMaxDelayMeasurements) { + int output_delay_bytes = buffers_state.hardware_delay_bytes; +#if defined(OS_WIN) + // Special fix for Windows in combination with Wave where the + // pending bytes field of the audio buffer state is used to + // report the delay. + if (!CoreAudioUtil::IsSupported()) { + output_delay_bytes = buffers_state.pending_bytes; + } +#endif delay_states_[output_elements_to_write_].output_delay_ms = - BytesToMilliseconds(total_bytes_delay); + BytesToMilliseconds(output_delay_bytes); ++output_elements_to_write_; } diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc index 845af9a..fb01254 100644 --- a/media/audio/audio_output_controller.cc +++ b/media/audio/audio_output_controller.cc @@ -290,7 +290,7 @@ void AudioOutputController::DoReportError() { } int AudioOutputController::OnMoreData(AudioBus* dest, - int total_bytes_delay) { + AudioBuffersState buffers_state) { TRACE_EVENT0("audio", "AudioOutputController::OnMoreData"); // Indicate that we haven't wedged (at least not indefinitely, WedgeCheck() @@ -304,7 +304,7 @@ int AudioOutputController::OnMoreData(AudioBus* dest, const int frames = dest->frames(); sync_reader_->UpdatePendingBytes( - total_bytes_delay + frames * params_.GetBytesPerFrame()); + buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); #if defined(AUDIO_POWER_MONITORING) power_monitor_.Scan(*dest, frames); diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h index 795b4cf..0b02ee2 100644 --- a/media/audio/audio_output_controller.h +++ b/media/audio/audio_output_controller.h @@ -149,7 +149,7 @@ class MEDIA_EXPORT AudioOutputController // AudioSourceCallback implementation. virtual int OnMoreData(AudioBus* dest, - int total_bytes_delay) OVERRIDE; + AudioBuffersState buffers_state) OVERRIDE; virtual void OnError(AudioOutputStream* stream) OVERRIDE; // AudioDeviceListener implementation. When called AudioOutputController will diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc index a4ecdb8..125763c 100644 --- a/media/audio/audio_output_controller_unittest.cc +++ b/media/audio/audio_output_controller_unittest.cc @@ -192,7 +192,7 @@ class AudioOutputControllerTest : public testing::Test { scoped_ptr<AudioBus> dest = AudioBus::Create(params_); ASSERT_TRUE(!!mock_stream_.callback()); const int frames_read = - mock_stream_.callback()->OnMoreData(dest.get(), 0); + mock_stream_.callback()->OnMoreData(dest.get(), AudioBuffersState()); EXPECT_LT(0, frames_read); EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]); } diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc index 5f0ab06..b8f23ac 100644 --- a/media/audio/audio_output_proxy_unittest.cc +++ b/media/audio/audio_output_proxy_unittest.cc @@ -25,6 +25,7 @@ using ::testing::NotNull; using ::testing::Return; using ::testing::SetArrayArgument; using media::AudioBus; +using media::AudioBuffersState; using media::AudioInputStream; using media::AudioManager; using media::AudioManagerBase; @@ -124,7 +125,7 @@ class MockAudioManager : public AudioManagerBase { class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { public: - int OnMoreData(AudioBus* audio_bus, int total_bytes_delay) { + int OnMoreData(AudioBus* audio_bus, AudioBuffersState buffers_state) { audio_bus->Zero(); return audio_bus->frames(); } diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc index 6375096..15633bb 100644 --- a/media/audio/audio_output_resampler.cc +++ b/media/audio/audio_output_resampler.cc @@ -30,7 +30,7 @@ class OnMoreDataConverter // AudioSourceCallback interface. virtual int OnMoreData(AudioBus* dest, - int total_bytes_delay) OVERRIDE; + AudioBuffersState buffers_state) OVERRIDE; virtual void OnError(AudioOutputStream* stream) OVERRIDE; // Sets |source_callback_|. If this is not a new object, then Stop() must be @@ -54,9 +54,9 @@ class OnMoreDataConverter // Source callback. AudioOutputStream::AudioSourceCallback* source_callback_; - // Last |total_bytes_delay| received via OnMoreData(), used to correct + // Last AudioBuffersState object received via OnMoreData(), used to correct // playback delay by ProvideInput() and passed on to |source_callback_|. - int current_total_bytes_delay_; + AudioBuffersState current_buffers_state_; const int input_bytes_per_second_; @@ -327,8 +327,8 @@ void OnMoreDataConverter::Stop() { } int OnMoreDataConverter::OnMoreData(AudioBus* dest, - int total_bytes_delay) { - current_total_bytes_delay_ = total_bytes_delay; + AudioBuffersState buffers_state) { + current_buffers_state_ = buffers_state; audio_converter_.Convert(dest); // Always return the full number of frames requested, ProvideInput() @@ -341,12 +341,13 @@ double OnMoreDataConverter::ProvideInput(AudioBus* dest, // Adjust playback delay to include |buffer_delay|. // TODO(dalecurtis): Stop passing bytes around, it doesn't make sense since // AudioBus is just float data. Use TimeDelta instead. - int new_total_bytes_delay = - io_ratio_ * (current_total_bytes_delay_ + + AudioBuffersState new_buffers_state; + new_buffers_state.pending_bytes = + io_ratio_ * (current_buffers_state_.total_bytes() + buffer_delay.InSecondsF() * input_bytes_per_second_); // Retrieve data from the original callback. - const int frames = source_callback_->OnMoreData(dest, new_total_bytes_delay); + const int frames = source_callback_->OnMoreData(dest, new_buffers_state); // Zero any unfilled frames if anything was filled, otherwise we'll just // return a volume of zero and let AudioConverter drop the output. diff --git a/media/audio/audio_output_resampler.h b/media/audio/audio_output_resampler.h index af7ebf2..fa488aa 100644 --- a/media/audio/audio_output_resampler.h +++ b/media/audio/audio_output_resampler.h @@ -24,8 +24,8 @@ class OnMoreDataConverter; // AudioConverter class for details on the conversion process. // // AOR works by intercepting the AudioSourceCallback provided to StartStream() -// and redirecting it through an AudioConverter instance. |total_bytes_delay| -// is adjusted for buffer delay caused by the conversion process. +// and redirecting it through an AudioConverter instance. AudioBuffersState is +// adjusted for buffer delay caused by the conversion process. // // AOR will automatically fall back from AUDIO_PCM_LOW_LATENCY to // AUDIO_PCM_LINEAR if the output device fails to open at the requested output diff --git a/media/audio/cras/cras_unified.cc b/media/audio/cras/cras_unified.cc index 232fee1..25af383 100644 --- a/media/audio/cras/cras_unified.cc +++ b/media/audio/cras/cras_unified.cc @@ -358,7 +358,8 @@ uint32 CrasUnifiedStream::ReadWriteAudio(size_t frames, total_delay_bytes += GetBytesLatency(latency_ts); int frames_filled = source_callback_->OnMoreData( - output_bus_.get(), total_delay_bytes); + output_bus_.get(), + AudioBuffersState(0, total_delay_bytes)); output_bus_->ToInterleaved(frames_filled, bytes_per_sample, output_samples); @@ -375,7 +376,7 @@ uint32 CrasUnifiedStream::WriteAudio(size_t frames, cras_client_calc_playback_latency(sample_ts, &latency_ts); int frames_filled = source_callback_->OnMoreData( - output_bus_.get(), GetBytesLatency(latency_ts)); + output_bus_.get(), AudioBuffersState(0, GetBytesLatency(latency_ts))); // Note: If this ever changes to output raw float the data must be clipped and // sanitized since it may come from an untrusted source such as NaCl. diff --git a/media/audio/fake_audio_consumer_unittest.cc b/media/audio/fake_audio_consumer_unittest.cc index ad04cb6..cb2f75c 100644 --- a/media/audio/fake_audio_consumer_unittest.cc +++ b/media/audio/fake_audio_consumer_unittest.cc @@ -5,6 +5,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/time/time.h" +#include "media/audio/audio_buffers_state.h" #include "media/audio/audio_parameters.h" #include "media/audio/fake_audio_consumer.h" #include "media/audio/simple_sources.h" @@ -29,7 +30,7 @@ class FakeAudioConsumerTest : public testing::Test { virtual ~FakeAudioConsumerTest() {} void ConsumeData(AudioBus* audio_bus) { - source_.OnMoreData(audio_bus, 0); + source_.OnMoreData(audio_bus, AudioBuffersState()); } void RunOnAudioThread() { diff --git a/media/audio/fake_audio_output_stream.cc b/media/audio/fake_audio_output_stream.cc index d5e0d5f..0448c23 100644 --- a/media/audio/fake_audio_output_stream.cc +++ b/media/audio/fake_audio_output_stream.cc @@ -61,7 +61,7 @@ void FakeAudioOutputStream::GetVolume(double* volume) { void FakeAudioOutputStream::CallOnMoreData(AudioBus* audio_bus) { DCHECK(audio_manager_->GetWorkerTaskRunner()->BelongsToCurrentThread()); - callback_->OnMoreData(audio_bus, 0); + callback_->OnMoreData(audio_bus, AudioBuffersState()); } } // namespace media diff --git a/media/audio/mac/audio_auhal_mac.cc b/media/audio/mac/audio_auhal_mac.cc index 92a1b18..41fc57c 100644 --- a/media/audio/mac/audio_auhal_mac.cc +++ b/media/audio/mac/audio_auhal_mac.cc @@ -228,8 +228,9 @@ void AUHALStream::ProvideInput(int frame_delay, AudioBus* dest) { // Supply the input data and render the output data. source_->OnMoreData( dest, - current_hardware_pending_bytes_ + - frame_delay * params_.GetBytesPerFrame()); + AudioBuffersState(0, + current_hardware_pending_bytes_ + + frame_delay * params_.GetBytesPerFrame())); dest->Scale(volume_); } diff --git a/media/audio/mock_audio_source_callback.h b/media/audio/mock_audio_source_callback.h index 89814cf..d24ce44 100644 --- a/media/audio/mock_audio_source_callback.h +++ b/media/audio/mock_audio_source_callback.h @@ -16,7 +16,7 @@ class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { virtual ~MockAudioSourceCallback(); MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus, - int total_bytes_delay)); + AudioBuffersState buffers_state)); MOCK_METHOD1(OnError, void(AudioOutputStream* stream)); private: diff --git a/media/audio/pulse/pulse_output.cc b/media/audio/pulse/pulse_output.cc index 1048113..e0a0b42 100644 --- a/media/audio/pulse/pulse_output.cc +++ b/media/audio/pulse/pulse_output.cc @@ -133,7 +133,7 @@ void PulseAudioOutputStream::FulfillWriteRequest(size_t requested_bytes) { const uint32 hardware_delay = pulse::GetHardwareLatencyInBytes( pa_stream_, params_.sample_rate(), params_.GetBytesPerFrame()); frames_filled = source_callback_->OnMoreData( - audio_bus_.get(), hardware_delay); + audio_bus_.get(), AudioBuffersState(0, hardware_delay)); // Zero any unfilled data so it plays back as silence. if (frames_filled < audio_bus_->frames()) { diff --git a/media/audio/simple_sources.cc b/media/audio/simple_sources.cc index 2c22e16..039029e 100644 --- a/media/audio/simple_sources.cc +++ b/media/audio/simple_sources.cc @@ -29,7 +29,7 @@ SineWaveAudioSource::SineWaveAudioSource(int channels, // The implementation could be more efficient if a lookup table is constructed // but it is efficient enough for our simple needs. int SineWaveAudioSource::OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) { + AudioBuffersState audio_buffers) { base::AutoLock auto_lock(time_lock_); callbacks_++; diff --git a/media/audio/simple_sources.h b/media/audio/simple_sources.h index feda33b..6303386 100644 --- a/media/audio/simple_sources.h +++ b/media/audio/simple_sources.h @@ -28,7 +28,7 @@ class MEDIA_EXPORT SineWaveAudioSource // Implementation of AudioSourceCallback. virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) OVERRIDE; + AudioBuffersState audio_buffers) OVERRIDE; virtual void OnError(AudioOutputStream* stream) OVERRIDE; // The number of OnMoreData()+OnMoreIOData() and OnError() calls respectively. diff --git a/media/audio/simple_sources_unittest.cc b/media/audio/simple_sources_unittest.cc index 51cb740..5ee8686 100644 --- a/media/audio/simple_sources_unittest.cc +++ b/media/audio/simple_sources_unittest.cc @@ -26,7 +26,7 @@ TEST(SimpleSources, SineWaveAudioSource) { SineWaveAudioSource source(1, freq, params.sample_rate()); scoped_ptr<AudioBus> audio_bus = AudioBus::Create(params); - source.OnMoreData(audio_bus.get(), 0); + source.OnMoreData(audio_bus.get(), AudioBuffersState()); EXPECT_EQ(1, source.callbacks()); EXPECT_EQ(0, source.errors()); @@ -56,13 +56,13 @@ TEST(SimpleSources, SineWaveAudioCapped) { scoped_ptr<AudioBus> audio_bus = AudioBus::Create(1, 2 * kSampleCap); EXPECT_EQ(source.OnMoreData( - audio_bus.get(), 0), kSampleCap); + audio_bus.get(), AudioBuffersState()), kSampleCap); EXPECT_EQ(1, source.callbacks()); - EXPECT_EQ(source.OnMoreData(audio_bus.get(), 0), 0); + EXPECT_EQ(source.OnMoreData(audio_bus.get(), AudioBuffersState()), 0); EXPECT_EQ(2, source.callbacks()); source.Reset(); EXPECT_EQ(source.OnMoreData( - audio_bus.get(), 0), kSampleCap); + audio_bus.get(), AudioBuffersState()), kSampleCap); EXPECT_EQ(3, source.callbacks()); EXPECT_EQ(0, source.errors()); } diff --git a/media/audio/sounds/audio_stream_handler.cc b/media/audio/sounds/audio_stream_handler.cc index 7e48b2d..645fcb3 100644 --- a/media/audio/sounds/audio_stream_handler.cc +++ b/media/audio/sounds/audio_stream_handler.cc @@ -105,7 +105,7 @@ class AudioStreamHandler::AudioStreamContainer // AudioOutputStream::AudioSourceCallback overrides: // Following methods could be called from *ANY* thread. virtual int OnMoreData(AudioBus* dest, - int /* total_bytes_delay */) OVERRIDE { + AudioBuffersState /* state */) OVERRIDE { base::AutoLock al(state_lock_); size_t bytes_written = 0; diff --git a/media/audio/virtual_audio_input_stream_unittest.cc b/media/audio/virtual_audio_input_stream_unittest.cc index c82a9ff..3aa87b0 100644 --- a/media/audio/virtual_audio_input_stream_unittest.cc +++ b/media/audio/virtual_audio_input_stream_unittest.cc @@ -67,9 +67,8 @@ class TestAudioSource : public SineWaveAudioSource { virtual ~TestAudioSource() {} virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) OVERRIDE { - const int ret = SineWaveAudioSource::OnMoreData(audio_bus, - total_bytes_delay); + AudioBuffersState audio_buffers) OVERRIDE { + const int ret = SineWaveAudioSource::OnMoreData(audio_bus, audio_buffers); data_pulled_.Signal(); return ret; } diff --git a/media/audio/virtual_audio_output_stream.cc b/media/audio/virtual_audio_output_stream.cc index 016c2f3..43b83cf 100644 --- a/media/audio/virtual_audio_output_stream.cc +++ b/media/audio/virtual_audio_output_stream.cc @@ -77,7 +77,7 @@ double VirtualAudioOutputStream::ProvideInput(AudioBus* audio_bus, // platform. DCHECK(callback_); - const int frames = callback_->OnMoreData(audio_bus, 0); + const int frames = callback_->OnMoreData(audio_bus, AudioBuffersState()); if (frames < audio_bus->frames()) audio_bus->ZeroFramesPartial(frames, audio_bus->frames() - frames); diff --git a/media/audio/win/audio_low_latency_output_win.cc b/media/audio/win/audio_low_latency_output_win.cc index 99576a6..15cabbaf 100644 --- a/media/audio/win/audio_low_latency_output_win.cc +++ b/media/audio/win/audio_low_latency_output_win.cc @@ -498,9 +498,13 @@ bool WASAPIAudioOutputStream::RenderAudioFromSource(UINT64 device_frequency) { // Read a data packet from the registered client source and // deliver a delay estimate in the same callback to the client. + // A time stamp is also stored in the AudioBuffersState. This + // time stamp can be used at the client side to compensate for + // the delay between the usage of the delay value and the time + // of generation. int frames_filled = source_->OnMoreData( - audio_bus_.get(), audio_delay_bytes); + audio_bus_.get(), AudioBuffersState(0, audio_delay_bytes)); uint32 num_filled_bytes = frames_filled * format_.Format.nBlockAlign; DCHECK_LE(num_filled_bytes, packet_size_bytes_); diff --git a/media/audio/win/audio_low_latency_output_win_unittest.cc b/media/audio/win/audio_low_latency_output_win_unittest.cc index 30fa9ca..ed03d2b 100644 --- a/media/audio/win/audio_low_latency_output_win_unittest.cc +++ b/media/audio/win/audio_low_latency_output_win_unittest.cc @@ -52,7 +52,7 @@ MATCHER_P(HasValidDelay, value, "") { // It is difficult to come up with a perfect test condition for the delay // estimation. For now, verify that the produced output delay is always // larger than the selected buffer size. - return arg >= value; + return arg.hardware_delay_bytes >= value.hardware_delay_bytes; } // Used to terminate a loop from a different thread than the loop belongs to. @@ -103,7 +103,7 @@ class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback { // AudioOutputStream::AudioSourceCallback implementation. virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) { + AudioBuffersState buffers_state) { // Store time difference between two successive callbacks in an array. // These values will be written to a file in the destructor. const base::TimeTicks now_time = base::TimeTicks::Now(); @@ -396,11 +396,14 @@ TEST(WASAPIAudioOutputStreamTest, ValidPacketSize) { EXPECT_TRUE(aos->Open()); // Derive the expected size in bytes of each packet. - int bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * - (aosw.bits_per_sample() / 8); + uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * + (aosw.bits_per_sample() / 8); + + // Set up expected minimum delay estimation. + AudioBuffersState state(0, bytes_per_packet); // Wait for the first callback and verify its parameters. - EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet))) + EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state))) .WillOnce(DoAll( QuitLoop(loop.message_loop_proxy()), Return(aosw.samples_per_packet()))); @@ -597,11 +600,14 @@ TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt48kHz) { EXPECT_TRUE(aos->Open()); // Derive the expected size in bytes of each packet. - int bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * + uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * (aosw.bits_per_sample() / 8); + // Set up expected minimum delay estimation. + AudioBuffersState state(0, bytes_per_packet); + // Wait for the first callback and verify its parameters. - EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet))) + EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state))) .WillOnce(DoAll( QuitLoop(loop.message_loop_proxy()), Return(aosw.samples_per_packet()))) @@ -635,11 +641,14 @@ TEST(WASAPIAudioOutputStreamTest, ExclusiveModeMinBufferSizeAt44kHz) { EXPECT_TRUE(aos->Open()); // Derive the expected size in bytes of each packet. - int bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * + uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * (aosw.bits_per_sample() / 8); + // Set up expected minimum delay estimation. + AudioBuffersState state(0, bytes_per_packet); + // Wait for the first callback and verify its parameters. - EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet))) + EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state))) .WillOnce(DoAll( QuitLoop(loop.message_loop_proxy()), Return(aosw.samples_per_packet()))) diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc index 6257a60..2902657 100644 --- a/media/audio/win/audio_output_win_unittest.cc +++ b/media/audio/win/audio_output_win_unittest.cc @@ -37,7 +37,7 @@ namespace media { static const wchar_t kAudioFile1_16b_m_16K[] = L"media\\test\\data\\sweep02_16b_mono_16KHz.raw"; -static int ClearData(AudioBus* audio_bus, int total_bytes_delay) { +static int ClearData(AudioBus* audio_bus, AudioBuffersState buffers_state) { audio_bus->Zero(); return audio_bus->frames(); } @@ -52,7 +52,7 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback { } // AudioSourceCallback::OnMoreData implementation: virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) { + AudioBuffersState buffers_state) { ++callback_count_; // Touch the channel memory value to make sure memory is good. audio_bus->Zero(); @@ -89,9 +89,9 @@ class TestSourceLaggy : public TestSourceBasic { : laggy_after_buffer_(laggy_after_buffer), lag_in_ms_(lag_in_ms) { } virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) { + AudioBuffersState buffers_state) { // Call the base, which increments the callback_count_. - TestSourceBasic::OnMoreData(audio_bus, total_bytes_delay); + TestSourceBasic::OnMoreData(audio_bus, buffers_state); if (callback_count() > kMaxNumBuffers) { ::Sleep(lag_in_ms_); } @@ -520,22 +520,32 @@ TEST(WinAudioTest, PCMWaveStreamPendingBytes) { // pending bytes will go down and eventually read zero. InSequence s; - EXPECT_CALL(source, OnMoreData(NotNull(), 0)) + EXPECT_CALL(source, OnMoreData(NotNull(), + Field(&AudioBuffersState::pending_bytes, 0))) .WillOnce(Invoke(ClearData)); // Note: If AudioManagerWin::NumberOfWaveOutBuffers() ever changes, or if this // test is run on Vista, these expectations will fail. - EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms)) + EXPECT_CALL(source, OnMoreData(NotNull(), + Field(&AudioBuffersState::pending_bytes, + bytes_100_ms))) .WillOnce(Invoke(ClearData)); - EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms)) + EXPECT_CALL(source, OnMoreData(NotNull(), + Field(&AudioBuffersState::pending_bytes, + 2 * bytes_100_ms))) .WillOnce(Invoke(ClearData)); - EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms)) + EXPECT_CALL(source, OnMoreData(NotNull(), + Field(&AudioBuffersState::pending_bytes, + 2 * bytes_100_ms))) .Times(AnyNumber()) .WillRepeatedly(Return(0)); - EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms)) + EXPECT_CALL(source, OnMoreData(NotNull(), + Field(&AudioBuffersState::pending_bytes, + bytes_100_ms))) .Times(AnyNumber()) .WillRepeatedly(Return(0)); - EXPECT_CALL(source, OnMoreData(NotNull(), 0)) + EXPECT_CALL(source, OnMoreData(NotNull(), + Field(&AudioBuffersState::pending_bytes, 0))) .Times(AnyNumber()) .WillRepeatedly(Return(0)); @@ -561,8 +571,8 @@ class SyncSocketSource : public AudioOutputStream::AudioSourceCallback { // AudioSourceCallback::OnMoreData implementation: virtual int OnMoreData(AudioBus* audio_bus, - int total_bytes_delay) { - socket_->Send(&total_bytes_delay, sizeof(total_bytes_delay)); + AudioBuffersState buffers_state) { + socket_->Send(&buffers_state, sizeof(buffers_state)); uint32 size = socket_->Receive(data_.get(), data_size_); DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); audio_bus_->CopyTo(audio_bus); @@ -570,7 +580,7 @@ class SyncSocketSource : public AudioOutputStream::AudioSourceCallback { } virtual int OnMoreIOData(AudioBus* source, AudioBus* dest, - int total_bytes_delay) { + AudioBuffersState buffers_state) { NOTREACHED(); return 0; } @@ -612,13 +622,13 @@ DWORD __stdcall SyncSocketThread(void* context) { SineWaveAudioSource sine(1, ctx.sine_freq, ctx.sample_rate); const int kTwoSecFrames = ctx.sample_rate * 2; - int total_bytes_delay = 0; + AudioBuffersState buffers_state; int times = 0; for (int ix = 0; ix < kTwoSecFrames; ix += ctx.frames) { - if (ctx.socket->Receive(&total_bytes_delay, sizeof(total_bytes_delay)) == 0) + if (ctx.socket->Receive(&buffers_state, sizeof(buffers_state)) == 0) break; - if ((times > 0) && (total_bytes_delay < 1000)) __debugbreak(); - sine.OnMoreData(audio_bus.get(), total_bytes_delay); + if ((times > 0) && (buffers_state.pending_bytes < 1000)) __debugbreak(); + sine.OnMoreData(audio_bus.get(), buffers_state); ctx.socket->Send(data.get(), ctx.packet_size_bytes); ++times; } diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc index 4d11e08..0f54817 100644 --- a/media/audio/win/waveout_output_win.cc +++ b/media/audio/win/waveout_output_win.cc @@ -325,10 +325,9 @@ void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) { // return to us how many bytes were used. // TODO(fbarchard): Handle used 0 by queueing more. - // TODO(sergeyu): Specify correct hardware delay for |total_delay_bytes|. - int total_delay_bytes = pending_bytes_; + // TODO(sergeyu): Specify correct hardware delay for AudioBuffersState. int frames_filled = callback_->OnMoreData( - audio_bus_.get(), total_delay_bytes); + audio_bus_.get(), AudioBuffersState(pending_bytes_, 0)); uint32 used = frames_filled * audio_bus_->channels() * format_.Format.wBitsPerSample / 8; diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc index 7ded86a..65b0e60 100644 --- a/media/cast/test/receiver.cc +++ b/media/cast/test/receiver.cc @@ -316,7 +316,7 @@ class NaivePlayer : public InProcessReceiver, //////////////////////////////////////////////////////////////////// // AudioSourceCallback implementation. - virtual int OnMoreData(AudioBus* dest, int total_bytes_delay) + virtual int OnMoreData(AudioBus* dest, AudioBuffersState buffers_state) OVERRIDE { // Note: This method is being invoked by a separate thread unknown to us // (i.e., outside of CastEnvironment). @@ -329,8 +329,8 @@ class NaivePlayer : public InProcessReceiver, base::AutoLock auto_lock(audio_lock_); // Prune the queue, skipping entries that are too old. - // TODO(miu): Use |total_bytes_delay| to account for audio buffering - // delays upstream. + // TODO(miu): Use |buffers_state| to account for audio buffering delays + // upstream. const base::TimeTicks earliest_time_to_play = cast_env()->Clock()->NowTicks() - max_frame_age_; while (!audio_playout_queue_.empty() && diff --git a/media/cast/test/utility/audio_utility.cc b/media/cast/test/utility/audio_utility.cc index 094f141..8dde4dd 100644 --- a/media/cast/test/utility/audio_utility.cc +++ b/media/cast/test/utility/audio_utility.cc @@ -36,7 +36,7 @@ scoped_ptr<AudioBus> TestAudioBusFactory::NextAudioBus( const int num_samples = static_cast<int>((sample_rate_ * duration) / base::TimeDelta::FromSeconds(1)); scoped_ptr<AudioBus> bus(AudioBus::Create(num_channels_, num_samples)); - source_.OnMoreData(bus.get(), 0); + source_.OnMoreData(bus.get(), AudioBuffersState()); bus->Scale(volume_); return bus.Pass(); } diff --git a/media/media.gyp b/media/media.gyp index 5adb828..027cb55 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -91,6 +91,8 @@ 'audio/android/opensles_output.cc', 'audio/android/opensles_output.h', 'audio/android/opensles_wrapper.cc', + 'audio/audio_buffers_state.cc', + 'audio/audio_buffers_state.h', 'audio/audio_device_name.cc', 'audio/audio_device_name.h', 'audio/audio_device_thread.cc', |