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