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

Side by Side Diff: media/blink/buffered_data_source_host_impl.cc

Issue 2796193002: fix canplaythrough (Closed)
Patch Set: comments addressed Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 "media/blink/buffered_data_source_host_impl.h" 5 #include "media/blink/buffered_data_source_host_impl.h"
6 6
7 #include "media/base/timestamp_constants.h" 7 #include "media/base/timestamp_constants.h"
8 8
9 namespace media { 9 namespace media {
10 10
11 BufferedDataSourceHostImpl::BufferedDataSourceHostImpl() 11 const double kDownloadHistoryWindowSeconds = 10.0;
DaleCurtis 2017/04/06 22:51:39 Add comments detailing how these were chosen.
hubbe 2017/04/07 19:35:51 Done.
12 const size_t kDownloadHistoryMaxEntries = 1024;
13 const int64_t kDownloadHistoryMinBytesPerEntry = 1000;
14
15 BufferedDataSourceHostImpl::BufferedDataSourceHostImpl(
16 const base::Closure& progress_cb)
12 : total_bytes_(0), 17 : total_bytes_(0),
13 did_loading_progress_(false) { } 18 did_loading_progress_(false),
19 progress_cb_(progress_cb) {}
14 20
15 BufferedDataSourceHostImpl::~BufferedDataSourceHostImpl() { } 21 BufferedDataSourceHostImpl::~BufferedDataSourceHostImpl() { }
16 22
17 void BufferedDataSourceHostImpl::SetTotalBytes(int64_t total_bytes) { 23 void BufferedDataSourceHostImpl::SetTotalBytes(int64_t total_bytes) {
18 total_bytes_ = total_bytes; 24 total_bytes_ = total_bytes;
19 } 25 }
20 26
27 int64_t BufferedDataSourceHostImpl::UnloadedBytesInInterval(
28 const Interval<int64_t>& interval) const {
29 int64_t bytes = 0;
30 auto i = buffered_byte_ranges_.find(interval.begin);
31 while (i != buffered_byte_ranges_.end()) {
32 if (i.interval_begin() >= interval.end)
33 break;
34 if (!i.value()) {
35 Interval<int64_t> intersection = i.interval().Intersect(interval);
36 if (!intersection.Empty()) {
DaleCurtis 2017/04/06 22:51:39 Drop single line {}
hubbe 2017/04/07 19:35:51 Done.
37 bytes += intersection.end - intersection.begin;
38 }
39 }
40 ++i;
41 }
42 return bytes;
43 }
44
21 void BufferedDataSourceHostImpl::AddBufferedByteRange(int64_t start, 45 void BufferedDataSourceHostImpl::AddBufferedByteRange(int64_t start,
22 int64_t end) { 46 int64_t end) {
23 const auto i = buffered_byte_ranges_.find(start); 47 int64_t new_bytes = UnloadedBytesInInterval(Interval<int64_t>(start, end));
DaleCurtis 2017/04/06 22:51:39 Seems like there might be a simpler calculation si
hubbe 2017/04/07 19:35:50 Seeks cause non-continuous ranges. The removed cod
24 if (i.value() && i.interval_end() >= end) { 48 if (new_bytes == 0) {
25 // No change 49 // No change
26 return; 50 return;
27 } 51 }
28 buffered_byte_ranges_.SetInterval(start, end, 1); 52 buffered_byte_ranges_.SetInterval(start, end, 1);
29 did_loading_progress_ = true; 53 did_loading_progress_ = true;
54
55 base::TimeTicks now = base::TimeTicks::Now();
56 int64_t bytes_so_far = 0;
57 if (!download_history_.empty())
58 bytes_so_far = download_history_.back().second;
59 bytes_so_far += new_bytes;
60
61 // If the difference between the last entry and the second to last entry is
62 // less than kDownloadHistoryMinBytesPerEntry, just overwrite the last entry.
63 if (download_history_.size() > 1 &&
64 download_history_.back().second - (download_history_.end() - 2)->second <
65 kDownloadHistoryMinBytesPerEntry) {
66 download_history_.back() = std::make_pair(now, bytes_so_far);
67 } else {
68 download_history_.push_back(std::make_pair(now, bytes_so_far));
69 }
70 // Drop entries that are too old.
DaleCurtis 2017/04/06 22:51:39 DCHECK_GE(size, 1u) above.
hubbe 2017/04/07 19:35:50 Done.
71 while (download_history_.size() > kDownloadHistoryMaxEntries ||
72 download_history_.back().first - download_history_.front().first >
73 base::TimeDelta::FromSecondsD(kDownloadHistoryWindowSeconds)) {
74 download_history_.pop_front();
75 }
76 if (!progress_cb_.is_null()) {
DaleCurtis 2017/04/06 22:51:39 Drop single line {} Require so you don't have to c
hubbe 2017/04/07 19:35:51 Done.
77 progress_cb_.Run();
78 }
30 } 79 }
31 80
32 static base::TimeDelta TimeForByteOffset(int64_t byte_offset, 81 static base::TimeDelta TimeForByteOffset(int64_t byte_offset,
33 int64_t total_bytes, 82 int64_t total_bytes,
34 base::TimeDelta duration) { 83 base::TimeDelta duration) {
35 double position = static_cast<double>(byte_offset) / total_bytes; 84 double position = static_cast<double>(byte_offset) / total_bytes;
36 // Snap to the beginning/end where the approximation can look especially bad. 85 // Snap to the beginning/end where the approximation can look especially bad.
37 if (position < 0.01) 86 if (position < 0.01)
38 return base::TimeDelta(); 87 return base::TimeDelta();
39 if (position > 0.99) 88 if (position > 0.99)
(...skipping 19 matching lines...) Expand all
59 } 108 }
60 } 109 }
61 } 110 }
62 111
63 bool BufferedDataSourceHostImpl::DidLoadingProgress() { 112 bool BufferedDataSourceHostImpl::DidLoadingProgress() {
64 bool ret = did_loading_progress_; 113 bool ret = did_loading_progress_;
65 did_loading_progress_ = false; 114 did_loading_progress_ = false;
66 return ret; 115 return ret;
67 } 116 }
68 117
118 double BufferedDataSourceHostImpl::DownloadRate() const {
119 if (download_history_.size() < 5)
DaleCurtis 2017/04/06 22:51:39 Comment.
hubbe 2017/04/07 19:35:51 Done.
120 return 0.0;
121
122 // The data we get is bursty, so we get multiple measuring points very close
123 // together. These bursts will often lead us to over-estimate the download
124 // rate. By iterating over the beginning of the time series and picking the
125 // data point that has the lowest download rate, we avoid over-estimating.
126 double download_rate = 1.0E20;
127 for (int i = 0; i < std::min<int>(20, download_history_.size() - 3); i++) {
128 int64_t downloaded_bytes =
129 download_history_.back().second - download_history_[i].second;
130 double downloaded_seconds =
DaleCurtis 2017/04/06 22:51:39 base::TimeDelta?
hubbe 2017/04/07 19:35:50 Done.
131 (download_history_.back().first - download_history_[i].first)
132 .InSecondsF();
133 if (downloaded_seconds <= 0.0)
134 continue;
135 download_rate =
136 std::min(download_rate, downloaded_bytes / downloaded_seconds);
DaleCurtis 2017/04/06 22:51:39 Then just InSecondsF() here.
hubbe 2017/04/07 19:35:51 Done.
137 }
138 if (download_rate == 1.0E20)
DaleCurtis 2017/04/06 22:51:39 Ternary. Extract value to constant with explanatio
hubbe 2017/04/07 19:35:51 Done.
139 return 0.0;
140 return download_rate;
141 }
142
143 bool BufferedDataSourceHostImpl::CanPlayThrough(
144 base::TimeDelta current_position,
145 base::TimeDelta media_duration,
146 double playback_rate) const {
147 if (!total_bytes_ || media_duration <= base::TimeDelta())
DaleCurtis 2017/04/06 22:51:39 DCHECK_GE(playback_rate, 0); Also keep in mind me
148 return false;
149 if (current_position > media_duration)
150 return true;
151 double fraction = current_position.InSecondsF() / media_duration.InSecondsF();
152 int64_t byte_pos = total_bytes_ * fraction;
153 if (byte_pos < 0)
154 byte_pos = 0;
155
156 double download_rate = DownloadRate();
157 if (download_rate == 0.0)
DaleCurtis 2017/04/06 22:51:39 Seems a risky test due to precision. <= 0?
hubbe 2017/04/07 19:35:50 Sure. This was just to avoid a division by zero wh
158 return false;
159
160 int64_t unloaded_bytes =
161 UnloadedBytesInInterval(Interval<int64_t>(byte_pos, total_bytes_));
162 return unloaded_bytes / download_rate <
163 (media_duration - current_position).InSecondsF() / playback_rate;
164 }
165
69 } // namespace media 166 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698