summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/audio/audio_output.h6
-rw-r--r--media/audio/fake_audio_output_stream.cc2
-rw-r--r--media/audio/linux/alsa_output.cc8
-rw-r--r--media/audio/linux/alsa_output.h3
-rw-r--r--media/audio/linux/alsa_output_unittest.cc8
-rw-r--r--media/audio/mac/audio_output_mac.cc4
-rw-r--r--media/audio/mac/audio_output_mac_unittest.cc2
-rw-r--r--media/audio/simple_sources.cc8
-rw-r--r--media/audio/simple_sources.h8
-rw-r--r--media/audio/simple_sources_unittest.cc2
-rw-r--r--media/audio/win/audio_output_win_unittest.cc76
-rw-r--r--media/audio/win/waveout_output_win.cc18
-rw-r--r--media/audio/win/waveout_output_win.h3
-rw-r--r--media/filters/audio_renderer_impl.cc11
-rw-r--r--media/filters/audio_renderer_impl.h4
15 files changed, 126 insertions, 37 deletions
diff --git a/media/audio/audio_output.h b/media/audio/audio_output.h
index f27858b..e6a1ee5 100644
--- a/media/audio/audio_output.h
+++ b/media/audio/audio_output.h
@@ -53,8 +53,10 @@ class AudioOutputStream {
// buffer size is usually what is specified in Open(). The source
// will return the number of bytes it filled. The expected structure of
// |dest| is platform and format specific.
- virtual size_t OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size) = 0;
+ // |pending_bytes| is the number of bytes will be played before the
+ // requested data is played.
+ virtual size_t OnMoreData(AudioOutputStream* stream, void* dest,
+ size_t max_size, int pending_bytes) = 0;
// The stream is done with this callback. After this call the audio source
// can go away or be destroyed.
diff --git a/media/audio/fake_audio_output_stream.cc b/media/audio/fake_audio_output_stream.cc
index 6eb5417..af69a2f 100644
--- a/media/audio/fake_audio_output_stream.cc
+++ b/media/audio/fake_audio_output_stream.cc
@@ -33,7 +33,7 @@ bool FakeAudioOutputStream::Open(size_t packet_size) {
void FakeAudioOutputStream::Start(AudioSourceCallback* callback) {
callback_ = callback;
memset(buffer_.get(), 0, packet_size_);
- callback_->OnMoreData(this, buffer_.get(), packet_size_);
+ callback_->OnMoreData(this, buffer_.get(), packet_size_, 0);
}
void FakeAudioOutputStream::Stop() {
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
index 522b8c4..8a59e33 100644
--- a/media/audio/linux/alsa_output.cc
+++ b/media/audio/linux/alsa_output.cc
@@ -390,8 +390,9 @@ void AlsaPcmOutputStream::BufferPacket(Packet* packet) {
// Request more data if we don't have any cached.
if (packet->used >= packet->size) {
packet->used = 0;
+ // TODO(hclam): Provide pending bytes.
packet->size = shared_data_.OnMoreData(this, packet->buffer.get(),
- packet->capacity);
+ packet->capacity, 0);
CHECK(packet->size <= packet->capacity) << "Data source overran buffer.";
// This should not happen, but incase it does, drop any trailing bytes
@@ -629,10 +630,11 @@ void AlsaPcmOutputStream::SharedData::set_volume(float v) {
size_t AlsaPcmOutputStream::SharedData::OnMoreData(AudioOutputStream* stream,
void* dest,
- size_t max_size) {
+ size_t max_size,
+ int pending_bytes) {
AutoLock l(lock_);
if (source_callback_) {
- return source_callback_->OnMoreData(stream, dest, max_size);
+ return source_callback_->OnMoreData(stream, dest, max_size, pending_bytes);
}
return 0;
diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h
index 7d5f381..409b158 100644
--- a/media/audio/linux/alsa_output.h
+++ b/media/audio/linux/alsa_output.h
@@ -168,7 +168,8 @@ class AlsaPcmOutputStream :
// 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.
- size_t OnMoreData(AudioOutputStream* stream, void* dest, size_t max_size);
+ size_t OnMoreData(AudioOutputStream* stream, void* dest,
+ size_t max_size, int pending_bytes);
void OnClose(AudioOutputStream* stream);
void OnError(AudioOutputStream* stream, int code);
diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc
index 8e262b1..d736d93 100644
--- a/media/audio/linux/alsa_output_unittest.cc
+++ b/media/audio/linux/alsa_output_unittest.cc
@@ -40,8 +40,8 @@ class MockAlsaWrapper : public AlsaWrapper {
class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
public:
- MOCK_METHOD3(OnMoreData, size_t(AudioOutputStream* stream,
- void* dest, size_t max_size));
+ MOCK_METHOD4(OnMoreData, size_t(AudioOutputStream* stream, void* dest,
+ size_t max_size, int pending_bytes));
MOCK_METHOD1(OnClose, void(AudioOutputStream* stream));
MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
};
@@ -273,7 +273,7 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
// Expect the pre-roll.
MockAudioSourceCallback mock_callback;
EXPECT_CALL(mock_callback,
- OnMoreData(test_stream_.get(), _, kTestPacketSize))
+ OnMoreData(test_stream_.get(), _, kTestPacketSize, 0))
.Times(2)
.WillRepeatedly(Return(kTestPacketSize));
EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _))
@@ -363,7 +363,7 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket) {
MockAudioSourceCallback mock_callback;
EXPECT_CALL(mock_callback,
OnMoreData(test_stream_.get(), packet_.buffer.get(),
- packet_.capacity))
+ packet_.capacity, 0))
.WillOnce(Return(10));
test_stream_->shared_data_.set_source_callback(&mock_callback);
diff --git a/media/audio/mac/audio_output_mac.cc b/media/audio/mac/audio_output_mac.cc
index 657e91a..2f79233 100644
--- a/media/audio/mac/audio_output_mac.cc
+++ b/media/audio/mac/audio_output_mac.cc
@@ -160,7 +160,9 @@ void PCMQueueOutAudioOutputStream::RenderCallback(void* p_this,
if (!source)
return;
size_t capacity = buffer->mAudioDataBytesCapacity;
- size_t filled = source->OnMoreData(audio_stream, buffer->mAudioData, capacity);
+ // TODO(hclam): Provide pending bytes.
+ size_t filled = source->OnMoreData(audio_stream, buffer->mAudioData,
+ capacity, 0);
if (filled > capacity) {
// User probably overran our buffer.
audio_stream->HandleError(0);
diff --git a/media/audio/mac/audio_output_mac_unittest.cc b/media/audio/mac/audio_output_mac_unittest.cc
index d6abefd..d6908cb 100644
--- a/media/audio/mac/audio_output_mac_unittest.cc
+++ b/media/audio/mac/audio_output_mac_unittest.cc
@@ -19,7 +19,7 @@ TEST(MacAudioTest, SineWaveAudio16MonoTest) {
// TODO(cpu): Put the real test when the mock renderer is ported.
int16 buffer[samples] = { 0xffff };
- source.OnMoreData(NULL, buffer, sizeof(buffer));
+ source.OnMoreData(NULL, buffer, sizeof(buffer), 0);
EXPECT_EQ(0, buffer[0]);
EXPECT_EQ(5126, buffer[1]);
}
diff --git a/media/audio/simple_sources.cc b/media/audio/simple_sources.cc
index eaf671d..d9b30c7 100644
--- a/media/audio/simple_sources.cc
+++ b/media/audio/simple_sources.cc
@@ -25,8 +25,8 @@ SineWaveAudioSource::SineWaveAudioSource(Format format, int channels,
// The implementation could be more efficient if a lookup table is constructed
// but it is efficient enough for our simple needs.
-size_t SineWaveAudioSource::OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size) {
+size_t SineWaveAudioSource::OnMoreData(AudioOutputStream* stream, void* dest,
+ size_t max_size, int pending_bytes) {
const double kTwoPi = 2.0 * 3.141592653589;
double f = freq_ / sample_freq_;
int16* sin_tbl = reinterpret_cast<int16*>(dest);
@@ -59,8 +59,8 @@ PushSource::~PushSource() {
CleanUp();
}
-size_t PushSource::OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size) {
+size_t PushSource::OnMoreData(AudioOutputStream* stream, void* dest,
+ size_t max_size, int pending_bytes) {
size_t copied = 0;
while (copied < max_size) {
AutoLock auto_lock(lock_);
diff --git a/media/audio/simple_sources.h b/media/audio/simple_sources.h
index 4a3db8d..d43fcdf 100644
--- a/media/audio/simple_sources.h
+++ b/media/audio/simple_sources.h
@@ -26,7 +26,7 @@ class SineWaveAudioSource : public AudioOutputStream::AudioSourceCallback {
// Implementation of AudioSourceCallback.
virtual size_t OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size);
+ void* dest, size_t max_size, int pending_bytes);
virtual void OnClose(AudioOutputStream* stream);
virtual void OnError(AudioOutputStream* stream, int code);
@@ -73,12 +73,12 @@ class PushSource : public AudioOutputStream::AudioSourceCallback,
// Implementation of AudioSourceCallback.
virtual size_t OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size);
+ void* dest, size_t max_size, int pending_bytes);
virtual void OnClose(AudioOutputStream* stream);
virtual void OnError(AudioOutputStream* stream, int code);
private:
- // Defines the unit of playback. We own the memory pointed by |buffer|.
+ // Defines the unit of playback. We own the memory pointed by |buffer|.
struct Packet {
char* buffer;
size_t size;
@@ -88,7 +88,7 @@ class PushSource : public AudioOutputStream::AudioSourceCallback,
void CleanUp();
const size_t packet_size_;
- typedef std::list<Packet> PacketList;
+ typedef std::list<Packet> PacketList;
PacketList packets_;
size_t buffered_bytes_;
size_t front_buffer_consumed_;
diff --git a/media/audio/simple_sources_unittest.cc b/media/audio/simple_sources_unittest.cc
index ef6a5a7..51eb8db 100644
--- a/media/audio/simple_sources_unittest.cc
+++ b/media/audio/simple_sources_unittest.cc
@@ -54,7 +54,7 @@ TEST(SimpleSourcesTest, PushSourceSmallerWrite) {
// Read everything from the push source.
for (size_t i = 0; i < kDataSize; i += kReadSize) {
size_t size = std::min(kDataSize - i , kReadSize);
- EXPECT_EQ(size, push_source.OnMoreData(NULL, read_data.get(), size));
+ EXPECT_EQ(size, push_source.OnMoreData(NULL, read_data.get(), size, 0));
EXPECT_EQ(0, memcmp(data.get() + i, read_data.get(), size));
}
EXPECT_EQ(0u, push_source.UnProcessedBytes());
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc
index 2393957..38a32f8 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -9,8 +9,17 @@
#include "base/file_util.h"
#include "media/audio/audio_output.h"
#include "media/audio/simple_sources.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::DoAll;
+using ::testing::InSequence;
+using ::testing::NiceMock;
+using ::testing::NotNull;
+using ::testing::Return;
+
namespace {
const wchar_t kAudioFile1_16b_m_16K[]
@@ -27,7 +36,7 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback {
}
// AudioSourceCallback::OnMoreData implementation:
virtual size_t OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size) {
+ void* dest, size_t max_size, int pending_bytes) {
++callback_count_;
// Touch the first byte to make sure memory is good.
if (max_size)
@@ -83,9 +92,9 @@ class TestSourceTripleBuffer : public TestSourceBasic {
}
// Override of TestSourceBasic::OnMoreData.
virtual size_t OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size) {
+ void* dest, size_t max_size, int pending_bytes) {
// Call the base, which increments the callback_count_.
- TestSourceBasic::OnMoreData(stream, dest, max_size);
+ TestSourceBasic::OnMoreData(stream, dest, max_size, 0);
if (callback_count() % kNumBuffers == 2) {
set_error(!CompareExistingIfNotNULL(2, dest));
} else if (callback_count() % kNumBuffers == 1) {
@@ -119,9 +128,9 @@ class TestSourceLaggy : public TestSourceBasic {
: laggy_after_buffer_(laggy_after_buffer), lag_in_ms_(lag_in_ms) {
}
virtual size_t OnMoreData(AudioOutputStream* stream,
- void* dest, size_t max_size) {
+ void* dest, size_t max_size, int pending_bytes) {
// Call the base, which increments the callback_count_.
- TestSourceBasic::OnMoreData(stream, dest, max_size);
+ TestSourceBasic::OnMoreData(stream, dest, max_size, 0);
if (callback_count() > kNumBuffers) {
::Sleep(lag_in_ms_);
}
@@ -132,6 +141,14 @@ class TestSourceLaggy : public TestSourceBasic {
int lag_in_ms_;
};
+class MockAudioSource : public AudioOutputStream::AudioSourceCallback {
+ public:
+ MOCK_METHOD4(OnMoreData, size_t(AudioOutputStream* stream, void* dest,
+ size_t max_size, int pending_bytes));
+ MOCK_METHOD1(OnClose, void(AudioOutputStream* stream));
+ MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
+};
+
// Helper class to memory map an entire file. The mapping is read-only. Don't
// use for gigabyte-sized files. Attempts to write to this memory generate
// memory access violations.
@@ -479,12 +496,12 @@ TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) {
if (!audio_man->HasAudioDevices())
return;
AudioOutputStream* oas =
- audio_man->MakeAudioStream(AudioManager::AUDIO_PCM_LINEAR, 1,
- AudioManager::kAudioCDSampleRate, 16);
+ audio_man->MakeAudioStream(AudioManager::AUDIO_PCM_LINEAR, 1,
+ AudioManager::kAudioCDSampleRate, 16);
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
- 200.0, AudioManager::kAudioCDSampleRate);
+ 200.0, AudioManager::kAudioCDSampleRate);
size_t bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2;
EXPECT_TRUE(oas->Open(bytes_100_ms));
@@ -506,3 +523,46 @@ TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) {
oas->Close();
}
+// Check that the pending bytes value is correct what the stream starts.
+TEST(WinAudioTest, PCMWaveStreamPendingBytes) {
+ if (IsRunningHeadless())
+ return;
+ AudioManager* audio_man = AudioManager::GetAudioManager();
+ ASSERT_TRUE(NULL != audio_man);
+ if (!audio_man->HasAudioDevices())
+ return;
+ AudioOutputStream* oas =
+ audio_man->MakeAudioStream(AudioManager::AUDIO_PCM_LINEAR, 1,
+ AudioManager::kAudioCDSampleRate, 16);
+ ASSERT_TRUE(NULL != oas);
+
+ NiceMock<MockAudioSource> source;
+ size_t bytes_100_ms = (AudioManager::kAudioCDSampleRate / 10) * 2;
+ EXPECT_TRUE(oas->Open(bytes_100_ms));
+
+ // We expect the amount of pending bytes will reaching 2 times of
+ // |bytes_100_ms| because the audio output stream has a triple buffer scheme.
+ // And then we will try to provide zero data so the amount of pending bytes
+ // will go down and eventually read zero.
+ InSequence s;
+ EXPECT_CALL(source, OnMoreData(oas, NotNull(), bytes_100_ms, 0))
+ .WillOnce(Return(bytes_100_ms));
+ EXPECT_CALL(source, OnMoreData(oas, NotNull(), bytes_100_ms, bytes_100_ms))
+ .WillOnce(Return(bytes_100_ms));
+ EXPECT_CALL(source, OnMoreData(oas, NotNull(),
+ bytes_100_ms, 2 * bytes_100_ms))
+ .WillOnce(Return(bytes_100_ms));
+ EXPECT_CALL(source, OnMoreData(oas, NotNull(),
+ bytes_100_ms, 2 * bytes_100_ms))
+ .WillOnce(Return(0));
+ EXPECT_CALL(source, OnMoreData(oas, NotNull(), bytes_100_ms, bytes_100_ms))
+ .WillOnce(Return(0));
+ EXPECT_CALL(source, OnMoreData(oas, NotNull(), bytes_100_ms, 0))
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(0));
+
+ oas->Start(&source);
+ ::Sleep(500);
+ oas->Stop();
+ oas->Close();
+}
diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc
index 0b4cc6f..21532b7 100644
--- a/media/audio/win/waveout_output_win.cc
+++ b/media/audio/win/waveout_output_win.cc
@@ -58,7 +58,8 @@ PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream(
buffer_(NULL),
buffer_size_(0),
volume_(1),
- channels_(channels) {
+ channels_(channels),
+ pending_bytes_(0) {
format_.wFormatTag = WAVE_FORMAT_PCM;
format_.nChannels = channels > 2 ? 2 : channels;
format_.nSamplesPerSec = sampling_rate;
@@ -144,6 +145,7 @@ void PCMWaveOutAudioOutputStream::Start(AudioSourceCallback* callback) {
WAVEHDR* buffer = buffer_;
for (int ix = 0; ix != kNumBuffers; ++ix) {
QueueNextPacket(buffer); // Read more data.
+ pending_bytes_ += buffer->dwBufferLength;
buffer = GetNextBuffer(buffer);
}
buffer = buffer_;
@@ -235,8 +237,12 @@ void PCMWaveOutAudioOutputStream::HandleError(MMRESULT error) {
void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) {
// Call the source which will fill our buffer with pleasant sounds and
// return to us how many bytes were used.
+ // If we are down sampling to a smaller number of channels, we need to
+ // scale up the amount of pending bytes.
// TODO(fbarchard): Handle used 0 by queueing more.
- size_t used = callback_->OnMoreData(this, buffer->lpData, buffer_size_);
+ int scaled_pending_bytes = pending_bytes_ * channels_ / format_.nChannels;
+ size_t used = callback_->OnMoreData(this, buffer->lpData, buffer_size_,
+ scaled_pending_bytes);
if (used <= buffer_size_) {
buffer->dwBufferLength = used * format_.nChannels / channels_;
if (channels_ > 2 && format_.nChannels == 2) {
@@ -248,7 +254,6 @@ void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) {
format_.nChannels, format_.wBitsPerSample >> 3,
volume_);
}
-
} else {
HandleError(0);
return;
@@ -282,6 +287,11 @@ void PCMWaveOutAudioOutputStream::WaveCallback(HWAVEOUT hwo, UINT msg,
// Not sure if ever hit this but just in case.
return;
}
+
+ // Before we queue the next packet, we need to adjust the number of pending
+ // bytes since the last write to hardware.
+ obj->pending_bytes_ -= buffer->dwBufferLength;
+
obj->QueueNextPacket(buffer);
// Time to send the buffer to the audio driver. Since we are reusing
@@ -290,6 +300,8 @@ void PCMWaveOutAudioOutputStream::WaveCallback(HWAVEOUT hwo, UINT msg,
if (result != MMSYSERR_NOERROR)
obj->HandleError(result);
+ obj->pending_bytes_ += buffer->dwBufferLength;
+
} else if (msg == WOM_CLOSE) {
// We can be closed before calling Start, so it is possible to have a
// null callback at this point.
diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h
index e072851..4f090ba 100644
--- a/media/audio/win/waveout_output_win.h
+++ b/media/audio/win/waveout_output_win.h
@@ -89,6 +89,9 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream {
// Channels from 0 to 6.
int channels_;
+ // Number of bytes yet to be played in the hardware buffer.
+ int pending_bytes_;
+
// The id assigned by the operating system to the selected wave output
// hardware device. Usually this is just -1 which means 'default device'.
UINT device_id_;
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index 6576679..cf31af7 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -13,7 +13,8 @@ static const size_t kSamplesPerBuffer = 8*1024;
AudioRendererImpl::AudioRendererImpl()
: AudioRendererBase(),
- stream_(NULL) {
+ stream_(NULL),
+ bytes_per_second_(0) {
}
AudioRendererImpl::~AudioRendererImpl() {
@@ -48,7 +49,7 @@ void AudioRendererImpl::SetVolume(float volume) {
}
size_t AudioRendererImpl::OnMoreData(AudioOutputStream* stream, void* dest_void,
- size_t len) {
+ size_t len, int pending_bytes) {
// TODO(scherkus): handle end of stream.
if (!stream_)
return 0;
@@ -56,7 +57,9 @@ size_t AudioRendererImpl::OnMoreData(AudioOutputStream* stream, void* dest_void,
// TODO(scherkus): Maybe change OnMoreData to pass in char/uint8 or similar.
// TODO(fbarchard): Waveout_output_win.h should handle zero length buffers
// without clicking.
- return FillBuffer(static_cast<uint8*>(dest_void), len, base::TimeDelta());
+ base::TimeDelta delay = base::TimeDelta::FromMicroseconds(
+ base::Time::kMicrosecondsPerSecond * pending_bytes / bytes_per_second_);
+ return FillBuffer(static_cast<uint8*>(dest_void), len, delay);
}
void AudioRendererImpl::OnClose(AudioOutputStream* stream) {
@@ -78,6 +81,8 @@ bool AudioRendererImpl::OnInitialize(const MediaFormat& media_format) {
return false;
}
+ bytes_per_second_ = sample_rate * channels * sample_bits / 8;
+
// Create our audio stream.
stream_ = AudioManager::GetAudioManager()->MakeAudioStream(
AudioManager::AUDIO_PCM_LINEAR, channels, sample_rate, sample_bits);
diff --git a/media/filters/audio_renderer_impl.h b/media/filters/audio_renderer_impl.h
index 1a6c5a1..b15c83d 100644
--- a/media/filters/audio_renderer_impl.h
+++ b/media/filters/audio_renderer_impl.h
@@ -43,7 +43,8 @@ class AudioRendererImpl : public AudioRendererBase,
virtual void SetVolume(float volume);
// AudioSourceCallback implementation.
- virtual size_t OnMoreData(AudioOutputStream* stream, void* dest, size_t len);
+ virtual size_t OnMoreData(AudioOutputStream* stream, void* dest,
+ size_t len, int pending_bytes);
virtual void OnClose(AudioOutputStream* stream);
virtual void OnError(AudioOutputStream* stream, int code);
@@ -60,6 +61,7 @@ class AudioRendererImpl : public AudioRendererBase,
private:
// Audio output stream device.
AudioOutputStream* stream_;
+ int bytes_per_second_;
DISALLOW_COPY_AND_ASSIGN(AudioRendererImpl);
};