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

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

Issue 9113023: Fire canplaythrough as soon as download defers to fix autoplay (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase to ToT Created 8 years, 11 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
« no previous file with comments | « media/base/download_rate_monitor.cc ('k') | webkit/media/buffered_data_source.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "media/base/download_rate_monitor.h" 5 #include "media/base/download_rate_monitor.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "testing/gmock/include/gmock/gmock.h" 9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
11 11
12 using ::testing::Mock; 12 using ::testing::Mock;
13 13
14 namespace media { 14 namespace media {
15 15
16 class DownloadRateMonitorTest : public ::testing::Test { 16 class DownloadRateMonitorTest : public ::testing::Test {
17 public: 17 public:
18 DownloadRateMonitorTest() { 18 DownloadRateMonitorTest()
19 monitor_.set_total_bytes(kMediaSizeInBytes); 19 : canplaythrough_cb_(base::Bind(&DownloadRateMonitorTest::CanPlayThrough,
20 } 20 base::Unretained(this))) { }
21 21
22 virtual ~DownloadRateMonitorTest() { } 22 virtual ~DownloadRateMonitorTest() { }
23 23
24 MOCK_METHOD0(CanPlayThrough, void()); 24 MOCK_METHOD0(CanPlayThrough, void());
25 25
26 protected: 26 protected:
27 static const int kMediaSizeInBytes = 20 * 1024 * 1024; 27 static const int kMediaDuration = 120;
28 28 static const int kMediaBitrate = 1024 * 1024 * 8;
29 // Simulates downloading of the media file. Packets are timed evenly in 29 static const int kMediaByterate = kMediaBitrate / 8;
30 // |ms_between_packets| intervals, starting at |starting_time|, which is 30 static const int kMediaSizeInBytes = kMediaDuration * kMediaByterate;
31 // number of seconds since unix epoch (Jan 1, 1970). 31 static const int kDeferThreshold = 30 * kMediaByterate;
32 // Returns the number of bytes buffered in the media file after the 32
33 // network activity. 33 // Simulates downloading |bytes_to_download| bytes of the media file, at
34 int SimulateNetwork(double starting_time, 34 // |download_speed_in_bps| bytes per second.
35 int starting_bytes, 35 void SimulateNetwork(int bytes_to_download, int download_speed_in_bps) {
36 int bytes_per_packet, 36 int bytes_downloaded = 0;
37 int ms_between_packets, 37 while (bytes_downloaded < bytes_to_download &&
38 int number_of_packets) { 38 !data_source_.is_deferred()) {
39 int bytes_buffered = starting_bytes; 39 int bytes_left_to_download = bytes_to_download - bytes_downloaded;
40 base::Time packet_time = base::Time::FromDoubleT(starting_time); 40 int packet_size = std::min(download_speed_in_bps, bytes_left_to_download);
41 41 time_elapsed_ += base::TimeDelta::FromMilliseconds(
42 monitor_.SetNetworkActivity(true); 42 1000 * packet_size / download_speed_in_bps);
43 // Loop executes (number_of_packets + 1) times because a packet needs a 43 data_source_.ReceiveData(
44 // starting and end point. 44 packet_size, time_elapsed_ + base::Time::UnixEpoch());
45 for (int i = 0; i < number_of_packets + 1; ++i) { 45 bytes_downloaded += packet_size;
46 monitor_.SetBufferedBytes(bytes_buffered, packet_time); 46 }
47 packet_time += base::TimeDelta::FromMilliseconds(ms_between_packets); 47 }
48 bytes_buffered += bytes_per_packet; 48
49 } 49 void Initialize() {
50 monitor_.SetNetworkActivity(false); 50 Initialize(false, false);
51 return bytes_buffered; 51 }
52 } 52
53 53 void Initialize(bool streaming, bool local_source) {
54 void StartMonitor(int bitrate) { 54 data_source_.Initialize(
55 StartMonitor(bitrate, false, false); 55 kMediaBitrate, streaming, local_source, canplaythrough_cb_);
56 } 56 }
57 57
58 void StartMonitor(int bitrate, bool streaming, bool local_source) { 58 bool DownloadIsDeferred() {
59 monitor_.Start(base::Bind(&DownloadRateMonitorTest::CanPlayThrough, 59 return data_source_.is_deferred();
60 base::Unretained(this)), bitrate, streaming, local_source); 60 }
61 } 61
62 62 void SeekTo(int offset) {
63 DownloadRateMonitor monitor_; 63 data_source_.SeekTo(offset);
64 }
65
66 // Returns the size of |seconds| seconds of media data in bytes.
67 int SecondsToBytes(int seconds) {
68 return seconds * kMediaByterate;
69 }
64 70
65 private: 71 private:
72 // Helper class to simulate a buffered data source.
73 class FakeDataSource {
74 public:
75 FakeDataSource()
76 : total_bytes_(kMediaSizeInBytes),
77 buffered_bytes_(0),
78 offset_(0),
79 defer_threshold_(kDeferThreshold),
80 is_downloading_data_(true) { }
81
82 bool is_deferred() { return !is_downloading_data_; }
83
84 void ReceiveData(int bytes_received, base::Time packet_time) {
85 CHECK(is_downloading_data_);
86 buffered_bytes_ += bytes_received;
87 // This simulates that the download is being deferred.
88 if (buffered_bytes_ >= defer_threshold_)
89 is_downloading_data_ = false;
90
91 // Update monitor's state.
92 monitor_.SetNetworkActivity(is_downloading_data_);
93 monitor_.set_total_bytes(total_bytes_);
94 monitor_.SetBufferedBytes(buffered_bytes_ + offset_, packet_time);
95 }
96
97 void Initialize(int bitrate, bool streaming, bool local_source,
98 const base::Closure& canplaythrough_cb) {
99 monitor_.Start(canplaythrough_cb, bitrate, streaming, local_source);
100 }
101
102 void SeekTo(int byte_position) {
103 offset_ = byte_position;
104 // Simulate recreating the buffer after a seek.
105 buffered_bytes_ = 0;
106 is_downloading_data_ = true;
107 }
108
109 private:
110 DownloadRateMonitor monitor_;
111
112 // Size of the media file being downloaded, in bytes.
113 int total_bytes_;
114
115 // Number of bytes currently in buffer.
116 int buffered_bytes_;
117
118 // The byte offset into the file from which the download began.
119 int offset_;
120
121 // The size of |buffered_bytes_| at which downloading should defer.
122 int defer_threshold_;
123
124 // True if download is active (not deferred_, false otherwise.
125 bool is_downloading_data_;
126 };
127
128 FakeDataSource data_source_;
129 base::Closure canplaythrough_cb_;
130
131 // Amount of time elapsed while downloading data.
132 base::TimeDelta time_elapsed_;
133
66 DISALLOW_COPY_AND_ASSIGN(DownloadRateMonitorTest); 134 DISALLOW_COPY_AND_ASSIGN(DownloadRateMonitorTest);
67 }; 135 };
68 136
69 TEST_F(DownloadRateMonitorTest, DownloadRateGreaterThanBitrate) { 137 TEST_F(DownloadRateMonitorTest, DownloadRateGreaterThanBitrate) {
70 static const int media_bitrate = 1024 * 1024 * 8;
71
72 // Simulate downloading at double the media's bitrate. 138 // Simulate downloading at double the media's bitrate.
73 StartMonitor(media_bitrate); 139 Initialize();
74 EXPECT_CALL(*this, CanPlayThrough()); 140 EXPECT_CALL(*this, CanPlayThrough());
75 SimulateNetwork(1, 0, 2 * media_bitrate / 8, 1000, 10); 141 SimulateNetwork(SecondsToBytes(20), 2 * kMediaByterate);
76 } 142 }
77 143
78 // If the user pauses and the pipeline stops downloading data, make sure the 144 TEST_F(DownloadRateMonitorTest, DownloadRateLessThanBitrate_Defer) {
79 // DownloadRateMonitor understands that the download is not stalling. 145 Initialize();
80 TEST_F(DownloadRateMonitorTest, DownloadRateGreaterThanBitrate_Pause) { 146
81 static const int media_bitrate = 1024 * 1024 * 8; 147 // Download slower than the media's bitrate, but buffer enough data such that
82 static const int download_byte_rate = 1.1 * media_bitrate / 8; 148 // the data source defers.
83 149 EXPECT_CALL(*this, CanPlayThrough());
150 SimulateNetwork(kDeferThreshold, 0.3 * kMediaByterate);
151 CHECK(DownloadIsDeferred());
152 }
153
154 TEST_F(DownloadRateMonitorTest, DownloadRateGreaterThanBitrate_SeekForward) {
84 // Start downloading faster than the media's bitrate. 155 // Start downloading faster than the media's bitrate.
85 StartMonitor(media_bitrate); 156 Initialize();
86 EXPECT_CALL(*this, CanPlayThrough()); 157 SimulateNetwork(SecondsToBytes(3), 1.1 * kMediaByterate);
87 int buffered = SimulateNetwork(1, 0, download_byte_rate, 1000, 2);
88
89 // Then "pause" for 3 minutes and continue downloading at same rate.
90 SimulateNetwork(60 * 3, buffered, download_byte_rate, 1000, 4);
91 }
92
93 TEST_F(DownloadRateMonitorTest, DownloadRateGreaterThanBitrate_SeekForward) {
94 static const int media_bitrate = 1024 * 1024 * 8;
95 static const int download_byte_rate = 1.1 * media_bitrate / 8;
96
97 // Start downloading faster than the media's bitrate.
98 EXPECT_CALL(*this, CanPlayThrough());
99 StartMonitor(media_bitrate);
100 SimulateNetwork(1, 0, download_byte_rate, 1000, 2);
101 158
102 // Then seek forward mid-file and continue downloading at same rate. 159 // Then seek forward mid-file and continue downloading at same rate.
103 SimulateNetwork(4, kMediaSizeInBytes / 2, download_byte_rate, 1000, 4); 160 SeekTo(kMediaSizeInBytes / 2);
161 EXPECT_CALL(*this, CanPlayThrough());
162 SimulateNetwork(7 * kMediaByterate, 1.1 * kMediaByterate);
163
164 // Verify deferring is not what caused CanPlayThrough to fire.
165 CHECK(!DownloadIsDeferred());
104 } 166 }
105 167
106 TEST_F(DownloadRateMonitorTest, DownloadRateGreaterThanBitrate_SeekBackward) { 168 TEST_F(DownloadRateMonitorTest, DownloadRateGreaterThanBitrate_SeekBackward) {
107 static const int media_bitrate = 1024 * 1024 * 8;
108 static const int download_byte_rate = 1.1 * media_bitrate / 8;
109
110 // Start downloading faster than the media's bitrate, in middle of file. 169 // Start downloading faster than the media's bitrate, in middle of file.
111 StartMonitor(media_bitrate); 170 Initialize();
112 SimulateNetwork(1, kMediaSizeInBytes / 2, download_byte_rate, 1000, 2); 171 SeekTo(kMediaSizeInBytes / 2);
172 SimulateNetwork(SecondsToBytes(3), 1.1 * kMediaByterate);
113 173
114 // Then seek back to beginning and continue downloading at same rate. 174 // Then seek back to beginning and continue downloading at same rate.
115 EXPECT_CALL(*this, CanPlayThrough()); 175 SeekTo(0);
116 SimulateNetwork(4, 0, download_byte_rate, 1000, 4); 176 EXPECT_CALL(*this, CanPlayThrough());
117 } 177 SimulateNetwork(SecondsToBytes(7), 1.1 * kMediaByterate);
118 178
119 TEST_F(DownloadRateMonitorTest, DownloadRateLessThanBitrate) { 179 // Verify deferring is not what caused CanPlayThrough to fire.
120 static const int media_bitrate = 1024 * 1024 * 8; 180 CHECK(!DownloadIsDeferred());
121 181 }
182
183 TEST_F(DownloadRateMonitorTest, DownloadRateLessThanByterate) {
122 // Simulate downloading at half the media's bitrate. 184 // Simulate downloading at half the media's bitrate.
123 EXPECT_CALL(*this, CanPlayThrough()) 185 EXPECT_CALL(*this, CanPlayThrough())
124 .Times(0); 186 .Times(0);
125 StartMonitor(media_bitrate); 187 Initialize();
126 SimulateNetwork(1, 0, media_bitrate / 8 / 2, 1000, 10); 188 SimulateNetwork(SecondsToBytes(10), kMediaByterate / 2);
127 } 189 }
128 190
129 TEST_F(DownloadRateMonitorTest, MediaSourceIsLocal) { 191 TEST_F(DownloadRateMonitorTest, MediaSourceIsLocal) {
130 static const int media_bitrate = 1024 * 1024 * 8;
131
132 // Simulate no data downloaded. 192 // Simulate no data downloaded.
133 EXPECT_CALL(*this, CanPlayThrough()); 193 EXPECT_CALL(*this, CanPlayThrough());
134 StartMonitor(media_bitrate, false, true); 194 Initialize(false, true);
135 } 195 }
136 196
137 TEST_F(DownloadRateMonitorTest, MediaSourceIsStreaming) { 197 TEST_F(DownloadRateMonitorTest, MediaSourceIsStreaming) {
138 static const int media_bitrate = 1024 * 1024 * 8;
139
140 // Simulate downloading at the media's bitrate while streaming. 198 // Simulate downloading at the media's bitrate while streaming.
141 EXPECT_CALL(*this, CanPlayThrough()); 199 EXPECT_CALL(*this, CanPlayThrough());
142 StartMonitor(media_bitrate, true, false); 200 Initialize(true, false);
143 SimulateNetwork(1, 0, media_bitrate / 8, 1000, 10); 201 SimulateNetwork(SecondsToBytes(10), kMediaByterate);
144 } 202 }
145 203
146 TEST_F(DownloadRateMonitorTest, VeryFastDownloadRate) { 204 TEST_F(DownloadRateMonitorTest, VeryFastDownloadRate) {
147 static const int media_bitrate = 1024 * 1024 * 8;
148
149 // Simulate downloading half the video very quickly in one chunk. 205 // Simulate downloading half the video very quickly in one chunk.
150 StartMonitor(media_bitrate); 206 Initialize();
151 EXPECT_CALL(*this, CanPlayThrough()); 207 EXPECT_CALL(*this, CanPlayThrough());
152 SimulateNetwork(1, 0, kMediaSizeInBytes / 2, 10, 1); 208 SimulateNetwork(kMediaSizeInBytes / 2, kMediaSizeInBytes * 10);
153 } 209 }
154 210
155 TEST_F(DownloadRateMonitorTest, DownloadEntireVideo) { 211 TEST_F(DownloadRateMonitorTest, DownloadEntireVideo) {
156 static const int seconds_of_data = 20;
157 static const int media_bitrate = kMediaSizeInBytes * 8 / seconds_of_data;
158
159 // Simulate downloading entire video at half the bitrate of the video. 212 // Simulate downloading entire video at half the bitrate of the video.
160 StartMonitor(media_bitrate); 213 Initialize();
161 EXPECT_CALL(*this, CanPlayThrough()); 214 EXPECT_CALL(*this, CanPlayThrough());
162 SimulateNetwork(1, 0, media_bitrate / 8 / 2, 1000, seconds_of_data * 2); 215 SimulateNetwork(kMediaSizeInBytes, kMediaByterate / 2);
216 }
217
218 TEST_F(DownloadRateMonitorTest, DownloadEndOfVideo) {
219 Initialize();
220 // Seek to 10s before the end of the file, then download the remainder of the
221 // file at half the bitrate.
222 SeekTo((kMediaDuration - 10) * kMediaByterate);
223 EXPECT_CALL(*this, CanPlayThrough());
224 SimulateNetwork(SecondsToBytes(10), kMediaByterate/ 2);
225
226 // Verify deferring is not what caused CanPlayThrough to fire.
227 CHECK(!DownloadIsDeferred());
163 } 228 }
164 229
165 } // namespace media 230 } // namespace media
OLDNEW
« no previous file with comments | « media/base/download_rate_monitor.cc ('k') | webkit/media/buffered_data_source.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698