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 "base/memory/scoped_ptr.h"
6 #include "media/base/audio_buffer.h"
7 #include "media/base/audio_bus.h"
8 #include "media/base/audio_splicer.h"
9 #include "media/base/audio_timestamp_helper.h"
10 #include "media/base/buffers.h"
11 #include "media/base/test_helpers.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 static const SampleFormat kSampleFormat
= kSampleFormatF32
;
17 static const int kChannels
= 1;
18 static const int kDefaultSampleRate
= 44100;
19 static const int kDefaultBufferSize
= 100;
21 class AudioSplicerTest
: public ::testing::Test
{
24 : splicer_(kDefaultSampleRate
),
25 input_timestamp_helper_(kDefaultSampleRate
) {
26 input_timestamp_helper_
.SetBaseTimestamp(base::TimeDelta());
29 scoped_refptr
<AudioBuffer
> GetNextInputBuffer(float value
) {
30 return GetNextInputBuffer(value
, kDefaultBufferSize
);
33 scoped_refptr
<AudioBuffer
> GetNextInputBuffer(float value
, int frame_size
) {
34 scoped_refptr
<AudioBuffer
> buffer
= MakeInterleavedAudioBuffer
<float>(
40 input_timestamp_helper_
.GetTimestamp(),
41 input_timestamp_helper_
.GetFrameDuration(frame_size
));
42 input_timestamp_helper_
.AddFrames(frame_size
);
46 bool VerifyData(scoped_refptr
<AudioBuffer
> buffer
, float value
) {
47 int frames
= buffer
->frame_count();
48 scoped_ptr
<AudioBus
> bus
= AudioBus::Create(kChannels
, frames
);
49 buffer
->ReadFrames(frames
, 0, 0, bus
.get());
50 for (int i
= 0; i
< frames
; ++i
) {
51 if (bus
->channel(0)[i
] != value
)
58 AudioSplicer splicer_
;
59 AudioTimestampHelper input_timestamp_helper_
;
61 DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest
);
64 TEST_F(AudioSplicerTest
, PassThru
) {
65 EXPECT_FALSE(splicer_
.HasNextBuffer());
67 // Test single buffer pass-thru behavior.
68 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
69 EXPECT_TRUE(splicer_
.AddInput(input_1
));
70 EXPECT_TRUE(splicer_
.HasNextBuffer());
72 scoped_refptr
<AudioBuffer
> output_1
= splicer_
.GetNextBuffer();
73 EXPECT_FALSE(splicer_
.HasNextBuffer());
74 EXPECT_EQ(input_1
->timestamp(), output_1
->timestamp());
75 EXPECT_EQ(input_1
->duration(), output_1
->duration());
76 EXPECT_EQ(input_1
->frame_count(), output_1
->frame_count());
77 EXPECT_TRUE(VerifyData(output_1
, 0.1f
));
79 // Test that multiple buffers can be queued in the splicer.
80 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
81 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.3f
);
82 EXPECT_TRUE(splicer_
.AddInput(input_2
));
83 EXPECT_TRUE(splicer_
.AddInput(input_3
));
84 EXPECT_TRUE(splicer_
.HasNextBuffer());
86 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
87 EXPECT_TRUE(splicer_
.HasNextBuffer());
88 EXPECT_EQ(input_2
->timestamp(), output_2
->timestamp());
89 EXPECT_EQ(input_2
->duration(), output_2
->duration());
90 EXPECT_EQ(input_2
->frame_count(), output_2
->frame_count());
92 scoped_refptr
<AudioBuffer
> output_3
= splicer_
.GetNextBuffer();
93 EXPECT_FALSE(splicer_
.HasNextBuffer());
94 EXPECT_EQ(input_3
->timestamp(), output_3
->timestamp());
95 EXPECT_EQ(input_3
->duration(), output_3
->duration());
96 EXPECT_EQ(input_3
->frame_count(), output_3
->frame_count());
99 TEST_F(AudioSplicerTest
, Reset
) {
100 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
101 EXPECT_TRUE(splicer_
.AddInput(input_1
));
102 EXPECT_TRUE(splicer_
.HasNextBuffer());
105 EXPECT_FALSE(splicer_
.HasNextBuffer());
107 // Add some bytes to the timestamp helper so that the
108 // next buffer starts many frames beyond the end of
109 // |input_1|. This is to make sure that Reset() actually
110 // clears its state and doesn't try to insert a gap.
111 input_timestamp_helper_
.AddFrames(100);
113 // Verify that a new input buffer passes through as expected.
114 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
115 EXPECT_TRUE(splicer_
.AddInput(input_2
));
116 EXPECT_TRUE(splicer_
.HasNextBuffer());
118 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
119 EXPECT_FALSE(splicer_
.HasNextBuffer());
120 EXPECT_EQ(input_2
->timestamp(), output_2
->timestamp());
121 EXPECT_EQ(input_2
->duration(), output_2
->duration());
122 EXPECT_EQ(input_2
->frame_count(), output_2
->frame_count());
125 TEST_F(AudioSplicerTest
, EndOfStream
) {
126 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
127 scoped_refptr
<AudioBuffer
> input_2
= AudioBuffer::CreateEOSBuffer();
128 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.2f
);
129 EXPECT_TRUE(input_2
->end_of_stream());
131 EXPECT_TRUE(splicer_
.AddInput(input_1
));
132 EXPECT_TRUE(splicer_
.AddInput(input_2
));
133 EXPECT_TRUE(splicer_
.HasNextBuffer());
135 scoped_refptr
<AudioBuffer
> output_1
= splicer_
.GetNextBuffer();
136 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
137 EXPECT_FALSE(splicer_
.HasNextBuffer());
138 EXPECT_EQ(input_1
->timestamp(), output_1
->timestamp());
139 EXPECT_EQ(input_1
->duration(), output_1
->duration());
140 EXPECT_EQ(input_1
->frame_count(), output_1
->frame_count());
142 EXPECT_TRUE(output_2
->end_of_stream());
144 // Verify that buffers can be added again after Reset().
146 EXPECT_TRUE(splicer_
.AddInput(input_3
));
147 scoped_refptr
<AudioBuffer
> output_3
= splicer_
.GetNextBuffer();
148 EXPECT_FALSE(splicer_
.HasNextBuffer());
149 EXPECT_EQ(input_3
->timestamp(), output_3
->timestamp());
150 EXPECT_EQ(input_3
->duration(), output_3
->duration());
151 EXPECT_EQ(input_3
->frame_count(), output_3
->frame_count());
155 // Test the gap insertion code.
156 // +--------------+ +--------------+
157 // |11111111111111| |22222222222222|
158 // +--------------+ +--------------+
160 // +--------------+----+--------------+
161 // |11111111111111|0000|22222222222222|
162 // +--------------+----+--------------+
163 TEST_F(AudioSplicerTest
, GapInsertion
) {
164 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
166 // Add bytes to the timestamp helper so that the next buffer
167 // will have a starting timestamp that indicates a gap is
169 const int kGapSize
= 7;
170 input_timestamp_helper_
.AddFrames(kGapSize
);
171 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
173 EXPECT_TRUE(splicer_
.AddInput(input_1
));
174 EXPECT_TRUE(splicer_
.AddInput(input_2
));
176 // Verify that a gap buffer is generated.
177 EXPECT_TRUE(splicer_
.HasNextBuffer());
178 scoped_refptr
<AudioBuffer
> output_1
= splicer_
.GetNextBuffer();
179 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
180 scoped_refptr
<AudioBuffer
> output_3
= splicer_
.GetNextBuffer();
181 EXPECT_FALSE(splicer_
.HasNextBuffer());
183 // Verify that the first input buffer passed through unmodified.
184 EXPECT_EQ(input_1
->timestamp(), output_1
->timestamp());
185 EXPECT_EQ(input_1
->duration(), output_1
->duration());
186 EXPECT_EQ(input_1
->frame_count(), output_1
->frame_count());
187 EXPECT_TRUE(VerifyData(output_1
, 0.1f
));
189 // Verify the contents of the gap buffer.
190 base::TimeDelta gap_timestamp
=
191 input_1
->timestamp() + input_1
->duration();
192 base::TimeDelta gap_duration
= input_2
->timestamp() - gap_timestamp
;
193 EXPECT_GT(gap_duration
, base::TimeDelta());
194 EXPECT_EQ(gap_timestamp
, output_2
->timestamp());
195 EXPECT_EQ(gap_duration
, output_2
->duration());
196 EXPECT_EQ(kGapSize
, output_2
->frame_count());
197 EXPECT_TRUE(VerifyData(output_2
, 0.0f
));
199 // Verify that the second input buffer passed through unmodified.
200 EXPECT_EQ(input_2
->timestamp(), output_3
->timestamp());
201 EXPECT_EQ(input_2
->duration(), output_3
->duration());
202 EXPECT_EQ(input_2
->frame_count(), output_3
->frame_count());
203 EXPECT_TRUE(VerifyData(output_3
, 0.2f
));
207 // Test that an error is signalled when the gap between input buffers is
209 TEST_F(AudioSplicerTest
, GapTooLarge
) {
210 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
212 // Add a seconds worth of bytes so that an unacceptably large
213 // gap exists between |input_1| and |input_2|.
214 const int kGapSize
= kDefaultSampleRate
;
215 input_timestamp_helper_
.AddFrames(kGapSize
);
216 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
218 EXPECT_TRUE(splicer_
.AddInput(input_1
));
219 EXPECT_FALSE(splicer_
.AddInput(input_2
));
221 EXPECT_TRUE(splicer_
.HasNextBuffer());
222 scoped_refptr
<AudioBuffer
> output_1
= splicer_
.GetNextBuffer();
224 // Verify that the first input buffer passed through unmodified.
225 EXPECT_EQ(input_1
->timestamp(), output_1
->timestamp());
226 EXPECT_EQ(input_1
->duration(), output_1
->duration());
227 EXPECT_EQ(input_1
->frame_count(), output_1
->frame_count());
228 EXPECT_TRUE(VerifyData(output_1
, 0.1f
));
230 // Verify that the second buffer is not available.
231 EXPECT_FALSE(splicer_
.HasNextBuffer());
233 // Reset the timestamp helper so it can generate a buffer that is
234 // right after |input_1|.
235 input_timestamp_helper_
.SetBaseTimestamp(
236 input_1
->timestamp() + input_1
->duration());
238 // Verify that valid buffers are still accepted.
239 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.3f
);
240 EXPECT_TRUE(splicer_
.AddInput(input_3
));
241 EXPECT_TRUE(splicer_
.HasNextBuffer());
242 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
243 EXPECT_FALSE(splicer_
.HasNextBuffer());
244 EXPECT_EQ(input_3
->timestamp(), output_2
->timestamp());
245 EXPECT_EQ(input_3
->duration(), output_2
->duration());
246 EXPECT_EQ(input_3
->frame_count(), output_2
->frame_count());
247 EXPECT_TRUE(VerifyData(output_2
, 0.3f
));
251 // Verifies that an error is signalled if AddInput() is called
252 // with a timestamp that is earlier than the first buffer added.
253 TEST_F(AudioSplicerTest
, BufferAddedBeforeBase
) {
254 input_timestamp_helper_
.SetBaseTimestamp(
255 base::TimeDelta::FromMicroseconds(10));
256 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
258 // Reset the timestamp helper so the next buffer will have a timestamp earlier
260 input_timestamp_helper_
.SetBaseTimestamp(base::TimeDelta::FromSeconds(0));
261 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.1f
);
263 EXPECT_GT(input_1
->timestamp(), input_2
->timestamp());
264 EXPECT_TRUE(splicer_
.AddInput(input_1
));
265 EXPECT_FALSE(splicer_
.AddInput(input_2
));
269 // Test when one buffer partially overlaps another.
277 // +--------------+----------+
278 // |11111111111111|2222222222|
279 // +--------------+----------+
280 TEST_F(AudioSplicerTest
, PartialOverlap
) {
281 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
283 // Reset timestamp helper so that the next buffer will have a
284 // timestamp that starts in the middle of |input_1|.
285 const int kOverlapSize
= input_1
->frame_count() / 4;
286 input_timestamp_helper_
.SetBaseTimestamp(input_1
->timestamp());
287 input_timestamp_helper_
.AddFrames(input_1
->frame_count() - kOverlapSize
);
289 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
);
291 EXPECT_TRUE(splicer_
.AddInput(input_1
));
292 EXPECT_TRUE(splicer_
.AddInput(input_2
));
294 EXPECT_TRUE(splicer_
.HasNextBuffer());
295 scoped_refptr
<AudioBuffer
> output_1
= splicer_
.GetNextBuffer();
296 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
297 EXPECT_FALSE(splicer_
.HasNextBuffer());
299 // Verify that the first input buffer passed through unmodified.
300 EXPECT_EQ(input_1
->timestamp(), output_1
->timestamp());
301 EXPECT_EQ(input_1
->duration(), output_1
->duration());
302 EXPECT_EQ(input_1
->frame_count(), output_1
->frame_count());
303 EXPECT_TRUE(VerifyData(output_1
, 0.1f
));
305 // Verify that the second input buffer was truncated to only contain
306 // the samples that are after the end of |input_1|. Note that data is not
307 // copied, so |input_2|'s values are modified.
308 base::TimeDelta expected_timestamp
=
309 input_1
->timestamp() + input_1
->duration();
310 base::TimeDelta expected_duration
=
311 (input_2
->timestamp() + input_2
->duration()) - expected_timestamp
;
312 EXPECT_EQ(expected_timestamp
, output_2
->timestamp());
313 EXPECT_EQ(expected_duration
, output_2
->duration());
314 EXPECT_TRUE(VerifyData(output_2
, 0.2f
));
318 // Test that an input buffer that is completely overlapped by a buffer
319 // that was already added is dropped.
330 // +--------------+-------------+
331 // |11111111111111|3333333333333|
332 // +--------------+-------------+
333 TEST_F(AudioSplicerTest
, DropBuffer
) {
334 scoped_refptr
<AudioBuffer
> input_1
= GetNextInputBuffer(0.1f
);
336 // Reset timestamp helper so that the next buffer will have a
337 // timestamp that starts in the middle of |input_1|.
338 const int kOverlapOffset
= input_1
->frame_count() / 2;
339 const int kOverlapSize
= input_1
->frame_count() / 4;
340 input_timestamp_helper_
.SetBaseTimestamp(input_1
->timestamp());
341 input_timestamp_helper_
.AddFrames(kOverlapOffset
);
343 scoped_refptr
<AudioBuffer
> input_2
= GetNextInputBuffer(0.2f
, kOverlapSize
);
345 // Reset the timestamp helper so the next buffer will be right after
347 input_timestamp_helper_
.SetBaseTimestamp(input_1
->timestamp());
348 input_timestamp_helper_
.AddFrames(input_1
->frame_count());
349 scoped_refptr
<AudioBuffer
> input_3
= GetNextInputBuffer(0.3f
);
351 EXPECT_TRUE(splicer_
.AddInput(input_1
));
352 EXPECT_TRUE(splicer_
.AddInput(input_2
));
353 EXPECT_TRUE(splicer_
.AddInput(input_3
));
355 EXPECT_TRUE(splicer_
.HasNextBuffer());
356 scoped_refptr
<AudioBuffer
> output_1
= splicer_
.GetNextBuffer();
357 scoped_refptr
<AudioBuffer
> output_2
= splicer_
.GetNextBuffer();
358 EXPECT_FALSE(splicer_
.HasNextBuffer());
360 // Verify that the first input buffer passed through unmodified.
361 EXPECT_EQ(input_1
->timestamp(), output_1
->timestamp());
362 EXPECT_EQ(input_1
->duration(), output_1
->duration());
363 EXPECT_EQ(input_1
->frame_count(), output_1
->frame_count());
364 EXPECT_TRUE(VerifyData(output_1
, 0.1f
));
366 // Verify that the second output buffer only contains
367 // the samples that are in |input_3|.
368 EXPECT_EQ(input_3
->timestamp(), output_2
->timestamp());
369 EXPECT_EQ(input_3
->duration(), output_2
->duration());
370 EXPECT_EQ(input_3
->frame_count(), output_2
->frame_count());
371 EXPECT_TRUE(VerifyData(output_2
, 0.3f
));