summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/audio/alsa/alsa_output.cc2
-rw-r--r--media/audio/alsa/alsa_output_unittest.cc8
-rw-r--r--media/audio/android/audio_android_unittest.cc20
-rw-r--r--media/audio/android/opensles_output.cc4
-rw-r--r--media/audio/audio_device_thread.h4
-rw-r--r--media/audio/audio_input_device.cc4
-rw-r--r--media/audio/audio_io.h5
-rw-r--r--media/audio/audio_low_latency_input_output_unittest.cc4
-rw-r--r--media/audio/audio_output_controller.cc11
-rw-r--r--media/audio/audio_output_controller.h13
-rw-r--r--media/audio/audio_output_controller_unittest.cc8
-rw-r--r--media/audio/audio_output_device.cc34
-rw-r--r--media/audio/audio_output_device_unittest.cc15
-rw-r--r--media/audio/audio_output_proxy_unittest.cc4
-rw-r--r--media/audio/audio_output_resampler.cc10
-rw-r--r--media/audio/audio_output_stream_sink.cc5
-rw-r--r--media/audio/audio_output_stream_sink.h4
-rw-r--r--media/audio/audio_parameters.h25
-rw-r--r--media/audio/clockless_audio_sink.cc2
-rw-r--r--media/audio/cras/cras_unified.cc2
-rw-r--r--media/audio/cras/cras_unified_unittest.cc8
-rw-r--r--media/audio/fake_audio_input_stream.cc2
-rw-r--r--media/audio/fake_audio_output_stream.cc2
-rw-r--r--media/audio/mac/audio_auhal_mac.cc10
-rw-r--r--media/audio/mac/audio_auhal_mac.h7
-rw-r--r--media/audio/mac/audio_auhal_mac_unittest.cc2
-rw-r--r--media/audio/mock_audio_source_callback.h6
-rw-r--r--media/audio/null_audio_sink.cc2
-rw-r--r--media/audio/pulse/pulse_output.cc4
-rw-r--r--media/audio/simple_sources.cc11
-rw-r--r--media/audio/simple_sources.h12
-rw-r--r--media/audio/simple_sources_unittest.cc16
-rw-r--r--media/audio/sounds/audio_stream_handler.cc4
-rw-r--r--media/audio/virtual_audio_input_stream_unittest.cc8
-rw-r--r--media/audio/virtual_audio_output_stream.cc2
-rw-r--r--media/audio/win/audio_low_latency_output_win.cc4
-rw-r--r--media/audio/win/audio_low_latency_output_win_unittest.cc10
-rw-r--r--media/audio/win/audio_output_win_unittest.cc33
-rw-r--r--media/audio/win/waveout_output_win.cc4
-rw-r--r--media/base/audio_bus_perftest.cc2
-rw-r--r--media/base/audio_converter_unittest.cc2
-rw-r--r--media/base/audio_hash_unittest.cc2
-rw-r--r--media/base/audio_renderer_mixer.cc3
-rw-r--r--media/base/audio_renderer_mixer.h4
-rw-r--r--media/base/audio_renderer_mixer_input.cc2
-rw-r--r--media/base/audio_renderer_mixer_unittest.cc8
-rw-r--r--media/base/audio_renderer_sink.h7
-rw-r--r--media/base/fake_audio_render_callback.cc5
-rw-r--r--media/base/fake_audio_render_callback.h4
-rw-r--r--media/base/fake_audio_renderer_sink.cc5
-rw-r--r--media/base/fake_audio_renderer_sink.h3
-rw-r--r--media/blink/webaudiosourceprovider_impl.cc2
-rw-r--r--media/blink/webaudiosourceprovider_impl_unittest.cc6
-rw-r--r--media/cast/test/receiver.cc4
-rw-r--r--media/cast/test/utility/audio_utility.cc2
-rw-r--r--media/renderers/audio_renderer_impl.cc3
-rw-r--r--media/renderers/audio_renderer_impl.h4
57 files changed, 251 insertions, 148 deletions
diff --git a/media/audio/alsa/alsa_output.cc b/media/audio/alsa/alsa_output.cc
index 554aa5f..046c9bc 100644
--- a/media/audio/alsa/alsa_output.cc
+++ b/media/audio/alsa/alsa_output.cc
@@ -781,7 +781,7 @@ int AlsaPcmOutputStream::RunDataCallback(AudioBus* audio_bus,
TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback");
if (source_callback_)
- return source_callback_->OnMoreData(audio_bus, total_bytes_delay);
+ return source_callback_->OnMoreData(audio_bus, total_bytes_delay, 0);
return 0;
}
diff --git a/media/audio/alsa/alsa_output_unittest.cc b/media/audio/alsa/alsa_output_unittest.cc
index 8996dbc..af2c46a 100644
--- a/media/audio/alsa/alsa_output_unittest.cc
+++ b/media/audio/alsa/alsa_output_unittest.cc
@@ -422,7 +422,7 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
.WillRepeatedly(Return(SND_PCM_STATE_RUNNING));
EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _))
.WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0)));
- EXPECT_CALL(mock_callback, OnMoreData(_, _))
+ EXPECT_CALL(mock_callback, OnMoreData(_, _, 0))
.WillRepeatedly(DoAll(ClearBuffer(), Return(kTestFramesPerPacket)));
EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _))
.WillRepeatedly(Return(kTestFramesPerPacket));
@@ -585,7 +585,7 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket) {
.WillRepeatedly(Return(0)); // Buffer is full.
// Return a partially filled packet.
- EXPECT_CALL(mock_callback, OnMoreData(_, _))
+ EXPECT_CALL(mock_callback, OnMoreData(_, _, 0))
.WillOnce(DoAll(ClearBuffer(), Return(kTestFramesPerPacket / 2)));
bool source_exhausted;
@@ -611,7 +611,7 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) {
.WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0)));
EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_))
.WillRepeatedly(Return(0)); // Buffer is full.
- EXPECT_CALL(mock_callback, OnMoreData(_, _))
+ EXPECT_CALL(mock_callback, OnMoreData(_, _, 0))
.WillOnce(DoAll(ClearBuffer(), Return(kTestFramesPerPacket / 2)));
bool source_exhausted;
@@ -635,7 +635,7 @@ 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(_, 0, 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 9140f22..68b53ed 100644
--- a/media/audio/android/audio_android_unittest.cc
+++ b/media/audio/android/audio_android_unittest.cc
@@ -121,7 +121,9 @@ void CheckDeviceNames(const AudioDeviceNames& device_names) {
}
// We clear the data bus to ensure that the test does not cause noise.
-int RealOnMoreData(AudioBus* dest, uint32 total_bytes_delay) {
+int RealOnMoreData(AudioBus* dest,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
dest->Zero();
return dest->frames();
}
@@ -177,7 +179,9 @@ class FileAudioSource : public AudioOutputStream::AudioSourceCallback {
// Use samples read from a data file and fill up the audio buffer
// provided to us in the callback.
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
bool stop_playing = false;
int max_size =
audio_bus->frames() * audio_bus->channels() * kBytesPerSample;
@@ -352,7 +356,9 @@ class FullDuplexAudioSinkSource
void OnError(AudioInputStream* stream) override {}
// AudioOutputStream::AudioSourceCallback implementation
- int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) override {
+ int OnMoreData(AudioBus* dest,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
const int size_in_bytes =
(params_.bits_per_sample() / 8) * dest->frames() * dest->channels();
EXPECT_EQ(size_in_bytes, params_.GetBytesPerBuffer());
@@ -491,11 +497,11 @@ class AudioAndroidOutputTest : public testing::Test {
int count = 0;
MockAudioSourceCallback source;
- EXPECT_CALL(source, OnMoreData(NotNull(), _))
+ EXPECT_CALL(source, OnMoreData(NotNull(), _, 0))
.Times(AtLeast(num_callbacks))
.WillRepeatedly(
- DoAll(CheckCountAndPostQuitTask(&count, num_callbacks, loop()),
- Invoke(RealOnMoreData)));
+ DoAll(CheckCountAndPostQuitTask(&count, num_callbacks, loop()),
+ Invoke(RealOnMoreData)));
EXPECT_CALL(source, OnError(audio_output_stream_)).Times(0);
OpenAndStartAudioOutputStreamOnAudioThread(&source);
@@ -895,7 +901,7 @@ TEST_P(AudioAndroidInputTest, DISABLED_RunDuplexInputStreamWithFileAsSink) {
FileAudioSink sink(&event, in_params, file_name);
MockAudioSourceCallback source;
- EXPECT_CALL(source, OnMoreData(NotNull(), _))
+ EXPECT_CALL(source, OnMoreData(NotNull(), _, 0))
.WillRepeatedly(Invoke(RealOnMoreData));
EXPECT_CALL(source, OnError(audio_output_stream_)).Times(0);
diff --git a/media/audio/android/opensles_output.cc b/media/audio/android/opensles_output.cc
index 2974e14..7fffe3b 100644
--- a/media/audio/android/opensles_output.cc
+++ b/media/audio/android/opensles_output.cc
@@ -331,8 +331,8 @@ void OpenSLESOutputStream::FillBufferQueueNoLock() {
// TODO(henrika): Investigate if it is possible to get a more accurate
// delay estimation.
const uint32 hardware_delay = buffer_size_bytes_;
- int frames_filled = callback_->OnMoreData(
- audio_bus_.get(), hardware_delay);
+ int frames_filled =
+ callback_->OnMoreData(audio_bus_.get(), hardware_delay, 0);
if (frames_filled <= 0) {
// Audio source is shutting down, or halted on error.
return;
diff --git a/media/audio/audio_device_thread.h b/media/audio/audio_device_thread.h
index 7e8e2bf..b910c71 100644
--- a/media/audio/audio_device_thread.h
+++ b/media/audio/audio_device_thread.h
@@ -50,8 +50,8 @@ class MEDIA_EXPORT AudioDeviceThread {
// before Process can be called.
virtual void MapSharedMemory() = 0;
- // Called whenever we receive notifications about pending data.
- virtual void Process(uint32 pending_data) = 0;
+ // Called whenever we receive notifications about pending input data.
+ virtual void Process(uint32_t pending_data) = 0;
protected:
// Protected so that derived classes can access directly.
diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc
index 02fa7a7..074291f 100644
--- a/media/audio/audio_input_device.cc
+++ b/media/audio/audio_input_device.cc
@@ -36,7 +36,7 @@ class AudioInputDevice::AudioThreadCallback
void MapSharedMemory() override;
// Called whenever we receive notifications about pending data.
- void Process(uint32 pending_data) override;
+ void Process(uint32_t pending_data) override;
private:
int current_segment_id_;
@@ -297,7 +297,7 @@ void AudioInputDevice::AudioThreadCallback::MapSharedMemory() {
}
}
-void AudioInputDevice::AudioThreadCallback::Process(uint32 pending_data) {
+void AudioInputDevice::AudioThreadCallback::Process(uint32_t pending_data) {
// The shared memory represents parameters, size of the data buffer and the
// actual data buffer containing audio data. Map the memory into this
// structure and parse out parameters and the data area.
diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h
index 5639215..45af3d2 100644
--- a/media/audio/audio_io.h
+++ b/media/audio/audio_io.h
@@ -61,7 +61,10 @@ class MEDIA_EXPORT AudioOutputStream {
// 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.
- virtual int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) = 0;
+ // |frames_skipped| contains the number of frames skipped by the consumer.
+ virtual int OnMoreData(AudioBus* dest,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) = 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 b24f501..b47c785 100644
--- a/media/audio/audio_low_latency_input_output_unittest.cc
+++ b/media/audio/audio_low_latency_input_output_unittest.cc
@@ -216,7 +216,9 @@ class FullDuplexAudioSinkSource
void OnError(AudioInputStream* stream) override {}
// AudioOutputStream::AudioSourceCallback.
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
base::AutoLock lock(lock_);
// Update one component in the AudioDelayState for the packet
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index f092496..d780687 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -164,7 +164,7 @@ void AudioOutputController::DoPlay() {
return;
// Ask for first packet.
- sync_reader_->UpdatePendingBytes(0);
+ sync_reader_->UpdatePendingBytes(0, 0);
state_ = kPlaying;
@@ -217,7 +217,7 @@ void AudioOutputController::DoPause() {
// Let the renderer know we've stopped. Necessary to let PPAPI clients know
// audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have
// a better way to know when it should exit PPB_Audio_Shared::Run().
- sync_reader_->UpdatePendingBytes(std::numeric_limits<uint32_t>::max());
+ sync_reader_->UpdatePendingBytes(std::numeric_limits<uint32_t>::max(), 0);
handler_->OnPaused();
}
@@ -284,7 +284,8 @@ void AudioOutputController::DoReportError() {
}
int AudioOutputController::OnMoreData(AudioBus* dest,
- uint32_t total_bytes_delay) {
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
TRACE_EVENT0("audio", "AudioOutputController::OnMoreData");
// Indicate that we haven't wedged (at least not indefinitely, WedgeCheck()
@@ -297,8 +298,8 @@ int AudioOutputController::OnMoreData(AudioBus* dest,
sync_reader_->Read(dest);
const int frames = dest->frames();
- sync_reader_->UpdatePendingBytes(base::saturated_cast<uint32_t>(
- total_bytes_delay + frames * params_.GetBytesPerFrame()));
+ sync_reader_->UpdatePendingBytes(
+ total_bytes_delay + frames * params_.GetBytesPerFrame(), frames_skipped);
if (will_monitor_audio_levels())
power_monitor_.Scan(*dest, frames);
diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h
index 7820665..95be9f4 100644
--- a/media/audio/audio_output_controller.h
+++ b/media/audio/audio_output_controller.h
@@ -8,6 +8,7 @@
#include "base/atomic_ref_count.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
+#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "media/audio/audio_io.h"
@@ -82,8 +83,12 @@ class MEDIA_EXPORT AudioOutputController
// Notify the synchronous reader the number of bytes in the
// AudioOutputController not yet played. This is used by SyncReader to
- // prepare more data and perform synchronization.
- virtual void UpdatePendingBytes(uint32 bytes) = 0;
+ // prepare more data and perform synchronization. Also inform about if any
+ // frames has been skipped by the renderer (typically the OS). The renderer
+ // source can handle this appropriately depending on the type of source. An
+ // ordinary file playout would ignore this.
+ virtual void UpdatePendingBytes(uint32_t bytes,
+ uint32_t frames_skipped) = 0;
// Attempts to completely fill |dest|, zeroing |dest| if the request can not
// be fulfilled (due to timeout).
@@ -153,7 +158,9 @@ class MEDIA_EXPORT AudioOutputController
const base::Closure& callback);
// AudioSourceCallback implementation.
- int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) override;
+ int OnMoreData(AudioBus* dest,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override;
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 b68dea2..9addca8 100644
--- a/media/audio/audio_output_controller_unittest.cc
+++ b/media/audio/audio_output_controller_unittest.cc
@@ -51,7 +51,8 @@ class MockAudioOutputControllerSyncReader
public:
MockAudioOutputControllerSyncReader() {}
- MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
+ MOCK_METHOD2(UpdatePendingBytes,
+ void(uint32_t bytes, uint32_t frames_skipped));
MOCK_METHOD1(Read, void(AudioBus* dest));
MOCK_METHOD0(Close, void());
@@ -132,8 +133,7 @@ class AudioOutputControllerTest : public testing::Test {
// During playback, the mock pretends to provide audio data rendered and
// sent from the render process.
- EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
- .Times(AtLeast(1));
+ EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_, _)).Times(AtLeast(1));
EXPECT_CALL(mock_sync_reader_, Read(_))
.WillRepeatedly(DoAll(PopulateBuffer(),
SignalEvent(&read_event_)));
@@ -190,7 +190,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(), 0, 0);
EXPECT_LT(0, frames_read);
EXPECT_EQ(kBufferNonZeroData, dest->channel(0)[0]);
}
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc
index 9924f76..cc0804b 100644
--- a/media/audio/audio_output_device.cc
+++ b/media/audio/audio_output_device.cc
@@ -28,12 +28,13 @@ class AudioOutputDevice::AudioThreadCallback
void MapSharedMemory() override;
// Called whenever we receive notifications about pending data.
- void Process(uint32 pending_data) override;
+ void Process(uint32_t pending_data) override;
private:
AudioRendererSink::RenderCallback* render_callback_;
scoped_ptr<AudioBus> output_bus_;
uint64 callback_num_;
+
DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback);
};
@@ -395,16 +396,19 @@ AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() {
void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() {
CHECK_EQ(total_segments_, 1);
CHECK(shared_memory_.Map(memory_length_));
- DCHECK_EQ(memory_length_, AudioBus::CalculateMemorySize(audio_parameters_));
+ DCHECK_EQ(static_cast<size_t>(memory_length_),
+ sizeof(AudioOutputBufferParameters) +
+ AudioBus::CalculateMemorySize(audio_parameters_));
- output_bus_ =
- AudioBus::WrapMemory(audio_parameters_, shared_memory_.memory());
+ AudioOutputBuffer* buffer =
+ reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory());
+ output_bus_ = AudioBus::WrapMemory(audio_parameters_, buffer->audio);
}
// Called whenever we receive notifications about pending data.
-void AudioOutputDevice::AudioThreadCallback::Process(uint32 pending_data) {
+void AudioOutputDevice::AudioThreadCallback::Process(uint32_t pending_data) {
// Convert the number of pending bytes in the render buffer into milliseconds.
- int audio_delay_milliseconds = pending_data / bytes_per_ms_;
+ uint32_t audio_delay_milliseconds = pending_data / bytes_per_ms_;
callback_num_++;
TRACE_EVENT1("audio", "AudioOutputDevice::FireRenderCallback",
@@ -417,10 +421,18 @@ void AudioOutputDevice::AudioThreadCallback::Process(uint32 pending_data) {
TRACE_EVENT_ASYNC_END0("audio", "StartingPlayback", this);
}
- // Update the audio-delay measurement then ask client to render audio. Since
- // |output_bus_| is wrapping the shared memory the Render() call is writing
- // directly into the shared memory.
- render_callback_->Render(output_bus_.get(), audio_delay_milliseconds);
+ // Read and reset the number of frames skipped.
+ AudioOutputBuffer* buffer =
+ reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory());
+ uint32_t frames_skipped = buffer->params.frames_skipped;
+ buffer->params.frames_skipped = 0;
+
+ // Update the audio-delay measurement, inform about the number of skipped
+ // frames, and ask client to render audio. Since |output_bus_| is wrapping
+ // the shared memory the Render() call is writing directly into the shared
+ // memory.
+ render_callback_->Render(output_bus_.get(), audio_delay_milliseconds,
+ frames_skipped);
}
-} // namespace media.
+} // namespace media
diff --git a/media/audio/audio_output_device_unittest.cc b/media/audio/audio_output_device_unittest.cc
index 5faa119..aa7e649 100644
--- a/media/audio/audio_output_device_unittest.cc
+++ b/media/audio/audio_output_device_unittest.cc
@@ -44,7 +44,10 @@ class MockRenderCallback : public AudioRendererSink::RenderCallback {
MockRenderCallback() {}
virtual ~MockRenderCallback() {}
- MOCK_METHOD2(Render, int(AudioBus* dest, int audio_delay_milliseconds));
+ MOCK_METHOD3(Render,
+ int(AudioBus* dest,
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped));
MOCK_METHOD0(OnRenderError, void());
};
@@ -117,7 +120,8 @@ class AudioOutputDeviceTest
int AudioOutputDeviceTest::CalculateMemorySize() {
// Calculate output memory size.
- return AudioBus::CalculateMemorySize(default_audio_parameters_);
+ return sizeof(AudioOutputBufferParameters) +
+ AudioBus::CalculateMemorySize(default_audio_parameters_);
}
AudioOutputDeviceTest::AudioOutputDeviceTest()
@@ -214,10 +218,9 @@ void AudioOutputDeviceTest::ExpectRenderCallback() {
// So, for the sake of this test, we consider the call to Render a sign
// of success and quit the loop.
const int kNumberOfFramesToProcess = 0;
- EXPECT_CALL(callback_, Render(_, _))
- .WillOnce(DoAll(
- QuitLoop(io_loop_.task_runner()),
- Return(kNumberOfFramesToProcess)));
+ EXPECT_CALL(callback_, Render(_, _, _))
+ .WillOnce(DoAll(QuitLoop(io_loop_.task_runner()),
+ Return(kNumberOfFramesToProcess)));
}
void AudioOutputDeviceTest::WaitUntilRenderCallback() {
diff --git a/media/audio/audio_output_proxy_unittest.cc b/media/audio/audio_output_proxy_unittest.cc
index 6f8befb..71c2ad9 100644
--- a/media/audio/audio_output_proxy_unittest.cc
+++ b/media/audio/audio_output_proxy_unittest.cc
@@ -124,7 +124,9 @@ class MockAudioManager : public AudioManagerBase {
class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
public:
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) {
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
audio_bus->Zero();
return audio_bus->frames();
}
diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc
index 29f6d26..ba33835 100644
--- a/media/audio/audio_output_resampler.cc
+++ b/media/audio/audio_output_resampler.cc
@@ -28,7 +28,9 @@ class OnMoreDataConverter
~OnMoreDataConverter() override;
// AudioSourceCallback interface.
- int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) override;
+ int OnMoreData(AudioBus* dest,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override;
void OnError(AudioOutputStream* stream) override;
// Sets |source_callback_|. If this is not a new object, then Stop() must be
@@ -370,7 +372,8 @@ void OnMoreDataConverter::Stop() {
}
int OnMoreDataConverter::OnMoreData(AudioBus* dest,
- uint32 total_bytes_delay) {
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
current_total_bytes_delay_ = total_bytes_delay;
audio_converter_.Convert(dest);
@@ -389,7 +392,8 @@ double OnMoreDataConverter::ProvideInput(AudioBus* dest,
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_total_bytes_delay, 0);
// 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_stream_sink.cc b/media/audio/audio_output_stream_sink.cc
index ceb943f..92739b3 100644
--- a/media/audio/audio_output_stream_sink.cc
+++ b/media/audio/audio_output_stream_sink.cc
@@ -76,14 +76,15 @@ OutputDevice* AudioOutputStreamSink::GetOutputDevice() {
}
int AudioOutputStreamSink::OnMoreData(AudioBus* dest,
- uint32 total_bytes_delay) {
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
// Note: Runs on the audio thread created by the OS.
base::AutoLock al(callback_lock_);
if (!active_render_callback_)
return 0;
return active_render_callback_->Render(
- dest, total_bytes_delay * 1000.0 / active_params_.GetBytesPerSecond());
+ dest, total_bytes_delay * 1000.0 / active_params_.GetBytesPerSecond(), 0);
}
void AudioOutputStreamSink::OnError(AudioOutputStream* stream) {
diff --git a/media/audio/audio_output_stream_sink.h b/media/audio/audio_output_stream_sink.h
index 1a5701b..b8eed26 100644
--- a/media/audio/audio_output_stream_sink.h
+++ b/media/audio/audio_output_stream_sink.h
@@ -39,7 +39,9 @@ class MEDIA_EXPORT AudioOutputStreamSink
OutputDevice* GetOutputDevice() override;
// AudioSourceCallback implementation.
- int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) override;
+ int OnMoreData(AudioBus* dest,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override;
void OnError(AudioOutputStream* stream) override;
private:
diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h
index c59dd30..f936881 100644
--- a/media/audio/audio_parameters.h
+++ b/media/audio/audio_parameters.h
@@ -19,25 +19,28 @@
namespace media {
// Use a struct-in-struct approach to ensure that we can calculate the required
-// size as sizeof(AudioInputBufferParameters) + #(bytes in audio buffer) without
-// using packing. Also align AudioInputBufferParameters instead of in
-// AudioInputBuffer to be able to calculate size like so. Use a macro for the
-// alignment value that's the same as AudioBus::kChannelAlignment, since MSVC
-// doesn't accept the latter to be used.
+// size as sizeof(Audio{Input,Output}BufferParameters) + #(bytes in audio
+// buffer) without using packing. Also align Audio{Input,Output}BufferParameters
+// instead of in Audio{Input,Output}Buffer to be able to calculate size like so.
+// Use a macro for the alignment value that's the same as
+// AudioBus::kChannelAlignment, since MSVC doesn't accept the latter to be used.
#if defined(OS_WIN)
#pragma warning(push)
#pragma warning(disable: 4324) // Disable warning for added padding.
#endif
#define PARAMETERS_ALIGNMENT 16
static_assert(AudioBus::kChannelAlignment == PARAMETERS_ALIGNMENT,
- "AudioInputBufferParameters alignment not same as AudioBus");
+ "Audio buffer parameters struct alignment not same as AudioBus");
struct MEDIA_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT) AudioInputBufferParameters {
double volume;
- uint32 size;
+ uint32_t size;
uint32_t hardware_delay_bytes;
uint32_t id;
bool key_pressed;
};
+struct MEDIA_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT) AudioOutputBufferParameters {
+ uint32_t frames_skipped;
+};
#undef PARAMETERS_ALIGNMENT
#if defined(OS_WIN)
#pragma warning(pop)
@@ -47,11 +50,19 @@ static_assert(sizeof(AudioInputBufferParameters) %
AudioBus::kChannelAlignment ==
0,
"AudioInputBufferParameters not aligned");
+static_assert(sizeof(AudioOutputBufferParameters) %
+ AudioBus::kChannelAlignment ==
+ 0,
+ "AudioOutputBufferParameters not aligned");
struct MEDIA_EXPORT AudioInputBuffer {
AudioInputBufferParameters params;
int8 audio[1];
};
+struct MEDIA_EXPORT AudioOutputBuffer {
+ AudioOutputBufferParameters params;
+ int8 audio[1];
+};
class MEDIA_EXPORT AudioParameters {
public:
diff --git a/media/audio/clockless_audio_sink.cc b/media/audio/clockless_audio_sink.cc
index 940ab2e..33d6aff 100644
--- a/media/audio/clockless_audio_sink.cc
+++ b/media/audio/clockless_audio_sink.cc
@@ -49,7 +49,7 @@ class ClocklessAudioSinkThread : public base::DelegateSimpleThread::Delegate {
void Run() override {
base::TimeTicks start;
while (!stop_event_->IsSignaled()) {
- const int frames_received = callback_->Render(audio_bus_.get(), 0);
+ const int frames_received = callback_->Render(audio_bus_.get(), 0, 0);
DCHECK_GE(frames_received, 0);
if (audio_hash_)
audio_hash_->Update(audio_bus_.get(), frames_received);
diff --git a/media/audio/cras/cras_unified.cc b/media/audio/cras/cras_unified.cc
index 1656624..180cfc1 100644
--- a/media/audio/cras/cras_unified.cc
+++ b/media/audio/cras/cras_unified.cc
@@ -306,7 +306,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(), GetBytesLatency(latency_ts), 0);
// 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/cras/cras_unified_unittest.cc b/media/audio/cras/cras_unified_unittest.cc
index 2f29bfa..64014c6 100644
--- a/media/audio/cras/cras_unified_unittest.cc
+++ b/media/audio/cras/cras_unified_unittest.cc
@@ -142,10 +142,10 @@ TEST_F(CrasUnifiedStreamTest, RenderFrames) {
base::WaitableEvent event(false, false);
- EXPECT_CALL(mock_callback, OnMoreData(_, _))
- .WillRepeatedly(DoAll(
- InvokeWithoutArgs(&event, &base::WaitableEvent::Signal),
- Return(kTestFramesPerPacket)));
+ EXPECT_CALL(mock_callback, OnMoreData(_, _, 0))
+ .WillRepeatedly(
+ DoAll(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal),
+ Return(kTestFramesPerPacket)));
test_stream->Start(&mock_callback);
diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc
index 458118da..d437d29 100644
--- a/media/audio/fake_audio_input_stream.cc
+++ b/media/audio/fake_audio_input_stream.cc
@@ -98,7 +98,7 @@ void FakeAudioInputStream::ReadAudioFromSource() {
audio_source_ = ChooseSource();
const int kNoDelay = 0;
- audio_source_->OnMoreData(audio_bus_.get(), kNoDelay);
+ audio_source_->OnMoreData(audio_bus_.get(), kNoDelay, 0);
callback_->OnData(this, audio_bus_.get(), 0, 1.0);
}
diff --git a/media/audio/fake_audio_output_stream.cc b/media/audio/fake_audio_output_stream.cc
index b919b84..d91d525 100644
--- a/media/audio/fake_audio_output_stream.cc
+++ b/media/audio/fake_audio_output_stream.cc
@@ -63,7 +63,7 @@ void FakeAudioOutputStream::GetVolume(double* volume) {
void FakeAudioOutputStream::CallOnMoreData() {
DCHECK(audio_manager_->GetWorkerTaskRunner()->BelongsToCurrentThread());
- callback_->OnMoreData(audio_bus_.get(), 0);
+ callback_->OnMoreData(audio_bus_.get(), 0, 0);
}
} // namespace media
diff --git a/media/audio/mac/audio_auhal_mac.cc b/media/audio/mac/audio_auhal_mac.cc
index 39c4610..4092a44 100644
--- a/media/audio/mac/audio_auhal_mac.cc
+++ b/media/audio/mac/audio_auhal_mac.cc
@@ -53,6 +53,7 @@ AUHALStream::AUHALStream(AudioManagerMac* manager,
hardware_latency_frames_(0),
stopped_(true),
current_hardware_pending_bytes_(0),
+ current_lost_frames_(0),
last_sample_time_(0.0),
last_number_of_frames_(0),
total_lost_frames_(0),
@@ -248,11 +249,11 @@ 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());
+ source_->OnMoreData(dest, current_hardware_pending_bytes_ +
+ frame_delay * params_.GetBytesPerFrame(),
+ current_lost_frames_);
dest->Scale(volume_);
+ current_lost_frames_ = 0;
}
// AUHAL callback.
@@ -360,6 +361,7 @@ void AUHALStream::UpdatePlayoutTimestamp(const AudioTimeStamp* timestamp) {
// glitch count etc and keep a record of the largest glitch.
auto lost_frames = diff - last_number_of_frames_;
total_lost_frames_ += lost_frames;
+ current_lost_frames_ += lost_frames;
if (lost_frames > largest_glitch_frames_)
largest_glitch_frames_ = lost_frames;
++glitches_detected_;
diff --git a/media/audio/mac/audio_auhal_mac.h b/media/audio/mac/audio_auhal_mac.h
index 0cd648a..351c662 100644
--- a/media/audio/mac/audio_auhal_mac.h
+++ b/media/audio/mac/audio_auhal_mac.h
@@ -126,6 +126,8 @@ class AUHALStream : public AudioOutputStream {
// Gets the current playout latency value.
double GetPlayoutLatency(const AudioTimeStamp* output_time_stamp);
+ // Updates playout timestamp, current lost frames, and total lost frames and
+ // glitches.
void UpdatePlayoutTimestamp(const AudioTimeStamp* timestamp);
// Called from the dtor and when the stream is reset.
@@ -182,6 +184,11 @@ class AUHALStream : public AudioOutputStream {
// Current buffer delay. Set by Render().
uint32 current_hardware_pending_bytes_;
+ // Lost frames not yet reported to the provider. Increased in
+ // UpdatePlayoutTimestamp() if any lost frame since last time. Forwarded to
+ // the provider and reset in ProvideInput().
+ uint32_t current_lost_frames_;
+
// Stores the timestamp of the previous audio buffer requested by the OS.
// We use this in combination with |last_number_of_frames_| to detect when
// the OS has decided to skip rendering frames (i.e. a glitch).
diff --git a/media/audio/mac/audio_auhal_mac_unittest.cc b/media/audio/mac/audio_auhal_mac_unittest.cc
index b9c857d..14499b7 100644
--- a/media/audio/mac/audio_auhal_mac_unittest.cc
+++ b/media/audio/mac/audio_auhal_mac_unittest.cc
@@ -88,7 +88,7 @@ TEST_F(AUHALStreamTest, CreateOpenStartStopClose) {
// Wait for the first data callback from the OS.
base::WaitableEvent event(false, false);
- EXPECT_CALL(source_, OnMoreData(_, _))
+ EXPECT_CALL(source_, OnMoreData(_, _, _))
.WillOnce(DoAll(ZeroBuffer(), SignalEvent(&event), Return(0)));
EXPECT_CALL(source_, OnError(_)).Times(0);
stream->Start(&source_);
diff --git a/media/audio/mock_audio_source_callback.h b/media/audio/mock_audio_source_callback.h
index 9284d0bf..df661fc 100644
--- a/media/audio/mock_audio_source_callback.h
+++ b/media/audio/mock_audio_source_callback.h
@@ -15,8 +15,10 @@ class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
MockAudioSourceCallback();
virtual ~MockAudioSourceCallback();
- MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus,
- uint32 total_bytes_delay));
+ MOCK_METHOD3(OnMoreData,
+ int(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped));
MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
private:
diff --git a/media/audio/null_audio_sink.cc b/media/audio/null_audio_sink.cc
index 5b043a0..e9f65fd4 100644
--- a/media/audio/null_audio_sink.cc
+++ b/media/audio/null_audio_sink.cc
@@ -82,7 +82,7 @@ OutputDevice* NullAudioSink::GetOutputDevice() {
void NullAudioSink::CallRender() {
DCHECK(task_runner_->BelongsToCurrentThread());
- int frames_received = callback_->Render(audio_bus_.get(), 0);
+ int frames_received = callback_->Render(audio_bus_.get(), 0, 0);
if (!audio_hash_ || frames_received <= 0)
return;
diff --git a/media/audio/pulse/pulse_output.cc b/media/audio/pulse/pulse_output.cc
index 0ba728d..1077e25 100644
--- a/media/audio/pulse/pulse_output.cc
+++ b/media/audio/pulse/pulse_output.cc
@@ -132,8 +132,8 @@ void PulseAudioOutputStream::FulfillWriteRequest(size_t requested_bytes) {
if (source_callback_) {
const uint32 hardware_delay = pulse::GetHardwareLatencyInBytes(
pa_stream_, params_.sample_rate(), params_.GetBytesPerFrame());
- frames_filled = source_callback_->OnMoreData(
- audio_bus_.get(), hardware_delay);
+ frames_filled =
+ source_callback_->OnMoreData(audio_bus_.get(), hardware_delay, 0);
// 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 4ded6bd..b75b96d 100644
--- a/media/audio/simple_sources.cc
+++ b/media/audio/simple_sources.cc
@@ -110,7 +110,8 @@ SineWaveAudioSource::~SineWaveAudioSource() {
// 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,
- uint32 total_bytes_delay) {
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
base::AutoLock auto_lock(time_lock_);
callbacks_++;
@@ -193,7 +194,9 @@ void FileSource::LoadWavFile(const base::FilePath& path_to_wav_file) {
file_audio_converter_->AddInput(this);
}
-int FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) {
+int FileSource::OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
// Load the file if we haven't already. This load needs to happen on the
// audio thread, otherwise we'll run on the UI thread on Mac for instance.
// This will massively delay the first OnMoreData, but we'll catch up.
@@ -242,7 +245,9 @@ BeepingSource::BeepingSource(const AudioParameters& params)
BeepingSource::~BeepingSource() {
}
-int BeepingSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) {
+int BeepingSource::OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
// Accumulate the time from the last beep.
interval_from_last_beep_ += base::TimeTicks::Now() - last_callback_time_;
diff --git a/media/audio/simple_sources.h b/media/audio/simple_sources.h
index 7a10a34..075b4a7 100644
--- a/media/audio/simple_sources.h
+++ b/media/audio/simple_sources.h
@@ -31,7 +31,9 @@ class MEDIA_EXPORT SineWaveAudioSource
void Reset();
// Implementation of AudioSourceCallback.
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override;
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override;
void OnError(AudioOutputStream* stream) override;
// The number of OnMoreData() and OnError() calls respectively.
@@ -56,7 +58,9 @@ class MEDIA_EXPORT FileSource : public AudioOutputStream::AudioSourceCallback,
~FileSource() override;
// Implementation of AudioSourceCallback.
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override;
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override;
void OnError(AudioOutputStream* stream) override;
private:
@@ -87,7 +91,9 @@ class BeepingSource : public AudioOutputStream::AudioSourceCallback {
~BeepingSource() override;
// Implementation of AudioSourceCallback.
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override;
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override;
void OnError(AudioOutputStream* stream) override;
static void BeepOnce();
diff --git a/media/audio/simple_sources_unittest.cc b/media/audio/simple_sources_unittest.cc
index 8702af5..86963bc 100644
--- a/media/audio/simple_sources_unittest.cc
+++ b/media/audio/simple_sources_unittest.cc
@@ -28,7 +28,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(), 0, 0);
EXPECT_EQ(1, source.callbacks());
EXPECT_EQ(0, source.errors());
@@ -57,14 +57,12 @@ TEST(SimpleSources, SineWaveAudioCapped) {
source.CapSamples(kSampleCap);
scoped_ptr<AudioBus> audio_bus = AudioBus::Create(1, 2 * kSampleCap);
- EXPECT_EQ(source.OnMoreData(
- audio_bus.get(), 0), kSampleCap);
+ EXPECT_EQ(source.OnMoreData(audio_bus.get(), 0, 0), kSampleCap);
EXPECT_EQ(1, source.callbacks());
- EXPECT_EQ(source.OnMoreData(audio_bus.get(), 0), 0);
+ EXPECT_EQ(source.OnMoreData(audio_bus.get(), 0, 0), 0);
EXPECT_EQ(2, source.callbacks());
source.Reset();
- EXPECT_EQ(source.OnMoreData(
- audio_bus.get(), 0), kSampleCap);
+ EXPECT_EQ(source.OnMoreData(audio_bus.get(), 0, 0), kSampleCap);
EXPECT_EQ(3, source.callbacks());
EXPECT_EQ(0, source.errors());
}
@@ -97,7 +95,7 @@ TEST(SimpleSources, FileSourceTestData) {
// Create a FileSource that reads this file.
FileSource source(params, temp_path);
- EXPECT_EQ(kNumFrames, source.OnMoreData(audio_bus.get(), 0));
+ EXPECT_EQ(kNumFrames, source.OnMoreData(audio_bus.get(), 0, 0));
// Convert the test data (little-endian) into floats and compare.
const int kFirstSampleIndex = 12 + 8 + 16 + 8;
@@ -133,7 +131,7 @@ TEST(SimpleSources, BadFilePathFails) {
.Append(FILE_PATH_LITERAL("not"))
.Append(FILE_PATH_LITERAL("exist"));
FileSource source(params, path);
- EXPECT_EQ(0, source.OnMoreData(audio_bus.get(), 0));
+ EXPECT_EQ(0, source.OnMoreData(audio_bus.get(), 0, 0));
// Confirm all frames are zero-padded.
for (int channel = 0; channel < audio_bus->channels(); ++channel) {
@@ -167,7 +165,7 @@ TEST(SimpleSources, FileSourceCorruptTestDataFails) {
// Create a FileSource that reads this file.
FileSource source(params, temp_path);
- EXPECT_EQ(0, source.OnMoreData(audio_bus.get(), 0));
+ EXPECT_EQ(0, source.OnMoreData(audio_bus.get(), 0, 0));
// Confirm all frames are zero-padded.
for (int channel = 0; channel < audio_bus->channels(); ++channel) {
diff --git a/media/audio/sounds/audio_stream_handler.cc b/media/audio/sounds/audio_stream_handler.cc
index ee27312..85ee6533 100644
--- a/media/audio/sounds/audio_stream_handler.cc
+++ b/media/audio/sounds/audio_stream_handler.cc
@@ -106,7 +106,9 @@ class AudioStreamHandler::AudioStreamContainer
private:
// AudioOutputStream::AudioSourceCallback overrides:
// Following methods could be called from *ANY* thread.
- int OnMoreData(AudioBus* dest, uint32 /* total_bytes_delay */) override {
+ int OnMoreData(AudioBus* dest,
+ uint32_t /* total_bytes_delay */,
+ uint32_t /* frames_skipped */) 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 06b3011..48a8e61 100644
--- a/media/audio/virtual_audio_input_stream_unittest.cc
+++ b/media/audio/virtual_audio_input_stream_unittest.cc
@@ -66,9 +66,11 @@ class TestAudioSource : public SineWaveAudioSource {
~TestAudioSource() override {}
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
- const int ret = SineWaveAudioSource::OnMoreData(audio_bus,
- total_bytes_delay);
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
+ const int ret = SineWaveAudioSource::OnMoreData(
+ audio_bus, total_bytes_delay, frames_skipped);
data_pulled_.Signal();
return ret;
}
diff --git a/media/audio/virtual_audio_output_stream.cc b/media/audio/virtual_audio_output_stream.cc
index 29e3804..149f3cc 100644
--- a/media/audio/virtual_audio_output_stream.cc
+++ b/media/audio/virtual_audio_output_stream.cc
@@ -82,7 +82,7 @@ double VirtualAudioOutputStream::ProvideInput(AudioBus* audio_bus,
params_.GetBytesPerSecond() * buffer_delay /
base::TimeDelta::FromSeconds(1);
const int frames = callback_->OnMoreData(
- audio_bus, static_cast<uint32>(upstream_delay_in_bytes));
+ audio_bus, static_cast<uint32>(upstream_delay_in_bytes), 0);
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 829d18f..9ead48a 100644
--- a/media/audio/win/audio_low_latency_output_win.cc
+++ b/media/audio/win/audio_low_latency_output_win.cc
@@ -532,8 +532,8 @@ 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.
- int frames_filled = source_->OnMoreData(
- audio_bus_.get(), audio_delay_bytes);
+ int frames_filled =
+ source_->OnMoreData(audio_bus_.get(), audio_delay_bytes, 0);
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 5c2d457..8f30411 100644
--- a/media/audio/win/audio_low_latency_output_win_unittest.cc
+++ b/media/audio/win/audio_low_latency_output_win_unittest.cc
@@ -103,7 +103,9 @@ class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback {
}
// AudioOutputStream::AudioSourceCallback implementation.
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
// 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();
@@ -382,7 +384,7 @@ TEST(WASAPIAudioOutputStreamTest, ValidPacketSize) {
// Wait for the first callback and verify its parameters. Ignore any
// subsequent callbacks that might arrive.
- EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet)))
+ EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0))
.WillOnce(DoAll(QuitLoop(loop.task_runner()),
Return(aosw.samples_per_packet())))
.WillRepeatedly(Return(0));
@@ -576,7 +578,7 @@ TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeMinBufferSizeAt48kHz) {
(aosw.bits_per_sample() / 8);
// Wait for the first callback and verify its parameters.
- EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet)))
+ EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0))
.WillOnce(DoAll(QuitLoop(loop.task_runner()),
Return(aosw.samples_per_packet())))
.WillRepeatedly(Return(aosw.samples_per_packet()));
@@ -610,7 +612,7 @@ TEST(WASAPIAudioOutputStreamTest, DISABLED_ExclusiveModeMinBufferSizeAt44kHz) {
(aosw.bits_per_sample() / 8);
// Wait for the first callback and verify its parameters.
- EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet)))
+ EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0))
.WillOnce(DoAll(QuitLoop(loop.task_runner()),
Return(aosw.samples_per_packet())))
.WillRepeatedly(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 68f61ea..1028488 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -32,7 +32,9 @@ using ::testing::Return;
namespace media {
-static int ClearData(AudioBus* audio_bus, uint32 total_bytes_delay) {
+static int ClearData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) {
audio_bus->Zero();
return audio_bus->frames();
}
@@ -46,7 +48,9 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback {
had_error_(0) {
}
// AudioSourceCallback::OnMoreData implementation:
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
++callback_count_;
// Touch the channel memory value to make sure memory is good.
audio_bus->Zero();
@@ -80,9 +84,11 @@ class TestSourceLaggy : public TestSourceBasic {
explicit TestSourceLaggy(int lag_in_ms)
: lag_in_ms_(lag_in_ms) {
}
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
// Call the base, which increments the callback_count_.
- TestSourceBasic::OnMoreData(audio_bus, total_bytes_delay);
+ TestSourceBasic::OnMoreData(audio_bus, total_bytes_delay, frames_skipped);
if (callback_count() > kMaxNumBuffers) {
::Sleep(lag_in_ms_);
}
@@ -474,22 +480,21 @@ TEST(WinAudioTest, PCMWaveStreamPendingBytes) {
// pending bytes will go down and eventually read zero.
InSequence s;
- EXPECT_CALL(source, OnMoreData(NotNull(), 0))
- .WillOnce(Invoke(ClearData));
+ EXPECT_CALL(source, OnMoreData(NotNull(), 0, 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(), bytes_100_ms, 0))
.WillOnce(Invoke(ClearData));
- EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms))
+ EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms, 0))
.WillOnce(Invoke(ClearData));
- EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms))
+ EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms, 0))
.Times(AnyNumber())
.WillRepeatedly(Return(0));
- EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms))
+ EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 0))
.Times(AnyNumber())
.WillRepeatedly(Return(0));
- EXPECT_CALL(source, OnMoreData(NotNull(), 0))
+ EXPECT_CALL(source, OnMoreData(NotNull(), 0, 0))
.Times(AnyNumber())
.WillRepeatedly(Return(0));
@@ -514,7 +519,9 @@ class SyncSocketSource : public AudioOutputStream::AudioSourceCallback {
~SyncSocketSource() override {}
// AudioSourceCallback::OnMoreData implementation:
- int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override {
+ int OnMoreData(AudioBus* audio_bus,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) override {
socket_->Send(&total_bytes_delay, sizeof(total_bytes_delay));
uint32 size = socket_->Receive(data_.get(), data_size_);
DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U);
@@ -565,7 +572,7 @@ DWORD __stdcall SyncSocketThread(void* context) {
if (ctx.socket->Receive(&total_bytes_delay, sizeof(total_bytes_delay)) == 0)
break;
if ((times > 0) && (total_bytes_delay < 1000)) __debugbreak();
- sine.OnMoreData(audio_bus.get(), total_bytes_delay);
+ sine.OnMoreData(audio_bus.get(), total_bytes_delay, 0);
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 5be9e0a..456124d 100644
--- a/media/audio/win/waveout_output_win.cc
+++ b/media/audio/win/waveout_output_win.cc
@@ -327,8 +327,8 @@ void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) {
// TODO(sergeyu): Specify correct hardware delay for |total_delay_bytes|.
uint32 total_delay_bytes = pending_bytes_;
- int frames_filled = callback_->OnMoreData(
- audio_bus_.get(), total_delay_bytes);
+ int frames_filled =
+ callback_->OnMoreData(audio_bus_.get(), total_delay_bytes, 0);
uint32 used = frames_filled * audio_bus_->channels() *
format_.Format.wBitsPerSample / 8;
diff --git a/media/base/audio_bus_perftest.cc b/media/base/audio_bus_perftest.cc
index 71e8132..c126d99 100644
--- a/media/base/audio_bus_perftest.cc
+++ b/media/base/audio_bus_perftest.cc
@@ -43,7 +43,7 @@ void RunInterleaveBench(AudioBus* bus, const std::string& trace_name) {
TEST(AudioBusPerfTest, Interleave) {
scoped_ptr<AudioBus> bus = AudioBus::Create(2, 48000 * 120);
FakeAudioRenderCallback callback(0.2);
- callback.Render(bus.get(), 0);
+ callback.Render(bus.get(), 0, 0);
RunInterleaveBench<int8>(bus.get(), "int8");
RunInterleaveBench<int16>(bus.get(), "int16");
diff --git a/media/base/audio_converter_unittest.cc b/media/base/audio_converter_unittest.cc
index 741027f..d427923 100644
--- a/media/base/audio_converter_unittest.cc
+++ b/media/base/audio_converter_unittest.cc
@@ -111,7 +111,7 @@ class AudioConverterTest
converter_->Convert(audio_bus_.get());
// Render expected audio data.
- expected_callback_->Render(expected_audio_bus_.get(), 0);
+ expected_callback_->Render(expected_audio_bus_.get(), 0, 0);
// Zero out unused channels in the expected AudioBus just as AudioConverter
// would during channel mixing.
diff --git a/media/base/audio_hash_unittest.cc b/media/base/audio_hash_unittest.cc
index 1adf5bc..742deed 100644
--- a/media/base/audio_hash_unittest.cc
+++ b/media/base/audio_hash_unittest.cc
@@ -34,7 +34,7 @@ class AudioHashTest : public testing::Test {
// audio data, we need to fill each channel manually.
for (int ch = 0; ch < audio_bus->channels(); ++ch) {
wrapped_bus->SetChannelData(0, audio_bus->channel(ch));
- fake_callback_.Render(wrapped_bus.get(), 0);
+ fake_callback_.Render(wrapped_bus.get(), 0, 0);
}
}
diff --git a/media/base/audio_renderer_mixer.cc b/media/base/audio_renderer_mixer.cc
index 26171f9..218bb9e 100644
--- a/media/base/audio_renderer_mixer.cc
+++ b/media/base/audio_renderer_mixer.cc
@@ -117,7 +117,8 @@ OutputDevice* AudioRendererMixer::GetOutputDevice() {
}
int AudioRendererMixer::Render(AudioBus* audio_bus,
- int audio_delay_milliseconds) {
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped) {
base::AutoLock auto_lock(lock_);
// If there are no mixer inputs and we haven't seen one for a while, pause the
diff --git a/media/base/audio_renderer_mixer.h b/media/base/audio_renderer_mixer.h
index e8a0f8d..80e9d9b 100644
--- a/media/base/audio_renderer_mixer.h
+++ b/media/base/audio_renderer_mixer.h
@@ -54,7 +54,9 @@ class MEDIA_EXPORT AudioRendererMixer
typedef std::map<int, scoped_ptr<LoopbackAudioConverter>> AudioConvertersMap;
// AudioRendererSink::RenderCallback implementation.
- int Render(AudioBus* audio_bus, int audio_delay_milliseconds) override;
+ int Render(AudioBus* audio_bus,
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped) override;
void OnRenderError() override;
bool is_master_sample_rate(int sample_rate) {
diff --git a/media/base/audio_renderer_mixer_input.cc b/media/base/audio_renderer_mixer_input.cc
index 539cdf3..d0d38d3 100644
--- a/media/base/audio_renderer_mixer_input.cc
+++ b/media/base/audio_renderer_mixer_input.cc
@@ -166,7 +166,7 @@ OutputDeviceStatus AudioRendererMixerInput::GetDeviceStatus() {
double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus,
base::TimeDelta buffer_delay) {
int frames_filled = callback_->Render(
- audio_bus, static_cast<int>(buffer_delay.InMillisecondsF() + 0.5));
+ audio_bus, static_cast<int>(buffer_delay.InMillisecondsF() + 0.5), 0);
// AudioConverter expects unfilled frames to be zeroed.
if (frames_filled < audio_bus->frames()) {
diff --git a/media/base/audio_renderer_mixer_unittest.cc b/media/base/audio_renderer_mixer_unittest.cc
index bae2ebb..8f45c2b 100644
--- a/media/base/audio_renderer_mixer_unittest.cc
+++ b/media/base/audio_renderer_mixer_unittest.cc
@@ -156,12 +156,12 @@ class AudioRendererMixerTest
}
// Render actual audio data.
- int frames = mixer_callback_->Render(audio_bus_.get(), 0);
+ int frames = mixer_callback_->Render(audio_bus_.get(), 0, 0);
if (frames != audio_bus_->frames())
return false;
// Render expected audio data (without scaling).
- expected_callback_->Render(expected_audio_bus_.get(), 0);
+ expected_callback_->Render(expected_audio_bus_.get(), 0, 0);
if (half_fill_) {
// In this case, just verify that every frame was initialized, this will
@@ -486,7 +486,7 @@ TEST_P(AudioRendererMixerBehavioralTest, MixerPausesStream) {
const base::TimeDelta kSleepTime = base::TimeDelta::FromMilliseconds(100);
base::TimeTicks start_time = base::TimeTicks::Now();
while (!pause_event.IsSignaled()) {
- mixer_callback_->Render(audio_bus_.get(), 0);
+ mixer_callback_->Render(audio_bus_.get(), 0, 0);
base::PlatformThread::Sleep(kSleepTime);
ASSERT_TRUE(base::TimeTicks::Now() - start_time < kTestTimeout);
}
@@ -501,7 +501,7 @@ TEST_P(AudioRendererMixerBehavioralTest, MixerPausesStream) {
// Ensure once the input is paused the sink eventually pauses.
start_time = base::TimeTicks::Now();
while (!pause_event.IsSignaled()) {
- mixer_callback_->Render(audio_bus_.get(), 0);
+ mixer_callback_->Render(audio_bus_.get(), 0, 0);
base::PlatformThread::Sleep(kSleepTime);
ASSERT_TRUE(base::TimeTicks::Now() - start_time < kTestTimeout);
}
diff --git a/media/base/audio_renderer_sink.h b/media/base/audio_renderer_sink.h
index 30cbfef..b45c0fc 100644
--- a/media/base/audio_renderer_sink.h
+++ b/media/base/audio_renderer_sink.h
@@ -35,8 +35,11 @@ class AudioRendererSink
class RenderCallback {
public:
// Attempts to completely fill all channels of |dest|, returns actual
- // number of frames filled.
- virtual int Render(AudioBus* dest, int audio_delay_milliseconds) = 0;
+ // number of frames filled. |frames_skipped| contains the number of frames
+ // the consumer has skipped, if any.
+ virtual int Render(AudioBus* dest,
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped) = 0;
// Signals an error has occurred.
virtual void OnRenderError() = 0;
diff --git a/media/base/fake_audio_render_callback.cc b/media/base/fake_audio_render_callback.cc
index 73d606e..8d7ef20 100644
--- a/media/base/fake_audio_render_callback.cc
+++ b/media/base/fake_audio_render_callback.cc
@@ -23,7 +23,8 @@ FakeAudioRenderCallback::FakeAudioRenderCallback(double step)
FakeAudioRenderCallback::~FakeAudioRenderCallback() {}
int FakeAudioRenderCallback::Render(AudioBus* audio_bus,
- int audio_delay_milliseconds) {
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped) {
last_audio_delay_milliseconds_ = audio_delay_milliseconds;
last_channel_count_ = audio_bus->channels();
@@ -46,7 +47,7 @@ int FakeAudioRenderCallback::Render(AudioBus* audio_bus,
double FakeAudioRenderCallback::ProvideInput(AudioBus* audio_bus,
base::TimeDelta buffer_delay) {
- Render(audio_bus, buffer_delay.InMillisecondsF() + 0.5);
+ Render(audio_bus, buffer_delay.InMillisecondsF() + 0.5, 0);
return volume_;
}
diff --git a/media/base/fake_audio_render_callback.h b/media/base/fake_audio_render_callback.h
index 65d7df2..49d64ba 100644
--- a/media/base/fake_audio_render_callback.h
+++ b/media/base/fake_audio_render_callback.h
@@ -26,7 +26,9 @@ class FakeAudioRenderCallback
// Renders a sine wave into the provided audio data buffer. If |half_fill_|
// is set, will only fill half the buffer.
- int Render(AudioBus* audio_bus, int audio_delay_milliseconds) override;
+ int Render(AudioBus* audio_bus,
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped) override;
MOCK_METHOD0(OnRenderError, void());
// AudioTransform::ProvideAudioTransformInput implementation.
diff --git a/media/base/fake_audio_renderer_sink.cc b/media/base/fake_audio_renderer_sink.cc
index d8a7262..5ce6074 100644
--- a/media/base/fake_audio_renderer_sink.cc
+++ b/media/base/fake_audio_renderer_sink.cc
@@ -60,12 +60,13 @@ OutputDevice* FakeAudioRendererSink::GetOutputDevice() {
return output_device_.get();
}
-bool FakeAudioRendererSink::Render(AudioBus* dest, int audio_delay_milliseconds,
+bool FakeAudioRendererSink::Render(AudioBus* dest,
+ uint32_t audio_delay_milliseconds,
int* frames_written) {
if (state_ != kPlaying)
return false;
- *frames_written = callback_->Render(dest, audio_delay_milliseconds);
+ *frames_written = callback_->Render(dest, audio_delay_milliseconds, 0);
return true;
}
diff --git a/media/base/fake_audio_renderer_sink.h b/media/base/fake_audio_renderer_sink.h
index 0a9bd93..765257d 100644
--- a/media/base/fake_audio_renderer_sink.h
+++ b/media/base/fake_audio_renderer_sink.h
@@ -43,7 +43,8 @@ class FakeAudioRendererSink : public AudioRendererSink {
// Returns false if this object is in a state where calling Render()
// should not occur. (i.e., in the kPaused or kStopped state.) The
// value of |frames_written| is undefined if false is returned.
- bool Render(AudioBus* dest, int audio_delay_milliseconds,
+ bool Render(AudioBus* dest,
+ uint32_t audio_delay_milliseconds,
int* frames_written);
void OnRenderError();
diff --git a/media/blink/webaudiosourceprovider_impl.cc b/media/blink/webaudiosourceprovider_impl.cc
index ddc79fe..0276a7b 100644
--- a/media/blink/webaudiosourceprovider_impl.cc
+++ b/media/blink/webaudiosourceprovider_impl.cc
@@ -114,7 +114,7 @@ void WebAudioSourceProviderImpl::provideInput(
DCHECK(renderer_);
DCHECK(client_);
DCHECK_EQ(channels_, bus_wrapper_->channels());
- const int frames = renderer_->Render(bus_wrapper_.get(), 0);
+ const int frames = renderer_->Render(bus_wrapper_.get(), 0, 0);
if (frames < static_cast<int>(number_of_frames)) {
bus_wrapper_->ZeroFramesPartial(
frames,
diff --git a/media/blink/webaudiosourceprovider_impl_unittest.cc b/media/blink/webaudiosourceprovider_impl_unittest.cc
index c0d6070..fddabbc 100644
--- a/media/blink/webaudiosourceprovider_impl_unittest.cc
+++ b/media/blink/webaudiosourceprovider_impl_unittest.cc
@@ -197,7 +197,7 @@ TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
// Ensure volume adjustment is working.
fake_callback_.reset();
- fake_callback_.Render(bus2.get(), 0);
+ fake_callback_.Render(bus2.get(), 0, 0);
bus2->Scale(kTestVolume);
fake_callback_.reset();
@@ -216,9 +216,9 @@ TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
// configuring the fake callback to return half the data. After these calls
// bus1 is full of junk data, and bus2 is partially filled.
wasp_impl_->SetVolume(1);
- fake_callback_.Render(bus1.get(), 0);
+ fake_callback_.Render(bus1.get(), 0, 0);
fake_callback_.reset();
- fake_callback_.Render(bus2.get(), 0);
+ fake_callback_.Render(bus2.get(), 0, 0);
bus2->ZeroFramesPartial(bus2->frames() / 2,
bus2->frames() - bus2->frames() / 2);
fake_callback_.reset();
diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc
index 6c07e37..ed069b6 100644
--- a/media/cast/test/receiver.cc
+++ b/media/cast/test/receiver.cc
@@ -316,7 +316,9 @@ class NaivePlayer : public InProcessReceiver,
////////////////////////////////////////////////////////////////////
// AudioSourceCallback implementation.
- int OnMoreData(AudioBus* dest, uint32 total_bytes_delay) final {
+ int OnMoreData(AudioBus* dest,
+ uint32_t total_bytes_delay,
+ uint32_t frames_skipped) final {
// Note: This method is being invoked by a separate thread unknown to us
// (i.e., outside of CastEnvironment).
diff --git a/media/cast/test/utility/audio_utility.cc b/media/cast/test/utility/audio_utility.cc
index 094f141..41ecd15 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(), 0, 0);
bus->Scale(volume_);
return bus.Pass();
}
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc
index db1948e..424b2d3 100644
--- a/media/renderers/audio_renderer_impl.cc
+++ b/media/renderers/audio_renderer_impl.cc
@@ -626,7 +626,8 @@ bool AudioRendererImpl::IsBeforeStartTime(
}
int AudioRendererImpl::Render(AudioBus* audio_bus,
- int audio_delay_milliseconds) {
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped) {
const int requested_frames = audio_bus->frames();
base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds(
audio_delay_milliseconds);
diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h
index de0cbda..7674851 100644
--- a/media/renderers/audio_renderer_impl.h
+++ b/media/renderers/audio_renderer_impl.h
@@ -151,7 +151,9 @@ class MEDIA_EXPORT AudioRendererImpl
// timestamp in the pipeline will be ahead of the actual audio playback. In
// this case |audio_delay_milliseconds| should be used to indicate when in the
// future should the filled buffer be played.
- int Render(AudioBus* audio_bus, int audio_delay_milliseconds) override;
+ int Render(AudioBus* audio_bus,
+ uint32_t audio_delay_milliseconds,
+ uint32_t frames_skipped) override;
void OnRenderError() override;
// Helper methods that schedule an asynchronous read from the decoder as long