- add sources.
[platform/framework/web/crosswalk.git] / src / media / base / audio_splicer_unittest.cc
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.
4
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"
13
14 namespace media {
15
16 static const SampleFormat kSampleFormat = kSampleFormatF32;
17 static const int kChannels = 1;
18 static const int kDefaultSampleRate = 44100;
19 static const int kDefaultBufferSize = 100;
20
21 class AudioSplicerTest : public ::testing::Test {
22  public:
23   AudioSplicerTest()
24       : splicer_(kDefaultSampleRate),
25         input_timestamp_helper_(kDefaultSampleRate) {
26     input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta());
27   }
28
29   scoped_refptr<AudioBuffer> GetNextInputBuffer(float value) {
30     return GetNextInputBuffer(value, kDefaultBufferSize);
31   }
32
33   scoped_refptr<AudioBuffer> GetNextInputBuffer(float value, int frame_size) {
34     scoped_refptr<AudioBuffer> buffer = MakeInterleavedAudioBuffer<float>(
35         kSampleFormat,
36         kChannels,
37         value,
38         0.0f,
39         frame_size,
40         input_timestamp_helper_.GetTimestamp(),
41         input_timestamp_helper_.GetFrameDuration(frame_size));
42     input_timestamp_helper_.AddFrames(frame_size);
43     return buffer;
44   }
45
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)
52         return false;
53     }
54     return true;
55   }
56
57  protected:
58   AudioSplicer splicer_;
59   AudioTimestampHelper input_timestamp_helper_;
60
61   DISALLOW_COPY_AND_ASSIGN(AudioSplicerTest);
62 };
63
64 TEST_F(AudioSplicerTest, PassThru) {
65   EXPECT_FALSE(splicer_.HasNextBuffer());
66
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());
71
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));
78
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());
85
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());
91
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());
97 }
98
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());
103
104   splicer_.Reset();
105   EXPECT_FALSE(splicer_.HasNextBuffer());
106
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);
112
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());
117
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());
123 }
124
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());
130
131   EXPECT_TRUE(splicer_.AddInput(input_1));
132   EXPECT_TRUE(splicer_.AddInput(input_2));
133   EXPECT_TRUE(splicer_.HasNextBuffer());
134
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());
141
142   EXPECT_TRUE(output_2->end_of_stream());
143
144   // Verify that buffers can be added again after Reset().
145   splicer_.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());
152 }
153
154
155 // Test the gap insertion code.
156 // +--------------+    +--------------+
157 // |11111111111111|    |22222222222222|
158 // +--------------+    +--------------+
159 // Results in:
160 // +--------------+----+--------------+
161 // |11111111111111|0000|22222222222222|
162 // +--------------+----+--------------+
163 TEST_F(AudioSplicerTest, GapInsertion) {
164   scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);
165
166   // Add bytes to the timestamp helper so that the next buffer
167   // will have a starting timestamp that indicates a gap is
168   // present.
169   const int kGapSize = 7;
170   input_timestamp_helper_.AddFrames(kGapSize);
171   scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);
172
173   EXPECT_TRUE(splicer_.AddInput(input_1));
174   EXPECT_TRUE(splicer_.AddInput(input_2));
175
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());
182
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));
188
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));
198
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));
204 }
205
206
207 // Test that an error is signalled when the gap between input buffers is
208 // too large.
209 TEST_F(AudioSplicerTest, GapTooLarge) {
210   scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);
211
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);
217
218   EXPECT_TRUE(splicer_.AddInput(input_1));
219   EXPECT_FALSE(splicer_.AddInput(input_2));
220
221   EXPECT_TRUE(splicer_.HasNextBuffer());
222   scoped_refptr<AudioBuffer> output_1 = splicer_.GetNextBuffer();
223
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));
229
230   // Verify that the second buffer is not available.
231   EXPECT_FALSE(splicer_.HasNextBuffer());
232
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());
237
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));
248 }
249
250
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);
257
258   // Reset the timestamp helper so the next buffer will have a timestamp earlier
259   // than |input_1|.
260   input_timestamp_helper_.SetBaseTimestamp(base::TimeDelta::FromSeconds(0));
261   scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.1f);
262
263   EXPECT_GT(input_1->timestamp(), input_2->timestamp());
264   EXPECT_TRUE(splicer_.AddInput(input_1));
265   EXPECT_FALSE(splicer_.AddInput(input_2));
266 }
267
268
269 // Test when one buffer partially overlaps another.
270 // +--------------+
271 // |11111111111111|
272 // +--------------+
273 //            +--------------+
274 //            |22222222222222|
275 //            +--------------+
276 // Results in:
277 // +--------------+----------+
278 // |11111111111111|2222222222|
279 // +--------------+----------+
280 TEST_F(AudioSplicerTest, PartialOverlap) {
281   scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);
282
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);
288
289   scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f);
290
291   EXPECT_TRUE(splicer_.AddInput(input_1));
292   EXPECT_TRUE(splicer_.AddInput(input_2));
293
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());
298
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));
304
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));
315 }
316
317
318 // Test that an input buffer that is completely overlapped by a buffer
319 // that was already added is dropped.
320 // +--------------+
321 // |11111111111111|
322 // +--------------+
323 //       +-----+
324 //       |22222|
325 //       +-----+
326 //                +-------------+
327 //                |3333333333333|
328 //                +-------------+
329 // Results in:
330 // +--------------+-------------+
331 // |11111111111111|3333333333333|
332 // +--------------+-------------+
333 TEST_F(AudioSplicerTest, DropBuffer) {
334   scoped_refptr<AudioBuffer> input_1 = GetNextInputBuffer(0.1f);
335
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);
342
343   scoped_refptr<AudioBuffer> input_2 = GetNextInputBuffer(0.2f, kOverlapSize);
344
345   // Reset the timestamp helper so the next buffer will be right after
346   // |input_1|.
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);
350
351   EXPECT_TRUE(splicer_.AddInput(input_1));
352   EXPECT_TRUE(splicer_.AddInput(input_2));
353   EXPECT_TRUE(splicer_.AddInput(input_3));
354
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());
359
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));
365
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));
372 }
373
374 }  // namespace media