Ignore title parameter for navigator.registerProtocolHandler
[chromium-blink-merge.git] / media / base / audio_discard_helper_unittest.cc
blob55d2b6175ccb04ff8ed57b9a39d122f9da3f124a
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.
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"
14 namespace media {
16 static const float kDataStep = 0.01f;
17 static const size_t kSampleRate = 48000;
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;
28 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) {
29 return MakeAudioBuffer(kSampleFormatPlanarF32,
30 CHANNEL_LAYOUT_MONO,
32 kSampleRate,
33 0.0f,
34 kDataStep,
35 frames,
36 kNoTimestamp());
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];
48 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
49 AudioDiscardHelper discard_helper(kSampleRate, 0);
51 EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
52 EXPECT_EQ(
53 kSampleRate / 100,
54 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10)));
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)));
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)));
72 TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
73 AudioDiscardHelper discard_helper(kSampleRate, 0);
74 ASSERT_FALSE(discard_helper.initialized());
76 const base::TimeDelta kTimestamp = base::TimeDelta();
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);
85 scoped_refptr<DecoderBuffer> encoded_buffer =
86 CreateEncodedBuffer(kTimestamp, kEstimatedDuration);
87 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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());
96 // Verify a Reset() takes us back to an uninitialized state.
97 discard_helper.Reset(0);
98 ASSERT_FALSE(discard_helper.initialized());
100 // Verify a NULL output buffer returns false.
101 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
104 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) {
105 AudioDiscardHelper discard_helper(kSampleRate, 0);
106 ASSERT_FALSE(discard_helper.initialized());
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);
112 scoped_refptr<DecoderBuffer> encoded_buffer =
113 CreateEncodedBuffer(kTimestamp, kDuration);
114 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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());
124 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
125 AudioDiscardHelper discard_helper(kSampleRate, 0);
126 ASSERT_FALSE(discard_helper.initialized());
128 const base::TimeDelta kTimestamp = base::TimeDelta();
129 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
130 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
132 // Tell the helper we want to discard half of the initial frames.
133 const int kDiscardFrames = kTestFrames / 2;
134 discard_helper.Reset(kDiscardFrames);
136 scoped_refptr<DecoderBuffer> encoded_buffer =
137 CreateEncodedBuffer(kTimestamp, kDuration);
138 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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));
150 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
151 AudioDiscardHelper discard_helper(kSampleRate, 0);
152 ASSERT_FALSE(discard_helper.initialized());
154 const base::TimeDelta kTimestamp = base::TimeDelta();
155 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
156 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
158 // Tell the helper we want to discard 1.5 buffers worth of frames.
159 discard_helper.Reset(kTestFrames * 1.5);
161 scoped_refptr<DecoderBuffer> encoded_buffer =
162 CreateEncodedBuffer(kTimestamp, kDuration);
163 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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());
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));
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));
183 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
184 AudioDiscardHelper discard_helper(kSampleRate, 0);
185 ASSERT_FALSE(discard_helper.initialized());
187 const base::TimeDelta kTimestamp = base::TimeDelta();
188 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
189 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
191 scoped_refptr<DecoderBuffer> encoded_buffer =
192 CreateEncodedBuffer(kTimestamp, kDuration);
193 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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());
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());
209 TEST(AudioDiscardHelperTest, DiscardEndPadding) {
210 AudioDiscardHelper discard_helper(kSampleRate, 0);
211 ASSERT_FALSE(discard_helper.initialized());
213 const base::TimeDelta kTimestamp = base::TimeDelta();
214 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
215 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
217 scoped_refptr<DecoderBuffer> encoded_buffer =
218 CreateEncodedBuffer(kTimestamp, kDuration);
219 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
221 // Set a discard padding equivalent to half the buffer.
222 encoded_buffer->set_discard_padding(
223 std::make_pair(base::TimeDelta(), kDuration / 2));
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());
232 TEST(AudioDiscardHelperTest, BadDiscardEndPadding) {
233 AudioDiscardHelper discard_helper(kSampleRate, 0);
234 ASSERT_FALSE(discard_helper.initialized());
236 const base::TimeDelta kTimestamp = base::TimeDelta();
237 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
238 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
240 scoped_refptr<DecoderBuffer> encoded_buffer =
241 CreateEncodedBuffer(kTimestamp, kDuration);
242 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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));
248 // Verify the end discard padding is rejected.
249 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
250 ASSERT_TRUE(discard_helper.initialized());
253 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) {
254 AudioDiscardHelper discard_helper(kSampleRate, 0);
255 ASSERT_FALSE(discard_helper.initialized());
257 const base::TimeDelta kTimestamp = base::TimeDelta();
258 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
259 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
261 scoped_refptr<DecoderBuffer> encoded_buffer =
262 CreateEncodedBuffer(kTimestamp, kDuration);
263 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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));
269 // Set an initial discard of a quarter of the buffer.
270 const int kDiscardFrames = kTestFrames / 4;
271 discard_helper.Reset(kDiscardFrames);
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));
282 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
283 AudioDiscardHelper discard_helper(kSampleRate, 0);
284 ASSERT_FALSE(discard_helper.initialized());
286 const base::TimeDelta kTimestamp = base::TimeDelta();
287 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
288 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
290 scoped_refptr<DecoderBuffer> encoded_buffer =
291 CreateEncodedBuffer(kTimestamp, kDuration);
292 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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);
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());
309 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndCodecDelay) {
310 // Use a codec delay of 5ms.
311 const int kCodecDelay = kSampleRate / 100 / 2;
312 AudioDiscardHelper discard_helper(kSampleRate, kCodecDelay);
313 ASSERT_FALSE(discard_helper.initialized());
314 discard_helper.Reset(kCodecDelay);
316 const base::TimeDelta kTimestamp = base::TimeDelta();
317 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
318 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
320 scoped_refptr<DecoderBuffer> encoded_buffer =
321 CreateEncodedBuffer(kTimestamp, kDuration);
322 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
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()));
328 // All of the first buffer should be discarded.
329 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
330 ASSERT_TRUE(discard_helper.initialized());
332 // Processing another buffer (with the same discard padding) should discard
333 // the back half of the buffer since kCodecDelay is half a buffer.
334 encoded_buffer->set_timestamp(kTimestamp + kDuration);
335 decoded_buffer = CreateDecodedBuffer(kTestFrames);
336 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
337 ASSERT_NEAR(kCodecDelay * kDataStep,
338 ExtractDecodedData(decoded_buffer, kCodecDelay),
339 kDataStep * 1000);
340 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
341 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
342 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
343 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
345 // Verify it was actually the latter half of the buffer that was removed.
346 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
349 TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) {
350 AudioDiscardHelper discard_helper(kSampleRate, 0);
351 ASSERT_FALSE(discard_helper.initialized());
353 const base::TimeDelta kTimestamp = base::TimeDelta();
354 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
355 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
357 scoped_refptr<DecoderBuffer> encoded_buffer =
358 CreateEncodedBuffer(kTimestamp, kDuration);
360 // Set all the discard values to be different to ensure each is properly used.
361 const int kDiscardFrames = kTestFrames / 4;
362 encoded_buffer->set_discard_padding(
363 std::make_pair(kDuration / 8, kDuration / 16));
364 discard_helper.Reset(kDiscardFrames);
366 // Verify nothing is output for the first buffer, yet initialized is true.
367 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
368 ASSERT_TRUE(discard_helper.initialized());
370 // Create an encoded buffer with no discard padding.
371 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
372 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
374 // Verify that when the decoded buffer is consumed, the discards from the
375 // previous encoded buffer are applied.
376 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
377 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
378 EXPECT_EQ(kDuration - kDuration / 4 - kDuration / 8 - kDuration / 16,
379 decoded_buffer->duration());
380 EXPECT_EQ(kTestFrames - kTestFrames / 4 - kTestFrames / 8 - kTestFrames / 16,
381 decoded_buffer->frame_count());
384 } // namespace media