summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-21 20:00:30 +0000
committerajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-21 20:00:30 +0000
commit9d8c6da308c378adb3236b3723918897aca039e6 (patch)
tree7bc73d33668d886c6abbbc86e7946425b42bbc5a
parent1ba48dd0630846f6c7e9ebd3ec16335fbb7b8c58 (diff)
downloadchromium_src-9d8c6da308c378adb3236b3723918897aca039e6.zip
chromium_src-9d8c6da308c378adb3236b3723918897aca039e6.tar.gz
chromium_src-9d8c6da308c378adb3236b3723918897aca039e6.tar.bz2
Correct network state and ready state reporting.
For network state, make it return "loading" for everything that's not a file source since our cache does not yet reliably support caching the full media w/o need for a network. For ready state, correctly handle seeks to drop from HaveEnoughData down to HaveMetaData until the seek completes. Also implement the seeking() function. BUG=18975 TEST=none Review URL: http://codereview.chromium.org/165432 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24002 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--media/base/filter_host.h3
-rw-r--r--media/base/mock_filter_host.h1
-rw-r--r--media/base/pipeline.h4
-rw-r--r--media/base/pipeline_impl.cc12
-rw-r--r--media/base/pipeline_impl.h6
-rw-r--r--webkit/glue/media/buffered_data_source.cc3
-rw-r--r--webkit/glue/media/buffered_data_source_unittest.cc44
-rw-r--r--webkit/glue/media/simple_data_source.cc2
-rw-r--r--webkit/glue/webmediaplayer_impl.cc13
9 files changed, 75 insertions, 13 deletions
diff --git a/media/base/filter_host.h b/media/base/filter_host.h
index 02ae399..2b288d2 100644
--- a/media/base/filter_host.h
+++ b/media/base/filter_host.h
@@ -61,6 +61,9 @@ class FilterHost {
// endpoints such as renderers.
virtual void NotifyEnded() = 0;
+ // Sets the flag to indicate that our media is now loaded.
+ virtual void SetLoaded(bool loaded) = 0;
+
// Broadcast a message of type |message| to all other filters from |source|.
virtual void BroadcastMessage(FilterMessage message) = 0;
diff --git a/media/base/mock_filter_host.h b/media/base/mock_filter_host.h
index 439eda8..dfcf403 100644
--- a/media/base/mock_filter_host.h
+++ b/media/base/mock_filter_host.h
@@ -37,6 +37,7 @@ class MockFilterHost : public FilterHost {
MOCK_METHOD1(SetBufferedBytes, void(int64 buffered_bytes));
MOCK_METHOD2(SetVideoSize, void(size_t width, size_t height));
MOCK_METHOD1(SetStreaming, void(bool streamed));
+ MOCK_METHOD1(SetLoaded, void(bool loaded));
MOCK_METHOD0(NotifyEnded, void());
MOCK_METHOD1(BroadcastMessage, void(FilterMessage message));
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index b54d442..dd571c9 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -151,6 +151,10 @@ class Pipeline : public base::RefCountedThreadSafe<Pipeline> {
// data source. Seeking may not be possible.
virtual bool IsStreaming() const = 0;
+ // If this method returns true, that means the data source has fully loaded
+ // the media and that the network is no longer needed.
+ virtual bool IsLoaded() const = 0;
+
// Gets the current error status for the pipeline. If the pipeline is
// operating correctly, this will return OK.
virtual PipelineError GetError() const = 0;
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index 270347c..49ebe4a 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -262,6 +262,11 @@ bool PipelineImpl::IsStreaming() const {
return streaming_;
}
+bool PipelineImpl::IsLoaded() const {
+ AutoLock auto_lock(lock_);
+ return loaded_;
+}
+
PipelineError PipelineImpl::GetError() const {
AutoLock auto_lock(lock_);
return error_;
@@ -287,6 +292,7 @@ void PipelineImpl::ResetState() {
buffered_time_ = kZero;
buffered_bytes_ = 0;
streaming_ = false;
+ loaded_ = false;
total_bytes_ = 0;
video_width_ = 0;
video_height_ = 0;
@@ -405,6 +411,12 @@ void PipelineImpl::NotifyEnded() {
NewRunnableMethod(this, &PipelineImpl::NotifyEndedTask));
}
+void PipelineImpl::SetLoaded(bool loaded) {
+ DCHECK(IsRunning());
+ AutoLock auto_lock(lock_);
+ loaded_ = loaded;
+}
+
void PipelineImpl::BroadcastMessage(FilterMessage message) {
DCHECK(IsRunning());
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index c448106..891404a 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -84,6 +84,7 @@ class PipelineImpl : public Pipeline, public FilterHost {
virtual int64 GetTotalBytes() const;
virtual void GetVideoSize(size_t* width_out, size_t* height_out) const;
virtual bool IsStreaming() const;
+ virtual bool IsLoaded() const;
virtual PipelineError GetError() const;
// Sets a permanent callback owned by the pipeline that will be executed when
@@ -143,6 +144,7 @@ class PipelineImpl : public Pipeline, public FilterHost {
virtual void SetBufferedBytes(int64 buffered_bytes);
virtual void SetVideoSize(size_t width, size_t height);
virtual void SetStreaming(bool streamed);
+ virtual void SetLoaded(bool loaded);
virtual void NotifyEnded();
virtual void BroadcastMessage(FilterMessage message);
@@ -293,6 +295,10 @@ class PipelineImpl : public Pipeline, public FilterHost {
// source.
bool streaming_;
+ // Sets by the filters to indicate whether the data source is a fully
+ // loaded source.
+ bool loaded_;
+
// Current volume level (from 0.0f to 1.0f). This value is set immediately
// via SetVolume() and a task is dispatched on the message loop to notify the
// filters.
diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc
index 5f739ba..6726885 100644
--- a/webkit/glue/media/buffered_data_source.cc
+++ b/webkit/glue/media/buffered_data_source.cc
@@ -765,6 +765,9 @@ void BufferedDataSource::InitialStartCallback(int error) {
host()->SetStreaming(true);
}
+ // Currently, only files can be used reliably w/o a network.
+ host()->SetLoaded(url_.SchemeIsFile());
+
initial_response_received_ = true;
if (probe_response_received_)
DoneInitialization();
diff --git a/webkit/glue/media/buffered_data_source_unittest.cc b/webkit/glue/media/buffered_data_source_unittest.cc
index 4d9efe8..003313c 100644
--- a/webkit/glue/media/buffered_data_source_unittest.cc
+++ b/webkit/glue/media/buffered_data_source_unittest.cc
@@ -30,8 +30,15 @@ using ::testing::WithArgs;
namespace {
const char* kHttpUrl = "http://test";
+const char* kFileUrl = "file://test";
const int kDataSize = 1024;
+enum NetworkState {
+ NONE,
+ LOADED,
+ LOADING
+};
+
} // namespace
namespace webkit_glue {
@@ -400,7 +407,7 @@ class BufferedDataSourceTest : public testing::Test {
}
}
- ~BufferedDataSourceTest() {
+ virtual ~BufferedDataSourceTest() {
if (data_source_) {
// Release the bridge factory because we don't own it.
// Expects bridge factory to be destroyed along with data source.
@@ -414,7 +421,7 @@ class BufferedDataSourceTest : public testing::Test {
}
void InitializeDataSource(const char* url, int error, int probe_error,
- int64 instance_size) {
+ int64 instance_size, NetworkState networkState) {
// Saves the url first.
gurl_ = GURL(url);
@@ -432,6 +439,14 @@ class BufferedDataSourceTest : public testing::Test {
loader_ = new StrictMock<MockBufferedResourceLoader>();
probe_loader_ = new StrictMock<MockBufferedResourceLoader>();
+ if (networkState == LOADED) {
+ EXPECT_CALL(host_, SetLoaded(true));
+ } else if (networkState == LOADING) {
+ EXPECT_CALL(host_, SetLoaded(false));
+ }
+
+ // TODO(ajwong): This mock is too strict. We do not need to guarantee a
+ // full sequencing each of these expectations.
InSequence s;
StrictMock<media::MockFilterCallback> callback;
@@ -448,6 +463,7 @@ class BufferedDataSourceTest : public testing::Test {
.WillOnce(DoAll(Assign(&error_, error),
Invoke(this,
&BufferedDataSourceTest::InvokeStartCallback)));
+
if (error == net::OK) {
EXPECT_CALL(*loader_, instance_size())
.WillOnce(Return(instance_size));
@@ -689,36 +705,36 @@ class BufferedDataSourceTest : public testing::Test {
};
TEST_F(BufferedDataSourceTest, InitializationSuccess) {
- InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024);
+ InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024, LOADING);
StopDataSource();
}
TEST_F(BufferedDataSourceTest, InitiailizationFailed) {
InitializeDataSource(kHttpUrl, net::ERR_FILE_NOT_FOUND,
- net::ERR_FILE_NOT_FOUND, 0);
+ net::ERR_FILE_NOT_FOUND, 0, NONE);
StopDataSource();
}
TEST_F(BufferedDataSourceTest, MissingContentLength) {
- InitializeDataSource(kHttpUrl, net::OK, net::OK, -1);
+ InitializeDataSource(kHttpUrl, net::OK, net::OK, -1, LOADING);
StopDataSource();
}
TEST_F(BufferedDataSourceTest, RangeRequestNotSupported) {
InitializeDataSource(kHttpUrl, net::OK,
- net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, 1024);
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, 1024, LOADING);
StopDataSource();
}
TEST_F(BufferedDataSourceTest,
MissingContentLengthAndRangeRequestNotSupported) {
InitializeDataSource(kHttpUrl, net::OK,
- net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, -1);
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, -1, LOADING);
StopDataSource();
}
TEST_F(BufferedDataSourceTest, ReadCacheHit) {
- InitializeDataSource(kHttpUrl, net::OK, net::OK, 25);
+ InitializeDataSource(kHttpUrl, net::OK, net::OK, 25, LOADING);
// Performs read with cache hit.
ReadDataSourceHit(10, 10, 10);
@@ -730,21 +746,27 @@ TEST_F(BufferedDataSourceTest, ReadCacheHit) {
}
TEST_F(BufferedDataSourceTest, ReadCacheMiss) {
- InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024);
+ InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024, LOADING);
ReadDataSourceMiss(1000, 10);
ReadDataSourceMiss(20, 10);
StopDataSource();
}
TEST_F(BufferedDataSourceTest, ReadFailed) {
- InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024);
+ InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024, LOADING);
ReadDataSourceHit(10, 10, 10);
ReadDataSourceFailed(10, 10, net::ERR_CONNECTION_RESET);
StopDataSource();
}
TEST_F(BufferedDataSourceTest, ReadTimesOut) {
- InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024);
+ InitializeDataSource(kHttpUrl, net::OK, net::OK, 1024, LOADING);
+ ReadDataSourceTimesOut(20, 10);
+ StopDataSource();
+}
+
+TEST_F(BufferedDataSourceTest, FileHasLoadedState) {
+ InitializeDataSource(kFileUrl, net::OK, net::OK, 1024, LOADED);
ReadDataSourceTimesOut(20, 10);
StopDataSource();
}
diff --git a/webkit/glue/media/simple_data_source.cc b/webkit/glue/media/simple_data_source.cc
index 639aa5f..52ea388 100644
--- a/webkit/glue/media/simple_data_source.cc
+++ b/webkit/glue/media/simple_data_source.cc
@@ -71,6 +71,8 @@ void SimpleDataSource::Initialize(const std::string& url,
return;
}
+ host()->SetLoaded(url_.SchemeIsFile());
+
// Post a task to the render thread to start loading the resource.
render_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &SimpleDataSource::StartTask));
diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc
index d3d3679..0438e54 100644
--- a/webkit/glue/webmediaplayer_impl.cc
+++ b/webkit/glue/webmediaplayer_impl.cc
@@ -272,6 +272,7 @@ void WebMediaPlayerImpl::seek(float seconds) {
// Try to preserve as much accuracy as possible.
float microseconds = seconds * base::Time::kMicrosecondsPerSecond;
+ SetReadyState(WebKit::WebMediaPlayer::HaveMetadata);
pipeline_->Seek(
base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)),
NewCallback(proxy_.get(),
@@ -361,7 +362,10 @@ bool WebMediaPlayerImpl::paused() const {
bool WebMediaPlayerImpl::seeking() const {
DCHECK(MessageLoop::current() == main_loop_);
- return false;
+ if (ready_state_ == WebKit::WebMediaPlayer::HaveNothing)
+ return false;
+
+ return ready_state_ == WebKit::WebMediaPlayer::HaveMetadata;
}
float WebMediaPlayerImpl::duration() const {
@@ -467,7 +471,11 @@ void WebMediaPlayerImpl::OnPipelineInitialize() {
// TODO(hclam): change this to report the correct status.
SetReadyState(WebKit::WebMediaPlayer::HaveMetadata);
SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData);
- SetNetworkState(WebKit::WebMediaPlayer::Loaded);
+ if (pipeline_->IsLoaded()) {
+ SetNetworkState(WebKit::WebMediaPlayer::Loaded);
+ } else {
+ SetNetworkState(WebKit::WebMediaPlayer::Loading);
+ }
} else {
// TODO(hclam): should use pipeline_->GetError() to determine the state
// properly and reports error using MediaError.
@@ -484,6 +492,7 @@ void WebMediaPlayerImpl::OnPipelineInitialize() {
void WebMediaPlayerImpl::OnPipelineSeek() {
DCHECK(MessageLoop::current() == main_loop_);
if (pipeline_->GetError() == media::PIPELINE_OK) {
+ SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData);
GetClient()->timeChanged();
}
}