summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/base/pipeline_impl.cc21
-rw-r--r--media/base/pipeline_impl.h4
-rw-r--r--media/base/pipeline_impl_unittest.cc36
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();