OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |