summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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/media/simple_data_source_unittest.cc24
-rw-r--r--webkit/glue/webmediaplayer_impl.cc13
10 files changed, 86 insertions, 26 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 5b6ef7e..f081f04 100644
--- a/webkit/glue/media/buffered_data_source.cc
+++ b/webkit/glue/media/buffered_data_source.cc
@@ -764,6 +764,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 fd3be2f..bcbec57 100644
--- a/webkit/glue/media/simple_data_source.cc
+++ b/webkit/glue/media/simple_data_source.cc
@@ -70,6 +70,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/media/simple_data_source_unittest.cc b/webkit/glue/media/simple_data_source_unittest.cc
index 9d367aa..eb5cd78 100644
--- a/webkit/glue/media/simple_data_source_unittest.cc
+++ b/webkit/glue/media/simple_data_source_unittest.cc
@@ -52,10 +52,7 @@ class SimpleDataSourceTest : public testing::Test {
}
}
- void InitializeDataSource(const char* url) {
- // Saves the url first.
- gurl_ = GURL(url);
-
+ void InitializeDataSource(const char* url, bool is_loaded) {
media::MediaFormat url_format;
url_format.SetAsString(media::MediaFormat::kMimeType,
media::mime_type::kURL);
@@ -66,9 +63,11 @@ class SimpleDataSourceTest : public testing::Test {
// There is no need to provide a message loop to data source.
data_source_->set_host(&host_);
+ EXPECT_CALL(host_, SetLoaded(is_loaded));
+
// First a bridge is created.
InSequence s;
- EXPECT_CALL(*bridge_factory_, CreateBridge(gurl_, _, -1, -1))
+ EXPECT_CALL(*bridge_factory_, CreateBridge(GURL(url), _, -1, -1))
.WillOnce(Return(bridge_.get()));
EXPECT_CALL(*bridge_, Start(data_source_.get()))
.WillOnce(Return(true));
@@ -165,32 +164,31 @@ class SimpleDataSourceTest : public testing::Test {
scoped_refptr<SimpleDataSource> data_source_;
StrictMock<media::MockFilterHost> host_;
StrictMock<media::MockFilterCallback> callback_;
- GURL gurl_;
char data_[kDataSize];
DISALLOW_COPY_AND_ASSIGN(SimpleDataSourceTest);
};
TEST_F(SimpleDataSourceTest, InitializeHTTP) {
- InitializeDataSource(kHttpUrl);
+ InitializeDataSource(kHttpUrl, false);
RequestSucceeded();
DestroyDataSource();
}
TEST_F(SimpleDataSourceTest, InitializeHTTPS) {
- InitializeDataSource(kHttpsUrl);
+ InitializeDataSource(kHttpsUrl, false);
RequestSucceeded();
DestroyDataSource();
}
TEST_F(SimpleDataSourceTest, InitializeFTP) {
- InitializeDataSource(kFtpUrl);
+ InitializeDataSource(kFtpUrl, false);
RequestSucceeded();
DestroyDataSource();
}
TEST_F(SimpleDataSourceTest, InitializeFile) {
- InitializeDataSource(kFileUrl);
+ InitializeDataSource(kFileUrl, true);
RequestSucceeded();
DestroyDataSource();
}
@@ -221,13 +219,13 @@ TEST_F(SimpleDataSourceTest, InitializeInvalid) {
}
TEST_F(SimpleDataSourceTest, RequestFailed) {
- InitializeDataSource(kHttpUrl);
+ InitializeDataSource(kHttpUrl, false);
RequestFailed();
DestroyDataSource();
}
TEST_F(SimpleDataSourceTest, StopWhenDownloading) {
- InitializeDataSource(kHttpUrl);
+ InitializeDataSource(kHttpUrl, false);
EXPECT_CALL(*bridge_, Cancel());
EXPECT_CALL(*bridge_, OnDestroy())
@@ -237,7 +235,7 @@ TEST_F(SimpleDataSourceTest, StopWhenDownloading) {
}
TEST_F(SimpleDataSourceTest, AsyncRead) {
- InitializeDataSource(kFileUrl);
+ InitializeDataSource(kFileUrl, true);
RequestSucceeded();
AsyncRead();
DestroyDataSource();
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();
}
}