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

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

Issue 2796193002: fix canplaythrough (Closed)
Patch Set: test compile fix 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;
12 const size_t kDownloadHistoryMaxEntries = 1024;
13
14 BufferedDataSourceHostImpl::BufferedDataSourceHostImpl(
15 const base::Closure& progress_cb)
12 : total_bytes_(0), 16 : total_bytes_(0),
13 did_loading_progress_(false) { } 17 did_loading_progress_(false),
18 progress_cb_(progress_cb) {}
14 19
15 BufferedDataSourceHostImpl::~BufferedDataSourceHostImpl() { } 20 BufferedDataSourceHostImpl::~BufferedDataSourceHostImpl() { }
16 21
17 void BufferedDataSourceHostImpl::SetTotalBytes(int64_t total_bytes) { 22 void BufferedDataSourceHostImpl::SetTotalBytes(int64_t total_bytes) {
18 total_bytes_ = total_bytes; 23 total_bytes_ = total_bytes;
19 } 24 }
20 25
26 int64_t BufferedDataSourceHostImpl::UnloadedBytesInInterval(
27 const Interval<int64_t>& interval) const {
28 int64_t bytes = 0;
29 auto i = buffered_byte_ranges_.find(interval.begin);
30 while (i != buffered_byte_ranges_.end()) {
31 if (i.interval_begin() >= interval.end)
32 break;
33 if (!i.value()) {
34 Interval<int64_t> intersection = i.interval().Intersect(interval);
35 if (!intersection.Empty()) {
36 bytes += intersection.end - intersection.begin;
37 }
38 }
39 ++i;
40 }
41 return bytes;
42 }
43
21 void BufferedDataSourceHostImpl::AddBufferedByteRange(int64_t start, 44 void BufferedDataSourceHostImpl::AddBufferedByteRange(int64_t start,
22 int64_t end) { 45 int64_t end) {
23 const auto i = buffered_byte_ranges_.find(start); 46 int64_t new_bytes = UnloadedBytesInInterval(Interval<int64_t>(start, end));
24 if (i.value() && i.interval_end() >= end) { 47 if (new_bytes == 0) {
25 // No change 48 // No change
26 return; 49 return;
27 } 50 }
28 buffered_byte_ranges_.SetInterval(start, end, 1); 51 buffered_byte_ranges_.SetInterval(start, end, 1);
29 did_loading_progress_ = true; 52 did_loading_progress_ = true;
53
54 base::TimeTicks now = base::TimeTicks::Now();
55 int64_t bytes_so_far = 0;
56 if (!download_history_.empty())
57 bytes_so_far = download_history_.back().second;
58 bytes_so_far += new_bytes;
59 if (download_history_.size() >= kDownloadHistoryMaxEntries) {
60 download_history_.back() = std::make_pair(now, bytes_so_far);
chcunningham 2017/04/06 16:55:41 why not always push_back? iiuc this is overwriting
hubbe 2017/04/06 21:25:38 We don't loose any data, we just loose precision i
61 } else {
62 download_history_.push_back(std::make_pair(now, bytes_so_far));
63 }
64 while (download_history_.back().first - download_history_.front().first >
65 base::TimeDelta::FromSecondsD(kDownloadHistoryWindowSeconds) ||
66 download_history_.size() >= kDownloadHistoryMaxEntries) {
67 download_history_.pop_front();
68 }
69 if (!progress_cb_.is_null()) {
70 progress_cb_.Run();
71 }
30 } 72 }
31 73
32 static base::TimeDelta TimeForByteOffset(int64_t byte_offset, 74 static base::TimeDelta TimeForByteOffset(int64_t byte_offset,
33 int64_t total_bytes, 75 int64_t total_bytes,
34 base::TimeDelta duration) { 76 base::TimeDelta duration) {
35 double position = static_cast<double>(byte_offset) / total_bytes; 77 double position = static_cast<double>(byte_offset) / total_bytes;
36 // Snap to the beginning/end where the approximation can look especially bad. 78 // Snap to the beginning/end where the approximation can look especially bad.
37 if (position < 0.01) 79 if (position < 0.01)
38 return base::TimeDelta(); 80 return base::TimeDelta();
39 if (position > 0.99) 81 if (position > 0.99)
(...skipping 19 matching lines...) Expand all
59 } 101 }
60 } 102 }
61 } 103 }
62 104
63 bool BufferedDataSourceHostImpl::DidLoadingProgress() { 105 bool BufferedDataSourceHostImpl::DidLoadingProgress() {
64 bool ret = did_loading_progress_; 106 bool ret = did_loading_progress_;
65 did_loading_progress_ = false; 107 did_loading_progress_ = false;
66 return ret; 108 return ret;
67 } 109 }
68 110
111 double BufferedDataSourceHostImpl::DownloadRate() const {
112 if (download_history_.size() < 5)
113 return 0.0;
114
115 // The data we get is bursty, so we get multiple measuring points very close
116 // together. These bursts will often lead us to over-estimate the download
117 // rate. By iterating over the beginning of the time series and picking the
118 // data point that has the lowest download rate, we avoid over-estimating.
119 double download_rate = 1.0E20;
mlamouri (slow - plz ping) 2017/04/06 11:32:56 Why 1e20 and not a negative value instead?
hubbe 2017/04/06 21:25:38 Because I use std::min() below.
mlamouri (slow - plz ping) 2017/04/07 11:23:44 Missed that. Can you use INT_MAX? `std::numeric_li
120 for (int i = 0; i < std::min<int>(20, download_history_.size() - 3); i++) {
chcunningham 2017/04/06 16:55:41 I don't follow the min(20, ...). If you only want
hubbe 2017/04/06 21:25:38 Each entry contains the cumulative downloaded byte
121 int64_t downloaded_bytes =
122 download_history_.back().second - download_history_[i].second;
123 double downloaded_seconds =
124 (download_history_.back().first - download_history_[i].first)
125 .InSecondsF();
126 if (downloaded_seconds <= 0.0)
127 continue;
128 download_rate =
129 std::min(download_rate, downloaded_bytes / downloaded_seconds);
130 }
131 if (download_rate == 1.0E20)
132 return 0.0;
133 return download_rate;
134 }
135
136 bool BufferedDataSourceHostImpl::CanPlayThrough(
137 base::TimeDelta current_position,
138 base::TimeDelta media_duration,
139 double playback_rate) const {
140 if (!total_bytes_ || media_duration <= base::TimeDelta())
141 return false;
142 if (current_position > media_duration)
143 return true;
144 double fraction = current_position.InSecondsF() / media_duration.InSecondsF();
145 int64_t byte_pos = total_bytes_ * fraction;
146 if (byte_pos < 0)
147 byte_pos = 0;
148
149 double download_rate = DownloadRate();
150 if (download_rate == 0.0)
151 return false;
152
153 int64_t unloaded_bytes =
154 UnloadedBytesInInterval(Interval<int64_t>(byte_pos, total_bytes_));
155 return unloaded_bytes / download_rate <
156 (media_duration - current_position).InSecondsF() / playback_rate;
157 }
158
69 } // namespace media 159 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698