summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authoracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-18 22:08:24 +0000
committeracolwell@chromium.org <acolwell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-18 22:09:57 +0000
commit1fdcfb56d3e76afa29cfc4ff795ba9c1353b0f54 (patch)
tree097d5a5114f0b70be2c2041d9d5be2fc70f23d6c /media
parent73a643f618a1329425fcecb4d3c9d5ea890b636c (diff)
downloadchromium_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')
-rw-r--r--media/audio/BUILD.gn2
-rw-r--r--media/audio/alsa/alsa_output.cc6
-rw-r--r--media/audio/alsa/alsa_output.h2
-rw-r--r--media/audio/alsa/alsa_output_unittest.cc5
-rw-r--r--media/audio/android/audio_android_unittest.cc6
-rw-r--r--media/audio/android/opensles_output.cc2
-rw-r--r--media/audio/audio_buffers_state.cc20
-rw-r--r--media/audio/audio_buffers_state.h32
-rw-r--r--media/audio/audio_io.h7
-rw-r--r--media/audio/audio_low_latency_input_output_unittest.cc13
-rw-r--r--media/audio/audio_output_controller.cc4
-rw-r--r--media/audio/audio_output_controller.h2
-rw-r--r--media/audio/audio_output_controller_unittest.cc2
-rw-r--r--media/audio/audio_output_proxy_unittest.cc3
-rw-r--r--media/audio/audio_output_resampler.cc17
-rw-r--r--media/audio/audio_output_resampler.h4
-rw-r--r--media/audio/cras/cras_unified.cc5
-rw-r--r--media/audio/fake_audio_consumer_unittest.cc3
-rw-r--r--media/audio/fake_audio_output_stream.cc2
-rw-r--r--media/audio/mac/audio_auhal_mac.cc5
-rw-r--r--media/audio/mock_audio_source_callback.h2
-rw-r--r--media/audio/pulse/pulse_output.cc2
-rw-r--r--media/audio/simple_sources.cc2
-rw-r--r--media/audio/simple_sources.h2
-rw-r--r--media/audio/simple_sources_unittest.cc8
-rw-r--r--media/audio/sounds/audio_stream_handler.cc2
-rw-r--r--media/audio/virtual_audio_input_stream_unittest.cc5
-rw-r--r--media/audio/virtual_audio_output_stream.cc2
-rw-r--r--media/audio/win/audio_low_latency_output_win.cc6
-rw-r--r--media/audio/win/audio_low_latency_output_win_unittest.cc27
-rw-r--r--media/audio/win/audio_output_win_unittest.cc44
-rw-r--r--media/audio/win/waveout_output_win.cc5
-rw-r--r--media/cast/test/receiver.cc6
-rw-r--r--media/cast/test/utility/audio_utility.cc2
-rw-r--r--media/media.gyp2
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',