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

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: Rebase. Created 6 years, 7 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_bus.h"
8 #include "media/base/audio_discard_helper.h" 8 #include "media/base/audio_discard_helper.h"
9 #include "media/base/buffers.h" 9 #include "media/base/buffers.h"
10 #include "media/base/decoder_buffer.h" 10 #include "media/base/decoder_buffer.h"
(...skipping 29 matching lines...) Expand all
40 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer, 40 static float ExtractDecodedData(const scoped_refptr<AudioBuffer>& buffer,
41 int index) { 41 int index) {
42 // This is really inefficient, but we can't access the raw AudioBuffer if any 42 // This is really inefficient, but we can't access the raw AudioBuffer if any
43 // start trimming has been applied. 43 // start trimming has been applied.
44 scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1); 44 scoped_ptr<AudioBus> temp_bus = AudioBus::Create(buffer->channel_count(), 1);
45 buffer->ReadFrames(1, index, 0, temp_bus.get()); 45 buffer->ReadFrames(1, index, 0, temp_bus.get());
46 return temp_bus->channel(0)[0]; 46 return temp_bus->channel(0)[0];
47 } 47 }
48 48
49 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) { 49 TEST(AudioDiscardHelperTest, TimeDeltaToFrames) {
50 AudioDiscardHelper discard_helper(kSampleRate); 50 AudioDiscardHelper discard_helper(kSampleRate, 0);
51 51
52 EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta())); 52 EXPECT_EQ(0u, discard_helper.TimeDeltaToFrames(base::TimeDelta()));
53 EXPECT_EQ( 53 EXPECT_EQ(
54 kSampleRate / 100, 54 kSampleRate / 100,
55 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10))); 55 discard_helper.TimeDeltaToFrames(base::TimeDelta::FromMilliseconds(10)));
56 56
57 // Ensure partial frames are rounded down correctly. The equation below 57 // Ensure partial frames are rounded down correctly. The equation below
58 // calculates a frame count with a fractional part < 0.5. 58 // calculates a frame count with a fractional part < 0.5.
59 const int small_remainder = 59 const int small_remainder =
60 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate; 60 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.9) / kSampleRate;
61 EXPECT_EQ(kSampleRate - 1, 61 EXPECT_EQ(kSampleRate - 1,
62 discard_helper.TimeDeltaToFrames( 62 discard_helper.TimeDeltaToFrames(
63 base::TimeDelta::FromMicroseconds(small_remainder))); 63 base::TimeDelta::FromMicroseconds(small_remainder)));
64 64
65 // Ditto, but rounded up using a fractional part > 0.5. 65 // Ditto, but rounded up using a fractional part > 0.5.
66 const int large_remainder = 66 const int large_remainder =
67 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate; 67 base::Time::kMicrosecondsPerSecond * (kSampleRate - 0.4) / kSampleRate;
68 EXPECT_EQ(kSampleRate, 68 EXPECT_EQ(kSampleRate,
69 discard_helper.TimeDeltaToFrames( 69 discard_helper.TimeDeltaToFrames(
70 base::TimeDelta::FromMicroseconds(large_remainder))); 70 base::TimeDelta::FromMicroseconds(large_remainder)));
71 } 71 }
72 72
73 TEST(AudioDiscardHelperTest, BasicProcessBuffers) { 73 TEST(AudioDiscardHelperTest, BasicProcessBuffers) {
74 AudioDiscardHelper discard_helper(kSampleRate); 74 AudioDiscardHelper discard_helper(kSampleRate, 0);
75 ASSERT_FALSE(discard_helper.initialized()); 75 ASSERT_FALSE(discard_helper.initialized());
76 76
77 const base::TimeDelta kTimestamp = base::TimeDelta(); 77 const base::TimeDelta kTimestamp = base::TimeDelta();
78 78
79 // Use an estimated duration which doesn't match the number of decoded frames 79 // Use an estimated duration which doesn't match the number of decoded frames
80 // to ensure the helper is correctly setting durations based on output frames. 80 // to ensure the helper is correctly setting durations based on output frames.
81 const base::TimeDelta kEstimatedDuration = 81 const base::TimeDelta kEstimatedDuration =
82 base::TimeDelta::FromMilliseconds(9); 82 base::TimeDelta::FromMilliseconds(9);
83 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10); 83 const base::TimeDelta kActualDuration = base::TimeDelta::FromMilliseconds(10);
84 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration); 84 const int kTestFrames = discard_helper.TimeDeltaToFrames(kActualDuration);
(...skipping 11 matching lines...) Expand all
96 96
97 // Verify a Reset() takes us back to an uninitialized state. 97 // Verify a Reset() takes us back to an uninitialized state.
98 discard_helper.Reset(0); 98 discard_helper.Reset(0);
99 ASSERT_FALSE(discard_helper.initialized()); 99 ASSERT_FALSE(discard_helper.initialized());
100 100
101 // Verify a NULL output buffer returns false. 101 // Verify a NULL output buffer returns false.
102 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL)); 102 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
103 } 103 }
104 104
105 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) { 105 TEST(AudioDiscardHelperTest, NegativeTimestampClampsToZero) {
106 AudioDiscardHelper discard_helper(kSampleRate); 106 AudioDiscardHelper discard_helper(kSampleRate, 0);
107 ASSERT_FALSE(discard_helper.initialized()); 107 ASSERT_FALSE(discard_helper.initialized());
108 108
109 const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1); 109 const base::TimeDelta kTimestamp = -base::TimeDelta::FromSeconds(1);
110 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 110 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
111 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 111 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
112 112
113 scoped_refptr<DecoderBuffer> encoded_buffer = 113 scoped_refptr<DecoderBuffer> encoded_buffer =
114 CreateEncodedBuffer(kTimestamp, kDuration); 114 CreateEncodedBuffer(kTimestamp, kDuration);
115 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 115 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
116 116
117 // Verify the basic case where nothing is discarded. 117 // Verify the basic case where nothing is discarded.
118 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 118 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
119 ASSERT_TRUE(discard_helper.initialized()); 119 ASSERT_TRUE(discard_helper.initialized());
120 EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp()); 120 EXPECT_EQ(base::TimeDelta(), decoded_buffer->timestamp());
121 EXPECT_EQ(kDuration, decoded_buffer->duration()); 121 EXPECT_EQ(kDuration, decoded_buffer->duration());
122 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 122 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
123 } 123 }
124 124
125 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) { 125 TEST(AudioDiscardHelperTest, ProcessBuffersWithInitialDiscard) {
126 AudioDiscardHelper discard_helper(kSampleRate); 126 AudioDiscardHelper discard_helper(kSampleRate, 0);
127 ASSERT_FALSE(discard_helper.initialized()); 127 ASSERT_FALSE(discard_helper.initialized());
128 128
129 const base::TimeDelta kTimestamp = base::TimeDelta(); 129 const base::TimeDelta kTimestamp = base::TimeDelta();
130 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 130 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
131 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 131 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
132 132
133 // Tell the helper we want to discard half of the initial frames. 133 // Tell the helper we want to discard half of the initial frames.
134 const int kDiscardFrames = kTestFrames / 2; 134 const int kDiscardFrames = kTestFrames / 2;
135 discard_helper.Reset(kDiscardFrames); 135 discard_helper.Reset(kDiscardFrames);
136 136
137 scoped_refptr<DecoderBuffer> encoded_buffer = 137 scoped_refptr<DecoderBuffer> encoded_buffer =
138 CreateEncodedBuffer(kTimestamp, kDuration); 138 CreateEncodedBuffer(kTimestamp, kDuration);
139 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 139 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
140 140
141 // Verify half the frames end up discarded. 141 // Verify half the frames end up discarded.
142 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 142 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
143 ASSERT_TRUE(discard_helper.initialized()); 143 ASSERT_TRUE(discard_helper.initialized());
144 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 144 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
145 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 145 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
146 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); 146 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
147 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, 147 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
148 ExtractDecodedData(decoded_buffer, 0)); 148 ExtractDecodedData(decoded_buffer, 0));
149 } 149 }
150 150
151 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) { 151 TEST(AudioDiscardHelperTest, ProcessBuffersWithLargeInitialDiscard) {
152 AudioDiscardHelper discard_helper(kSampleRate); 152 AudioDiscardHelper discard_helper(kSampleRate, 0);
153 ASSERT_FALSE(discard_helper.initialized()); 153 ASSERT_FALSE(discard_helper.initialized());
154 154
155 const base::TimeDelta kTimestamp = base::TimeDelta(); 155 const base::TimeDelta kTimestamp = base::TimeDelta();
156 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 156 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
157 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 157 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
158 158
159 // Tell the helper we want to discard 1.5 buffers worth of frames. 159 // Tell the helper we want to discard 1.5 buffers worth of frames.
160 discard_helper.Reset(kTestFrames * 1.5); 160 discard_helper.Reset(kTestFrames * 1.5);
161 161
162 scoped_refptr<DecoderBuffer> encoded_buffer = 162 scoped_refptr<DecoderBuffer> encoded_buffer =
(...skipping 12 matching lines...) Expand all
175 // The timestamp should match that of the initial buffer. 175 // The timestamp should match that of the initial buffer.
176 const int kDiscardFrames = kTestFrames / 2; 176 const int kDiscardFrames = kTestFrames / 2;
177 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 177 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
178 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 178 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
179 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count()); 179 EXPECT_EQ(kDiscardFrames, decoded_buffer->frame_count());
180 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, 180 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
181 ExtractDecodedData(decoded_buffer, 0)); 181 ExtractDecodedData(decoded_buffer, 0));
182 } 182 }
183 183
184 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) { 184 TEST(AudioDiscardHelperTest, AllowNonMonotonicTimestamps) {
185 AudioDiscardHelper discard_helper(kSampleRate); 185 AudioDiscardHelper discard_helper(kSampleRate, 0);
186 ASSERT_FALSE(discard_helper.initialized()); 186 ASSERT_FALSE(discard_helper.initialized());
187 187
188 const base::TimeDelta kTimestamp = base::TimeDelta(); 188 const base::TimeDelta kTimestamp = base::TimeDelta();
189 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 189 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
190 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 190 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
191 191
192 scoped_refptr<DecoderBuffer> encoded_buffer = 192 scoped_refptr<DecoderBuffer> encoded_buffer =
193 CreateEncodedBuffer(kTimestamp, kDuration); 193 CreateEncodedBuffer(kTimestamp, kDuration);
194 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 194 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
195 195
196 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 196 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
197 ASSERT_TRUE(discard_helper.initialized()); 197 ASSERT_TRUE(discard_helper.initialized());
198 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 198 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
199 EXPECT_EQ(kDuration, decoded_buffer->duration()); 199 EXPECT_EQ(kDuration, decoded_buffer->duration());
200 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 200 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
201 201
202 // Process the same input buffer again to ensure input timestamps which go 202 // Process the same input buffer again to ensure input timestamps which go
203 // backwards in time are not errors. 203 // backwards in time are not errors.
204 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 204 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
205 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp()); 205 EXPECT_EQ(kTimestamp + kDuration, decoded_buffer->timestamp());
206 EXPECT_EQ(kDuration, decoded_buffer->duration()); 206 EXPECT_EQ(kDuration, decoded_buffer->duration());
207 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count()); 207 EXPECT_EQ(kTestFrames, decoded_buffer->frame_count());
208 } 208 }
209 209
210 TEST(AudioDiscardHelperTest, DiscardPadding) { 210 TEST(AudioDiscardHelperTest, DiscardEndPadding) {
211 AudioDiscardHelper discard_helper(kSampleRate); 211 AudioDiscardHelper discard_helper(kSampleRate, 0);
212 ASSERT_FALSE(discard_helper.initialized()); 212 ASSERT_FALSE(discard_helper.initialized());
213 213
214 const base::TimeDelta kTimestamp = base::TimeDelta(); 214 const base::TimeDelta kTimestamp = base::TimeDelta();
215 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 215 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
216 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 216 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
217 217
218 scoped_refptr<DecoderBuffer> encoded_buffer = 218 scoped_refptr<DecoderBuffer> encoded_buffer =
219 CreateEncodedBuffer(kTimestamp, kDuration); 219 CreateEncodedBuffer(kTimestamp, kDuration);
220 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 220 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
221 221
222 // Set a discard padding equivalent to half the buffer. 222 // Set a discard padding equivalent to half the buffer.
223 encoded_buffer->set_discard_padding(kDuration / 2); 223 encoded_buffer->set_discard_padding(
224 std::make_pair(base::TimeDelta(), kDuration / 2));
224 225
225 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 226 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
226 ASSERT_TRUE(discard_helper.initialized()); 227 ASSERT_TRUE(discard_helper.initialized());
227 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 228 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
228 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 229 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
229 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 230 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
230 ASSERT_FLOAT_EQ(0, ExtractDecodedData(decoded_buffer, 0));
231 } 231 }
232 232
233 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) { 233 TEST(AudioDiscardHelperTest, BadDiscardEndPadding) {
234 AudioDiscardHelper discard_helper(kSampleRate); 234 AudioDiscardHelper discard_helper(kSampleRate, 0);
235 ASSERT_FALSE(discard_helper.initialized()); 235 ASSERT_FALSE(discard_helper.initialized());
236 236
237 const base::TimeDelta kTimestamp = base::TimeDelta(); 237 const base::TimeDelta kTimestamp = base::TimeDelta();
238 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
239 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
240
241 scoped_refptr<DecoderBuffer> encoded_buffer =
242 CreateEncodedBuffer(kTimestamp, kDuration);
243 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
244
245 // Set a discard padding equivalent to double the buffer size.
246 encoded_buffer->set_discard_padding(
247 std::make_pair(base::TimeDelta(), kDuration * 2));
248
249 // Verify the end discard padding is rejected.
250 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
251 ASSERT_TRUE(discard_helper.initialized());
252 }
253
254 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardEndPadding) {
255 AudioDiscardHelper discard_helper(kSampleRate, 0);
256 ASSERT_FALSE(discard_helper.initialized());
257
258 const base::TimeDelta kTimestamp = base::TimeDelta();
238 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10); 259 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
239 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration); 260 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
240 261
241 scoped_refptr<DecoderBuffer> encoded_buffer = 262 scoped_refptr<DecoderBuffer> encoded_buffer =
242 CreateEncodedBuffer(kTimestamp, kDuration); 263 CreateEncodedBuffer(kTimestamp, kDuration);
243 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames); 264 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
244 265
245 // Set a discard padding equivalent to a quarter of the buffer. 266 // Set a discard padding equivalent to a quarter of the buffer.
246 encoded_buffer->set_discard_padding(kDuration / 4); 267 encoded_buffer->set_discard_padding(
268 std::make_pair(base::TimeDelta(), kDuration / 4));
247 269
248 // Set an initial discard of a quarter of the buffer. 270 // Set an initial discard of a quarter of the buffer.
249 const int kDiscardFrames = kTestFrames / 4; 271 const int kDiscardFrames = kTestFrames / 4;
250 discard_helper.Reset(kDiscardFrames); 272 discard_helper.Reset(kDiscardFrames);
251 273
252 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer)); 274 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
253 ASSERT_TRUE(discard_helper.initialized()); 275 ASSERT_TRUE(discard_helper.initialized());
254 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp()); 276 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
255 EXPECT_EQ(kDuration / 2, decoded_buffer->duration()); 277 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
256 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count()); 278 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
257 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep, 279 ASSERT_FLOAT_EQ(kDiscardFrames * kDataStep,
258 ExtractDecodedData(decoded_buffer, 0)); 280 ExtractDecodedData(decoded_buffer, 0));
259 } 281 }
260 282
283 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPadding) {
284 AudioDiscardHelper discard_helper(kSampleRate, 0);
285 ASSERT_FALSE(discard_helper.initialized());
286
287 const base::TimeDelta kTimestamp = base::TimeDelta();
288 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
289 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
290
291 scoped_refptr<DecoderBuffer> encoded_buffer =
292 CreateEncodedBuffer(kTimestamp, kDuration);
293 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
294
295 // Set a discard padding equivalent to a quarter of the buffer.
296 encoded_buffer->set_discard_padding(
297 std::make_pair(kDuration / 4, kDuration / 4));
298
299 // Set an initial discard of a quarter of the buffer.
300 const int kDiscardFrames = kTestFrames / 4;
301 discard_helper.Reset(kDiscardFrames);
302
303 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
304 ASSERT_TRUE(discard_helper.initialized());
305 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
306 EXPECT_EQ(kDuration / 4, decoded_buffer->duration());
307 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count());
308 }
309
310 TEST(AudioDiscardHelperTest, InitialDiscardAndDiscardPaddingAndCodecDelay) {
311 // Use a codec delay of 5ms.
312 const int kCodecDelay = kSampleRate / 100 / 2;
313 AudioDiscardHelper discard_helper(kSampleRate, kCodecDelay);
314 ASSERT_FALSE(discard_helper.initialized());
315 discard_helper.Reset(kCodecDelay);
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 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
324
325 // Set a discard padding equivalent to half of the buffer.
326 encoded_buffer->set_discard_padding(
327 std::make_pair(kDuration / 2, base::TimeDelta()));
328
329 // All of the first buffer should be discarded.
330 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
331 ASSERT_TRUE(discard_helper.initialized());
332
333 // Processing another buffer (with the same discard padding) should discard
334 // the back half of the buffer since kCodecDelay is half a buffer.
335 encoded_buffer->set_timestamp(kTimestamp + kDuration);
336 decoded_buffer = CreateDecodedBuffer(kTestFrames);
337 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
338 ASSERT_NEAR(kCodecDelay * kDataStep,
339 ExtractDecodedData(decoded_buffer, kCodecDelay),
340 kDataStep * 1000);
341 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
342 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
343 EXPECT_EQ(kDuration / 2, decoded_buffer->duration());
344 EXPECT_EQ(kTestFrames / 2, decoded_buffer->frame_count());
345
346 // Verify it was actually the latter half of the buffer that was removed.
347 ASSERT_FLOAT_EQ(0.0f, ExtractDecodedData(decoded_buffer, 0));
348 }
349
350 TEST(AudioDiscardHelperTest, DelayedDiscardInitialDiscardAndDiscardPadding) {
351 AudioDiscardHelper discard_helper(kSampleRate, 0);
352 ASSERT_FALSE(discard_helper.initialized());
353
354 const base::TimeDelta kTimestamp = base::TimeDelta();
355 const base::TimeDelta kDuration = base::TimeDelta::FromMilliseconds(10);
356 const int kTestFrames = discard_helper.TimeDeltaToFrames(kDuration);
357
358 scoped_refptr<DecoderBuffer> encoded_buffer =
359 CreateEncodedBuffer(kTimestamp, kDuration);
360
361 // Set a discard padding equivalent to a quarter of the buffer.
362 encoded_buffer->set_discard_padding(
363 std::make_pair(kDuration / 4, kDuration / 4));
364
365 // Set an initial discard of a quarter of the buffer.
366 discard_helper.Reset(kTestFrames / 4);
367
368 // Verify nothing is output for the first buffer, yet initialized is true.
369 ASSERT_FALSE(discard_helper.ProcessBuffers(encoded_buffer, NULL));
370 ASSERT_TRUE(discard_helper.initialized());
371
372 // Create an encoded buffer with no discard padding.
373 encoded_buffer = CreateEncodedBuffer(kTimestamp + kDuration, kDuration);
374 scoped_refptr<AudioBuffer> decoded_buffer = CreateDecodedBuffer(kTestFrames);
375
376 // Verify that when the decoded buffer is consumed, the discards from the
377 // previous encoded buffer are applied.
378 ASSERT_TRUE(discard_helper.ProcessBuffers(encoded_buffer, decoded_buffer));
379 EXPECT_EQ(kTimestamp, decoded_buffer->timestamp());
380 EXPECT_EQ(kDuration / 4, decoded_buffer->duration());
381 EXPECT_EQ(kTestFrames / 4, decoded_buffer->frame_count());
382 }
383
261 } // namespace media 384 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698