audio_splicer_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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
14namespace media {
15
16static const SampleFormat kSampleFormat = kSampleFormatF32;
17static const int kChannels = 1;
18static const int kDefaultSampleRate = 44100;
19static const int kDefaultBufferSize = 100;
20
21class 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
64TEST_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
99TEST_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
125TEST_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// +--------------+----+--------------+
163TEST_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.
209TEST_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.
253TEST_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// +--------------+----------+
280TEST_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// +--------------+-------------+
333TEST_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
375