OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <deque> | 5 #include <deque> |
6 #include <string> | 6 #include <string> |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "media/blink/multibuffer.h" | 12 #include "media/blink/multibuffer.h" |
13 #include "media/blink/multibuffer_reader.h" | 13 #include "media/blink/multibuffer_reader.h" |
14 #include "media/blink/test_random.h" | 14 #include "media/blink/test_random.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 const int kBlockSizeShift = 8; | 17 const int kBlockSizeShift = 8; |
18 const size_t kBlockSize = 1UL << kBlockSizeShift; | 18 const size_t kBlockSize = 1UL << kBlockSizeShift; |
19 | 19 |
20 namespace media { | 20 namespace media { |
21 class TestMultiBufferDataProvider; | |
22 | 21 |
23 std::vector<TestMultiBufferDataProvider*> writers; | 22 class FakeMultiBufferDataProvider; |
24 | 23 |
25 class TestMultiBufferDataProvider : public media::MultiBuffer::DataProvider { | 24 namespace { |
| 25 std::vector<FakeMultiBufferDataProvider*> writers; |
| 26 } // namespace |
| 27 |
| 28 class FakeMultiBufferDataProvider : public MultiBuffer::DataProvider { |
26 public: | 29 public: |
27 TestMultiBufferDataProvider(MultiBufferBlockId pos, | 30 FakeMultiBufferDataProvider(MultiBufferBlockId pos, |
28 size_t file_size, | 31 size_t file_size, |
29 int max_blocks_after_defer, | 32 int max_blocks_after_defer, |
30 bool must_read_whole_file, | 33 bool must_read_whole_file, |
31 media::TestRandom* rnd) | 34 MultiBuffer* multibuffer, |
| 35 TestRandom* rnd) |
32 : pos_(pos), | 36 : pos_(pos), |
33 blocks_until_deferred_(1 << 30), | 37 blocks_until_deferred_(1 << 30), |
34 max_blocks_after_defer_(max_blocks_after_defer), | 38 max_blocks_after_defer_(max_blocks_after_defer), |
35 file_size_(file_size), | 39 file_size_(file_size), |
36 must_read_whole_file_(must_read_whole_file), | 40 must_read_whole_file_(must_read_whole_file), |
| 41 multibuffer_(multibuffer), |
37 rnd_(rnd) { | 42 rnd_(rnd) { |
38 writers.push_back(this); | 43 writers.push_back(this); |
39 } | 44 } |
40 | 45 |
41 ~TestMultiBufferDataProvider() override { | 46 ~FakeMultiBufferDataProvider() override { |
42 if (must_read_whole_file_) { | 47 if (must_read_whole_file_) { |
43 CHECK_GE(pos_ * kBlockSize, file_size_); | 48 CHECK_GE(pos_ * kBlockSize, file_size_); |
44 } | 49 } |
45 for (size_t i = 0; i < writers.size(); i++) { | 50 for (size_t i = 0; i < writers.size(); i++) { |
46 if (writers[i] == this) { | 51 if (writers[i] == this) { |
47 writers[i] = writers.back(); | 52 writers[i] = writers.back(); |
48 writers.pop_back(); | 53 writers.pop_back(); |
49 return; | 54 return; |
50 } | 55 } |
51 } | 56 } |
52 LOG(FATAL) << "Couldn't find myself in writers!"; | 57 LOG(FATAL) << "Couldn't find myself in writers!"; |
53 } | 58 } |
54 | 59 |
55 MultiBufferBlockId Tell() const override { return pos_; } | 60 MultiBufferBlockId Tell() const override { return pos_; } |
56 | 61 |
57 bool Available() const override { return !fifo_.empty(); } | 62 bool Available() const override { return !fifo_.empty(); } |
58 | 63 |
59 scoped_refptr<DataBuffer> Read() override { | 64 scoped_refptr<DataBuffer> Read() override { |
60 DCHECK(Available()); | 65 DCHECK(Available()); |
61 scoped_refptr<DataBuffer> ret = fifo_.front(); | 66 scoped_refptr<DataBuffer> ret = fifo_.front(); |
62 fifo_.pop_front(); | 67 fifo_.pop_front(); |
63 ++pos_; | 68 ++pos_; |
64 return ret; | 69 return ret; |
65 } | 70 } |
66 | 71 |
67 void SetAvailableCallback(const base::Closure& cb) override { | |
68 DCHECK(!Available()); | |
69 cb_ = cb; | |
70 } | |
71 | |
72 void SetDeferred(bool deferred) override { | 72 void SetDeferred(bool deferred) override { |
73 if (deferred) { | 73 if (deferred) { |
74 if (max_blocks_after_defer_ > 0) { | 74 if (max_blocks_after_defer_ > 0) { |
75 blocks_until_deferred_ = rnd_->Rand() % max_blocks_after_defer_; | 75 blocks_until_deferred_ = rnd_->Rand() % max_blocks_after_defer_; |
76 } else if (max_blocks_after_defer_ < 0) { | 76 } else if (max_blocks_after_defer_ < 0) { |
77 blocks_until_deferred_ = -max_blocks_after_defer_; | 77 blocks_until_deferred_ = -max_blocks_after_defer_; |
78 } else { | 78 } else { |
79 blocks_until_deferred_ = 0; | 79 blocks_until_deferred_ = 0; |
80 } | 80 } |
81 } else { | 81 } else { |
82 blocks_until_deferred_ = 1 << 30; | 82 blocks_until_deferred_ = 1 << 30; |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 bool Advance() { | 86 bool Advance() { |
87 if (blocks_until_deferred_ == 0) | 87 if (blocks_until_deferred_ == 0) |
88 return false; | 88 return false; |
89 --blocks_until_deferred_; | 89 --blocks_until_deferred_; |
90 | 90 |
91 bool ret = true; | 91 bool ret = true; |
92 scoped_refptr<media::DataBuffer> block = new media::DataBuffer(kBlockSize); | 92 scoped_refptr<DataBuffer> block = new DataBuffer(kBlockSize); |
93 size_t x = 0; | 93 size_t x = 0; |
94 size_t byte_pos = (fifo_.size() + pos_) * kBlockSize; | 94 size_t byte_pos = (fifo_.size() + pos_) * kBlockSize; |
95 for (x = 0; x < kBlockSize; x++, byte_pos++) { | 95 for (x = 0; x < kBlockSize; x++, byte_pos++) { |
96 if (byte_pos >= file_size_) | 96 if (byte_pos >= file_size_) |
97 break; | 97 break; |
98 block->writable_data()[x] = | 98 block->writable_data()[x] = |
99 static_cast<uint8_t>((byte_pos * 15485863) >> 16); | 99 static_cast<uint8_t>((byte_pos * 15485863) >> 16); |
100 } | 100 } |
101 block->set_data_size(static_cast<int>(x)); | 101 block->set_data_size(static_cast<int>(x)); |
102 fifo_.push_back(block); | 102 fifo_.push_back(block); |
103 if (byte_pos == file_size_) { | 103 if (byte_pos == file_size_) { |
104 fifo_.push_back(DataBuffer::CreateEOSBuffer()); | 104 fifo_.push_back(DataBuffer::CreateEOSBuffer()); |
105 ret = false; | 105 ret = false; |
106 } | 106 } |
107 cb_.Run(); | 107 multibuffer_->OnDataProviderEvent(this); |
108 return ret; | 108 return ret; |
109 } | 109 } |
110 | 110 |
111 private: | 111 private: |
112 std::deque<scoped_refptr<media::DataBuffer>> fifo_; | 112 std::deque<scoped_refptr<DataBuffer>> fifo_; |
113 MultiBufferBlockId pos_; | 113 MultiBufferBlockId pos_; |
114 int32_t blocks_until_deferred_; | 114 int32_t blocks_until_deferred_; |
115 int32_t max_blocks_after_defer_; | 115 int32_t max_blocks_after_defer_; |
116 size_t file_size_; | 116 size_t file_size_; |
117 bool must_read_whole_file_; | 117 bool must_read_whole_file_; |
118 base::Closure cb_; | 118 MultiBuffer* multibuffer_; |
119 media::TestRandom* rnd_; | 119 TestRandom* rnd_; |
120 }; | 120 }; |
121 | 121 |
122 class TestMultiBuffer : public media::MultiBuffer { | 122 class TestMultiBuffer : public MultiBuffer { |
123 public: | 123 public: |
124 explicit TestMultiBuffer( | 124 explicit TestMultiBuffer(int32_t shift, |
125 int32_t shift, | 125 const scoped_refptr<MultiBuffer::GlobalLRU>& lru, |
126 const scoped_refptr<media::MultiBuffer::GlobalLRU>& lru, | 126 TestRandom* rnd) |
127 media::TestRandom* rnd) | 127 : MultiBuffer(shift, lru), |
128 : media::MultiBuffer(shift, lru), | |
129 range_supported_(false), | 128 range_supported_(false), |
130 create_ok_(true), | 129 create_ok_(true), |
131 max_writers_(10000), | 130 max_writers_(10000), |
132 file_size_(1 << 30), | 131 file_size_(1 << 30), |
133 max_blocks_after_defer_(0), | 132 max_blocks_after_defer_(0), |
134 must_read_whole_file_(false), | 133 must_read_whole_file_(false), |
135 writers_created_(0), | 134 writers_created_(0), |
136 rnd_(rnd) {} | 135 rnd_(rnd) {} |
137 | 136 |
138 void SetMaxWriters(size_t max_writers) { max_writers_ = max_writers; } | 137 void SetMaxWriters(size_t max_writers) { max_writers_ = max_writers; } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 177 |
179 void SetMustReadWholeFile(bool must_read_whole_file) { | 178 void SetMustReadWholeFile(bool must_read_whole_file) { |
180 must_read_whole_file_ = must_read_whole_file; | 179 must_read_whole_file_ = must_read_whole_file; |
181 } | 180 } |
182 | 181 |
183 int32_t writers_created() const { return writers_created_; } | 182 int32_t writers_created() const { return writers_created_; } |
184 | 183 |
185 void SetRangeSupported(bool supported) { range_supported_ = supported; } | 184 void SetRangeSupported(bool supported) { range_supported_ = supported; } |
186 | 185 |
187 protected: | 186 protected: |
188 DataProvider* CreateWriter(const MultiBufferBlockId& pos) override { | 187 scoped_ptr<DataProvider> CreateWriter( |
| 188 const MultiBufferBlockId& pos) override { |
189 DCHECK(create_ok_); | 189 DCHECK(create_ok_); |
190 writers_created_++; | 190 writers_created_++; |
191 CHECK_LT(writers.size(), max_writers_); | 191 CHECK_LT(writers.size(), max_writers_); |
192 return new TestMultiBufferDataProvider( | 192 return scoped_ptr<DataProvider>(new FakeMultiBufferDataProvider( |
193 pos, file_size_, max_blocks_after_defer_, must_read_whole_file_, rnd_); | 193 pos, file_size_, max_blocks_after_defer_, must_read_whole_file_, this, |
| 194 rnd_)); |
194 } | 195 } |
195 void Prune(size_t max_to_free) override { | 196 void Prune(size_t max_to_free) override { |
196 // Prune should not cause additional writers to be spawned. | 197 // Prune should not cause additional writers to be spawned. |
197 create_ok_ = false; | 198 create_ok_ = false; |
198 MultiBuffer::Prune(max_to_free); | 199 MultiBuffer::Prune(max_to_free); |
199 create_ok_ = true; | 200 create_ok_ = true; |
200 } | 201 } |
201 | 202 |
202 bool RangeSupported() const override { return range_supported_; } | 203 bool RangeSupported() const override { return range_supported_; } |
203 | 204 |
204 private: | 205 private: |
205 bool range_supported_; | 206 bool range_supported_; |
206 bool create_ok_; | 207 bool create_ok_; |
207 size_t max_writers_; | 208 size_t max_writers_; |
208 size_t file_size_; | 209 size_t file_size_; |
209 int32_t max_blocks_after_defer_; | 210 int32_t max_blocks_after_defer_; |
210 bool must_read_whole_file_; | 211 bool must_read_whole_file_; |
211 int32_t writers_created_; | 212 int32_t writers_created_; |
212 media::TestRandom* rnd_; | 213 TestRandom* rnd_; |
213 }; | 214 }; |
214 } | |
215 | 215 |
216 class MultiBufferTest : public testing::Test { | 216 class MultiBufferTest : public testing::Test { |
217 public: | 217 public: |
218 MultiBufferTest() | 218 MultiBufferTest() |
219 : rnd_(42), | 219 : rnd_(42), |
220 lru_(new media::MultiBuffer::GlobalLRU()), | 220 lru_(new MultiBuffer::GlobalLRU()), |
221 multibuffer_(kBlockSizeShift, lru_, &rnd_) {} | 221 multibuffer_(kBlockSizeShift, lru_, &rnd_) {} |
222 | 222 |
223 void Advance() { | 223 void Advance() { |
224 CHECK(media::writers.size()); | 224 CHECK(writers.size()); |
225 media::writers[rnd_.Rand() % media::writers.size()]->Advance(); | 225 writers[rnd_.Rand() % writers.size()]->Advance(); |
226 } | 226 } |
227 | 227 |
228 bool AdvanceAll() { | 228 bool AdvanceAll() { |
229 bool advanced = false; | 229 bool advanced = false; |
230 for (size_t i = 0; i < media::writers.size(); i++) { | 230 for (size_t i = 0; i < writers.size(); i++) { |
231 advanced |= media::writers[i]->Advance(); | 231 advanced |= writers[i]->Advance(); |
232 } | 232 } |
233 multibuffer_.CheckLRUState(); | 233 multibuffer_.CheckLRUState(); |
234 return advanced; | 234 return advanced; |
235 } | 235 } |
236 | 236 |
237 protected: | 237 protected: |
238 media::TestRandom rnd_; | 238 TestRandom rnd_; |
239 scoped_refptr<media::MultiBuffer::GlobalLRU> lru_; | 239 scoped_refptr<MultiBuffer::GlobalLRU> lru_; |
240 media::TestMultiBuffer multibuffer_; | 240 TestMultiBuffer multibuffer_; |
241 base::MessageLoop message_loop_; | 241 base::MessageLoop message_loop_; |
242 }; | 242 }; |
243 | 243 |
244 TEST_F(MultiBufferTest, ReadAll) { | 244 TEST_F(MultiBufferTest, ReadAll) { |
245 multibuffer_.SetMaxWriters(1); | 245 multibuffer_.SetMaxWriters(1); |
246 size_t pos = 0; | 246 size_t pos = 0; |
247 size_t end = 10000; | 247 size_t end = 10000; |
248 multibuffer_.SetFileSize(10000); | 248 multibuffer_.SetFileSize(10000); |
249 multibuffer_.SetMustReadWholeFile(true); | 249 multibuffer_.SetMustReadWholeFile(true); |
250 media::MultiBufferReader reader(&multibuffer_, pos, end, | 250 MultiBufferReader reader(&multibuffer_, pos, end, |
251 base::Callback<void(int64_t, int64_t)>()); | 251 base::Callback<void(int64_t, int64_t)>()); |
252 reader.SetMaxBuffer(2000, 5000); | 252 reader.SetMaxBuffer(2000, 5000); |
253 reader.SetPreload(1000, 1000); | 253 reader.SetPreload(1000, 1000); |
254 while (pos < end) { | 254 while (pos < end) { |
255 unsigned char buffer[27]; | 255 unsigned char buffer[27]; |
256 buffer[17] = 17; | 256 buffer[17] = 17; |
257 size_t to_read = std::min<size_t>(end - pos, 17); | 257 size_t to_read = std::min<size_t>(end - pos, 17); |
258 int64_t bytes_read = reader.TryRead(buffer, to_read); | 258 int64_t bytes_read = reader.TryRead(buffer, to_read); |
259 if (bytes_read) { | 259 if (bytes_read) { |
260 EXPECT_EQ(buffer[17], 17); | 260 EXPECT_EQ(buffer[17], 17); |
261 for (int64_t i = 0; i < bytes_read; i++) { | 261 for (int64_t i = 0; i < bytes_read; i++) { |
262 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); | 262 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); |
263 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; | 263 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; |
264 pos++; | 264 pos++; |
265 } | 265 } |
266 } else { | 266 } else { |
267 Advance(); | 267 Advance(); |
268 } | 268 } |
269 } | 269 } |
270 } | 270 } |
271 | 271 |
272 TEST_F(MultiBufferTest, ReadAllAdvanceFirst) { | 272 TEST_F(MultiBufferTest, ReadAllAdvanceFirst) { |
273 multibuffer_.SetMaxWriters(1); | 273 multibuffer_.SetMaxWriters(1); |
274 size_t pos = 0; | 274 size_t pos = 0; |
275 size_t end = 10000; | 275 size_t end = 10000; |
276 multibuffer_.SetFileSize(10000); | 276 multibuffer_.SetFileSize(10000); |
277 multibuffer_.SetMustReadWholeFile(true); | 277 multibuffer_.SetMustReadWholeFile(true); |
278 media::MultiBufferReader reader(&multibuffer_, pos, end, | 278 MultiBufferReader reader(&multibuffer_, pos, end, |
279 base::Callback<void(int64_t, int64_t)>()); | 279 base::Callback<void(int64_t, int64_t)>()); |
280 reader.SetMaxBuffer(2000, 5000); | 280 reader.SetMaxBuffer(2000, 5000); |
281 reader.SetPreload(1000, 1000); | 281 reader.SetPreload(1000, 1000); |
282 while (pos < end) { | 282 while (pos < end) { |
283 unsigned char buffer[27]; | 283 unsigned char buffer[27]; |
284 buffer[17] = 17; | 284 buffer[17] = 17; |
285 size_t to_read = std::min<size_t>(end - pos, 17); | 285 size_t to_read = std::min<size_t>(end - pos, 17); |
286 while (AdvanceAll()) | 286 while (AdvanceAll()) |
287 ; | 287 ; |
288 int64_t bytes = reader.TryRead(buffer, to_read); | 288 int64_t bytes = reader.TryRead(buffer, to_read); |
289 EXPECT_GT(bytes, 0); | 289 EXPECT_GT(bytes, 0); |
290 EXPECT_EQ(buffer[17], 17); | 290 EXPECT_EQ(buffer[17], 17); |
291 for (int64_t i = 0; i < bytes; i++) { | 291 for (int64_t i = 0; i < bytes; i++) { |
292 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); | 292 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); |
293 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; | 293 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; |
294 pos++; | 294 pos++; |
295 } | 295 } |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 // Checks that if the data provider provides too much data after we told it | 299 // Checks that if the data provider provides too much data after we told it |
300 // to defer, we kill it. | 300 // to defer, we kill it. |
301 TEST_F(MultiBufferTest, ReadAllAdvanceFirst_NeverDefer) { | 301 TEST_F(MultiBufferTest, ReadAllAdvanceFirst_NeverDefer) { |
302 multibuffer_.SetMaxWriters(1); | 302 multibuffer_.SetMaxWriters(1); |
303 size_t pos = 0; | 303 size_t pos = 0; |
304 size_t end = 10000; | 304 size_t end = 10000; |
305 multibuffer_.SetFileSize(10000); | 305 multibuffer_.SetFileSize(10000); |
306 multibuffer_.SetMaxBlocksAfterDefer(-10000); | 306 multibuffer_.SetMaxBlocksAfterDefer(-10000); |
307 multibuffer_.SetRangeSupported(true); | 307 multibuffer_.SetRangeSupported(true); |
308 media::MultiBufferReader reader(&multibuffer_, pos, end, | 308 MultiBufferReader reader(&multibuffer_, pos, end, |
309 base::Callback<void(int64_t, int64_t)>()); | 309 base::Callback<void(int64_t, int64_t)>()); |
310 reader.SetMaxBuffer(2000, 5000); | 310 reader.SetMaxBuffer(2000, 5000); |
311 reader.SetPreload(1000, 1000); | 311 reader.SetPreload(1000, 1000); |
312 while (pos < end) { | 312 while (pos < end) { |
313 unsigned char buffer[27]; | 313 unsigned char buffer[27]; |
314 buffer[17] = 17; | 314 buffer[17] = 17; |
315 size_t to_read = std::min<size_t>(end - pos, 17); | 315 size_t to_read = std::min<size_t>(end - pos, 17); |
316 while (AdvanceAll()) | 316 while (AdvanceAll()) |
317 ; | 317 ; |
318 int64_t bytes = reader.TryRead(buffer, to_read); | 318 int64_t bytes = reader.TryRead(buffer, to_read); |
319 EXPECT_GT(bytes, 0); | 319 EXPECT_GT(bytes, 0); |
320 EXPECT_EQ(buffer[17], 17); | 320 EXPECT_EQ(buffer[17], 17); |
321 for (int64_t i = 0; i < bytes; i++) { | 321 for (int64_t i = 0; i < bytes; i++) { |
322 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); | 322 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); |
323 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; | 323 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; |
324 pos++; | 324 pos++; |
325 } | 325 } |
326 } | 326 } |
327 EXPECT_GT(multibuffer_.writers_created(), 1); | 327 EXPECT_GT(multibuffer_.writers_created(), 1); |
328 } | 328 } |
329 | 329 |
330 // Same as ReadAllAdvanceFirst_NeverDefer, but the url doesn't support | 330 // Same as ReadAllAdvanceFirst_NeverDefer, but the url doesn't support |
331 // ranges, so we don't destroy it no matter how much data it provides. | 331 // ranges, so we don't destroy it no matter how much data it provides. |
332 TEST_F(MultiBufferTest, ReadAllAdvanceFirst_NeverDefer2) { | 332 TEST_F(MultiBufferTest, ReadAllAdvanceFirst_NeverDefer2) { |
333 multibuffer_.SetMaxWriters(1); | 333 multibuffer_.SetMaxWriters(1); |
334 size_t pos = 0; | 334 size_t pos = 0; |
335 size_t end = 10000; | 335 size_t end = 10000; |
336 multibuffer_.SetFileSize(10000); | 336 multibuffer_.SetFileSize(10000); |
337 multibuffer_.SetMustReadWholeFile(true); | 337 multibuffer_.SetMustReadWholeFile(true); |
338 multibuffer_.SetMaxBlocksAfterDefer(-10000); | 338 multibuffer_.SetMaxBlocksAfterDefer(-10000); |
339 media::MultiBufferReader reader(&multibuffer_, pos, end, | 339 MultiBufferReader reader(&multibuffer_, pos, end, |
340 base::Callback<void(int64_t, int64_t)>()); | 340 base::Callback<void(int64_t, int64_t)>()); |
341 reader.SetMaxBuffer(2000, 5000); | 341 reader.SetMaxBuffer(2000, 5000); |
342 reader.SetPreload(1000, 1000); | 342 reader.SetPreload(1000, 1000); |
343 while (pos < end) { | 343 while (pos < end) { |
344 unsigned char buffer[27]; | 344 unsigned char buffer[27]; |
345 buffer[17] = 17; | 345 buffer[17] = 17; |
346 size_t to_read = std::min<size_t>(end - pos, 17); | 346 size_t to_read = std::min<size_t>(end - pos, 17); |
347 while (AdvanceAll()) | 347 while (AdvanceAll()) |
348 ; | 348 ; |
349 int64_t bytes = reader.TryRead(buffer, to_read); | 349 int64_t bytes = reader.TryRead(buffer, to_read); |
350 EXPECT_GT(bytes, 0); | 350 EXPECT_GT(bytes, 0); |
351 EXPECT_EQ(buffer[17], 17); | 351 EXPECT_EQ(buffer[17], 17); |
352 for (int64_t i = 0; i < bytes; i++) { | 352 for (int64_t i = 0; i < bytes; i++) { |
353 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); | 353 uint8_t expected = static_cast<uint8_t>((pos * 15485863) >> 16); |
354 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; | 354 EXPECT_EQ(expected, buffer[i]) << " pos = " << pos; |
355 pos++; | 355 pos++; |
356 } | 356 } |
357 } | 357 } |
358 } | 358 } |
359 | 359 |
360 TEST_F(MultiBufferTest, LRUTest) { | 360 TEST_F(MultiBufferTest, LRUTest) { |
361 int64_t max_size = 17; | 361 int64_t max_size = 17; |
362 int64_t current_size = 0; | 362 int64_t current_size = 0; |
363 lru_->IncrementMaxSize(max_size); | 363 lru_->IncrementMaxSize(max_size); |
364 | 364 |
365 multibuffer_.SetMaxWriters(1); | 365 multibuffer_.SetMaxWriters(1); |
366 size_t pos = 0; | 366 size_t pos = 0; |
367 size_t end = 10000; | 367 size_t end = 10000; |
368 multibuffer_.SetFileSize(10000); | 368 multibuffer_.SetFileSize(10000); |
369 media::MultiBufferReader reader(&multibuffer_, pos, end, | 369 MultiBufferReader reader(&multibuffer_, pos, end, |
370 base::Callback<void(int64_t, int64_t)>()); | 370 base::Callback<void(int64_t, int64_t)>()); |
371 reader.SetPreload(10000, 10000); | 371 reader.SetPreload(10000, 10000); |
372 // Note, no pinning, all data should end up in LRU. | 372 // Note, no pinning, all data should end up in LRU. |
373 EXPECT_EQ(current_size, lru_->Size()); | 373 EXPECT_EQ(current_size, lru_->Size()); |
374 current_size += max_size; | 374 current_size += max_size; |
375 while (AdvanceAll()) | 375 while (AdvanceAll()) |
376 ; | 376 ; |
377 EXPECT_EQ(current_size, lru_->Size()); | 377 EXPECT_EQ(current_size, lru_->Size()); |
378 lru_->IncrementMaxSize(-max_size); | 378 lru_->IncrementMaxSize(-max_size); |
379 lru_->Prune(3); | 379 lru_->Prune(3); |
380 current_size -= 3; | 380 current_size -= 3; |
381 EXPECT_EQ(current_size, lru_->Size()); | 381 EXPECT_EQ(current_size, lru_->Size()); |
382 lru_->Prune(3); | 382 lru_->Prune(3); |
383 current_size -= 3; | 383 current_size -= 3; |
384 EXPECT_EQ(current_size, lru_->Size()); | 384 EXPECT_EQ(current_size, lru_->Size()); |
385 lru_->Prune(1000); | 385 lru_->Prune(1000); |
386 EXPECT_EQ(0, lru_->Size()); | 386 EXPECT_EQ(0, lru_->Size()); |
387 } | 387 } |
388 | 388 |
389 class ReadHelper { | 389 class ReadHelper { |
390 public: | 390 public: |
391 ReadHelper(size_t end, | 391 ReadHelper(size_t end, |
392 size_t max_read_size, | 392 size_t max_read_size, |
393 media::MultiBuffer* multibuffer, | 393 MultiBuffer* multibuffer, |
394 media::TestRandom* rnd) | 394 TestRandom* rnd) |
395 : pos_(0), | 395 : pos_(0), |
396 end_(end), | 396 end_(end), |
397 max_read_size_(max_read_size), | 397 max_read_size_(max_read_size), |
398 read_size_(0), | 398 read_size_(0), |
399 rnd_(rnd), | 399 rnd_(rnd), |
400 reader_(multibuffer, | 400 reader_(multibuffer, |
401 pos_, | 401 pos_, |
402 end_, | 402 end_, |
403 base::Callback<void(int64_t, int64_t)>()) { | 403 base::Callback<void(int64_t, int64_t)>()) { |
404 reader_.SetMaxBuffer(2000, 5000); | 404 reader_.SetMaxBuffer(2000, 5000); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 pos_ = rnd_->Rand() % end_; | 439 pos_ = rnd_->Rand() % end_; |
440 reader_.Seek(pos_); | 440 reader_.Seek(pos_); |
441 CHECK_EQ(pos_, reader_.Tell()); | 441 CHECK_EQ(pos_, reader_.Tell()); |
442 } | 442 } |
443 | 443 |
444 private: | 444 private: |
445 int64_t pos_; | 445 int64_t pos_; |
446 int64_t end_; | 446 int64_t end_; |
447 int64_t max_read_size_; | 447 int64_t max_read_size_; |
448 int64_t read_size_; | 448 int64_t read_size_; |
449 media::TestRandom* rnd_; | 449 TestRandom* rnd_; |
450 media::MultiBufferReader reader_; | 450 MultiBufferReader reader_; |
451 }; | 451 }; |
452 | 452 |
453 TEST_F(MultiBufferTest, RandomTest) { | 453 TEST_F(MultiBufferTest, RandomTest) { |
454 size_t file_size = 1000000; | 454 size_t file_size = 1000000; |
455 multibuffer_.SetFileSize(file_size); | 455 multibuffer_.SetFileSize(file_size); |
456 multibuffer_.SetMaxBlocksAfterDefer(10); | 456 multibuffer_.SetMaxBlocksAfterDefer(10); |
457 std::vector<ReadHelper*> read_helpers; | 457 std::vector<ReadHelper*> read_helpers; |
458 for (size_t i = 0; i < 20; i++) { | 458 for (size_t i = 0; i < 20; i++) { |
459 read_helpers.push_back( | 459 read_helpers.push_back( |
460 new ReadHelper(file_size, 1000, &multibuffer_, &rnd_)); | 460 new ReadHelper(file_size, 1000, &multibuffer_, &rnd_)); |
461 } | 461 } |
462 for (int i = 0; i < 100; i++) { | 462 for (int i = 0; i < 100; i++) { |
463 for (int j = 0; j < 100; j++) { | 463 for (int j = 0; j < 100; j++) { |
464 if (rnd_.Rand() & 1) { | 464 if (rnd_.Rand() & 1) { |
465 if (!media::writers.empty()) | 465 if (!writers.empty()) |
466 Advance(); | 466 Advance(); |
467 } else { | 467 } else { |
468 size_t j = rnd_.Rand() % read_helpers.size(); | 468 size_t j = rnd_.Rand() % read_helpers.size(); |
469 if (rnd_.Rand() % 100 < 3) | 469 if (rnd_.Rand() % 100 < 3) |
470 read_helpers[j]->Seek(); | 470 read_helpers[j]->Seek(); |
471 read_helpers[j]->StartRead(); | 471 read_helpers[j]->StartRead(); |
472 } | 472 } |
473 } | 473 } |
474 multibuffer_.CheckLRUState(); | 474 multibuffer_.CheckLRUState(); |
475 } | 475 } |
(...skipping 10 matching lines...) Expand all Loading... |
486 multibuffer_.SetMaxBlocksAfterDefer(10); | 486 multibuffer_.SetMaxBlocksAfterDefer(10); |
487 std::vector<ReadHelper*> read_helpers; | 487 std::vector<ReadHelper*> read_helpers; |
488 multibuffer_.SetRangeSupported(true); | 488 multibuffer_.SetRangeSupported(true); |
489 for (size_t i = 0; i < 20; i++) { | 489 for (size_t i = 0; i < 20; i++) { |
490 read_helpers.push_back( | 490 read_helpers.push_back( |
491 new ReadHelper(file_size, 1000, &multibuffer_, &rnd_)); | 491 new ReadHelper(file_size, 1000, &multibuffer_, &rnd_)); |
492 } | 492 } |
493 for (int i = 0; i < 100; i++) { | 493 for (int i = 0; i < 100; i++) { |
494 for (int j = 0; j < 100; j++) { | 494 for (int j = 0; j < 100; j++) { |
495 if (rnd_.Rand() & 1) { | 495 if (rnd_.Rand() & 1) { |
496 if (!media::writers.empty()) | 496 if (!writers.empty()) |
497 Advance(); | 497 Advance(); |
498 } else { | 498 } else { |
499 size_t j = rnd_.Rand() % read_helpers.size(); | 499 size_t j = rnd_.Rand() % read_helpers.size(); |
500 if (rnd_.Rand() % 100 < 3) | 500 if (rnd_.Rand() % 100 < 3) |
501 read_helpers[j]->Seek(); | 501 read_helpers[j]->Seek(); |
502 read_helpers[j]->StartRead(); | 502 read_helpers[j]->StartRead(); |
503 } | 503 } |
504 } | 504 } |
505 multibuffer_.CheckLRUState(); | 505 multibuffer_.CheckLRUState(); |
506 } | 506 } |
507 multibuffer_.CheckPresentState(); | 507 multibuffer_.CheckPresentState(); |
508 while (!read_helpers.empty()) { | 508 while (!read_helpers.empty()) { |
509 delete read_helpers.back(); | 509 delete read_helpers.back(); |
510 read_helpers.pop_back(); | 510 read_helpers.pop_back(); |
511 } | 511 } |
512 } | 512 } |
| 513 |
| 514 } // namespace media |
OLD | NEW |