summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorvrk@google.com <vrk@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-14 20:05:13 +0000
committervrk@google.com <vrk@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-14 20:05:13 +0000
commite63783695ea1efc9789883c132b7cfb56c26454c (patch)
tree923cc243b86b2f0a2d9192f388efc7ddffe1882f /media
parent8f46b2644162a0f97acf71098631469a49ca67bf (diff)
downloadchromium_src-e63783695ea1efc9789883c132b7cfb56c26454c.zip
chromium_src-e63783695ea1efc9789883c132b7cfb56c26454c.tar.gz
chromium_src-e63783695ea1efc9789883c132b7cfb56c26454c.tar.bz2
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
Diffstat (limited to 'media')
-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();