diff options
-rw-r--r-- | media/base/pipeline_impl.cc | 21 | ||||
-rw-r--r-- | media/base/pipeline_impl.h | 4 | ||||
-rw-r--r-- | media/base/pipeline_impl_unittest.cc | 36 |
3 files changed, 52 insertions, 9 deletions
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index d7f153d..ec0f791 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc @@ -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 { diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h index 836715b..327b64d 100644 --- a/media/base/pipeline_impl.h +++ b/media/base/pipeline_impl.h @@ -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); }; diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index 25f4f3f..718b3ef 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc @@ -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(); |