| Index: webkit/glue/media/buffered_resource_loader.cc
|
| diff --git a/webkit/glue/media/buffered_resource_loader.cc b/webkit/glue/media/buffered_resource_loader.cc
|
| index 07f5729693b20b4701209bbb2603b857595a390a..06de3f2ee90497f03515f4c6f260af912d4ee841 100644
|
| --- a/webkit/glue/media/buffered_resource_loader.cc
|
| +++ b/webkit/glue/media/buffered_resource_loader.cc
|
| @@ -35,11 +35,10 @@ static const int kHttpPartialContent = 206;
|
| // Define the number of bytes in a megabyte.
|
| static const size_t kMegabyte = 1024 * 1024;
|
|
|
| -// Default backward capacity of the buffer.
|
| -static const size_t kBackwardCapacity = 2 * kMegabyte;
|
| -
|
| -// Default forward capacity of the buffer.
|
| -static const size_t kForwardCapacity = 10 * kMegabyte;
|
| +// Minimum capacity of the buffer in forward or backward direction.
|
| +//
|
| +// 2MB is an arbitrary limit; it just seems to be "good enough" in practice.
|
| +static const size_t kMinBufferCapacity = 2 * kMegabyte;
|
|
|
| // Maximum capacity of the buffer in forward or backward direction. This is
|
| // effectively the largest single read the code path can handle.
|
| @@ -52,14 +51,60 @@ static const size_t kMaxBufferCapacity = 20 * kMegabyte;
|
| // location and will instead reset the request.
|
| static const int kForwardWaitThreshold = 2 * kMegabyte;
|
|
|
| +// Computes the suggested backward and forward capacity for the buffer
|
| +// if one wants to play at |playback_rate| * the natural playback speed.
|
| +// Use a value of 0 for |bitrate| if it is unknown.
|
| +static void ComputeTargetBufferWindow(float playback_rate, int bitrate,
|
| + size_t* out_backward_capacity,
|
| + size_t* out_forward_capacity) {
|
| + static const size_t kDefaultBitrate = 200 * 1024 * 8; // 200 Kbps.
|
| + static const size_t kMaxBitrate = 20 * kMegabyte * 8; // 20 Mbps.
|
| + static const float kMaxPlaybackRate = 25.0;
|
| + static const size_t kTargetSecondsBufferedAhead = 10;
|
| + static const size_t kTargetSecondsBufferedBehind = 2;
|
| +
|
| + // Use a default bit rate if unknown and clamp to prevent overflow.
|
| + if (bitrate <= 0)
|
| + bitrate = kDefaultBitrate;
|
| + bitrate = std::min(static_cast<size_t>(bitrate), kMaxBitrate);
|
| +
|
| + // Only scale the buffer window for playback rates greater than 1.0 in
|
| + // magnitude and clamp to prevent overflow.
|
| + bool backward_playback = false;
|
| + if (playback_rate < 0.0f) {
|
| + backward_playback = true;
|
| + playback_rate *= -1.0f;
|
| + }
|
| +
|
| + playback_rate = std::max(playback_rate, 1.0f);
|
| + playback_rate = std::min(playback_rate, kMaxPlaybackRate);
|
| +
|
| + size_t bytes_per_second = static_cast<size_t>(playback_rate * bitrate / 8.0);
|
| +
|
| + // Clamp between kMinBufferCapacity and kMaxBufferCapacity.
|
| + *out_forward_capacity = std::max(
|
| + kTargetSecondsBufferedAhead * bytes_per_second, kMinBufferCapacity);
|
| + *out_backward_capacity = std::max(
|
| + kTargetSecondsBufferedBehind * bytes_per_second, kMinBufferCapacity);
|
| +
|
| + *out_forward_capacity = std::min(*out_forward_capacity, kMaxBufferCapacity);
|
| + *out_backward_capacity = std::min(*out_backward_capacity, kMaxBufferCapacity);
|
| +
|
| + if (backward_playback)
|
| + std::swap(*out_forward_capacity, *out_backward_capacity);
|
| +}
|
| +
|
| +
|
| BufferedResourceLoader::BufferedResourceLoader(
|
| const GURL& url,
|
| int64 first_byte_position,
|
| int64 last_byte_position,
|
| + DeferStrategy strategy,
|
| + int bitrate,
|
| + float playback_rate,
|
| media::MediaLog* media_log)
|
| - : buffer_(new media::SeekableBuffer(kBackwardCapacity, kForwardCapacity)),
|
| - deferred_(false),
|
| - defer_strategy_(kReadThenDefer),
|
| + : deferred_(false),
|
| + defer_strategy_(strategy),
|
| completed_(false),
|
| range_requested_(false),
|
| range_supported_(false),
|
| @@ -79,9 +124,15 @@ BufferedResourceLoader::BufferedResourceLoader(
|
| first_offset_(0),
|
| last_offset_(0),
|
| keep_test_loader_(false),
|
| - bitrate_(0),
|
| - playback_rate_(0.0),
|
| + bitrate_(bitrate),
|
| + playback_rate_(playback_rate),
|
| media_log_(media_log) {
|
| +
|
| + size_t backward_capacity;
|
| + size_t forward_capacity;
|
| + ComputeTargetBufferWindow(
|
| + playback_rate_, bitrate_, &backward_capacity, &forward_capacity);
|
| + buffer_.reset(new media::SeekableBuffer(backward_capacity, forward_capacity));
|
| }
|
|
|
| BufferedResourceLoader::~BufferedResourceLoader() {
|
| @@ -232,7 +283,7 @@ void BufferedResourceLoader::Read(int64 position,
|
| saved_forward_capacity_ = buffer_->forward_capacity();
|
| buffer_->set_forward_capacity(read_size_);
|
| }
|
| - return;
|
| + return;
|
| }
|
|
|
| // Make a callback to report failure.
|
| @@ -498,6 +549,12 @@ void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) {
|
|
|
| void BufferedResourceLoader::SetPlaybackRate(float playback_rate) {
|
| playback_rate_ = playback_rate;
|
| +
|
| + // This is a pause so don't bother updating the buffer window as we'll likely
|
| + // get unpaused in the future.
|
| + if (playback_rate_ == 0.0)
|
| + return;
|
| +
|
| UpdateBufferWindow();
|
| }
|
|
|
| @@ -510,49 +567,10 @@ void BufferedResourceLoader::SetBitrate(int bitrate) {
|
| /////////////////////////////////////////////////////////////////////////////
|
| // Helper methods.
|
|
|
| -// Computes the suggested backward and forward capacity for the buffer
|
| -// if one wants to play at |playback_rate| * the natural playback speed.
|
| -// Use a value of 0 for |bitrate| if it is unknown.
|
| -static void ComputeTargetBufferWindow(float playback_rate, int bitrate,
|
| - size_t* out_backward_capacity,
|
| - size_t* out_forward_capacity) {
|
| - DCHECK_GE(bitrate, 0);
|
| - DCHECK_NE(playback_rate, 0.0);
|
| - static const size_t kDefaultBitrate = kMegabyte;
|
| - static const size_t kMaxBitrate = 50 * kMegabyte;
|
| - static const float kMaxPlaybackRate = 25.0;
|
| - static const size_t kTargetSecondsBufferedAhead = 10;
|
| - static const size_t kTargetSecondsBufferedBehind = 2;
|
| -
|
| - if (bitrate <= 0)
|
| - bitrate = kDefaultBitrate;
|
| -
|
| - bool backward_playback = playback_rate < 0.0;
|
| - if (backward_playback)
|
| - playback_rate *= -1.0;
|
| -
|
| - // Cap playback rate and bitrate to prevent overflow.
|
| - playback_rate = std::min(kMaxPlaybackRate, playback_rate);
|
| - bitrate = std::min(kMaxBitrate, static_cast<size_t>(bitrate));
|
| -
|
| - size_t bytes_per_second = static_cast<size_t>(playback_rate * bitrate / 8.0);
|
| -
|
| - *out_forward_capacity = std::min(
|
| - kTargetSecondsBufferedAhead * bytes_per_second, kMaxBufferCapacity);
|
| - *out_backward_capacity = std::min(
|
| - kTargetSecondsBufferedBehind * bytes_per_second, kMaxBufferCapacity);
|
| - if (backward_playback)
|
| - std::swap(*out_forward_capacity, *out_backward_capacity);
|
| -}
|
| -
|
| void BufferedResourceLoader::UpdateBufferWindow() {
|
| if (!buffer_.get())
|
| return;
|
|
|
| - // Don't adjust buffer window if video is paused.
|
| - if (playback_rate_ == 0.0)
|
| - return;
|
| -
|
| size_t backward_capacity;
|
| size_t forward_capacity;
|
| ComputeTargetBufferWindow(
|
|
|