Home | History | Annotate | Download | only in base
      1 // Copyright 2014 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_discard_helper.h"
      9 #include "media/base/buffers.h"
     10 #include "media/base/decoder_buffer.h"
     11 #include "media/base/test_helpers.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 namespace media {
     15 
     16 static const float kDataStep = 0.01f;
     17 static const size_t kSampleRate = 48000;
     18 
     19 static scoped_refptr<DecoderBuffer> CreateEncodedBuffer(
     20     base::TimeDelta timestamp,
     21     base::TimeDelta duration) {
     22   scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1));
     23   result->set_timestamp(timestamp);
     24   result->set_duration(duration);
     25   return result;
     26 }
     27 
     28 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) {
     29   return MakeAudioBuffer(kSampleFormatPlanarF32,
     30                          CHANNEL_LAYOUT_MONO,
     31                          1,
     32                          kSampleRate,
     33                          0.0f,
     34                          kDataStep,
     35                          frames,
     36                          kNoTimestamp());
     37 }
     38 
     39 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer,
     40                                 int index) {
     41   // This is really inefficient, but we can't access the raw AudioBuffer if any
     42   // start trimming has been applied.
     43   scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1);
     44   buffer->ReadFrames(1, index, 0, temp_bus.get());
     45   return temp_bus->channel(0)[0];
     46 }
     47 
     48 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
     49   AudioDiscardHelper discard_helper(kSampleRate, 0);
     50 
     51   EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
     52   EXPECT_EQ(
     53       kSampleRate / 100,
     54       discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10)));
     55 
     56   // Ensure partial frames are rounded down correctly.  The equation below
     57   // calculates a frame count with a fractional part < 0.5.
     58   const int small_remainder =
     59       base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate;
     60   EXPECT_EQ(kSampleRate - 1,
     61             discard_helper.TimeDeltaToFrames(
     62                 base::TimeDelta::FromMicroseconds(small_remainder)));
     63 
     64   // Ditto, but rounded up using a fractional part > 0.5.
     65   const int large_remainder =
     66       base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate;
     67   EXPECT_EQ(kSampleRate,
     68             discard_helper.TimeDeltaToFrames(
     69                 base::TimeDelta::FromMicroseconds(large_remainder)));
     70 }
     71 
     72 TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
     73   AudioDiscardHelper discard_helper(kSampleRate, 0);
     74   ASSERT_FALSE(discard_helper.initialized());
     75 
     76   const base::TimeDelta kTimestamp = base::TimeDelta();
     77 
     78   // Use an estimated duration which doesn't match the number of decoded frames
     79   // to ensure the helper is correctly setting durations based on output frames.
     80   const base::TimeDelta kEstimatedDuration =
     81       base::TimeDelta::FromMilliseconds(9);
     82   const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10);
     83   const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration);
     84 
     85   scoped_refptr<DecoderBuffer> encoded_buffer =
     86       CreateEncodedBuffer(kTimestamp, kEstimatedDuration);
     87   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
     88 
     89   // Verify the basic case where nothing is discarded.
     90   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
     91   ASSERT_TRUE(discard_helper.initialized());
     92   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
     93   EXPECT_EQ(kActualDuration, decoded_buffer->duration());
     94   EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
     95 
     96   // Verify a Reset() takes us back to an uninitialized state.
     97   discard_helper.Reset(0);
     98   ASSERT_FALSE(discard_helper.initialized());
     99 
    100   // Verify a NULL output buffer returns false.
    101   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
    102 }
    103 
    104 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) {
    105   AudioDiscardHelper discard_helper(kSampleRate, 0);
    106   ASSERT_FALSE(discard_helper.initialized());
    107 
    108   const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1);
    109   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    110   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    111 
    112   scoped_refptr<DecoderBuffer> encoded_buffer =
    113       CreateEncodedBuffer(kTimestamp, kDuration);
    114   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    115 
    116   // Verify the basic case where nothing is discarded.
    117   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    118   ASSERT_TRUE(discard_helper.initialized());
    119   EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp());
    120   EXPECT_EQ(kDuration, decoded_buffer->duration());
    121   EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
    122 }
    123 
    124 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
    125   AudioDiscardHelper discard_helper(kSampleRate, 0);
    126   ASSERT_FALSE(discard_helper.initialized());
    127 
    128   const base::TimeDelta kTimestamp = base::TimeDelta();
    129   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    130   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    131 
    132   // Tell the helper we want to discard half of the initial frames.
    133   const int kDiscardFrames = kTestFrames / 2;
    134   discard_helper.Reset(kDiscardFrames);
    135 
    136   scoped_refptr<DecoderBuffer> encoded_buffer =
    137       CreateEncodedBuffer(kTimestamp, kDuration);
    138   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    139 
    140   // Verify half the frames end up discarded.
    141   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    142   ASSERT_TRUE(discard_helper.initialized());
    143   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    144   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    145   EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
    146   ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
    147                   ExtractDecodedData(decoded_buffer, 0));
    148 }
    149 
    150 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
    151   AudioDiscardHelper discard_helper(kSampleRate, 0);
    152   ASSERT_FALSE(discard_helper.initialized());
    153 
    154   const base::TimeDelta kTimestamp = base::TimeDelta();
    155   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    156   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    157 
    158   // Tell the helper we want to discard 1.5 buffers worth of frames.
    159   discard_helper.Reset(kTestFrames * 1.5);
    160 
    161   scoped_refptr<DecoderBuffer> encoded_buffer =
    162       CreateEncodedBuffer(kTimestamp, kDuration);
    163   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    164 
    165   // The first call should fail since no output buffer remains.
    166   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    167   ASSERT_TRUE(discard_helper.initialized());
    168 
    169   // Generate another set of buffers and expect half the output frames.
    170   encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
    171   decoded_buffer = CreateDecodedBuffer(kTestFrames);
    172   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    173 
    174   // The timestamp should match that of the initial buffer.
    175   const int kDiscardFrames = kTestFrames / 2;
    176   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    177   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    178   EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
    179   ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
    180                   ExtractDecodedData(decoded_buffer, 0));
    181 }
    182 
    183 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
    184   AudioDiscardHelper discard_helper(kSampleRate, 0);
    185   ASSERT_FALSE(discard_helper.initialized());
    186 
    187   const base::TimeDelta kTimestamp = base::TimeDelta();
    188   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    189   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    190 
    191   scoped_refptr<DecoderBuffer> encoded_buffer =
    192       CreateEncodedBuffer(kTimestamp, kDuration);
    193   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    194 
    195   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    196   ASSERT_TRUE(discard_helper.initialized());
    197   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    198   EXPECT_EQ(kDuration, decoded_buffer->duration());
    199   EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
    200 
    201   // Process the same input buffer again to ensure input timestamps which go
    202   // backwards in time are not errors.
    203   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    204   EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp());
    205   EXPECT_EQ(kDuration, decoded_buffer->duration());
    206   EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
    207 }
    208 
    209 TEST(AudioDiscardHelperTest, DiscardEndPadding) {
    210   AudioDiscardHelper discard_helper(kSampleRate, 0);
    211   ASSERT_FALSE(discard_helper.initialized());
    212 
    213   const base::TimeDelta kTimestamp = base::TimeDelta();
    214   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    215   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    216 
    217   scoped_refptr<DecoderBuffer> encoded_buffer =
    218       CreateEncodedBuffer(kTimestamp, kDuration);
    219   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    220 
    221   // Set a discard padding equivalent to half the buffer.
    222   encoded_buffer->set_discard_padding(
    223       std::make_pair(base::TimeDelta(), kDuration / 2));
    224 
    225   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    226   ASSERT_TRUE(discard_helper.initialized());
    227   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    228   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    229   EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
    230 }
    231 
    232 TEST(AudioDiscardHelperTest, BadDiscardEndPadding) {
    233   AudioDiscardHelper discard_helper(kSampleRate, 0);
    234   ASSERT_FALSE(discard_helper.initialized());
    235 
    236   const base::TimeDelta kTimestamp = base::TimeDelta();
    237   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    238   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    239 
    240   scoped_refptr<DecoderBuffer> encoded_buffer =
    241       CreateEncodedBuffer(kTimestamp, kDuration);
    242   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    243 
    244   // Set a discard padding equivalent to double the buffer size.
    245   encoded_buffer->set_discard_padding(
    246       std::make_pair(base::TimeDelta(), kDuration * 2));
    247 
    248   // Verify the end discard padding is rejected.
    249   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    250   ASSERT_TRUE(discard_helper.initialized());
    251 }
    252 
    253 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) {
    254   AudioDiscardHelper discard_helper(kSampleRate, 0);
    255   ASSERT_FALSE(discard_helper.initialized());
    256 
    257   const base::TimeDelta kTimestamp = base::TimeDelta();
    258   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    259   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    260 
    261   scoped_refptr<DecoderBuffer> encoded_buffer =
    262       CreateEncodedBuffer(kTimestamp, kDuration);
    263   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    264 
    265   // Set a discard padding equivalent to a quarter of the buffer.
    266   encoded_buffer->set_discard_padding(
    267       std::make_pair(base::TimeDelta(), kDuration / 4));
    268 
    269   // Set an initial discard of a quarter of the buffer.
    270   const int kDiscardFrames = kTestFrames / 4;
    271   discard_helper.Reset(kDiscardFrames);
    272 
    273   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    274   ASSERT_TRUE(discard_helper.initialized());
    275   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    276   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    277   EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
    278   ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
    279                   ExtractDecodedData(decoded_buffer, 0));
    280 }
    281 
    282 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
    283   AudioDiscardHelper discard_helper(kSampleRate, 0);
    284   ASSERT_FALSE(discard_helper.initialized());
    285 
    286   const base::TimeDelta kTimestamp = base::TimeDelta();
    287   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    288   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    289 
    290   scoped_refptr<DecoderBuffer> encoded_buffer =
    291       CreateEncodedBuffer(kTimestamp, kDuration);
    292   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    293 
    294   // Set all the discard values to be different to ensure each is properly used.
    295   const int kDiscardFrames = kTestFrames / 4;
    296   encoded_buffer->set_discard_padding(
    297       std::make_pair(kDuration / 8, kDuration / 16));
    298   discard_helper.Reset(kDiscardFrames);
    299 
    300   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    301   ASSERT_TRUE(discard_helper.initialized());
    302   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    303   EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
    304             decoded_buffer->duration());
    305   EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
    306             decoded_buffer->frame_count());
    307 }
    308 
    309 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndDecoderDelay) {
    310   // Use a decoder delay of 5ms.
    311   const int kDecoderDelay = kSampleRate / 100 / 2;
    312   AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay);
    313   ASSERT_FALSE(discard_helper.initialized());
    314   discard_helper.Reset(kDecoderDelay);
    315 
    316   const base::TimeDelta kTimestamp = base::TimeDelta();
    317   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    318   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    319 
    320   scoped_refptr<DecoderBuffer> encoded_buffer =
    321       CreateEncodedBuffer(kTimestamp, kDuration);
    322   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    323 
    324   // Set a discard padding equivalent to half of the buffer.
    325   encoded_buffer->set_discard_padding(
    326       std::make_pair(kDuration / 2, base::TimeDelta()));
    327 
    328   // All of the first buffer should be discarded, half from the inital delay and
    329   // another half from the front discard padding.
    330   //
    331   //    Encoded                   Discard Delay
    332   //   |--------|     |---------|     |----|
    333   //   |AAAAAAAA| --> |....|AAAA| --> |AAAA| -------> NULL
    334   //   |--------|     |---------|     |----|
    335   //                    Decoded               Discard Front Padding
    336   //
    337   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    338   ASSERT_TRUE(discard_helper.initialized());
    339 
    340   // Processing another buffer that has front discard set to half the buffer's
    341   // duration should discard the back half of the buffer since kDecoderDelay is
    342   // half a buffer.  The end padding should not be discarded until another
    343   // buffer is processed.  kDuration / 4 is chosen for the end discard since it
    344   // will force the end discard to start after position zero within the next
    345   // decoded buffer.
    346   //
    347   //    Encoded                    Discard Front Padding (from B)
    348   //   |--------|     |---------|             |----|
    349   //   |BBBBBBBB| --> |AAAA|BBBB| ----------> |AAAA|
    350   //   |--------|     |---------|             |----|
    351   //                    Decoded
    352   //           (includes carryover from A)
    353   //
    354   encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration);
    355   encoded_buffer->set_discard_padding(
    356       std::make_pair(kDuration / 2, kDuration / 4));
    357   decoded_buffer = CreateDecodedBuffer(kTestFrames);
    358   ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
    359   ASSERT_NEAR(kDecoderDelay * kDataStep,
    360               ExtractDecodedData(decoded_buffer, kDecoderDelay),
    361               kDataStep / 1000);
    362   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    363   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    364   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    365   EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
    366 
    367   // Verify it was actually the latter half of the buffer that was removed.
    368   ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
    369 
    370   // Verify the end discard padding is carried over to the next buffer.  Use
    371   // kDuration / 2 for the end discard padding so that the next buffer has its
    372   // start entirely discarded.
    373   //
    374   //    Encoded                      Discard End Padding (from B)
    375   //   |--------|     |---------|             |-------|
    376   //   |CCCCCCCC| --> |BBBB|CCCC| ----------> |BB|CCCC|
    377   //   |--------|     |---------|             |-------|
    378   //                    Decoded
    379   //           (includes carryover from B)
    380   //
    381   encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration);
    382   encoded_buffer->set_discard_padding(
    383       std::make_pair(base::TimeDelta(), kDuration / 2));
    384   decoded_buffer = CreateDecodedBuffer(kTestFrames);
    385   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    386   EXPECT_EQ(kTimestamp + kDuration / 2, decoded_buffer->timestamp());
    387   EXPECT_EQ(3 * kDuration / 4, decoded_buffer->duration());
    388   EXPECT_EQ(3 * kTestFrames / 4, decoded_buffer->frame_count());
    389 
    390   // Verify it was actually the second quarter of the buffer that was removed.
    391   const int kDiscardFrames = kTestFrames / 4;
    392   ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
    393   ASSERT_FLOAT_EQ(
    394       kDiscardFrames * 2 * kDataStep,
    395       ExtractDecodedData(decoded_buffer, kDecoderDelay - kDiscardFrames));
    396 
    397   // One last test to ensure carryover discard from the start works.
    398   //
    399   //    Encoded                      Discard End Padding (from C)
    400   //   |--------|     |---------|             |----|
    401   //   |DDDDDDDD| --> |CCCC|DDDD| ----------> |DDDD|
    402   //   |--------|     |---------|             |----|
    403   //                    Decoded
    404   //           (includes carryover from C)
    405   //
    406   encoded_buffer->set_timestamp(encoded_buffer->timestamp() + kDuration);
    407   encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());
    408   decoded_buffer = CreateDecodedBuffer(kTestFrames);
    409   ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
    410   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    411   EXPECT_EQ(kTimestamp + kDuration / 2 + 3 * kDuration / 4,
    412             decoded_buffer->timestamp());
    413   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    414   EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
    415   ASSERT_FLOAT_EQ(kTestFrames / 2 * kDataStep,
    416                   ExtractDecodedData(decoded_buffer, 0));
    417 }
    418 
    419 TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) {
    420   AudioDiscardHelper discard_helper(kSampleRate, 0);
    421   ASSERT_FALSE(discard_helper.initialized());
    422 
    423   const base::TimeDelta kTimestamp = base::TimeDelta();
    424   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    425   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    426 
    427   scoped_refptr<DecoderBuffer> encoded_buffer =
    428       CreateEncodedBuffer(kTimestamp, kDuration);
    429 
    430   // Set all the discard values to be different to ensure each is properly used.
    431   const int kDiscardFrames = kTestFrames / 4;
    432   encoded_buffer->set_discard_padding(
    433       std::make_pair(kDuration / 8, kDuration / 16));
    434   discard_helper.Reset(kDiscardFrames);
    435 
    436   // Verify nothing is output for the first buffer, yet initialized is true.
    437   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
    438   ASSERT_TRUE(discard_helper.initialized());
    439 
    440   // Create an encoded buffer with no discard padding.
    441   encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
    442   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    443 
    444   // Verify that when the decoded buffer is consumed, the discards from the
    445   // previous encoded buffer are applied.
    446   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    447   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    448   EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
    449             decoded_buffer->duration());
    450   EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
    451             decoded_buffer->frame_count());
    452 }
    453 
    454 TEST(AudioDiscardHelperTest, CompleteDiscard) {
    455   AudioDiscardHelper discard_helper(kSampleRate, 0);
    456   ASSERT_FALSE(discard_helper.initialized());
    457 
    458   const base::TimeDelta kTimestamp = base::TimeDelta();
    459   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    460   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    461   discard_helper.Reset(0);
    462 
    463   scoped_refptr<DecoderBuffer> encoded_buffer =
    464       CreateEncodedBuffer(kTimestamp, kDuration);
    465   encoded_buffer->set_discard_padding(
    466       std::make_pair(kInfiniteDuration(), base::TimeDelta()));
    467   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    468 
    469   // Verify all of the first buffer is discarded.
    470   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    471   ASSERT_TRUE(discard_helper.initialized());
    472   encoded_buffer->set_timestamp(kTimestamp + kDuration);
    473   encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());
    474 
    475   // Verify a second buffer goes through untouched.
    476   decoded_buffer = CreateDecodedBuffer(kTestFrames / 2);
    477   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    478   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    479   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    480   EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
    481   ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
    482 }
    483 
    484 TEST(AudioDiscardHelperTest, CompleteDiscardWithDelayedDiscard) {
    485   AudioDiscardHelper discard_helper(kSampleRate, 0);
    486   ASSERT_FALSE(discard_helper.initialized());
    487 
    488   const base::TimeDelta kTimestamp = base::TimeDelta();
    489   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    490   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    491   discard_helper.Reset(0);
    492 
    493   scoped_refptr<DecoderBuffer> encoded_buffer =
    494       CreateEncodedBuffer(kTimestamp, kDuration);
    495   encoded_buffer->set_discard_padding(
    496       std::make_pair(kInfiniteDuration(), base::TimeDelta()));
    497   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    498 
    499   // Setup a delayed discard.
    500   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
    501   ASSERT_TRUE(discard_helper.initialized());
    502 
    503   // Verify the first output buffer is dropped.
    504   encoded_buffer->set_timestamp(kTimestamp + kDuration);
    505   encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());
    506   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    507 
    508   // Verify the second buffer goes through untouched.
    509   encoded_buffer->set_timestamp(kTimestamp + 2 * kDuration);
    510   decoded_buffer = CreateDecodedBuffer(kTestFrames / 2);
    511   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    512   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    513   EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
    514   EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
    515   ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
    516 }
    517 
    518 TEST(AudioDiscardHelperTest, CompleteDiscardWithInitialDiscardDecoderDelay) {
    519   // Use a decoder delay of 5ms.
    520   const int kDecoderDelay = kSampleRate / 100 / 2;
    521   AudioDiscardHelper discard_helper(kSampleRate, kDecoderDelay);
    522   ASSERT_FALSE(discard_helper.initialized());
    523   discard_helper.Reset(kDecoderDelay);
    524 
    525   const base::TimeDelta kTimestamp = base::TimeDelta();
    526   const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
    527   const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
    528 
    529   scoped_refptr<DecoderBuffer> encoded_buffer =
    530       CreateEncodedBuffer(kTimestamp, kDuration);
    531   encoded_buffer->set_discard_padding(
    532       std::make_pair(kInfiniteDuration(), base::TimeDelta()));
    533   scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
    534 
    535   // Verify all of the first buffer is discarded.
    536   ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    537   ASSERT_TRUE(discard_helper.initialized());
    538   encoded_buffer->set_timestamp(kTimestamp + kDuration);
    539   encoded_buffer->set_discard_padding(DecoderBuffer::DiscardPadding());
    540 
    541   // Verify 5ms off the front of the second buffer is discarded.
    542   decoded_buffer = CreateDecodedBuffer(kTestFrames * 2);
    543   ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
    544   EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
    545   EXPECT_EQ(kDuration * 2 - kDuration / 2, decoded_buffer->duration());
    546   EXPECT_EQ(kTestFrames * 2 - kDecoderDelay, decoded_buffer->frame_count());
    547   ASSERT_FLOAT_EQ(kDecoderDelay * kDataStep,
    548                   ExtractDecodedData(decoded_buffer, 0));
    549 }
    550 
    551 }  // namespace media
    552