Ensure low-memory renderers retry failed loads correctly.
[chromium-blink-merge.git] / remoting / client / audio_player_unittest.cc
blob8084ee515cd29bd00ba60bc0a47b48df7b279412
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/client/audio_player.h"
7 #include "base/compiler_specific.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace {
13 const int kAudioSamplesPerFrame = 25;
14 const int kAudioSampleBytes = 4;
15 const int kAudioFrameBytes = kAudioSamplesPerFrame * kAudioSampleBytes;
16 const int kPaddingBytes = 16;
18 // TODO(garykac): Generate random audio data in the tests rather than having
19 // a single constant value.
20 const uint8 kDefaultBufferData = 0x5A;
21 const uint8 kDummyAudioData = 0x8B;
23 } // namespace
25 namespace remoting {
27 class FakeAudioPlayer : public AudioPlayer {
28 public:
29 FakeAudioPlayer() {
32 bool ResetAudioPlayer(AudioPacket::SamplingRate) override { return true; }
34 uint32 GetSamplesPerFrame() override { return kAudioSamplesPerFrame; }
37 class AudioPlayerTest : public ::testing::Test {
38 protected:
39 void SetUp() override {
40 audio_.reset(new FakeAudioPlayer());
41 buffer_.reset(new char[kAudioFrameBytes + kPaddingBytes]);
44 void TearDown() override {}
46 void ConsumeAudioFrame() {
47 uint8* buffer = reinterpret_cast<uint8*>(buffer_.get());
48 memset(buffer, kDefaultBufferData, kAudioFrameBytes + kPaddingBytes);
49 AudioPlayer::AudioPlayerCallback(reinterpret_cast<void*>(buffer_.get()),
50 kAudioFrameBytes,
51 reinterpret_cast<void*>(audio_.get()));
52 // Verify we haven't written beyond the end of the buffer.
53 for (int i = 0; i < kPaddingBytes; i++)
54 ASSERT_EQ(kDefaultBufferData, *(buffer + kAudioFrameBytes + i));
57 // Check that the first |num_bytes| bytes are filled with audio data and
58 // the rest of the buffer is zero-filled.
59 void CheckAudioFrameBytes(int num_bytes) {
60 uint8* buffer = reinterpret_cast<uint8*>(buffer_.get());
61 int i = 0;
62 for (; i < num_bytes; i++) {
63 ASSERT_EQ(kDummyAudioData, *(buffer + i));
65 // Rest of audio frame must be filled with '0's.
66 for (; i < kAudioFrameBytes; i++) {
67 ASSERT_EQ(0, *(buffer + i));
71 int GetNumQueuedSamples() {
72 return audio_->queued_bytes_ / kAudioSampleBytes;
75 int GetNumQueuedPackets() {
76 return static_cast<int>(audio_->queued_packets_.size());
79 int GetBytesConsumed() {
80 return static_cast<int>(audio_->bytes_consumed_);
83 scoped_ptr<AudioPlayer> audio_;
84 scoped_ptr<char[]> buffer_;
87 scoped_ptr<AudioPacket> CreatePacketWithSamplingRate(
88 AudioPacket::SamplingRate rate, int samples) {
89 scoped_ptr<AudioPacket> packet(new AudioPacket());
90 packet->set_encoding(AudioPacket::ENCODING_RAW);
91 packet->set_sampling_rate(rate);
92 packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
93 packet->set_channels(AudioPacket::CHANNELS_STEREO);
95 // The data must be a multiple of 4 bytes (channels x bytes_per_sample).
96 std::string data;
97 data.resize(samples * kAudioSampleBytes, kDummyAudioData);
98 packet->add_data(data);
100 return packet.Pass();
103 scoped_ptr<AudioPacket> CreatePacket44100Hz(int samples) {
104 return CreatePacketWithSamplingRate(AudioPacket::SAMPLING_RATE_44100,
105 samples);
108 scoped_ptr<AudioPacket> CreatePacket48000Hz(int samples) {
109 return CreatePacketWithSamplingRate(AudioPacket::SAMPLING_RATE_48000,
110 samples);
113 TEST_F(AudioPlayerTest, Init) {
114 ASSERT_EQ(0, GetNumQueuedPackets());
116 audio_->ProcessAudioPacket(CreatePacket44100Hz(10));
117 ASSERT_EQ(1, GetNumQueuedPackets());
120 TEST_F(AudioPlayerTest, MultipleSamples) {
121 audio_->ProcessAudioPacket(CreatePacket44100Hz(10));
122 ASSERT_EQ(10, GetNumQueuedSamples());
123 ASSERT_EQ(1, GetNumQueuedPackets());
125 audio_->ProcessAudioPacket(CreatePacket44100Hz(20));
126 ASSERT_EQ(30, GetNumQueuedSamples());
127 ASSERT_EQ(2, GetNumQueuedPackets());
130 TEST_F(AudioPlayerTest, ChangeSampleRate) {
131 audio_->ProcessAudioPacket(CreatePacket44100Hz(10));
132 ASSERT_EQ(10, GetNumQueuedSamples());
133 ASSERT_EQ(1, GetNumQueuedPackets());
135 // New packet with different sampling rate causes previous samples to
136 // be removed.
137 audio_->ProcessAudioPacket(CreatePacket48000Hz(20));
138 ASSERT_EQ(20, GetNumQueuedSamples());
139 ASSERT_EQ(1, GetNumQueuedPackets());
142 TEST_F(AudioPlayerTest, ExceedLatency) {
143 // Push about 4 seconds worth of samples.
144 for (int i = 0; i < 100; ++i) {
145 audio_->ProcessAudioPacket(CreatePacket48000Hz(2000));
148 // Verify that we don't have more than 0.5s.
149 EXPECT_LT(GetNumQueuedSamples(), 24000);
152 // Incoming packets: 100
153 // Consume: 25 (w/ 75 remaining, offset 25 into packet)
154 TEST_F(AudioPlayerTest, ConsumePartialPacket) {
155 int total_samples = 0;
156 int bytes_consumed = 0;
158 // Process 100 samples.
159 int packet1_samples = 100;
160 total_samples += packet1_samples;
161 audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples));
162 ASSERT_EQ(total_samples, GetNumQueuedSamples());
163 ASSERT_EQ(1, GetNumQueuedPackets());
164 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
166 // Consume one frame (=25) of samples.
167 ConsumeAudioFrame();
168 total_samples -= kAudioSamplesPerFrame;
169 bytes_consumed += kAudioFrameBytes;
170 ASSERT_EQ(total_samples, GetNumQueuedSamples());
171 ASSERT_EQ(1, GetNumQueuedPackets());
172 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
173 CheckAudioFrameBytes(kAudioFrameBytes);
175 // Remaining samples.
176 ASSERT_EQ(75, total_samples);
177 ASSERT_EQ(25 * kAudioSampleBytes, bytes_consumed);
180 // Incoming packets: 20, 70
181 // Consume: 25, 25 (w/ 40 remaining, offset 30 into packet)
182 TEST_F(AudioPlayerTest, ConsumeAcrossPackets) {
183 int total_samples = 0;
184 int bytes_consumed = 0;
186 // Packet 1.
187 int packet1_samples = 20;
188 total_samples += packet1_samples;
189 audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples));
190 ASSERT_EQ(total_samples, GetNumQueuedSamples());
192 // Packet 2.
193 int packet2_samples = 70;
194 total_samples += packet2_samples;
195 audio_->ProcessAudioPacket(CreatePacket44100Hz(packet2_samples));
196 ASSERT_EQ(total_samples, GetNumQueuedSamples());
197 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
199 // Consume 1st frame of 25 samples.
200 // This will consume the entire 1st packet.
201 ConsumeAudioFrame();
202 total_samples -= kAudioSamplesPerFrame;
203 bytes_consumed += kAudioFrameBytes - (packet1_samples * kAudioSampleBytes);
204 ASSERT_EQ(total_samples, GetNumQueuedSamples());
205 ASSERT_EQ(1, GetNumQueuedPackets());
206 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
207 CheckAudioFrameBytes(kAudioFrameBytes);
209 // Consume 2nd frame of 25 samples.
210 ConsumeAudioFrame();
211 total_samples -= kAudioSamplesPerFrame;
212 bytes_consumed += kAudioFrameBytes;
213 ASSERT_EQ(total_samples, GetNumQueuedSamples());
214 ASSERT_EQ(1, GetNumQueuedPackets());
215 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
216 CheckAudioFrameBytes(kAudioFrameBytes);
218 // Remaining samples.
219 ASSERT_EQ(40, total_samples);
220 ASSERT_EQ(30 * kAudioSampleBytes, bytes_consumed);
223 // Incoming packets: 50, 30
224 // Consume: 25, 25, 25 (w/ 5 remaining, offset 25 into packet)
225 TEST_F(AudioPlayerTest, ConsumeEntirePacket) {
226 int total_samples = 0;
227 int bytes_consumed = 0;
229 // Packet 1.
230 int packet1_samples = 50;
231 total_samples += packet1_samples;
232 audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples));
233 ASSERT_EQ(total_samples, GetNumQueuedSamples());
234 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
236 // Packet 2.
237 int packet2_samples = 30;
238 total_samples += packet2_samples;
239 audio_->ProcessAudioPacket(CreatePacket44100Hz(packet2_samples));
240 ASSERT_EQ(total_samples, GetNumQueuedSamples());
241 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
243 // Consume 1st frame of 25 samples.
244 ConsumeAudioFrame();
245 total_samples -= kAudioSamplesPerFrame;
246 bytes_consumed += kAudioFrameBytes;
247 ASSERT_EQ(total_samples, GetNumQueuedSamples());
248 ASSERT_EQ(2, GetNumQueuedPackets());
249 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
250 CheckAudioFrameBytes(kAudioFrameBytes);
252 // Consume 2nd frame of 25 samples.
253 // This will consume the entire first packet (exactly), but the entry for
254 // this packet will stick around (empty) until the next audio chunk is
255 // consumed.
256 ConsumeAudioFrame();
257 total_samples -= kAudioSamplesPerFrame;
258 bytes_consumed += kAudioFrameBytes;
259 ASSERT_EQ(total_samples, GetNumQueuedSamples());
260 ASSERT_EQ(2, GetNumQueuedPackets());
261 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
262 CheckAudioFrameBytes(kAudioFrameBytes);
264 // Consume 3rd frame of 25 samples.
265 ConsumeAudioFrame();
266 total_samples -= kAudioSamplesPerFrame;
267 bytes_consumed += kAudioFrameBytes - (packet1_samples * kAudioSampleBytes);
268 ASSERT_EQ(total_samples, GetNumQueuedSamples());
269 ASSERT_EQ(1, GetNumQueuedPackets());
270 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
271 CheckAudioFrameBytes(kAudioFrameBytes);
273 // Remaining samples.
274 ASSERT_EQ(5, total_samples);
275 ASSERT_EQ(25 * kAudioSampleBytes, bytes_consumed);
278 // Incoming packets: <none>
279 // Consume: 25
280 TEST_F(AudioPlayerTest, NoDataToConsume) {
281 // Attempt to consume a frame of 25 samples.
282 ConsumeAudioFrame();
283 ASSERT_EQ(0, GetNumQueuedSamples());
284 ASSERT_EQ(0, GetNumQueuedPackets());
285 ASSERT_EQ(0, GetBytesConsumed());
286 CheckAudioFrameBytes(0);
289 // Incoming packets: 10
290 // Consume: 25
291 TEST_F(AudioPlayerTest, NotEnoughDataToConsume) {
292 int total_samples = 0;
293 int bytes_consumed = 0;
295 // Packet 1.
296 int packet1_samples = 10;
297 total_samples += packet1_samples;
298 audio_->ProcessAudioPacket(CreatePacket44100Hz(packet1_samples));
299 ASSERT_EQ(total_samples, GetNumQueuedSamples());
300 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
302 // Attempt to consume a frame of 25 samples.
303 ConsumeAudioFrame();
304 ASSERT_EQ(0, GetNumQueuedSamples());
305 ASSERT_EQ(0, GetNumQueuedPackets());
306 ASSERT_EQ(0, GetBytesConsumed());
307 CheckAudioFrameBytes(packet1_samples * kAudioSampleBytes);
310 } // namespace remoting