Added checks to GetBufferedTime() to cap at the media's duration
No longer tries to estimate buffered time when media is fully loaded. Also caps estimation at the duration of the media. BUG=none TEST=media_unittests Review URL: http://codereview.chromium.org/2782004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49714 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -221,11 +221,13 @@ base::TimeDelta PipelineImpl::GetCurrentTime() const {
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
|
||||
base::TimeDelta PipelineImpl::GetBufferedTime() {
|
||||
DCHECK(buffered_bytes_ >= current_bytes_);
|
||||
AutoLock auto_lock(lock_);
|
||||
|
||||
// If media is fully loaded, then return duration.
|
||||
if (loaded_)
|
||||
return duration_;
|
||||
|
||||
// If buffered time was set, we report that value directly.
|
||||
if (buffered_time_.ToInternalValue() > 0)
|
||||
return buffered_time_;
|
||||
@ -238,15 +240,18 @@ base::TimeDelta PipelineImpl::GetBufferedTime() {
|
||||
double current_time = static_cast<double>(current_bytes_) / total_bytes_ *
|
||||
duration_.InMilliseconds();
|
||||
double rate = current_time / current_bytes_;
|
||||
double buffered_time = rate * (buffered_bytes_ - current_bytes_) +
|
||||
current_time;
|
||||
DCHECK_GE(buffered_bytes_, current_bytes_);
|
||||
base::TimeDelta buffered_time = base::TimeDelta::FromMilliseconds(
|
||||
static_cast<int64>(rate * (buffered_bytes_ - current_bytes_) +
|
||||
current_time));
|
||||
|
||||
// Cap approximated buffered time at the length of the video.
|
||||
buffered_time = std::min(buffered_time, duration_);
|
||||
|
||||
// Only print the max buffered time for smooth buffering.
|
||||
if (buffered_time > max_buffered_time_)
|
||||
max_buffered_time_ = buffered_time;
|
||||
max_buffered_time_ = std::max(buffered_time, max_buffered_time_);
|
||||
|
||||
return base::TimeDelta::FromMilliseconds(
|
||||
static_cast<int64>(max_buffered_time_));
|
||||
return max_buffered_time_;
|
||||
}
|
||||
|
||||
base::TimeDelta PipelineImpl::GetMediaDuration() const {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "media/base/clock_impl.h"
|
||||
#include "media/base/filter_host.h"
|
||||
#include "media/base/pipeline.h"
|
||||
#include "testing/gtest/include/gtest/gtest_prod.h"
|
||||
|
||||
namespace media {
|
||||
|
||||
@ -385,7 +386,7 @@ class PipelineImpl : public Pipeline, public FilterHost {
|
||||
// Keep track of the maximum buffered position so the buffering appears
|
||||
// smooth.
|
||||
// TODO(vrk): This is a hack.
|
||||
double max_buffered_time_;
|
||||
base::TimeDelta max_buffered_time_;
|
||||
|
||||
// Filter factory as passed in by Start().
|
||||
scoped_refptr<FilterFactory> filter_factory_;
|
||||
@ -412,6 +413,7 @@ class PipelineImpl : public Pipeline, public FilterHost {
|
||||
typedef std::vector<base::Thread*> FilterThreadVector;
|
||||
FilterThreadVector filter_threads_;
|
||||
|
||||
FRIEND_TEST(PipelineImplTest, GetBufferedTime);
|
||||
DISALLOW_COPY_AND_ASSIGN(PipelineImpl);
|
||||
};
|
||||
|
||||
|
@ -502,6 +502,42 @@ TEST_F(PipelineImplTest, Properties) {
|
||||
pipeline_->GetBufferedTime().ToInternalValue());
|
||||
}
|
||||
|
||||
TEST_F(PipelineImplTest, GetBufferedTime) {
|
||||
CreateVideoStream();
|
||||
MockDemuxerStreamVector streams;
|
||||
streams.push_back(video_stream());
|
||||
|
||||
InitializeDataSource();
|
||||
const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
|
||||
InitializeDemuxer(&streams, kDuration);
|
||||
InitializeVideoDecoder(video_stream());
|
||||
InitializeVideoRenderer();
|
||||
|
||||
InitializePipeline();
|
||||
EXPECT_TRUE(pipeline_->IsInitialized());
|
||||
EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
|
||||
|
||||
// If media is loaded, we should return duration of media.
|
||||
pipeline_->SetLoaded(true);
|
||||
EXPECT_EQ(kDuration.ToInternalValue(),
|
||||
pipeline_->GetBufferedTime().ToInternalValue());
|
||||
pipeline_->SetLoaded(false);
|
||||
|
||||
// Buffered time is 0 if no bytes are buffered or read.
|
||||
pipeline_->SetBufferedBytes(0);
|
||||
EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue());
|
||||
pipeline_->SetBufferedBytes(kBufferedBytes);
|
||||
|
||||
pipeline_->SetCurrentReadPosition(0);
|
||||
EXPECT_EQ(0, pipeline_->GetBufferedTime().ToInternalValue());
|
||||
|
||||
// We should return buffered_time_ if it is set and valid.
|
||||
const base::TimeDelta buffered = base::TimeDelta::FromSeconds(10);
|
||||
pipeline_->SetBufferedTime(buffered);
|
||||
EXPECT_EQ(buffered.ToInternalValue(),
|
||||
pipeline_->GetBufferedTime().ToInternalValue());
|
||||
}
|
||||
|
||||
TEST_F(PipelineImplTest, DisableAudioRenderer) {
|
||||
CreateAudioStream();
|
||||
CreateVideoStream();
|
||||
|
Reference in New Issue
Block a user