[M120 Migration][hbbtv] Audio tracks count notification
[platform/framework/web/chromium-efl.git] / media / filters / audio_renderer_algorithm_unittest.cc
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // The format of these tests are to enqueue a known amount of data and then
6 // request the exact amount we expect in order to dequeue the known amount of
7 // data.  This ensures that for any rate we are consuming input data at the
8 // correct rate.  We always pass in a very large destination buffer with the
9 // expectation that FillBuffer() will fill as much as it can but no more.
10
11 #include "media/filters/audio_renderer_algorithm.h"
12
13 #include <stddef.h>
14 #include <stdint.h>
15
16 #include <algorithm>  // For std::min().
17 #include <cmath>
18 #include <memory>
19 #include <vector>
20
21 #include "base/functional/bind.h"
22 #include "base/functional/callback.h"
23 #include "media/base/audio_buffer.h"
24 #include "media/base/audio_bus.h"
25 #include "media/base/audio_timestamp_helper.h"
26 #include "media/base/channel_layout.h"
27 #include "media/base/media_util.h"
28 #include "media/base/test_helpers.h"
29 #include "media/base/timestamp_constants.h"
30 #include "media/filters/wsola_internals.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32
33 namespace media {
34
35 const int kFrameSize = 250;
36 const int kSamplesPerSecond = 3000;
37 const int kOutputDurationInSec = 10;
38
39 static void FillWithSquarePulseTrain(
40     int half_pulse_width, int offset, int num_samples, float* data) {
41   ASSERT_GE(offset, 0);
42   ASSERT_LE(offset, num_samples);
43
44   // Fill backward from |offset| - 1 toward zero, starting with -1, alternating
45   // between -1 and 1 every |pulse_width| samples.
46   float pulse = -1.0f;
47   for (int n = offset - 1, k = 0; n >= 0; --n, ++k) {
48     if (k >= half_pulse_width) {
49       pulse = -pulse;
50       k = 0;
51     }
52     data[n] = pulse;
53   }
54
55   // Fill forward from |offset| towards the end, starting with 1, alternating
56   // between 1 and -1 every |pulse_width| samples.
57   pulse = 1.0f;
58   for (int n = offset, k = 0; n < num_samples; ++n, ++k) {
59     if (k >= half_pulse_width) {
60       pulse = -pulse;
61       k = 0;
62     }
63     data[n] = pulse;
64   }
65 }
66
67 static void FillWithSquarePulseTrain(
68     int half_pulse_width, int offset, int channel, AudioBus* audio_bus) {
69   FillWithSquarePulseTrain(half_pulse_width, offset, audio_bus->frames(),
70                            audio_bus->channel(channel));
71 }
72
73 class AudioRendererAlgorithmTest : public testing::Test {
74  public:
75   AudioRendererAlgorithmTest()
76       : algorithm_(&media_log_),
77         frames_enqueued_(0),
78         channels_(0),
79         channel_layout_(CHANNEL_LAYOUT_NONE),
80         sample_format_(kUnknownSampleFormat),
81         samples_per_second_(0),
82         bytes_per_sample_(0) {}
83
84   ~AudioRendererAlgorithmTest() override = default;
85
86   void Initialize() {
87     Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, kSamplesPerSecond,
88                kSamplesPerSecond / 10);
89   }
90
91   void Initialize(ChannelLayout channel_layout,
92                   SampleFormat sample_format,
93                   int samples_per_second,
94                   int frames_per_buffer) {
95     Initialize(
96         channel_layout, sample_format, samples_per_second, frames_per_buffer,
97         std::vector<bool>(ChannelLayoutToChannelCount(channel_layout), true));
98   }
99
100   void Initialize(ChannelLayout channel_layout,
101                   SampleFormat sample_format,
102                   int samples_per_second,
103                   int frames_per_buffer,
104                   std::vector<bool> channel_mask) {
105     channels_ = ChannelLayoutToChannelCount(channel_layout);
106     samples_per_second_ = samples_per_second;
107     channel_layout_ = channel_layout;
108     sample_format_ = sample_format;
109     bytes_per_sample_ = SampleFormatToBytesPerChannel(sample_format);
110
111     media::AudioParameters::Format format =
112         media::AudioParameters::AUDIO_PCM_LINEAR;
113     if (sample_format == kSampleFormatAc3)
114       format = media::AudioParameters::AUDIO_BITSTREAM_AC3;
115     else if (sample_format == kSampleFormatEac3)
116       format = media::AudioParameters::AUDIO_BITSTREAM_EAC3;
117     else if (sample_format == kSampleFormatDts)
118       format = media::AudioParameters::AUDIO_BITSTREAM_DTS;
119
120     AudioParameters params(format,
121                            ChannelLayoutConfig(channel_layout, channels_),
122                            samples_per_second, frames_per_buffer);
123     is_bitstream_format_ = params.IsBitstreamFormat();
124     bool is_encrypted = false;
125     algorithm_.Initialize(params, is_encrypted);
126     algorithm_.SetChannelMask(std::move(channel_mask));
127     FillAlgorithmQueueUntilFull();
128   }
129
130   base::TimeDelta BufferedTime() {
131     return AudioTimestampHelper::FramesToTime(algorithm_.BufferedFrames(),
132                                               samples_per_second_);
133   }
134
135   scoped_refptr<AudioBuffer> MakeBuffer(int frame_size) {
136     // The value of the data is meaningless; we just want non-zero data to
137     // differentiate it from muted data.
138     scoped_refptr<AudioBuffer> buffer;
139     switch (sample_format_) {
140       case kSampleFormatAc3:
141       case kSampleFormatEac3:
142         buffer = MakeBitstreamAudioBuffer(
143             sample_format_, channel_layout_,
144             ChannelLayoutToChannelCount(channel_layout_), samples_per_second_,
145             1, 1, frame_size, kFrameSize, kNoTimestamp);
146         break;
147       case kSampleFormatU8:
148         buffer = MakeAudioBuffer<uint8_t>(
149             sample_format_, channel_layout_,
150             ChannelLayoutToChannelCount(channel_layout_), samples_per_second_,
151             1, 1, frame_size, kNoTimestamp);
152         break;
153       case kSampleFormatS16:
154         buffer = MakeAudioBuffer<int16_t>(
155             sample_format_, channel_layout_,
156             ChannelLayoutToChannelCount(channel_layout_), samples_per_second_,
157             1, 1, frame_size, kNoTimestamp);
158         break;
159       case kSampleFormatS32:
160         buffer = MakeAudioBuffer<int32_t>(
161             sample_format_, channel_layout_,
162             ChannelLayoutToChannelCount(channel_layout_), samples_per_second_,
163             1, 1, frame_size, kNoTimestamp);
164         break;
165       case kSampleFormatDts:
166       case kSampleFormatDtse:
167       case kSampleFormatDtsxP2:
168         buffer = MakeBitstreamAudioBuffer(
169             sample_format_, channel_layout_,
170             ChannelLayoutToChannelCount(channel_layout_), samples_per_second_,
171             1, 1, frame_size, kFrameSize, kNoTimestamp);
172         break;
173       default:
174         NOTREACHED() << "Unrecognized format " << sample_format_;
175     }
176     return buffer;
177   }
178
179   void FillAlgorithmQueueUntilAdequate() {
180     // Note: "adequate" may be <= "full" depending on current latency hint.
181     EXPECT_FALSE(algorithm_.IsQueueFull());
182     EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
183     while (!algorithm_.IsQueueAdequateForPlayback()) {
184       // "Adequate" tests may be sensitive to over-filling. Only add one buffer
185       // at a time to trigger "adequate" threshold precisely.
186       algorithm_.EnqueueBuffer(MakeBuffer(1));
187     }
188   }
189
190   void FillAlgorithmQueueUntilFull() {
191     while (!algorithm_.IsQueueFull()) {
192       algorithm_.EnqueueBuffer(MakeBuffer(kFrameSize));
193       frames_enqueued_ += kFrameSize;
194     }
195   }
196
197   bool VerifyAudioData(AudioBus* bus, int offset, int frames, float value) {
198     for (int ch = 0; ch < bus->channels(); ++ch) {
199       for (int i = offset; i < offset + frames; ++i) {
200         if (bus->channel(ch)[i] != value)
201           return false;
202       }
203     }
204     return true;
205   }
206
207   bool AudioDataIsMuted(AudioBus* audio_data, int frames_written, int offset) {
208     return VerifyAudioData(audio_data, offset, frames_written, 0);
209   }
210
211   int ComputeConsumedFrames(int initial_frames_enqueued,
212                             int initial_frames_buffered) {
213     int frame_delta = frames_enqueued_ - initial_frames_enqueued;
214     int buffered_delta = algorithm_.BufferedFrames() - initial_frames_buffered;
215     int consumed = frame_delta - buffered_delta;
216
217     CHECK_GE(consumed, 0);
218     return consumed;
219   }
220
221   void TestPlaybackRate(double playback_rate) {
222     const int kDefaultBufferSize = algorithm_.samples_per_second() / 100;
223     const int kDefaultFramesRequested = kOutputDurationInSec *
224         algorithm_.samples_per_second();
225
226     TestPlaybackRate(playback_rate, kDefaultBufferSize, kDefaultFramesRequested,
227                      0);
228   }
229
230   void TestPlaybackRate(double playback_rate,
231                         int buffer_size_in_frames,
232                         int total_frames_requested,
233                         int dest_offset) {
234     int initial_frames_enqueued = frames_enqueued_;
235
236     std::unique_ptr<AudioBus> bus =
237         AudioBus::Create(channels_, buffer_size_in_frames);
238     bus->ZeroFrames(dest_offset);
239
240     if (playback_rate == 0.0) {
241       int frames_written = algorithm_.FillBuffer(
242           bus.get(), 0, buffer_size_in_frames, playback_rate);
243       EXPECT_EQ(0, frames_written);
244       return;
245     }
246
247     if (!is_bitstream_format_) {
248       // When we switch playback rates (specifically from non-1.0 to 1.0), the
249       // BufferedFrames() can change since some internal buffers are cleared.
250       // Fill 0 frames to make sure the BufferedFrames() is correct for the
251       // |playback_rate|.
252       algorithm_.FillBuffer(bus.get(), 0, 0, playback_rate);
253     }
254     int initial_frames_buffered = algorithm_.BufferedFrames();
255
256     int frames_remaining = total_frames_requested;
257     bool first_fill_buffer = true;
258     while (frames_remaining > 0) {
259       int frames_requested =
260           std::min(buffer_size_in_frames - dest_offset, frames_remaining);
261       int frames_written = algorithm_.FillBuffer(
262           bus.get(), dest_offset, frames_requested, playback_rate);
263       ASSERT_GT(frames_written, 0) << "Requested: " << frames_requested
264                                    << ", playing at " << playback_rate;
265
266       // Do not check data if it is first pull out and only one frame written.
267       // The very first frame out of WSOLA is always zero because of
268       // overlap-and-add window, which is zero for the first sample. Therefore,
269       // if at very first buffer-fill only one frame is written, that is zero
270       // which might cause exception in CheckFakeData().
271       if (!first_fill_buffer || frames_written > 1)
272         ASSERT_FALSE(AudioDataIsMuted(bus.get(), frames_written, dest_offset));
273       first_fill_buffer = false;
274       frames_remaining -= frames_written;
275
276       FillAlgorithmQueueUntilFull();
277     }
278
279     EXPECT_EQ(algorithm_.BufferedFrames() * channels_ * sizeof(float),
280               static_cast<size_t>(algorithm_.GetMemoryUsage()));
281
282     int frames_consumed =
283         ComputeConsumedFrames(initial_frames_enqueued, initial_frames_buffered);
284
285     // If playing back at normal speed, we should always get back the same
286     // number of bytes requested.
287     if (playback_rate == 1.0) {
288       EXPECT_EQ(total_frames_requested, frames_consumed);
289       return;
290     }
291
292     // Otherwise, allow |kMaxAcceptableDelta| difference between the target and
293     // actual playback rate.
294     // When |kSamplesPerSecond| and |total_frames_requested| are reasonably
295     // large, one can expect less than a 1% difference in most cases. In our
296     // current implementation, sped up playback is less accurate than slowed
297     // down playback, and for playback_rate > 1, playback rate generally gets
298     // less and less accurate the farther it drifts from 1 (though this is
299     // nonlinear).
300     double actual_playback_rate =
301         1.0 * frames_consumed / total_frames_requested;
302     EXPECT_NEAR(playback_rate, actual_playback_rate, playback_rate / 100.0);
303   }
304
305   void TestResamplingWithUnderflow(double playback_rate, bool end_of_stream) {
306     // We are only testing the behavior of the resampling case.
307     algorithm_.SetPreservesPitch(false);
308
309     if (end_of_stream) {
310       algorithm_.MarkEndOfStream();
311     } else {
312       algorithm_.FlushBuffers();
313     }
314
315     const int buffer_size_in_frames = algorithm_.samples_per_second() / 10;
316     const int initial_frames_enqueued = frames_enqueued_;
317
318     std::unique_ptr<AudioBus> bus =
319         AudioBus::Create(channels_, buffer_size_in_frames);
320
321     FillAlgorithmQueueUntilFull();
322
323     int frames_written;
324     int total_frames_written = 0;
325     do {
326       frames_written = algorithm_.FillBuffer(
327           bus.get(), 0, buffer_size_in_frames, playback_rate);
328
329       total_frames_written += frames_written;
330     } while (frames_written && algorithm_.BufferedFrames() > 0);
331
332     int input_frames_enqueued = frames_enqueued_ - initial_frames_enqueued;
333
334     int ouput_frames_available =
335         static_cast<int>(input_frames_enqueued / playback_rate + 0.5);
336
337     if (end_of_stream) {
338       // If we marked the EOS, all data should we played out, possibly with some
339       // extra silence.
340       EXPECT_GE(total_frames_written, ouput_frames_available);
341     } else {
342       // If we don't mark the EOS, we expect to have lost some frames because
343       // we don't partially handle requests.
344       EXPECT_LE(total_frames_written, ouput_frames_available);
345     }
346   }
347
348   void WsolaTest(double playback_rate) {
349     const int kSampleRateHz = 48000;
350     constexpr ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
351     const int kNumFrames = kSampleRateHz / 100;  // 10 milliseconds.
352
353     channels_ = ChannelLayoutToChannelCount(kChannelLayout);
354     AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
355                            ChannelLayoutConfig::FromLayout<kChannelLayout>(),
356                            kSampleRateHz, kNumFrames);
357     bool is_encrypted = false;
358     algorithm_.Initialize(params, is_encrypted);
359
360     // A pulse is 6 milliseconds (even number of samples).
361     const int kPulseWidthSamples = 6 * kSampleRateHz / 1000;
362     const int kHalfPulseWidthSamples = kPulseWidthSamples / 2;
363
364     // For the ease of implementation get 1 frame every call to FillBuffer().
365     std::unique_ptr<AudioBus> output = AudioBus::Create(channels_, 1);
366
367     // Input buffer to inject pulses.
368     scoped_refptr<AudioBuffer> input =
369         AudioBuffer::CreateBuffer(kSampleFormatPlanarF32,
370                                   kChannelLayout,
371                                   channels_,
372                                   kSampleRateHz,
373                                   kPulseWidthSamples);
374
375     const std::vector<uint8_t*>& channel_data = input->channel_data();
376
377     // Fill |input| channels.
378     FillWithSquarePulseTrain(kHalfPulseWidthSamples, 0, kPulseWidthSamples,
379                              reinterpret_cast<float*>(channel_data[0]));
380     FillWithSquarePulseTrain(kHalfPulseWidthSamples, kHalfPulseWidthSamples,
381                              kPulseWidthSamples,
382                              reinterpret_cast<float*>(channel_data[1]));
383
384     // A buffer for the output until a complete pulse is created. Then
385     // reference pulse is compared with this buffer.
386     std::unique_ptr<AudioBus> pulse_buffer =
387         AudioBus::Create(channels_, kPulseWidthSamples);
388
389     const float kTolerance = 0.000001f;
390     // Equivalent of 4 seconds.
391     const int kNumRequestedPulses = kSampleRateHz * 4 / kPulseWidthSamples;
392     for (int n = 0; n < kNumRequestedPulses; ++n) {
393       int num_buffered_frames = 0;
394       while (num_buffered_frames < kPulseWidthSamples) {
395         int num_samples =
396             algorithm_.FillBuffer(output.get(), 0, 1, playback_rate);
397         ASSERT_LE(num_samples, 1);
398         if (num_samples > 0) {
399           output->CopyPartialFramesTo(0, num_samples, num_buffered_frames,
400                                       pulse_buffer.get());
401           num_buffered_frames++;
402         } else {
403           algorithm_.EnqueueBuffer(input);
404         }
405       }
406
407       // Pulses in the first half of WSOLA AOL frame are not constructed
408       // perfectly. Do not check them.
409       if (n > 3) {
410          for (int m = 0; m < channels_; ++m) {
411           const float* pulse_ch = pulse_buffer->channel(m);
412
413           // Because of overlap-and-add we might have round off error.
414           for (int k = 0; k < kPulseWidthSamples; ++k) {
415             ASSERT_NEAR(reinterpret_cast<float*>(channel_data[m])[k],
416                         pulse_ch[k], kTolerance) << " loop " << n
417                                 << " channel/sample " << m << "/" << k;
418           }
419         }
420       }
421
422       // Zero out the buffer to be sure the next comparison is relevant.
423       pulse_buffer->Zero();
424     }
425   }
426
427  protected:
428   AudioRendererAlgorithm algorithm_;
429   NullMediaLog media_log_;
430   int frames_enqueued_;
431   int channels_;
432   ChannelLayout channel_layout_;
433   SampleFormat sample_format_;
434   int samples_per_second_;
435   int bytes_per_sample_;
436   bool is_bitstream_format_;
437 };
438
439 TEST_F(AudioRendererAlgorithmTest, InitializeWithLargeParameters) {
440   const int kBufferSize = 0.5 * kSamplesPerSecond;
441   Initialize(CHANNEL_LAYOUT_MONO, kSampleFormatU8, kSamplesPerSecond,
442              kBufferSize);
443   EXPECT_LT(kBufferSize, algorithm_.QueueCapacity());
444   algorithm_.FlushBuffers();
445   EXPECT_LT(kBufferSize, algorithm_.QueueCapacity());
446 }
447
448 TEST_F(AudioRendererAlgorithmTest, FillBuffer_Bitstream) {
449   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatEac3, kSamplesPerSecond,
450              kSamplesPerSecond / 100);
451   TestPlaybackRate(1.0, kFrameSize, 16 * kFrameSize, /* dest_offset */ 0);
452 }
453
454 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NormalRate) {
455   Initialize();
456   TestPlaybackRate(1.0);
457 }
458
459 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalFasterRate) {
460   Initialize();
461   TestPlaybackRate(1.0001);
462 }
463
464 TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalSlowerRate) {
465   Initialize();
466   TestPlaybackRate(0.9999);
467 }
468
469 // This test verifies that the resampling based time stretch algorithms works.
470 // The range of playback rates in which we use resampling is [0.95, 1.06].
471 TEST_F(AudioRendererAlgorithmTest, FillBuffer_ResamplingRates) {
472   Initialize();
473   // WSOLA.
474   TestPlaybackRate(0.50);
475   TestPlaybackRate(0.95);
476   TestPlaybackRate(1.00);
477   TestPlaybackRate(1.05);
478   TestPlaybackRate(2.00);
479
480   // Resampling.
481   algorithm_.SetPreservesPitch(false);
482   TestPlaybackRate(0.50);
483   TestPlaybackRate(0.95);
484   TestPlaybackRate(1.00);
485   TestPlaybackRate(1.05);
486   TestPlaybackRate(2.00);
487 }
488
489 TEST_F(AudioRendererAlgorithmTest, FillBuffer_WithOffset) {
490   Initialize();
491   const int kBufferSize = algorithm_.samples_per_second() / 10;
492   const int kOffset = kBufferSize / 10;
493   const int kFramesRequested =
494       kOutputDurationInSec * algorithm_.samples_per_second();
495
496   // No time-strech.
497   TestPlaybackRate(1.00, kBufferSize, kFramesRequested, kOffset);
498
499   // Resampling based time-strech.
500   TestPlaybackRate(1.05, kBufferSize, kFramesRequested, kOffset);
501
502   // WSOLA based time-strech.
503   TestPlaybackRate(1.25, kBufferSize, kFramesRequested, kOffset);
504 }
505
506 TEST_F(AudioRendererAlgorithmTest, FillBuffer_UnderFlow) {
507   Initialize();
508   TestResamplingWithUnderflow(0.75, true);
509   TestResamplingWithUnderflow(0.75, false);
510   TestResamplingWithUnderflow(1.25, true);
511   TestResamplingWithUnderflow(1.25, false);
512 }
513
514 TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAQuarterRate) {
515   Initialize();
516   TestPlaybackRate(1.25);
517 }
518
519 TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAHalfRate) {
520   Initialize();
521   TestPlaybackRate(1.5);
522 }
523
524 TEST_F(AudioRendererAlgorithmTest, FillBuffer_DoubleRate) {
525   Initialize();
526   TestPlaybackRate(2.0);
527 }
528
529 TEST_F(AudioRendererAlgorithmTest, FillBuffer_EightTimesRate) {
530   Initialize();
531   TestPlaybackRate(8.0);
532 }
533
534 TEST_F(AudioRendererAlgorithmTest, FillBuffer_ThreeQuartersRate) {
535   Initialize();
536   TestPlaybackRate(0.75);
537 }
538
539 TEST_F(AudioRendererAlgorithmTest, FillBuffer_HalfRate) {
540   Initialize();
541   TestPlaybackRate(0.5);
542 }
543
544 TEST_F(AudioRendererAlgorithmTest, FillBuffer_QuarterRate) {
545   Initialize();
546   TestPlaybackRate(0.25);
547 }
548
549 TEST_F(AudioRendererAlgorithmTest, FillBuffer_Pause) {
550   Initialize();
551   TestPlaybackRate(0.0);
552 }
553
554 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SlowDown) {
555   Initialize();
556   TestPlaybackRate(4.5);
557   TestPlaybackRate(3.0);
558   TestPlaybackRate(2.0);
559   TestPlaybackRate(1.0);
560   TestPlaybackRate(0.5);
561   TestPlaybackRate(0.25);
562 }
563
564 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SpeedUp) {
565   Initialize();
566   TestPlaybackRate(0.25);
567   TestPlaybackRate(0.5);
568   TestPlaybackRate(1.0);
569   TestPlaybackRate(2.0);
570   TestPlaybackRate(3.0);
571   TestPlaybackRate(4.5);
572 }
573
574 TEST_F(AudioRendererAlgorithmTest, FillBuffer_JumpAroundSpeeds) {
575   Initialize();
576   TestPlaybackRate(2.1);
577   TestPlaybackRate(0.9);
578   TestPlaybackRate(0.6);
579   TestPlaybackRate(1.4);
580   TestPlaybackRate(0.3);
581 }
582
583 TEST_F(AudioRendererAlgorithmTest, FillBuffer_SmallBufferSize) {
584   Initialize();
585   static const int kBufferSizeInFrames = 1;
586   static const int kFramesRequested = kOutputDurationInSec * kSamplesPerSecond;
587   TestPlaybackRate(1.0, kBufferSizeInFrames, kFramesRequested, 0);
588   TestPlaybackRate(0.5, kBufferSizeInFrames, kFramesRequested, 0);
589   TestPlaybackRate(1.5, kBufferSizeInFrames, kFramesRequested, 0);
590 }
591
592 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LargeBufferSize) {
593   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 44100, 441);
594   TestPlaybackRate(1.0);
595   TestPlaybackRate(0.5);
596   TestPlaybackRate(1.5);
597 }
598
599 TEST_F(AudioRendererAlgorithmTest, FillBuffer_LowerQualityAudio) {
600   Initialize(CHANNEL_LAYOUT_MONO, kSampleFormatU8, kSamplesPerSecond,
601              kSamplesPerSecond / 100);
602   TestPlaybackRate(1.0);
603   TestPlaybackRate(0.5);
604   TestPlaybackRate(1.5);
605 }
606
607 TEST_F(AudioRendererAlgorithmTest, FillBuffer_HigherQualityAudio) {
608   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS32, kSamplesPerSecond,
609              kSamplesPerSecond / 100);
610   TestPlaybackRate(1.0);
611   TestPlaybackRate(0.5);
612   TestPlaybackRate(1.5);
613 }
614
615 TEST_F(AudioRendererAlgorithmTest, DotProduct) {
616   const int kChannels = 3;
617   const int kFrames = 20;
618   const int kHalfPulseWidth = 2;
619
620   std::unique_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames);
621   std::unique_ptr<AudioBus> b = AudioBus::Create(kChannels, kFrames);
622
623   auto dot_prod = std::make_unique<float[]>(kChannels);
624
625   FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, a.get());
626   FillWithSquarePulseTrain(kHalfPulseWidth, 1, 1, a.get());
627   FillWithSquarePulseTrain(kHalfPulseWidth, 2, 2, a.get());
628
629   FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, b.get());
630   FillWithSquarePulseTrain(kHalfPulseWidth, 0, 1, b.get());
631   FillWithSquarePulseTrain(kHalfPulseWidth, 0, 2, b.get());
632
633   internal::MultiChannelDotProduct(a.get(), 0, b.get(), 0, kFrames,
634                                    dot_prod.get());
635
636   EXPECT_FLOAT_EQ(kFrames, dot_prod[0]);
637   EXPECT_FLOAT_EQ(0, dot_prod[1]);
638   EXPECT_FLOAT_EQ(-kFrames, dot_prod[2]);
639
640   internal::MultiChannelDotProduct(a.get(), 4, b.get(), 8, kFrames / 2,
641                                    dot_prod.get());
642
643   EXPECT_FLOAT_EQ(kFrames / 2, dot_prod[0]);
644   EXPECT_FLOAT_EQ(0, dot_prod[1]);
645   EXPECT_FLOAT_EQ(-kFrames / 2, dot_prod[2]);
646 }
647
648 TEST_F(AudioRendererAlgorithmTest, MovingBlockEnergy) {
649   const int kChannels = 2;
650   const int kFrames = 20;
651   const int kFramesPerBlock = 3;
652   const int kNumBlocks = kFrames - (kFramesPerBlock - 1);
653   std::unique_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames);
654   auto energies = std::make_unique<float[]>(kChannels * kNumBlocks);
655   float* ch_left = a->channel(0);
656   float* ch_right = a->channel(1);
657
658   // Fill up both channels.
659   for (int n = 0; n < kFrames; ++n) {
660     ch_left[n] = n;
661     ch_right[n] = kFrames - 1 - n;
662   }
663
664   internal::MultiChannelMovingBlockEnergies(a.get(), kFramesPerBlock,
665                                             energies.get());
666
667   // Check if the energy of candidate blocks of each channel computed correctly.
668   for (int n = 0; n < kNumBlocks; ++n) {
669     float expected_energy = 0;
670     for (int k = 0; k < kFramesPerBlock; ++k)
671       expected_energy += ch_left[n + k] * ch_left[n + k];
672
673     // Left (first) channel.
674     EXPECT_FLOAT_EQ(expected_energy, energies[2 * n]);
675
676     expected_energy = 0;
677     for (int k = 0; k < kFramesPerBlock; ++k)
678       expected_energy += ch_right[n + k] * ch_right[n + k];
679
680     // Second (right) channel.
681     EXPECT_FLOAT_EQ(expected_energy, energies[2 * n + 1]);
682   }
683 }
684
685 TEST_F(AudioRendererAlgorithmTest, FullAndDecimatedSearch) {
686   const int kFramesInSearchRegion = 12;
687   const int kChannels = 2;
688   float ch_0[] = {
689       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f };
690   float ch_1[] = {
691       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 1.0f, 0.1f, 0.0f, 0.0f };
692   ASSERT_EQ(sizeof(ch_0), sizeof(ch_1));
693   ASSERT_EQ(static_cast<size_t>(kFramesInSearchRegion),
694             sizeof(ch_0) / sizeof(*ch_0));
695   std::unique_ptr<AudioBus> search_region =
696       AudioBus::Create(kChannels, kFramesInSearchRegion);
697   float* ch = search_region->channel(0);
698   memcpy(ch, ch_0, sizeof(float) * kFramesInSearchRegion);
699   ch = search_region->channel(1);
700   memcpy(ch, ch_1, sizeof(float) * kFramesInSearchRegion);
701
702   const int kFramePerBlock = 4;
703   float target_0[] = { 1.0f, 1.0f, 1.0f, 0.0f };
704   float target_1[] = { 0.0f, 1.0f, 0.1f, 1.0f };
705   ASSERT_EQ(sizeof(target_0), sizeof(target_1));
706   ASSERT_EQ(static_cast<size_t>(kFramePerBlock),
707             sizeof(target_0) / sizeof(*target_0));
708
709   std::unique_ptr<AudioBus> target =
710       AudioBus::Create(kChannels, kFramePerBlock);
711   ch = target->channel(0);
712   memcpy(ch, target_0, sizeof(float) * kFramePerBlock);
713   ch = target->channel(1);
714   memcpy(ch, target_1, sizeof(float) * kFramePerBlock);
715
716   auto energy_target = std::make_unique<float[]>(kChannels);
717
718   internal::MultiChannelDotProduct(target.get(), 0, target.get(), 0,
719                                    kFramePerBlock, energy_target.get());
720
721   ASSERT_EQ(3.f, energy_target[0]);
722   ASSERT_EQ(2.01f, energy_target[1]);
723
724   const int kNumCandidBlocks = kFramesInSearchRegion - (kFramePerBlock - 1);
725   auto energy_candid_blocks =
726       std::make_unique<float[]>(kNumCandidBlocks * kChannels);
727
728   internal::MultiChannelMovingBlockEnergies(
729       search_region.get(), kFramePerBlock, energy_candid_blocks.get());
730
731   // Check the energy of the candidate blocks of the first channel.
732   ASSERT_FLOAT_EQ(0, energy_candid_blocks[0]);
733   ASSERT_FLOAT_EQ(0, energy_candid_blocks[2]);
734   ASSERT_FLOAT_EQ(1, energy_candid_blocks[4]);
735   ASSERT_FLOAT_EQ(2, energy_candid_blocks[6]);
736   ASSERT_FLOAT_EQ(3, energy_candid_blocks[8]);
737   ASSERT_FLOAT_EQ(3, energy_candid_blocks[10]);
738   ASSERT_FLOAT_EQ(2, energy_candid_blocks[12]);
739   ASSERT_FLOAT_EQ(1, energy_candid_blocks[14]);
740   ASSERT_FLOAT_EQ(0, energy_candid_blocks[16]);
741
742   // Check the energy of the candidate blocks of the second channel.
743   ASSERT_FLOAT_EQ(0, energy_candid_blocks[1]);
744   ASSERT_FLOAT_EQ(0, energy_candid_blocks[3]);
745   ASSERT_FLOAT_EQ(0, energy_candid_blocks[5]);
746   ASSERT_FLOAT_EQ(0, energy_candid_blocks[7]);
747   ASSERT_FLOAT_EQ(0.01f, energy_candid_blocks[9]);
748   ASSERT_FLOAT_EQ(1.01f, energy_candid_blocks[11]);
749   ASSERT_FLOAT_EQ(1.02f, energy_candid_blocks[13]);
750   ASSERT_FLOAT_EQ(1.02f, energy_candid_blocks[15]);
751   ASSERT_FLOAT_EQ(1.01f, energy_candid_blocks[17]);
752
753   // An interval which is of no effect.
754   internal::Interval exclude_interval = std::make_pair(-100, -10);
755   EXPECT_EQ(5, internal::FullSearch(
756       0, kNumCandidBlocks - 1, exclude_interval, target.get(),
757       search_region.get(), energy_target.get(), energy_candid_blocks.get()));
758
759   // Exclude the the best match.
760   exclude_interval = std::make_pair(2, 5);
761   EXPECT_EQ(7, internal::FullSearch(
762       0, kNumCandidBlocks - 1, exclude_interval, target.get(),
763       search_region.get(), energy_target.get(), energy_candid_blocks.get()));
764
765   // An interval which is of no effect.
766   exclude_interval = std::make_pair(-100, -10);
767   EXPECT_EQ(4, internal::DecimatedSearch(
768       4, exclude_interval, target.get(), search_region.get(),
769       energy_target.get(), energy_candid_blocks.get()));
770
771   EXPECT_EQ(5, internal::OptimalIndex(search_region.get(), target.get(),
772                                       exclude_interval));
773 }
774
775 TEST_F(AudioRendererAlgorithmTest, QuadraticInterpolation) {
776   // Arbitrary coefficients.
777   const float kA = 0.7f;
778   const float kB = 1.2f;
779   const float kC = 0.8f;
780
781   float y_values[3];
782   y_values[0] = kA - kB + kC;
783   y_values[1] = kC;
784   y_values[2] = kA + kB + kC;
785
786   float extremum;
787   float extremum_value;
788
789   internal::QuadraticInterpolation(y_values, &extremum, &extremum_value);
790
791   float x_star = -kB / (2.f * kA);
792   float y_star = kA * x_star * x_star + kB * x_star + kC;
793
794   EXPECT_FLOAT_EQ(x_star, extremum);
795   EXPECT_FLOAT_EQ(y_star, extremum_value);
796 }
797
798 TEST_F(AudioRendererAlgorithmTest, QuadraticInterpolation_Colinear) {
799   float y_values[3];
800   y_values[0] = 1.0;
801   y_values[1] = 1.0;
802   y_values[2] = 1.0;
803
804   float extremum;
805   float extremum_value;
806
807   internal::QuadraticInterpolation(y_values, &extremum, &extremum_value);
808
809   EXPECT_FLOAT_EQ(extremum, 0.0);
810   EXPECT_FLOAT_EQ(extremum_value, 1.0);
811 }
812
813 TEST_F(AudioRendererAlgorithmTest, WsolaSlowdown) {
814   WsolaTest(0.6);
815 }
816
817 TEST_F(AudioRendererAlgorithmTest, WsolaSpeedup) {
818   WsolaTest(1.6);
819 }
820
821 TEST_F(AudioRendererAlgorithmTest, FillBufferOffset) {
822   Initialize();
823   // Pad the queue capacity so fill requests for all rates bellow can be fully
824   // satisfied.
825   algorithm_.IncreasePlaybackThreshold();
826
827   std::unique_ptr<AudioBus> bus = AudioBus::Create(channels_, kFrameSize);
828
829   // Verify that the first half of |bus| remains zero and the last half is
830   // filled appropriately at normal, above normal, and below normal.
831   const int kHalfSize = kFrameSize / 2;
832   const float kAudibleRates[] = {1.0f, 2.0f, 0.5f, 5.0f, 0.25f};
833   for (size_t i = 0; i < std::size(kAudibleRates); ++i) {
834     SCOPED_TRACE(kAudibleRates[i]);
835     bus->Zero();
836
837     const int frames_filled = algorithm_.FillBuffer(
838         bus.get(), kHalfSize, kHalfSize, kAudibleRates[i]);
839     ASSERT_EQ(kHalfSize, frames_filled);
840     ASSERT_TRUE(VerifyAudioData(bus.get(), 0, kHalfSize, 0));
841     ASSERT_FALSE(VerifyAudioData(bus.get(), kHalfSize, kHalfSize, 0));
842     FillAlgorithmQueueUntilFull();
843   }
844 }
845
846 TEST_F(AudioRendererAlgorithmTest, FillBuffer_ChannelMask) {
847   // Setup a quad channel layout where even channels are always muted.
848   Initialize(CHANNEL_LAYOUT_QUAD, kSampleFormatS16, 44100, 441,
849              {true, false, true, false});
850
851   std::unique_ptr<AudioBus> bus = AudioBus::Create(channels_, kFrameSize);
852   int frames_filled = algorithm_.FillBuffer(bus.get(), 0, kFrameSize, 2.0);
853   ASSERT_GT(frames_filled, 0);
854
855   // Verify the channels are muted appropriately; even though the created buffer
856   // actually has audio data in it.
857   for (int ch = 0; ch < bus->channels(); ++ch) {
858     double sum = 0;
859     for (int i = 0; i < bus->frames(); ++i)
860       sum += bus->channel(ch)[i];
861     if (ch % 2 == 1)
862       ASSERT_EQ(sum, 0);
863     else
864       ASSERT_NE(sum, 0);
865   }
866
867   // Update the channel mask and verify it's reflected correctly.
868   algorithm_.SetChannelMask({true, true, true, true});
869   frames_filled = algorithm_.FillBuffer(bus.get(), 0, kFrameSize, 2.0);
870   ASSERT_GT(frames_filled, 0);
871
872   // Verify no channels are muted now.
873   for (int ch = 0; ch < bus->channels(); ++ch) {
874     double sum = 0;
875     for (int i = 0; i < bus->frames(); ++i)
876       sum += bus->channel(ch)[i];
877     ASSERT_NE(sum, 0);
878   }
879 }
880
881 // The |plabyack_threshold_| should == |capacity_| by default, when no
882 // |latency_hint_| is set.
883 TEST_F(AudioRendererAlgorithmTest, NoLatencyHint) {
884   // Queue is initially empty. Capacity is unset.
885   EXPECT_EQ(algorithm_.BufferedFrames(), 0);
886   EXPECT_EQ(algorithm_.QueueCapacity(), 0);
887
888   // Initialize sets capacity fills queue.
889   Initialize();
890   EXPECT_GT(algorithm_.QueueCapacity(), 0);
891   EXPECT_TRUE(algorithm_.IsQueueFull());
892   EXPECT_TRUE(algorithm_.IsQueueAdequateForPlayback());
893
894   // No latency hint is set, so playback threshold should == capacity. Observe
895   // that the queue is neither "full" nor "adequate for playback" if we are one
896   // one frame below the capacity limit.
897   std::unique_ptr<AudioBus> bus = AudioBus::Create(channels_, kFrameSize);
898   int requested_frames =
899       (algorithm_.BufferedFrames() - algorithm_.QueueCapacity()) + 1;
900   const int frames_filled =
901       algorithm_.FillBuffer(bus.get(), 0, requested_frames, 1);
902   EXPECT_EQ(frames_filled, requested_frames);
903   EXPECT_EQ(algorithm_.BufferedFrames(), algorithm_.QueueCapacity() - 1);
904   EXPECT_FALSE(algorithm_.IsQueueFull());
905   EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
906
907   // Queue should again be "adequate for playback" and "full" it we add a single
908   // frame such that BufferedFrames() == QueueCapacity().
909   DCHECK_EQ(sample_format_, kSampleFormatS16);
910   algorithm_.EnqueueBuffer(MakeBuffer(1));
911   EXPECT_TRUE(algorithm_.IsQueueFull());
912   EXPECT_TRUE(algorithm_.IsQueueAdequateForPlayback());
913   EXPECT_EQ(algorithm_.BufferedFrames(), algorithm_.QueueCapacity());
914
915   // Increasing playback threshold should also increase capacity.
916   int orig_capacity = algorithm_.QueueCapacity();
917   algorithm_.IncreasePlaybackThreshold();
918   EXPECT_GT(algorithm_.QueueCapacity(), orig_capacity);
919   EXPECT_FALSE(algorithm_.IsQueueFull());
920   EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
921
922   // Filling again, 1 frame at a time, we should reach "adequate" and "full" in
923   // the same step.
924   while (!algorithm_.IsQueueFull()) {
925     algorithm_.EnqueueBuffer(MakeBuffer(1));
926     EXPECT_EQ(algorithm_.IsQueueFull(),
927               algorithm_.IsQueueAdequateForPlayback());
928   }
929
930   // Flushing should restore queue capacity and playback threshold to the
931   // original value.
932   algorithm_.FlushBuffers();
933   EXPECT_EQ(algorithm_.QueueCapacity(), orig_capacity);
934   EXPECT_FALSE(algorithm_.IsQueueFull());
935   EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
936
937   // Filling again, 1 frame at a time, we should reach "adequate" and "full" in
938   // the same step.
939   while (!algorithm_.IsQueueFull()) {
940     algorithm_.EnqueueBuffer(MakeBuffer(1));
941     EXPECT_EQ(algorithm_.IsQueueFull(),
942               algorithm_.IsQueueAdequateForPlayback());
943   }
944 }
945
946 // The |playback_threshold_| should be < |capacity_| when a latency hint is
947 // set to reduce the playback delay.
948 TEST_F(AudioRendererAlgorithmTest, LowLatencyHint) {
949   // Initialize with a buffer size that leaves some gap between the min capacity
950   // (2*buffer_size) and the default capacity (200ms).
951   const int kBufferSize = kSamplesPerSecond / 50;
952   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, kSamplesPerSecond,
953              kBufferSize);
954
955   // FlushBuffers to start out empty.
956   algorithm_.FlushBuffers();
957
958   EXPECT_GT(algorithm_.QueueCapacity(), 0);
959   EXPECT_FALSE(algorithm_.IsQueueFull());
960   EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
961
962   // Set a latency hint at half the default capacity.
963   const int orig_queue_capcity = algorithm_.QueueCapacity();
964   base::TimeDelta low_latency_hint = AudioTimestampHelper::FramesToTime(
965       orig_queue_capcity / 2, samples_per_second_);
966   algorithm_.SetLatencyHint(low_latency_hint);
967
968   // Hint is less than capacity, so capacity should be unchanged.
969   EXPECT_EQ(algorithm_.QueueCapacity(), orig_queue_capcity);
970
971   // Fill until "adequate". Verify "adequate" buffer time reflects the hinted
972   // latency, and that "adequate" is less than "full".
973   FillAlgorithmQueueUntilAdequate();
974   EXPECT_EQ(BufferedTime(), low_latency_hint);
975   EXPECT_FALSE(algorithm_.IsQueueFull());
976
977   // Set a new *slightly higher* hint. Verify we're no longer "adequate".
978   low_latency_hint += base::Milliseconds(10);
979   algorithm_.SetLatencyHint(low_latency_hint);
980   EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
981
982   // Fill until "adequate". Verify "adequate" buffer time reflects the
983   // *slightly higher* hinted latency, and that "adequate" is less than "full".
984   FillAlgorithmQueueUntilAdequate();
985   EXPECT_EQ(BufferedTime(), low_latency_hint);
986   EXPECT_FALSE(algorithm_.IsQueueFull());
987
988   // Clearing the hint should restore the higher default playback threshold,
989   // such that we no longer have enough buffer to be "adequate for playback".
990   algorithm_.SetLatencyHint(absl::nullopt);
991   EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
992
993   // Fill until "full". Verify that "adequate" now matches "full".
994   while (!algorithm_.IsQueueFull()) {
995     algorithm_.EnqueueBuffer(MakeBuffer(1));
996     EXPECT_EQ(algorithm_.IsQueueAdequateForPlayback(),
997               algorithm_.IsQueueFull());
998   }
999 }
1000
1001 // Note: the behavior of FlushBuffers() that is not specific to high vs low
1002 // latency hints. Testing it with "high" is slightly more interesting. Testing
1003 // with both "high" and "low" is excessive.
1004 TEST_F(AudioRendererAlgorithmTest, HighLatencyHint) {
1005   // Initialize with a buffer size that leaves some gap between the min capacity
1006   // (2*buffer_size) and the default capacity (200ms).
1007   const int kBufferSize = kSamplesPerSecond / 50;
1008   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, kSamplesPerSecond,
1009              kBufferSize);
1010   const int default_capacity = algorithm_.QueueCapacity();
1011
1012   // FlushBuffers to start out empty.
1013   algorithm_.FlushBuffers();
1014
1015   // Set a "high" latency hint.
1016   const base::TimeDelta high_latency_hint = AudioTimestampHelper::FramesToTime(
1017       algorithm_.QueueCapacity() * 2, samples_per_second_);
1018   algorithm_.SetLatencyHint(high_latency_hint);
1019   const int high_latency_capacity = algorithm_.QueueCapacity();
1020   EXPECT_GT(high_latency_capacity, default_capacity);
1021
1022   // Fill until "adequate". Verify it reflects the high latency hint.
1023   EXPECT_TRUE(BufferedTime().is_zero());
1024   FillAlgorithmQueueUntilAdequate();
1025   EXPECT_EQ(BufferedTime(), high_latency_hint);
1026
1027   // Flush the queue!
1028   algorithm_.FlushBuffers();
1029
1030   // Verify |capcity_| was not changed by flush. The latency hint supersedes any
1031   // automatic queue size adjustments.
1032   EXPECT_EQ(algorithm_.QueueCapacity(), high_latency_capacity);
1033
1034   // Similarly, verify that |playback_threshold_| was not changed by refilling
1035   // and observing that the "adequate" buffered time still matches the hint.
1036   FillAlgorithmQueueUntilAdequate();
1037   EXPECT_EQ(BufferedTime(), high_latency_hint);
1038
1039   // Clearing the hint should restore the lower default playback threshold and
1040   // capacity.
1041   algorithm_.SetLatencyHint(absl::nullopt);
1042   EXPECT_EQ(algorithm_.QueueCapacity(), default_capacity);
1043
1044   // The queue is over-full from our last fill when the hint was set. Flush and
1045   // refill to the reduced "adequate" threshold.
1046   algorithm_.FlushBuffers();
1047   FillAlgorithmQueueUntilAdequate();
1048   EXPECT_LT(BufferedTime(), high_latency_hint);
1049
1050   // With latency hint now unset, callers are now free to adjust the queue size
1051   // (e.g. in response to underflow). Lets increase the threshold!
1052   algorithm_.IncreasePlaybackThreshold();
1053
1054   // Verify higher capacity means we're no longer "adequate" nor "full".
1055   EXPECT_GT(algorithm_.QueueCapacity(), default_capacity);
1056   EXPECT_FALSE(algorithm_.IsQueueAdequateForPlayback());
1057   EXPECT_FALSE(algorithm_.IsQueueFull());
1058
1059   // Flush the queue and verify the increase has been reverted.
1060   algorithm_.FlushBuffers();
1061   EXPECT_EQ(algorithm_.QueueCapacity(), default_capacity);
1062
1063   // Refill to verify "adequate" matches the "full" at the default capacity.
1064   while (!algorithm_.IsQueueAdequateForPlayback()) {
1065     algorithm_.EnqueueBuffer(MakeBuffer(1));
1066     EXPECT_EQ(algorithm_.IsQueueAdequateForPlayback(),
1067               algorithm_.IsQueueFull());
1068   }
1069 }
1070
1071 // Algorithm should clam specified hint to a reasonable min/max.
1072 TEST_F(AudioRendererAlgorithmTest, ClampLatencyHint) {
1073   // Initialize with a buffer size that leaves some gap between the min capacity
1074   // (2*buffer_size) and the default capacity (200ms).
1075   const int kBufferSize = kSamplesPerSecond / 50;
1076   Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, kSamplesPerSecond,
1077              kBufferSize);
1078   const int default_capacity = algorithm_.QueueCapacity();
1079
1080   // FlushBuffers to start out empty.
1081   algorithm_.FlushBuffers();
1082
1083   // Set a crazy high latency hint.
1084   algorithm_.SetLatencyHint(base::Seconds(100));
1085
1086   const base::TimeDelta kDefaultMax = base::Seconds(3);
1087   // Verify "full" and "adequate" thresholds increased, but to a known max well
1088   // bellow the hinted value.
1089   EXPECT_GT(algorithm_.QueueCapacity(), default_capacity);
1090   FillAlgorithmQueueUntilAdequate();
1091   EXPECT_EQ(BufferedTime(), kDefaultMax);
1092
1093   // FlushBuffers to return to empty.
1094   algorithm_.FlushBuffers();
1095
1096   // Set an impossibly low latency hint.
1097   algorithm_.SetLatencyHint(base::Seconds(0));
1098
1099   // Verify "full" and "adequate" thresholds decreased, but to a known minimum
1100   // well above the hinted value.
1101   EXPECT_EQ(algorithm_.QueueCapacity(), default_capacity);
1102   FillAlgorithmQueueUntilAdequate();
1103   EXPECT_EQ(algorithm_.BufferedFrames(), 2 * kBufferSize);
1104 }
1105
1106 }  // namespace media