Home | History | Annotate | Download | only in base
      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
    375