| 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 "base/bind.h" | 5 #include "base/bind.h" |
| 6 #include "base/callback_helpers.h" | 6 #include "base/callback_helpers.h" |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "media/blink/multibuffer_reader.h" | 8 #include "media/blink/multibuffer_reader.h" |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 | 10 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 FROM_HERE, | 155 FROM_HERE, |
| 156 base::Bind(&MultiBufferReader::Call, weak_factory_.GetWeakPtr(), | 156 base::Bind(&MultiBufferReader::Call, weak_factory_.GetWeakPtr(), |
| 157 base::ResetAndReturn(&cb_))); | 157 base::ResetAndReturn(&cb_))); |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 void MultiBufferReader::Call(const base::Closure& cb) const { | 161 void MultiBufferReader::Call(const base::Closure& cb) const { |
| 162 cb.Run(); | 162 cb.Run(); |
| 163 } | 163 } |
| 164 | 164 |
| 165 void MultiBufferReader::UpdateEnd(MultiBufferBlockId p) { |
| 166 auto i = multibuffer_->map().find(p - 1); |
| 167 if (i != multibuffer_->map().end() && i->second->end_of_stream()) { |
| 168 // This is an upper limit because the last-to-one block is allowed |
| 169 // to be smaller than the rest of the blocks. |
| 170 int64_t size_upper_limit = static_cast<int64_t>(p) |
| 171 << multibuffer_->block_size_shift(); |
| 172 end_ = std::min(end_, size_upper_limit); |
| 173 } |
| 174 } |
| 175 |
| 165 void MultiBufferReader::NotifyAvailableRange( | 176 void MultiBufferReader::NotifyAvailableRange( |
| 166 const Interval<MultiBufferBlockId>& range) { | 177 const Interval<MultiBufferBlockId>& range) { |
| 167 // Update end_ if we can. | 178 // Update end_ if we can. |
| 168 if (range.end > range.begin) { | 179 if (range.end > range.begin) { |
| 169 auto i = multibuffer_->map().find(range.end - 1); | 180 UpdateEnd(range.end); |
| 170 DCHECK(i != multibuffer_->map().end()); | |
| 171 if (i->second->end_of_stream()) { | |
| 172 // This is an upper limit because the last-to-one block is allowed | |
| 173 // to be smaller than the rest of the blocks. | |
| 174 int64_t size_upper_limit = static_cast<int64_t>(range.end) | |
| 175 << multibuffer_->block_size_shift(); | |
| 176 end_ = std::min(end_, size_upper_limit); | |
| 177 } | |
| 178 } | 181 } |
| 179 UpdateInternalState(); | 182 UpdateInternalState(); |
| 180 if (!progress_callback_.is_null()) { | 183 if (!progress_callback_.is_null()) { |
| 181 // We redirect the call through a weak pointer to ourselves to guarantee | 184 // We redirect the call through a weak pointer to ourselves to guarantee |
| 182 // there are no callbacks from us after we've been destroyed. | 185 // there are no callbacks from us after we've been destroyed. |
| 183 base::MessageLoop::current()->PostTask( | 186 base::MessageLoop::current()->PostTask( |
| 184 FROM_HERE, | 187 FROM_HERE, |
| 185 base::Bind(&MultiBufferReader::Call, weak_factory_.GetWeakPtr(), | 188 base::Bind(&MultiBufferReader::Call, weak_factory_.GetWeakPtr(), |
| 186 base::Bind(progress_callback_, | 189 base::Bind(progress_callback_, |
| 187 static_cast<int64_t>(range.begin) | 190 static_cast<int64_t>(range.begin) |
| 188 << multibuffer_->block_size_shift(), | 191 << multibuffer_->block_size_shift(), |
| 189 static_cast<int64_t>(range.end) | 192 static_cast<int64_t>(range.end) |
| 190 << multibuffer_->block_size_shift()))); | 193 << multibuffer_->block_size_shift()))); |
| 191 // We may be destroyed, do not touch |this|. | 194 // We may be destroyed, do not touch |this|. |
| 192 } | 195 } |
| 193 } | 196 } |
| 194 | 197 |
| 195 void MultiBufferReader::UpdateInternalState() { | 198 void MultiBufferReader::UpdateInternalState() { |
| 196 int64_t effective_preload = loading_ ? preload_high_ : preload_low_; | 199 int64_t effective_preload = loading_ ? preload_high_ : preload_low_; |
| 197 | 200 |
| 198 loading_ = false; | 201 loading_ = false; |
| 199 if (preload_pos_ == -1) { | 202 if (preload_pos_ == -1) { |
| 200 preload_pos_ = block(pos_); | 203 preload_pos_ = block(pos_); |
| 201 DCHECK_GE(preload_pos_, 0); | 204 DCHECK_GE(preload_pos_, 0); |
| 202 } | 205 } |
| 203 MultiBuffer::BlockId max_preload = block_ceil( | |
| 204 std::min(end_, pos_ + std::max(effective_preload, current_wait_size_))); | |
| 205 | 206 |
| 206 // Note that we might not have been added to the multibuffer, | 207 // Note that we might not have been added to the multibuffer, |
| 207 // removing ourselves is a no-op in that case. | 208 // removing ourselves is a no-op in that case. |
| 208 multibuffer_->RemoveReader(preload_pos_, this); | 209 multibuffer_->RemoveReader(preload_pos_, this); |
| 209 | 210 |
| 210 // We explicitly allow preloading to go beyond the pinned region in the cache. | 211 // We explicitly allow preloading to go beyond the pinned region in the cache. |
| 211 // It only happens when we want to preload something into the disk cache. | 212 // It only happens when we want to preload something into the disk cache. |
| 212 // Thus it is possible to have blocks between our current reading position | 213 // Thus it is possible to have blocks between our current reading position |
| 213 // and preload_pos_ be unavailable. When we get a Seek() call (possibly | 214 // and preload_pos_ be unavailable. When we get a Seek() call (possibly |
| 214 // through TryRead()) we reset the preload_pos_ to the current reading | 215 // through TryRead()) we reset the preload_pos_ to the current reading |
| 215 // position, and preload_pos_ will become the first unavailable block after | 216 // position, and preload_pos_ will become the first unavailable block after |
| 216 // our current reading position again. | 217 // our current reading position again. |
| 217 preload_pos_ = multibuffer_->FindNextUnavailable(preload_pos_); | 218 preload_pos_ = multibuffer_->FindNextUnavailable(preload_pos_); |
| 219 UpdateEnd(preload_pos_); |
| 218 DCHECK_GE(preload_pos_, 0); | 220 DCHECK_GE(preload_pos_, 0); |
| 219 | 221 |
| 222 MultiBuffer::BlockId max_preload = block_ceil( |
| 223 std::min(end_, pos_ + std::max(effective_preload, current_wait_size_))); |
| 224 |
| 220 DVLOG(3) << "UpdateInternalState" | 225 DVLOG(3) << "UpdateInternalState" |
| 221 << " pp = " << preload_pos_ | 226 << " pp = " << preload_pos_ |
| 222 << " block_ceil(end_) = " << block_ceil(end_) << " end_ = " << end_ | 227 << " block_ceil(end_) = " << block_ceil(end_) << " end_ = " << end_ |
| 223 << " max_preload " << max_preload; | 228 << " max_preload " << max_preload; |
| 224 | 229 |
| 225 if (preload_pos_ < block_ceil(end_)) { | 230 if (preload_pos_ < block_ceil(end_)) { |
| 226 if (preload_pos_ < max_preload) { | 231 if (preload_pos_ < max_preload) { |
| 227 loading_ = true; | 232 loading_ = true; |
| 228 multibuffer_->AddReader(preload_pos_, this); | 233 multibuffer_->AddReader(preload_pos_, this); |
| 229 } else if (multibuffer_->Contains(preload_pos_ - 1)) { | 234 } else if (multibuffer_->Contains(preload_pos_ - 1)) { |
| 230 --preload_pos_; | 235 --preload_pos_; |
| 231 multibuffer_->AddReader(preload_pos_, this); | 236 multibuffer_->AddReader(preload_pos_, this); |
| 232 } | 237 } |
| 233 } | 238 } |
| 234 CheckWait(); | 239 CheckWait(); |
| 235 } | 240 } |
| 236 | 241 |
| 237 } // namespace media | 242 } // namespace media |
| OLD | NEW |