Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: media/base/audio_discard_helper_unittest.cc

Issue 251893002: Support start trimming post-decoding. Use it with FFmpegDemuxer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Typo. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/scoped_ptr.h" 5 #include "base/memory/scoped_ptr.h"
6 #include "media/base/audio_buffer.h" 6 #include "media/base/audio_buffer.h"
7 #include "media/base/audio_bus.h"
7 #include "media/base/audio_discard_helper.h" 8 #include "media/base/audio_discard_helper.h"
8 #include "media/base/buffers.h" 9 #include "media/base/buffers.h"
9 #include "media/base/decoder_buffer.h" 10 #include "media/base/decoder_buffer.h"
10 #include "media/base/test_helpers.h" 11 #include "media/base/test_helpers.h"
11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
12 13
13 namespace media { 14 namespace media {
14 15
16 static const float kDataStep = 0.01f;
15 static const int kSampleRate = 48000; 17 static const int kSampleRate = 48000;
16 18
17 static scoped_refptr<DecoderBuffer> CreateEncodedBuffer( 19 static scoped_refptr<DecoderBuffer> CreateEncodedBuffer(
18 base::TimeDelta timestamp, 20 base::TimeDelta timestamp,
19 base::TimeDelta duration) { 21 base::TimeDelta duration) {
20 scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1)); 22 scoped_refptr<DecoderBuffer> result(new DecoderBuffer(1));
21 result->set_timestamp(timestamp); 23 result->set_timestamp(timestamp);
22 result->set_duration(duration); 24 result->set_duration(duration);
23 return result; 25 return result;
24 } 26 }
25 27
26 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) { 28 static scoped_refptr<AudioBuffer> CreateDecodedBuffer(int frames) {
27 return MakeAudioBuffer(kSampleFormatPlanarF32, 29 return MakeAudioBuffer(kSampleFormatPlanarF32,
28 CHANNEL_LAYOUT_MONO, 30 CHANNEL_LAYOUT_MONO,
29 1, 31 1,
30 kSampleRate, 32 kSampleRate,
31 0.0f, 33 0.0f,
32 0.01f, 34 kDataStep,
33 frames, 35 frames,
34 kNoTimestamp(), 36 kNoTimestamp(),
35 kNoTimestamp()); 37 kNoTimestamp());
36 } 38 }
37 39
40 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer,
41 int index) {
42 // This is really inefficient, but we can't access the raw AudioBuffer if any
43 // start trimming has been applied.
44 scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1);
45 buffer->ReadFrames(1, index, 0, temp_bus.get());
46 return temp_bus->channel(0)[0];
47 }
48
38 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) { 49 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
39 AudioDiscardHelper discard_helper(kSampleRate); 50 AudioDiscardHelper discard_helper(kSampleRate, 0);
40 51
41 EXPECT_EQ(0, discard_helper.TimeDeltaToFrames(base::TimeDelta())); 52 EXPECT_EQ(0, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
42 EXPECT_EQ( 53 EXPECT_EQ(
43 kSampleRate / 100, 54 kSampleRate / 100,
44 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10))); 55 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10)));
45 56
46 // Ensure partial frames are always rounded up. The equation below calculates 57 // Ensure partial frames are always rounded up. The equation below calculates
47 // a frame count with a fractional part < 0.5. 58 // a frame count with a fractional part < 0.5.
48 const int small_remainder = 59 const int small_remainder =
49 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate; 60 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate;
50 EXPECT_EQ(kSampleRate, 61 EXPECT_EQ(kSampleRate,
51 discard_helper.TimeDeltaToFrames( 62 discard_helper.TimeDeltaToFrames(
52 base::TimeDelta::FromMicroseconds(small_remainder))); 63 base::TimeDelta::FromMicroseconds(small_remainder)));
53 } 64 }
54 65
55 TEST(AudioDiscardHelperTest, BasicProcessBuffers) { 66 TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
56 AudioDiscardHelper discard_helper(kSampleRate); 67 AudioDiscardHelper discard_helper(kSampleRate, 0);
57 ASSERT_FALSE(discard_helper.initialized()); 68 ASSERT_FALSE(discard_helper.initialized());
58 69
59 const base::TimeDelta kTimestamp = base::TimeDelta(); 70 const base::TimeDelta kTimestamp = base::TimeDelta();
60 71
61 // Use an estimated duration which doesn't match the number of decoded frames 72 // Use an estimated duration which doesn't match the number of decoded frames
62 // to ensure the helper is correctly setting durations based on output frames. 73 // to ensure the helper is correctly setting durations based on output frames.
63 const base::TimeDelta kEstimatedDuration = 74 const base::TimeDelta kEstimatedDuration =
64 base::TimeDelta::FromMilliseconds(9); 75 base::TimeDelta::FromMilliseconds(9);
65 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10); 76 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10);
66 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration); 77 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration);
(...skipping 11 matching lines...) Expand all
78 89
79 // Verify a Reset() takes us back to an uninitialized state. 90 // Verify a Reset() takes us back to an uninitialized state.
80 discard_helper.Reset(0); 91 discard_helper.Reset(0);
81 ASSERT_FALSE(discard_helper.initialized()); 92 ASSERT_FALSE(discard_helper.initialized());
82 93
83 // Verify a NULL output buffer returns false. 94 // Verify a NULL output buffer returns false.
84 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); 95 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
85 } 96 }
86 97
87 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) { 98 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
88 AudioDiscardHelper discard_helper(kSampleRate); 99 AudioDiscardHelper discard_helper(kSampleRate, 0);
89 ASSERT_FALSE(discard_helper.initialized()); 100 ASSERT_FALSE(discard_helper.initialized());
90 101
91 const base::TimeDelta kTimestamp = base::TimeDelta(); 102 const base::TimeDelta kTimestamp = base::TimeDelta();
92 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 103 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
93 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 104 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
94 105
95 // Tell the helper we want to discard half of the initial frames. 106 // Tell the helper we want to discard half of the initial frames.
96 discard_helper.Reset(kTestFrames / 2); 107 discard_helper.Reset(kTestFrames / 2);
97 108
98 scoped_refptr<DecoderBuffer> encoded_buffer = 109 scoped_refptr<DecoderBuffer> encoded_buffer =
99 CreateEncodedBuffer(kTimestamp, kDuration); 110 CreateEncodedBuffer(kTimestamp, kDuration);
100 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 111 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
101 112
102 // Verify half the frames end up discarded. 113 // Verify half the frames end up discarded.
103 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 114 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
104 ASSERT_TRUE(discard_helper.initialized()); 115 ASSERT_TRUE(discard_helper.initialized());
105 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 116 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
106 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 117 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
107 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 118 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
108 } 119 }
109 120
110 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) { 121 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
111 AudioDiscardHelper discard_helper(kSampleRate); 122 AudioDiscardHelper discard_helper(kSampleRate, 0);
112 ASSERT_FALSE(discard_helper.initialized()); 123 ASSERT_FALSE(discard_helper.initialized());
113 124
114 const base::TimeDelta kTimestamp = base::TimeDelta(); 125 const base::TimeDelta kTimestamp = base::TimeDelta();
115 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 126 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
116 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 127 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
117 128
118 // Tell the helper we want to discard 1.5 buffers worth of frames. 129 // Tell the helper we want to discard 1.5 buffers worth of frames.
119 discard_helper.Reset(kTestFrames * 1.5); 130 discard_helper.Reset(kTestFrames * 1.5);
120 131
121 scoped_refptr<DecoderBuffer> encoded_buffer = 132 scoped_refptr<DecoderBuffer> encoded_buffer =
122 CreateEncodedBuffer(kTimestamp, kDuration); 133 CreateEncodedBuffer(kTimestamp, kDuration);
123 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 134 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
124 135
125 // The first call should fail since no output buffer remains. 136 // The first call should fail since no output buffer remains.
126 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 137 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
127 ASSERT_TRUE(discard_helper.initialized()); 138 ASSERT_TRUE(discard_helper.initialized());
128 139
129 // Generate another set of buffers and expect half the output frames. 140 // Generate another set of buffers and expect half the output frames.
130 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration); 141 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
131 decoded_buffer = CreateDecodedBuffer(kTestFrames); 142 decoded_buffer = CreateDecodedBuffer(kTestFrames);
132 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 143 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
133 144
134 // The timestamp should match that of the initial buffer. 145 // The timestamp should match that of the initial buffer.
135 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 146 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
136 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 147 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
137 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 148 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
138 } 149 }
139 150
140 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) { 151 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
141 AudioDiscardHelper discard_helper(kSampleRate); 152 AudioDiscardHelper discard_helper(kSampleRate, 0);
142 ASSERT_FALSE(discard_helper.initialized()); 153 ASSERT_FALSE(discard_helper.initialized());
143 154
144 const base::TimeDelta kTimestamp = base::TimeDelta(); 155 const base::TimeDelta kTimestamp = base::TimeDelta();
145 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 156 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
146 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 157 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
147 158
148 scoped_refptr<DecoderBuffer> encoded_buffer = 159 scoped_refptr<DecoderBuffer> encoded_buffer =
149 CreateEncodedBuffer(kTimestamp, kDuration); 160 CreateEncodedBuffer(kTimestamp, kDuration);
150 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 161 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
151 162
152 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 163 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
153 ASSERT_TRUE(discard_helper.initialized()); 164 ASSERT_TRUE(discard_helper.initialized());
154 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 165 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
155 EXPECT_EQ(kDuration, decoded_buffer->duration()); 166 EXPECT_EQ(kDuration, decoded_buffer->duration());
156 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 167 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
157 168
158 // Process the same input buffer again to ensure input timestamps which go 169 // Process the same input buffer again to ensure input timestamps which go
159 // backwards in time are not errors. 170 // backwards in time are not errors.
160 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 171 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
161 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp()); 172 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp());
162 EXPECT_EQ(kDuration, decoded_buffer->duration()); 173 EXPECT_EQ(kDuration, decoded_buffer->duration());
163 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 174 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
164 } 175 }
165 176
166 TEST(AudioDiscardHelperTest, DiscardPadding) { 177 TEST(AudioDiscardHelperTest, DiscardEndPadding) {
167 AudioDiscardHelper discard_helper(kSampleRate); 178 AudioDiscardHelper discard_helper(kSampleRate, 0);
168 ASSERT_FALSE(discard_helper.initialized()); 179 ASSERT_FALSE(discard_helper.initialized());
169 180
170 const base::TimeDelta kTimestamp = base::TimeDelta(); 181 const base::TimeDelta kTimestamp = base::TimeDelta();
171 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 182 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
172 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 183 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
173 184
174 scoped_refptr<DecoderBuffer> encoded_buffer = 185 scoped_refptr<DecoderBuffer> encoded_buffer =
175 CreateEncodedBuffer(kTimestamp, kDuration); 186 CreateEncodedBuffer(kTimestamp, kDuration);
176 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 187 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
177 188
178 // Set a discard padding equivalent to half the buffer. 189 // Set a discard padding equivalent to half the buffer.
179 encoded_buffer->set_discard_padding(kDuration / 2); 190 encoded_buffer->set_discard_padding(
191 std::make_pair(base::TimeDelta(), kDuration / 2));
180 192
181 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 193 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
182 ASSERT_TRUE(discard_helper.initialized()); 194 ASSERT_TRUE(discard_helper.initialized());
195 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
196 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
197 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
198 }
199
200 TEST(AudioDiscardHelperTest, BadDiscardEndPadding) {
201 AudioDiscardHelper discard_helper(kSampleRate, 0);
202 ASSERT_FALSE(discard_helper.initialized());
203
204 const base::TimeDelta kTimestamp = base::TimeDelta();
205 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
206 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
207
208 scoped_refptr<DecoderBuffer> encoded_buffer =
209 CreateEncodedBuffer(kTimestamp, kDuration);
210 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
211
212 // Set a discard padding equivalent to double the buffer size.
213 encoded_buffer->set_discard_padding(
214 std::make_pair(base::TimeDelta(), kDuration * 2));
215
216 // Verify the end discard padding is rejected.
217 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
218 ASSERT_TRUE(discard_helper.initialized());
219 }
220
221 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) {
222 AudioDiscardHelper discard_helper(kSampleRate, 0);
223 ASSERT_FALSE(discard_helper.initialized());
224
225 const base::TimeDelta kTimestamp = base::TimeDelta();
226 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
227 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
228
229 scoped_refptr<DecoderBuffer> encoded_buffer =
230 CreateEncodedBuffer(kTimestamp, kDuration);
231 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
232
233 // Set a discard padding equivalent to a quarter of the buffer.
234 encoded_buffer->set_discard_padding(
235 std::make_pair(base::TimeDelta(), kDuration / 4));
236
237 // Set an initial discard of a quarter of the buffer.
238 discard_helper.Reset(kTestFrames / 4);
239
240 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
241 ASSERT_TRUE(discard_helper.initialized());
183 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 242 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
184 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 243 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
185 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 244 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
186 } 245 }
187 246
188 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) { 247 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
189 AudioDiscardHelper discard_helper(kSampleRate); 248 AudioDiscardHelper discard_helper(kSampleRate, 0);
190 ASSERT_FALSE(discard_helper.initialized()); 249 ASSERT_FALSE(discard_helper.initialized());
191 250
192 const base::TimeDelta kTimestamp = base::TimeDelta(); 251 const base::TimeDelta kTimestamp = base::TimeDelta();
193 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 252 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
194 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 253 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
195 254
196 scoped_refptr<DecoderBuffer> encoded_buffer = 255 scoped_refptr<DecoderBuffer> encoded_buffer =
197 CreateEncodedBuffer(kTimestamp, kDuration); 256 CreateEncodedBuffer(kTimestamp, kDuration);
198 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 257 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
199 258
200 // Set a discard padding equivalent to a quarter of the buffer. 259 // Set a discard padding equivalent to a quarter of the buffer.
201 encoded_buffer->set_discard_padding(kDuration / 4); 260 encoded_buffer->set_discard_padding(
261 std::make_pair(kDuration / 4, kDuration / 4));
202 262
203 // Set an initial discard of a quarter of the buffer. 263 // Set an initial discard of a quarter of the buffer.
204 discard_helper.Reset(kTestFrames / 4); 264 discard_helper.Reset(kTestFrames / 4);
205 265
206 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 266 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
207 ASSERT_TRUE(discard_helper.initialized()); 267 ASSERT_TRUE(discard_helper.initialized());
208 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 268 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
269 EXPECT_EQ(kDuration / 4, decoded_buffer->duration());
270 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count());
271 }
272
273 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndCodecDelay) {
274 // Use a codec delay of 5ms.
275 const int kCodecDelay = kSampleRate / 100 / 2;
276 AudioDiscardHelper discard_helper(kSampleRate, kCodecDelay);
277 ASSERT_FALSE(discard_helper.initialized());
278 discard_helper.Reset(kCodecDelay);
279
280 const base::TimeDelta kTimestamp = base::TimeDelta();
281 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
282 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
283
284 scoped_refptr<DecoderBuffer> encoded_buffer =
285 CreateEncodedBuffer(kTimestamp, kDuration);
286 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
287
288 // Set a discard padding equivalent to half of the buffer.
289 encoded_buffer->set_discard_padding(
290 std::make_pair(kDuration / 2, base::TimeDelta()));
291
292 // All of the first buffer should be discarded.
293 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
294 ASSERT_TRUE(discard_helper.initialized());
295
296 // Processing another buffer (with the same discard padding) should discard
297 // the back half of the buffer since kCodecDelay is half a buffer.
298 encoded_buffer->set_timestamp(kTimestamp + kDuration);
299 decoded_buffer = CreateDecodedBuffer(kTestFrames);
300 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
301 ASSERT_NEAR(kCodecDelay * kDataStep,
302 ExtractDecodedData(decoded_buffer, kCodecDelay),
303 kDataStep * 1000);
304 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
305 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
209 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 306 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
210 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 307 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
308
309 // Verify it was actually the latter half of the buffer that was removed.
310 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
211 } 311 }
212 312
313 TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) {
314 AudioDiscardHelper discard_helper(kSampleRate, 0);
315 ASSERT_FALSE(discard_helper.initialized());
316
317 const base::TimeDelta kTimestamp = base::TimeDelta();
318 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
319 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
320
321 scoped_refptr<DecoderBuffer> encoded_buffer =
322 CreateEncodedBuffer(kTimestamp, kDuration);
323
324 // Set a discard padding equivalent to a quarter of the buffer.
325 encoded_buffer->set_discard_padding(
326 std::make_pair(kDuration / 4, kDuration / 4));
327
328 // Set an initial discard of a quarter of the buffer.
329 discard_helper.Reset(kTestFrames / 4);
330
331 // Verify nothing is output for the first buffer, yet initialized is true.
332 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
333 ASSERT_TRUE(discard_helper.initialized());
334
335 // Create an encoded buffer with no discard padding.
336 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
337 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
338
339 // Verify that when the decoded buffer is consumed, the discards from the
340 // previous encoded buffer are applied.
341 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
342 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
343 EXPECT_EQ(kDuration / 4, decoded_buffer->duration());
344 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count());
345 }
213 346
214 } // namespace media 347 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698