summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-02 17:56:27 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-02 17:56:27 +0000
commit9bfe9b82466e685d48b0c8fa296e94900155c689 (patch)
treecb348420ed91125842c1eda89e67b8b36b5b7164
parent6d7406e0257912de103c719d8597554edb965271 (diff)
downloadchromium_src-9bfe9b82466e685d48b0c8fa296e94900155c689.zip
chromium_src-9bfe9b82466e685d48b0c8fa296e94900155c689.tar.gz
chromium_src-9bfe9b82466e685d48b0c8fa296e94900155c689.tar.bz2
Remove DemuxerFactory and URL parameter from Pipeline.
Since Demuxers still require asynchronous initialization DemuxerFactory::Build() has been replaced with Demuxer::Initialize(). Since FFmpegDemuxer is the only Demuxer requiring a DataSource it is now passed in via FFmpegDemuxer's constructor. Now that Demuxer::set_host() is guaranteed to be called prior to initialization we're able to tighten up some code inside ChunkDemuxer. We should still nuke set_host() (see bug 111585) but I'll leave that for a future CL. BUG=110804, 110809 Review URL: https://chromiumcodereview.appspot.com/9860027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130165 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/test/data/prerender/prerender_html5_common.js11
-rw-r--r--media/base/demuxer.h8
-rw-r--r--media/base/demuxer_factory.cc11
-rw-r--r--media/base/demuxer_factory.h32
-rw-r--r--media/base/filter_collection.cc9
-rw-r--r--media/base/filter_collection.h10
-rw-r--r--media/base/mock_filters.cc59
-rw-r--r--media/base/mock_filters.h36
-rw-r--r--media/base/pipeline.cc23
-rw-r--r--media/base/pipeline.h13
-rw-r--r--media/base/pipeline_unittest.cc81
-rw-r--r--media/filters/chunk_demuxer.cc40
-rw-r--r--media/filters/chunk_demuxer.h8
-rw-r--r--media/filters/chunk_demuxer_factory.cc38
-rw-r--r--media/filters/chunk_demuxer_factory.h36
-rw-r--r--media/filters/chunk_demuxer_unittest.cc41
-rw-r--r--media/filters/dummy_demuxer.cc8
-rw-r--r--media/filters/dummy_demuxer.h3
-rw-r--r--media/filters/dummy_demuxer_factory.cc29
-rw-r--r--media/filters/dummy_demuxer_factory.h33
-rw-r--r--media/filters/ffmpeg_demuxer.cc124
-rw-r--r--media/filters/ffmpeg_demuxer.h19
-rw-r--r--media/filters/ffmpeg_demuxer_factory.cc39
-rw-r--r--media/filters/ffmpeg_demuxer_factory.h36
-rw-r--r--media/filters/ffmpeg_demuxer_unittest.cc136
-rw-r--r--media/filters/pipeline_integration_test.cc2
-rw-r--r--media/filters/pipeline_integration_test_base.cc16
-rw-r--r--media/filters/pipeline_integration_test_base.h2
-rw-r--r--media/media.gyp12
-rw-r--r--media/tools/player_wtl/movie.cc9
-rw-r--r--media/tools/player_x11/player_x11.cc8
-rw-r--r--media/tools/seek_tester/seek_tester.cc4
-rw-r--r--webkit/media/filter_helpers.cc25
-rw-r--r--webkit/media/filter_helpers.h13
-rw-r--r--webkit/media/webmediaplayer_impl.cc14
-rw-r--r--webkit/media/webmediaplayer_impl.h2
36 files changed, 320 insertions, 670 deletions
diff --git a/chrome/test/data/prerender/prerender_html5_common.js b/chrome/test/data/prerender/prerender_html5_common.js
index 09d196b..2a4c0a4 100644
--- a/chrome/test/data/prerender/prerender_html5_common.js
+++ b/chrome/test/data/prerender/prerender_html5_common.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -20,7 +20,6 @@ function assert(bool) {
var canPlaySeen = false;
var playingSeen = false;
var canPlayThroughSeen = false;
-var stalledSeen = false;
var loadStartSeen = false;
var hasError = false;
@@ -49,16 +48,16 @@ function mediaEventHandler(e) {
loadStartSeen = true;
break;
case 'stalled':
- assert(loadStartSeen);
- stalledSeen = true;
+ // We should never see a stalled event during the display portion of the
+ // test.
+ assert(false);
break;
}
- var stallDone = !testNetworkEvents || stalledSeen;
var progressDone = (willPlay && canPlayThroughSeen && playingSeen) ||
(!willPlay && canPlayThroughSeen && !playingSeen);
- if (stallDone && progressDone)
+ if (progressDone)
document.title = 'PASS';
}
diff --git a/media/base/demuxer.h b/media/base/demuxer.h
index 044df3d..3647a9d 100644
--- a/media/base/demuxer.h
+++ b/media/base/demuxer.h
@@ -45,6 +45,12 @@ class MEDIA_EXPORT Demuxer
// to be released before the host object is destroyed by the pipeline.
virtual void set_host(DemuxerHost* host);
+ // Completes initialization of the demuxer.
+ //
+ // TODO(scherkus): pass in DemuxerHost here instead of using set_host(),
+ // see http://crbug.com/111585
+ virtual void Initialize(const PipelineStatusCB& status_cb) = 0;
+
// The pipeline playback rate has been changed. Demuxers may implement this
// method if they need to respond to this call.
virtual void SetPlaybackRate(float playback_rate);
@@ -76,6 +82,8 @@ class MEDIA_EXPORT Demuxer
// Returns true if the source is from a local file or stream (such as a
// webcam stream), false otherwise.
+ //
+ // TODO(scherkus): See http://crbug.com/120426 on why we should remove this.
virtual bool IsLocalSource() = 0;
// Returns true if seeking is possible; false otherwise.
diff --git a/media/base/demuxer_factory.cc b/media/base/demuxer_factory.cc
deleted file mode 100644
index 1f968d7..0000000
--- a/media/base/demuxer_factory.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/base/demuxer_factory.h"
-
-namespace media {
-
-DemuxerFactory::~DemuxerFactory() {}
-
-} // namespace media
diff --git a/media/base/demuxer_factory.h b/media/base/demuxer_factory.h
deleted file mode 100644
index 6a13356..0000000
--- a/media/base/demuxer_factory.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_BASE_DEMUXER_FACTORY_H_
-#define MEDIA_BASE_DEMUXER_FACTORY_H_
-
-#include <string>
-
-#include "base/callback.h"
-#include "media/base/media_export.h"
-#include "media/base/pipeline_status.h"
-
-namespace media {
-
-class Demuxer;
-
-// Asynchronous factory interface for building Demuxer objects.
-class MEDIA_EXPORT DemuxerFactory {
- public:
- // Ownership of the Demuxer is transferred through this callback.
- typedef base::Callback<void(PipelineStatus, Demuxer*)> BuildCallback;
-
- virtual ~DemuxerFactory();
-
- // Builds a Demuxer for |url| and returns it via |callback|.
- virtual void Build(const std::string& url, const BuildCallback& callback) = 0;
-};
-
-} // namespace media
-
-#endif // MEDIA_BASE_DEMUXER_FACTORY_H_
diff --git a/media/base/filter_collection.cc b/media/base/filter_collection.cc
index 3171399..537dd60 100644
--- a/media/base/filter_collection.cc
+++ b/media/base/filter_collection.cc
@@ -13,13 +13,12 @@ FilterCollection::FilterCollection() {}
FilterCollection::~FilterCollection() {}
-void FilterCollection::SetDemuxerFactory(scoped_ptr<DemuxerFactory> factory) {
- DCHECK(factory.get());
- demuxer_factory_ = factory.Pass();
+void FilterCollection::SetDemuxer(const scoped_refptr<Demuxer>& demuxer) {
+ demuxer_ = demuxer;
}
-DemuxerFactory* FilterCollection::GetDemuxerFactory() {
- return demuxer_factory_.get();
+const scoped_refptr<Demuxer>& FilterCollection::GetDemuxer() {
+ return demuxer_;
}
void FilterCollection::AddAudioDecoder(AudioDecoder* audio_decoder) {
diff --git a/media/base/filter_collection.h b/media/base/filter_collection.h
index c3629a1..8d8591d 100644
--- a/media/base/filter_collection.h
+++ b/media/base/filter_collection.h
@@ -8,7 +8,7 @@
#include <list>
#include "base/memory/ref_counted.h"
-#include "media/base/demuxer_factory.h"
+#include "media/base/demuxer.h"
#include "media/base/filters.h"
namespace media {
@@ -22,9 +22,9 @@ class MEDIA_EXPORT FilterCollection {
FilterCollection();
~FilterCollection();
- // DemuxerFactory accessor methods.
- void SetDemuxerFactory(scoped_ptr<DemuxerFactory> factory);
- DemuxerFactory* GetDemuxerFactory();
+ // Demuxer accessor methods.
+ void SetDemuxer(const scoped_refptr<Demuxer>& demuxer);
+ const scoped_refptr<Demuxer>& GetDemuxer();
// Adds a filter to the collection.
void AddAudioDecoder(AudioDecoder* audio_decoder);
@@ -60,7 +60,7 @@ class MEDIA_EXPORT FilterCollection {
typedef std::pair<FilterType, scoped_refptr<Filter> > FilterListElement;
typedef std::list<FilterListElement> FilterList;
FilterList filters_;
- scoped_ptr<DemuxerFactory> demuxer_factory_;
+ scoped_refptr<Demuxer> demuxer_;
std::list<scoped_refptr<AudioDecoder> > audio_decoders_;
std::list<scoped_refptr<VideoDecoder> > video_decoders_;
diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc
index e41ecb3..3502973 100644
--- a/media/base/mock_filters.cc
+++ b/media/base/mock_filters.cc
@@ -38,35 +38,6 @@ void MockDataSource::SetTotalAndBufferedBytes(int64 total_bytes,
buffered_bytes_ = buffered_bytes;
}
-MockDemuxerFactory::MockDemuxerFactory(MockDemuxer* demuxer)
- : demuxer_(demuxer), status_(PIPELINE_OK) {
-}
-
-MockDemuxerFactory::~MockDemuxerFactory() {}
-
-void MockDemuxerFactory::SetError(PipelineStatus error) {
- DCHECK_NE(error, PIPELINE_OK);
- status_ = error;
-}
-
-void MockDemuxerFactory::RunBuildCallback(const std::string& url,
- const BuildCallback& callback) {
- if (!demuxer_.get()) {
- callback.Run(PIPELINE_ERROR_REQUIRED_FILTER_MISSING, NULL);
- return;
- }
-
- scoped_refptr<MockDemuxer> demuxer = demuxer_;
- demuxer_ = NULL;
-
- if (status_ == PIPELINE_OK) {
- callback.Run(PIPELINE_OK, demuxer.get());
- return;
- }
-
- callback.Run(status_, NULL);
-}
-
MockDemuxer::MockDemuxer()
: total_bytes_(-1), buffered_bytes_(-1), duration_() {
EXPECT_CALL(*this, GetBitrate()).WillRepeatedly(Return(0));
@@ -128,28 +99,9 @@ MockFilterCollection::MockFilterCollection()
MockFilterCollection::~MockFilterCollection() {}
-scoped_ptr<FilterCollection> MockFilterCollection::filter_collection(
- bool include_demuxer,
- bool run_build_cb,
- bool run_build,
- PipelineStatus build_status) const {
+scoped_ptr<FilterCollection> MockFilterCollection::Create() {
scoped_ptr<FilterCollection> collection(new FilterCollection());
-
- scoped_ptr<MockDemuxerFactory> demuxer_factory(
- new MockDemuxerFactory(include_demuxer ? demuxer_ : NULL));
-
- if (build_status != PIPELINE_OK)
- demuxer_factory->SetError(build_status);
-
- if (run_build_cb) {
- ON_CALL(*demuxer_factory, Build(_, _)).WillByDefault(Invoke(
- demuxer_factory.get(), &MockDemuxerFactory::RunBuildCallback));
- } // else ignore Build calls.
-
- if (run_build)
- EXPECT_CALL(*demuxer_factory, Build(_, _));
-
- collection->SetDemuxerFactory(demuxer_factory.PassAs<DemuxerFactory>());
+ collection->SetDemuxer(demuxer_);
collection->AddVideoDecoder(video_decoder_);
collection->AddAudioDecoder(audio_decoder_);
collection->AddVideoRenderer(video_renderer_);
@@ -161,7 +113,12 @@ void RunFilterCallback(::testing::Unused, const base::Closure& closure) {
closure.Run();
}
-void RunPipelineStatusCB(::testing::Unused, const PipelineStatusCB& status_cb) {
+void RunPipelineStatusCB(const PipelineStatusCB& status_cb) {
+ status_cb.Run(PIPELINE_OK);
+}
+
+void RunPipelineStatusCB2(::testing::Unused,
+ const PipelineStatusCB& status_cb) {
status_cb.Run(PIPELINE_OK);
}
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 22cde25..75058fc 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -105,6 +105,7 @@ class MockDemuxer : public Demuxer {
public:
MockDemuxer();
+ MOCK_METHOD1(Initialize, void(const PipelineStatusCB& cb));
virtual void set_host(DemuxerHost* demuxer_host);
MOCK_METHOD1(Stop, void(const base::Closure& callback));
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
@@ -136,25 +137,6 @@ class MockDemuxer : public Demuxer {
DISALLOW_COPY_AND_ASSIGN(MockDemuxer);
};
-class MockDemuxerFactory : public DemuxerFactory {
- public:
- explicit MockDemuxerFactory(MockDemuxer* demuxer);
- virtual ~MockDemuxerFactory();
-
- void SetError(PipelineStatus error);
- void RunBuildCallback(const std::string& url, const BuildCallback& callback);
-
- // DemuxerFactory methods.
- MOCK_METHOD2(Build, void(const std::string& url,
- const BuildCallback& callback));
-
- private:
- scoped_refptr<MockDemuxer> demuxer_;
- PipelineStatus status_;
-
- DISALLOW_COPY_AND_ASSIGN(MockDemuxerFactory);
-};
-
class MockDemuxerStream : public DemuxerStream {
public:
MockDemuxerStream();
@@ -290,13 +272,8 @@ class MockFilterCollection {
MockVideoRenderer* video_renderer() const { return video_renderer_; }
MockAudioRenderer* audio_renderer() const { return audio_renderer_; }
- scoped_ptr<FilterCollection> filter_collection() const {
- return filter_collection(true, true, true, PIPELINE_OK).Pass();
- }
-
- scoped_ptr<FilterCollection> filter_collection(
- bool include_demuxer, bool run_build_cb, bool run_build,
- PipelineStatus build_status) const;
+ // Creates the FilterCollection containing the mocks.
+ scoped_ptr<FilterCollection> Create();
private:
scoped_refptr<MockDemuxer> demuxer_;
@@ -312,7 +289,8 @@ class MockFilterCollection {
// Closure on behalf of the provided filter. Can be used when mocking
// the Initialize() and Seek() methods.
void RunFilterCallback(::testing::Unused, const base::Closure& closure);
-void RunPipelineStatusCB(::testing::Unused, const PipelineStatusCB& status_cb);
+void RunPipelineStatusCB(const PipelineStatusCB& status_cb);
+void RunPipelineStatusCB2(::testing::Unused, const PipelineStatusCB& status_cb);
void RunPipelineStatusCB3(::testing::Unused, const PipelineStatusCB& status_cb,
::testing::Unused);
void RunPipelineStatusCB4(::testing::Unused, const PipelineStatusCB& status_cb,
@@ -321,6 +299,10 @@ void RunPipelineStatusCB4(::testing::Unused, const PipelineStatusCB& status_cb,
// provided filter. Can be used when mocking the Stop() method.
void RunStopFilterCallback(const base::Closure& closure);
+ACTION_P(RunPipelineStatusCBWithError, error) {
+ arg0.Run(error);
+}
+
// Helper gmock action that calls SetError() on behalf of the provided filter.
ACTION_P2(SetError, filter, error) {
filter->host()->SetError(error);
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index af62cb2..c30af3b 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -89,7 +89,6 @@ Pipeline::~Pipeline() {
}
void Pipeline::Start(scoped_ptr<FilterCollection> collection,
- const std::string& url,
const PipelineStatusCB& ended_cb,
const PipelineStatusCB& error_cb,
const NetworkEventCB& network_cb,
@@ -100,7 +99,7 @@ void Pipeline::Start(scoped_ptr<FilterCollection> collection,
running_ = true;
message_loop_->PostTask(FROM_HERE, base::Bind(
&Pipeline::StartTask, this, base::Passed(&collection),
- url, ended_cb, error_cb, network_cb, start_cb));
+ ended_cb, error_cb, network_cb, start_cb));
}
void Pipeline::Stop(const base::Closure& stop_cb) {
@@ -593,7 +592,6 @@ void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) {
}
void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection,
- const std::string& url,
const PipelineStatusCB& ended_cb,
const PipelineStatusCB& error_cb,
const NetworkEventCB& network_cb,
@@ -601,7 +599,6 @@ void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection,
DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK_EQ(kCreated, state_);
filter_collection_ = filter_collection.Pass();
- url_ = url;
ended_cb_ = ended_cb;
error_cb_ = error_cb;
network_cb_ = network_cb;
@@ -1088,26 +1085,28 @@ void Pipeline::InitializeDemuxer() {
DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(IsPipelineOk());
- filter_collection_->GetDemuxerFactory()->Build(
- url_, base::Bind(&Pipeline::OnDemuxerBuilt, this));
+ demuxer_ = filter_collection_->GetDemuxer();
+ if (!demuxer_) {
+ SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING);
+ return;
+ }
+
+ demuxer_->set_host(this);
+ demuxer_->Initialize(base::Bind(&Pipeline::OnDemuxerInitialized, this));
}
-void Pipeline::OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer) {
+void Pipeline::OnDemuxerInitialized(PipelineStatus status) {
if (MessageLoop::current() != message_loop_) {
message_loop_->PostTask(FROM_HERE, base::Bind(
- &Pipeline::OnDemuxerBuilt, this, status, make_scoped_refptr(demuxer)));
+ &Pipeline::OnDemuxerInitialized, this, status));
return;
}
- demuxer_ = demuxer;
if (status != PIPELINE_OK) {
SetError(status);
return;
}
- CHECK(demuxer_) << "Null demuxer encountered despite PIPELINE_OK.";
- demuxer_->set_host(this);
-
{
base::AutoLock auto_lock(lock_);
// We do not want to start the clock running. We only want to set the base
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 9c272ed..f2c7751 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -116,8 +116,8 @@ class MEDIA_EXPORT Pipeline
// Constructs a media pipeline that will execute on |message_loop|.
Pipeline(MessageLoop* message_loop, MediaLog* media_log);
- // Build a pipeline to render the given URL using the given filter collection
- // to construct a filter chain.
+ // Build a pipeline to using the given filter collection to construct a filter
+ // chain.
//
// Pipeline initialization is an inherently asynchronous process. Clients can
// either poll the IsInitialized() method (discouraged) or optionally pass in
@@ -137,7 +137,6 @@ class MEDIA_EXPORT Pipeline
//
// TODO(scherkus): remove IsInitialized() and force clients to use callbacks.
void Start(scoped_ptr<FilterCollection> filter_collection,
- const std::string& url,
const PipelineStatusCB& ended_cb,
const PipelineStatusCB& error_cb,
const NetworkEventCB& network_cb,
@@ -350,7 +349,6 @@ class MEDIA_EXPORT Pipeline
// methods are run as the result of posting a task to the PipelineInternal's
// message loop.
void StartTask(scoped_ptr<FilterCollection> filter_collection,
- const std::string& url,
const PipelineStatusCB& ended_cb,
const PipelineStatusCB& error_cb,
const NetworkEventCB& network_cb,
@@ -404,9 +402,9 @@ class MEDIA_EXPORT Pipeline
// of these methods are only called on the pipeline thread.
// The following initialize methods are used to select a specific type of
- // Filter object from FilterCollection and initialize it asynchronously.
+ // object from FilterCollection and initialize it asynchronously.
void InitializeDemuxer();
- void OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer);
+ void OnDemuxerInitialized(PipelineStatus status);
// Returns true if the asynchronous action of creating decoder has started.
// Returns false if this method did nothing because the corresponding
@@ -573,9 +571,6 @@ class MEDIA_EXPORT Pipeline
// Filter collection as passed in by Start().
scoped_ptr<FilterCollection> filter_collection_;
- // URL for the data source as passed in by Start().
- std::string url_;
-
// Callbacks for various pipeline operations.
PipelineStatusCB seek_cb_;
base::Closure stop_cb_;
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 42fd5bd..14d39d9 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -55,11 +55,6 @@ class CallbackHelper {
DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
};
-// Run |cb| w/ OK status.
-static void RunPipelineStatusOKCB(const PipelineStatusCB& cb) {
- cb.Run(PIPELINE_OK);
-}
-
// TODO(scherkus): even though some filters are initialized on separate
// threads these test aren't flaky... why? It's because filters' Initialize()
// is executed on |message_loop_| and the mock filters instantly call
@@ -93,6 +88,7 @@ class PipelineTest : public ::testing::Test {
base::Unretained(&callbacks_)));
message_loop_.RunAllPending();
+ pipeline_ = NULL;
mocks_.reset();
}
@@ -101,11 +97,13 @@ class PipelineTest : public ::testing::Test {
typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
void InitializeDemuxer(MockDemuxerStreamVector* streams,
const base::TimeDelta& duration) {
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_))
+ .WillOnce(Invoke(&RunPipelineStatusCB));
mocks_->demuxer()->SetTotalAndBufferedBytesAndDuration(
kTotalBytes, kBufferedBytes, duration);
EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->demuxer(), Seek(mocks_->demuxer()->GetStartTime(), _))
- .WillOnce(Invoke(&RunPipelineStatusCB));
+ .WillOnce(Invoke(&RunPipelineStatusCB2));
EXPECT_CALL(*mocks_->demuxer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
@@ -129,7 +127,7 @@ class PipelineTest : public ::testing::Test {
void InitializeVideoDecoder(MockDemuxerStream* stream) {
EXPECT_CALL(*mocks_->video_decoder(),
Initialize(stream, _, _))
- .WillOnce(WithArg<1>(Invoke(&RunPipelineStatusOKCB)));
+ .WillOnce(Invoke(&RunPipelineStatusCB3));
}
// Sets up expectations to allow the audio decoder to initialize.
@@ -146,7 +144,7 @@ class PipelineTest : public ::testing::Test {
EXPECT_CALL(*mocks_->video_renderer(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->video_renderer(),
Seek(mocks_->demuxer()->GetStartTime(), _))
- .WillOnce(Invoke(&RunPipelineStatusCB));
+ .WillOnce(Invoke(&RunPipelineStatusCB2));
EXPECT_CALL(*mocks_->video_renderer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
}
@@ -166,35 +164,22 @@ class PipelineTest : public ::testing::Test {
EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(1.0f));
EXPECT_CALL(*mocks_->audio_renderer(), Seek(base::TimeDelta(), _))
- .WillOnce(Invoke(&RunPipelineStatusCB));
+ .WillOnce(Invoke(&RunPipelineStatusCB2));
EXPECT_CALL(*mocks_->audio_renderer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
}
// Sets up expectations on the callback and initializes the pipeline. Called
// after tests have set expectations any filters they wish to use.
- void InitializePipeline() {
- InitializePipeline(PIPELINE_OK);
- }
- // Most tests can expect the |filter_collection|'s |build_status| to get
- // reflected in |Start()|'s argument.
void InitializePipeline(PipelineStatus start_status) {
- InitializePipeline(start_status, start_status);
- }
- // But some tests require different statuses in build & Start.
- void InitializePipeline(PipelineStatus build_status,
- PipelineStatus start_status) {
- // Expect an initialization callback.
EXPECT_CALL(callbacks_, OnStart(start_status));
pipeline_->Start(
- mocks_->filter_collection(true, true, true, build_status).Pass(),
- "",
+ mocks_->Create().Pass(),
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
NetworkEventCB(),
base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)));
-
message_loop_.RunAllPending();
}
@@ -217,16 +202,16 @@ class PipelineTest : public ::testing::Test {
void ExpectSeek(const base::TimeDelta& seek_time) {
// Every filter should receive a call to Seek().
EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _))
- .WillOnce(Invoke(&RunPipelineStatusCB));
+ .WillOnce(Invoke(&RunPipelineStatusCB2));
if (audio_stream_) {
EXPECT_CALL(*mocks_->audio_renderer(), Seek(seek_time, _))
- .WillOnce(Invoke(&RunPipelineStatusCB));
+ .WillOnce(Invoke(&RunPipelineStatusCB2));
}
if (video_stream_) {
EXPECT_CALL(*mocks_->video_renderer(), Seek(seek_time, _))
- .WillOnce(Invoke(&RunPipelineStatusCB));
+ .WillOnce(Invoke(&RunPipelineStatusCB2));
}
// We expect a successful seek callback.
@@ -295,12 +280,16 @@ TEST_F(PipelineTest, NotStarted) {
}
TEST_F(PipelineTest, NeverInitializes) {
+ // Don't execute the callback passed into Initialize().
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(Invoke(&RunStopFilterCallback));
+
// This test hangs during initialization by never calling
// InitializationComplete(). StrictMock<> will ensure that the callback is
// never executed.
pipeline_->Start(
- mocks_->filter_collection(false, false, true, PIPELINE_OK).Pass(),
- "",
+ mocks_->Create().Pass(),
base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
NetworkEventCB(),
@@ -317,37 +306,39 @@ TEST_F(PipelineTest, NeverInitializes) {
}
TEST_F(PipelineTest, RequiredFilterMissing) {
- // Sets up expectations on the callback and initializes the pipeline. Called
- // after tests have set expectations any filters they wish to use.
- // Expect an initialization callback.
- EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_REQUIRED_FILTER_MISSING));
-
// Create a filter collection with missing filter.
- scoped_ptr<FilterCollection> collection(mocks_->filter_collection(
- false, true, true, PIPELINE_ERROR_REQUIRED_FILTER_MISSING));
+ scoped_ptr<FilterCollection> collection(mocks_->Create());
+ collection->SetDemuxer(NULL);
+
+ EXPECT_CALL(callbacks_, OnStart(PIPELINE_ERROR_REQUIRED_FILTER_MISSING));
pipeline_->Start(
- collection.Pass(),
- "",
- base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
- NetworkEventCB(),
- base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)));
+ collection.Pass(),
+ base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
+ base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
+ NetworkEventCB(),
+ base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)));
message_loop_.RunAllPending();
-
EXPECT_FALSE(pipeline_->IsInitialized());
}
TEST_F(PipelineTest, URLNotFound) {
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_))
+ .WillOnce(RunPipelineStatusCBWithError(
+ PIPELINE_ERROR_URL_NOT_FOUND));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(Invoke(&RunStopFilterCallback));
+
InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND);
EXPECT_FALSE(pipeline_->IsInitialized());
}
TEST_F(PipelineTest, NoStreams) {
- // Manually set these expectations because SetPlaybackRate() is not called if
- // we cannot fully initialize the pipeline.
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_))
+ .WillOnce(Invoke(&RunPipelineStatusCB));
EXPECT_CALL(*mocks_->demuxer(), Stop(_))
.WillOnce(Invoke(&RunStopFilterCallback));
- InitializePipeline(PIPELINE_OK, PIPELINE_ERROR_COULD_NOT_RENDER);
+
+ InitializePipeline(PIPELINE_ERROR_COULD_NOT_RENDER);
EXPECT_FALSE(pipeline_->IsInitialized());
}
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index 44dd392..452d535 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -335,8 +335,7 @@ ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client)
: state_(WAITING_FOR_INIT),
client_(client),
buffered_bytes_(0),
- seek_waits_for_data_(true),
- deferred_error_(PIPELINE_OK) {
+ seek_waits_for_data_(true) {
DCHECK(client);
}
@@ -344,7 +343,7 @@ ChunkDemuxer::~ChunkDemuxer() {
DCHECK_NE(state_, INITIALIZED);
}
-void ChunkDemuxer::Init(const PipelineStatusCB& cb) {
+void ChunkDemuxer::Initialize(const PipelineStatusCB& cb) {
DVLOG(1) << "Init()";
{
base::AutoLock auto_lock(lock_);
@@ -362,17 +361,6 @@ void ChunkDemuxer::Init(const PipelineStatusCB& cb) {
client_->DemuxerOpened(this);
}
-void ChunkDemuxer::set_host(DemuxerHost* host) {
- DCHECK(state_ == INITIALIZED || state_ == PARSE_ERROR);
- Demuxer::set_host(host);
- host->SetDuration(duration_);
- host->SetCurrentReadPosition(0);
- if (deferred_error_ != PIPELINE_OK) {
- host->OnDemuxerError(deferred_error_);
- deferred_error_ = PIPELINE_OK;
- }
-}
-
void ChunkDemuxer::Stop(const base::Closure& callback) {
DVLOG(1) << "Stop()";
Shutdown();
@@ -549,16 +537,14 @@ bool ChunkDemuxer::AppendData(const uint8* data, size_t length) {
}
// Notify the host of 'network activity' because we got data.
- if (host()) {
- host()->SetBufferedBytes(buffered_bytes);
-
- if (buffered_ts.InSeconds() >= 0) {
- host()->SetBufferedTime(buffered_ts);
- }
+ host()->SetBufferedBytes(buffered_bytes);
- host()->SetNetworkActivity(true);
+ if (buffered_ts.InSeconds() >= 0) {
+ host()->SetBufferedTime(buffered_ts);
}
+ host()->SetNetworkActivity(true);
+
if (!cb.is_null())
cb.Run(PIPELINE_OK);
@@ -662,14 +648,8 @@ void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
return;
}
- DemuxerHost* demuxer_host = host();
- if (demuxer_host) {
- base::AutoUnlock auto_unlock(lock_);
- demuxer_host->OnDemuxerError(error);
- return;
- }
-
- deferred_error_ = error;
+ base::AutoUnlock auto_unlock(lock_);
+ host()->OnDemuxerError(error);
}
void ChunkDemuxer::OnStreamParserInitDone(bool success,
@@ -682,6 +662,8 @@ void ChunkDemuxer::OnStreamParserInitDone(bool success,
}
duration_ = duration;
+ host()->SetDuration(duration_);
+ host()->SetCurrentReadPosition(0);
ChangeState_Locked(INITIALIZED);
PipelineStatusCB cb;
diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h
index bf63527..8e141c8 100644
--- a/media/filters/chunk_demuxer.h
+++ b/media/filters/chunk_demuxer.h
@@ -25,10 +25,8 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer, public StreamParserHost {
explicit ChunkDemuxer(ChunkDemuxerClient* client);
virtual ~ChunkDemuxer();
- void Init(const PipelineStatusCB& cb);
-
// Demuxer implementation.
- virtual void set_host(DemuxerHost* host) OVERRIDE;
+ virtual void Initialize(const PipelineStatusCB& cb) OVERRIDE;
virtual void Stop(const base::Closure& callback) OVERRIDE;
virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE;
virtual void OnAudioRendererDisabled() OVERRIDE;
@@ -95,10 +93,6 @@ class MEDIA_EXPORT ChunkDemuxer : public Demuxer, public StreamParserHost {
ByteQueue byte_queue_;
- // Stores an error that happens after initilization but before set_host().
- // TODO(acolwell): Remove this when http://crbug.com/111585 is fixed.
- PipelineStatus deferred_error_;
-
DISALLOW_COPY_AND_ASSIGN(ChunkDemuxer);
};
diff --git a/media/filters/chunk_demuxer_factory.cc b/media/filters/chunk_demuxer_factory.cc
deleted file mode 100644
index 8455d58..0000000
--- a/media/filters/chunk_demuxer_factory.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/filters/chunk_demuxer_factory.h"
-
-#include "base/bind.h"
-#include "base/message_loop.h"
-#include "media/filters/chunk_demuxer.h"
-
-namespace media {
-
-static void InitDone(MessageLoop* message_loop,
- const DemuxerFactory::BuildCallback& cb,
- scoped_refptr<Demuxer> demuxer,
- PipelineStatus status) {
- if (status != PIPELINE_OK)
- demuxer = NULL;
- message_loop->PostTask(FROM_HERE, base::Bind(cb, status, demuxer));
-}
-
-ChunkDemuxerFactory::ChunkDemuxerFactory(ChunkDemuxerClient* client)
- : client_(client) {
- DCHECK(client_);
-}
-
-ChunkDemuxerFactory::~ChunkDemuxerFactory() {}
-
-void ChunkDemuxerFactory::Build(const std::string& url,
- const BuildCallback& cb) {
- scoped_refptr<ChunkDemuxer> demuxer(new ChunkDemuxer(client_));
-
- // Call Init() on demuxer. Note that ownership is being passed to the
- // callback here.
- demuxer->Init(base::Bind(&InitDone, MessageLoop::current(), cb, demuxer));
-}
-
-} // namespace media
diff --git a/media/filters/chunk_demuxer_factory.h b/media/filters/chunk_demuxer_factory.h
deleted file mode 100644
index 9e34a12..0000000
--- a/media/filters/chunk_demuxer_factory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_FILTERS_CHUNK_DEMUXER_FACTORY_H_
-#define MEDIA_FILTERS_CHUNK_DEMUXER_FACTORY_H_
-
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "media/base/demuxer_factory.h"
-
-namespace media {
-
-class ChunkDemuxer;
-class ChunkDemuxerClient;
-
-// Factory for building ChunkDemuxers. The factory will only build a
-// ChunkDemuxer with the given client.
-class MEDIA_EXPORT ChunkDemuxerFactory : public DemuxerFactory {
- public:
- ChunkDemuxerFactory(ChunkDemuxerClient* client);
- virtual ~ChunkDemuxerFactory();
-
- // DemuxerFactory methods.
- virtual void Build(const std::string& url, const BuildCallback& cb) OVERRIDE;
-
- private:
- ChunkDemuxerClient* client_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerFactory);
-};
-
-} // namespace media
-
-#endif // MEDIA_FILTERS_CHUNK_DEMUXER_FACTORY_H_
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
index 38e960ec..a6ebb97 100644
--- a/media/filters/chunk_demuxer_unittest.cc
+++ b/media/filters/chunk_demuxer_unittest.cc
@@ -90,6 +90,7 @@ class ChunkDemuxerTest : public testing::Test {
ChunkDemuxerTest()
: client_(new MockChunkDemuxerClient()),
demuxer_(new ChunkDemuxer(client_.get())) {
+ demuxer_->set_host(&mock_demuxer_host_);
}
virtual ~ChunkDemuxerTest() {
@@ -193,29 +194,21 @@ class ChunkDemuxerTest : public testing::Test {
return AppendData(info_tracks.get(), info_tracks_size);
}
- void InitDoneCalled(const base::TimeDelta& expected_duration,
- PipelineStatus expected_status,
- bool call_set_host,
+ void InitDoneCalled(PipelineStatus expected_status,
PipelineStatus status) {
EXPECT_EQ(status, expected_status);
+ }
- if (status == PIPELINE_OK) {
+ PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration,
+ PipelineStatus expected_status) {
+ if (expected_status == PIPELINE_OK) {
EXPECT_CALL(mock_demuxer_host_, SetDuration(expected_duration));
EXPECT_CALL(mock_demuxer_host_, SetCurrentReadPosition(_));
-
- if (call_set_host)
- demuxer_->set_host(&mock_demuxer_host_);
}
- }
- PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& duration,
- PipelineStatus expected_status,
- bool call_set_host) {
return base::Bind(&ChunkDemuxerTest::InitDoneCalled,
base::Unretained(this),
- duration,
- expected_status,
- call_set_host);
+ expected_status);
}
bool InitDemuxer(bool has_audio, bool has_video,
@@ -224,7 +217,8 @@ class ChunkDemuxerTest : public testing::Test {
(has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN;
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Init(CreateInitDoneCB(kDefaultDuration(), expected_status, true));
+ demuxer_->Initialize(CreateInitDoneCB(
+ kDefaultDuration(), expected_status));
return AppendInfoTracks(has_audio, has_video, video_content_encoded);
}
@@ -276,7 +270,7 @@ class ChunkDemuxerTest : public testing::Test {
int buffer_size = 0;
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Init(CreateInitDoneCB(duration, PIPELINE_OK, true));
+ demuxer_->Initialize(CreateInitDoneCB(duration, PIPELINE_OK));
// Read a WebM file into memory and send the data to the demuxer.
ReadTestDataFile(filename, &buffer, &buffer_size);
@@ -343,6 +337,7 @@ TEST_F(ChunkDemuxerTest, TestInit) {
client_.reset(new MockChunkDemuxerClient());
demuxer_ = new ChunkDemuxer(client_.get());
+ demuxer_->set_host(&mock_demuxer_host_);
ASSERT_TRUE(InitDemuxer(has_audio, has_video, video_content_encoded));
scoped_refptr<DemuxerStream> audio_stream =
@@ -639,7 +634,7 @@ TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) {
// INFO & TRACKS data.
TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) {
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Init(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
+ demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
ClusterBuilder cb;
cb.SetClusterTimecode(0);
@@ -652,7 +647,7 @@ TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) {
// Test cases where we get an EndOfStream() call during initialization.
TEST_F(ChunkDemuxerTest, TestEOSDuringInit) {
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Init(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
+ demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
demuxer_->EndOfStream(PIPELINE_OK);
}
@@ -836,7 +831,7 @@ TEST_F(ChunkDemuxerTest, TestReadsAfterEndOfStream) {
TEST_F(ChunkDemuxerTest, TestAppendingInPieces) {
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Init(CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK, true));
+ demuxer_->Initialize(CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK));
scoped_array<uint8> info_tracks;
int info_tracks_size = 0;
@@ -1031,15 +1026,15 @@ TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) {
TEST_F(ChunkDemuxerTest, TestParseErrorDuringInit) {
+ EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
+
EXPECT_CALL(*client_, DemuxerOpened(_));
- demuxer_->Init(CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK, false));
+ demuxer_->Initialize(CreateInitDoneCB(
+ kDefaultDuration(), PIPELINE_OK));
ASSERT_TRUE(AppendInfoTracks(true, true, false));
uint8 tmp = 0;
ASSERT_TRUE(demuxer_->AppendData(&tmp, 1));
-
- EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
- demuxer_->set_host(&mock_demuxer_host_);
}
} // namespace media
diff --git a/media/filters/dummy_demuxer.cc b/media/filters/dummy_demuxer.cc
index 1a8f43b..d5692da 100644
--- a/media/filters/dummy_demuxer.cc
+++ b/media/filters/dummy_demuxer.cc
@@ -47,8 +47,8 @@ DummyDemuxer::DummyDemuxer(bool has_video, bool has_audio, bool local_source)
DummyDemuxer::~DummyDemuxer() {}
-int DummyDemuxer::GetBitrate() {
- return 0;
+void DummyDemuxer::Initialize(const PipelineStatusCB& status_cb) {
+ status_cb.Run(PIPELINE_OK);
}
scoped_refptr<DemuxerStream> DummyDemuxer::GetStream(DemuxerStream::Type type) {
@@ -64,6 +64,10 @@ base::TimeDelta DummyDemuxer::GetStartTime() const {
return base::TimeDelta();
}
+int DummyDemuxer::GetBitrate() {
+ return 0;
+}
+
bool DummyDemuxer::IsLocalSource() {
return local_source_;
}
diff --git a/media/filters/dummy_demuxer.h b/media/filters/dummy_demuxer.h
index e248f68..7f59369 100644
--- a/media/filters/dummy_demuxer.h
+++ b/media/filters/dummy_demuxer.h
@@ -39,12 +39,13 @@ class DummyDemuxerStream : public DemuxerStream {
DISALLOW_COPY_AND_ASSIGN(DummyDemuxerStream);
};
-class DummyDemuxer : public Demuxer {
+class MEDIA_EXPORT DummyDemuxer : public Demuxer {
public:
DummyDemuxer(bool has_video, bool has_audio, bool local_source);
virtual ~DummyDemuxer();
// Demuxer implementation.
+ virtual void Initialize(const PipelineStatusCB& status_cb) OVERRIDE;
virtual scoped_refptr<DemuxerStream> GetStream(
DemuxerStream::Type type) OVERRIDE;
virtual void set_host(DemuxerHost* demuxer_host) OVERRIDE;
diff --git a/media/filters/dummy_demuxer_factory.cc b/media/filters/dummy_demuxer_factory.cc
deleted file mode 100644
index 34b79ba..0000000
--- a/media/filters/dummy_demuxer_factory.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/filters/dummy_demuxer_factory.h"
-
-#include "base/memory/scoped_ptr.h"
-#include "media/filters/dummy_demuxer.h"
-
-namespace media {
-
-DummyDemuxerFactory::DummyDemuxerFactory(bool has_video,
- bool has_audio,
- bool local_source)
- : has_video_(has_video),
- has_audio_(has_audio),
- local_source_(local_source) {
-}
-
-DummyDemuxerFactory::~DummyDemuxerFactory() {}
-
-void DummyDemuxerFactory::Build(const std::string& url,
- const BuildCallback& cb) {
- scoped_refptr<DummyDemuxer> demuxer =
- new DummyDemuxer(has_video_, has_audio_, local_source_);
- cb.Run(PIPELINE_OK, demuxer.get());
-}
-
-} // namespace media
diff --git a/media/filters/dummy_demuxer_factory.h b/media/filters/dummy_demuxer_factory.h
deleted file mode 100644
index 6bbf441..0000000
--- a/media/filters/dummy_demuxer_factory.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implements the DemuxerFactory interface using DummyDemuxer.
-
-#ifndef MEDIA_FILTERS_DUMMY_DEMUXER_FACTORY_H_
-#define MEDIA_FILTERS_DUMMY_DEMUXER_FACTORY_H_
-
-#include "base/compiler_specific.h"
-#include "media/base/demuxer_factory.h"
-
-namespace media {
-
-class MEDIA_EXPORT DummyDemuxerFactory : public DemuxerFactory {
- public:
- DummyDemuxerFactory(bool has_video, bool has_audio, bool local_source);
- virtual ~DummyDemuxerFactory();
-
- // DemuxerFactory methods.
- virtual void Build(const std::string& url, const BuildCallback& cb) OVERRIDE;
-
- private:
- bool has_video_;
- bool has_audio_;
- bool local_source_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(DummyDemuxerFactory);
-};
-
-} // namespace media
-
-#endif // MEDIA_FILTERS_DUMMY_DEMUXER_FACTORY_H_
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index 9429b0d..56db917 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -276,20 +276,24 @@ base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
//
// FFmpegDemuxer
//
-FFmpegDemuxer::FFmpegDemuxer(MessageLoop* message_loop, bool local_source)
+FFmpegDemuxer::FFmpegDemuxer(
+ MessageLoop* message_loop,
+ const scoped_refptr<DataSource>& data_source,
+ bool local_source)
: message_loop_(message_loop),
local_source_(local_source),
format_context_(NULL),
+ data_source_(data_source),
read_event_(false, false),
read_has_failed_(false),
last_read_bytes_(0),
read_position_(0),
- max_duration_(base::TimeDelta::FromMicroseconds(-1)),
- deferred_status_(PIPELINE_OK),
+ bitrate_(0),
first_seek_hack_(true),
start_time_(kNoTimestamp()),
audio_disabled_(false) {
DCHECK(message_loop_);
+ DCHECK(data_source_);
}
FFmpegDemuxer::~FFmpegDemuxer() {
@@ -336,22 +340,12 @@ void FFmpegDemuxer::OnAudioRendererDisabled() {
void FFmpegDemuxer::set_host(DemuxerHost* demuxer_host) {
Demuxer::set_host(demuxer_host);
- if (data_source_)
- data_source_->set_host(demuxer_host);
- if (max_duration_.InMicroseconds() >= 0)
- host()->SetDuration(max_duration_);
- if (read_position_ > 0)
- host()->SetCurrentReadPosition(read_position_);
- if (deferred_status_ != PIPELINE_OK)
- host()->OnDemuxerError(deferred_status_);
+ data_source_->set_host(demuxer_host);
}
-void FFmpegDemuxer::Initialize(DataSource* data_source,
- const PipelineStatusCB& status_cb) {
- message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&FFmpegDemuxer::InitializeTask, this,
- make_scoped_refptr(data_source), status_cb));
+void FFmpegDemuxer::Initialize(const PipelineStatusCB& status_cb) {
+ message_loop_->PostTask(FROM_HERE, base::Bind(
+ &FFmpegDemuxer::InitializeTask, this, status_cb));
}
scoped_refptr<DemuxerStream> FFmpegDemuxer::GetStream(
@@ -392,19 +386,14 @@ size_t FFmpegDemuxer::Read(size_t size, uint8* data) {
// let FFmpeg demuxer methods to run on.
int last_read_bytes = WaitForRead();
if (last_read_bytes == DataSource::kReadError) {
- if (host())
- host()->OnDemuxerError(PIPELINE_ERROR_READ);
- else
- deferred_status_ = PIPELINE_ERROR_READ;
+ host()->OnDemuxerError(PIPELINE_ERROR_READ);
// Returns with a negative number to signal an error to FFmpeg.
read_has_failed_ = true;
return AVERROR(EIO);
}
read_position_ += last_read_bytes;
-
- if (host())
- host()->SetCurrentReadPosition(read_position_);
+ host()->SetCurrentReadPosition(read_position_);
return last_read_bytes;
}
@@ -443,13 +432,44 @@ MessageLoop* FFmpegDemuxer::message_loop() {
return message_loop_;
}
-void FFmpegDemuxer::InitializeTask(DataSource* data_source,
- const PipelineStatusCB& status_cb) {
- DCHECK_EQ(MessageLoop::current(), message_loop_);
+// Helper for calculating the bitrate of the media based on information stored
+// in |format_context| or failing that the size and duration of the media.
+//
+// Returns 0 if a bitrate could not be determined.
+static int CalculateBitrate(
+ AVFormatContext* format_context,
+ const base::TimeDelta& duration,
+ int64 filesize_in_bytes) {
+ // If there is a bitrate set on the container, use it.
+ if (format_context->bit_rate > 0)
+ return format_context->bit_rate;
+
+ // Then try to sum the bitrates individually per stream.
+ int bitrate = 0;
+ for (size_t i = 0; i < format_context->nb_streams; ++i) {
+ AVCodecContext* codec_context = format_context->streams[i]->codec;
+ bitrate += codec_context->bit_rate;
+ }
+ if (bitrate > 0)
+ return bitrate;
+
+ // See if we can approximate the bitrate as long as we have a filesize and
+ // valid duration.
+ if (duration.InMicroseconds() <= 0 ||
+ duration == kInfiniteDuration() ||
+ filesize_in_bytes == 0) {
+ return 0;
+ }
+
+ // Do math in floating point as we'd overflow an int64 if the filesize was
+ // larger than ~1073GB.
+ double bytes = filesize_in_bytes;
+ double duration_us = duration.InMicroseconds();
+ return bytes * 8000000.0 / duration_us;
+}
- data_source_ = data_source;
- if (host())
- data_source_->set_host(host());
+void FFmpegDemuxer::InitializeTask(const PipelineStatusCB& status_cb) {
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
// Add ourself to Protocol list and get our unique key.
std::string key = FFmpegGlue::GetInstance()->AddProtocol(this);
@@ -538,47 +558,21 @@ void FFmpegDemuxer::InitializeTask(DataSource* data_source,
// Good to go: set the duration and bitrate and notify we're done
// initializing.
- if (host())
- host()->SetDuration(max_duration);
- max_duration_ = max_duration;
+ host()->SetDuration(max_duration);
- int bitrate = GetBitrate();
- if (bitrate > 0)
- data_source_->SetBitrate(bitrate);
+ int64 filesize_in_bytes = 0;
+ GetSize(&filesize_in_bytes);
+ bitrate_ = CalculateBitrate(format_context_, max_duration, filesize_in_bytes);
+ if (bitrate_ > 0)
+ data_source_->SetBitrate(bitrate_);
status_cb.Run(PIPELINE_OK);
}
-int FFmpegDemuxer::GetBitrate() {
- DCHECK(format_context_);
-
- // If there is a bitrate set on the container, use it.
- if (format_context_->bit_rate > 0)
- return format_context_->bit_rate;
- // Then try to sum the bitrates individually per stream.
- int bitrate = 0;
- for (size_t i = 0; i < format_context_->nb_streams; ++i) {
- AVCodecContext* codec_context = format_context_->streams[i]->codec;
- bitrate += codec_context->bit_rate;
- }
- if (bitrate > 0)
- return bitrate;
-
- // See if we can approximate the bitrate as long as we have a filesize and
- // valid duration.
- int64 filesize_in_bytes;
- if (max_duration_.InMicroseconds() <= 0 ||
- max_duration_ == kInfiniteDuration() ||
- !GetSize(&filesize_in_bytes)) {
- return 0;
- }
-
- // Do math in floating point as we'd overflow an int64 if the filesize was
- // larger than ~1073GB.
- double bytes = filesize_in_bytes;
- double duration = max_duration_.InMicroseconds();
- return bytes * 8000000.0 / duration;
+int FFmpegDemuxer::GetBitrate() {
+ DCHECK(format_context_) << "Initialize() has not been called";
+ return bitrate_;
}
bool FFmpegDemuxer::IsLocalSource() {
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h
index 711e609..6a6bc64 100644
--- a/media/filters/ffmpeg_demuxer.h
+++ b/media/filters/ffmpeg_demuxer.h
@@ -130,20 +130,20 @@ class FFmpegDemuxerStream : public DemuxerStream {
class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol {
public:
- FFmpegDemuxer(MessageLoop* message_loop, bool local_source);
+ FFmpegDemuxer(MessageLoop* message_loop,
+ const scoped_refptr<DataSource>& data_source,
+ bool local_source);
virtual ~FFmpegDemuxer();
// Posts a task to perform additional demuxing.
virtual void PostDemuxTask();
- void Initialize(
- DataSource* data_source, const PipelineStatusCB& status_cb);
-
// Demuxer implementation.
+ virtual void set_host(DemuxerHost* demuxer_host) OVERRIDE;
+ virtual void Initialize(const PipelineStatusCB& status_cb) OVERRIDE;
virtual void Stop(const base::Closure& callback) OVERRIDE;
virtual void Seek(base::TimeDelta time, const PipelineStatusCB& cb) OVERRIDE;
virtual void OnAudioRendererDisabled() OVERRIDE;
- virtual void set_host(DemuxerHost* demuxer_host) OVERRIDE;
virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
virtual scoped_refptr<DemuxerStream> GetStream(
DemuxerStream::Type type) OVERRIDE;
@@ -171,8 +171,7 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol {
FRIEND_TEST_ALL_PREFIXES(FFmpegDemuxerTest, ProtocolRead);
// Carries out initialization on the demuxer thread.
- void InitializeTask(
- DataSource* data_source, const PipelineStatusCB& status_cb);
+ void InitializeTask(const PipelineStatusCB& status_cb);
// Carries out a seek on the demuxer thread.
void SeekTask(base::TimeDelta time, const PipelineStatusCB& cb);
@@ -242,10 +241,8 @@ class MEDIA_EXPORT FFmpegDemuxer : public Demuxer, public FFmpegURLProtocol {
int last_read_bytes_;
int64 read_position_;
- // Initialization can happen before set_host() is called, in which case we
- // store these bits for deferred reporting to the DemuxerHost when we get one.
- base::TimeDelta max_duration_;
- PipelineStatus deferred_status_;
+ // Derived bitrate after initialization has completed.
+ int bitrate_;
// Used to skip the implicit "first seek" to avoid resetting FFmpeg's internal
// state.
diff --git a/media/filters/ffmpeg_demuxer_factory.cc b/media/filters/ffmpeg_demuxer_factory.cc
deleted file mode 100644
index 13494b9..0000000
--- a/media/filters/ffmpeg_demuxer_factory.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/bind.h"
-#include "base/message_loop.h"
-#include "googleurl/src/gurl.h"
-#include "media/filters/ffmpeg_demuxer.h"
-#include "media/filters/ffmpeg_demuxer_factory.h"
-
-namespace media {
-
-FFmpegDemuxerFactory::FFmpegDemuxerFactory(
- const scoped_refptr<DataSource>& data_source,
- MessageLoop* loop)
- : data_source_(data_source),
- loop_(loop) {
-}
-
-FFmpegDemuxerFactory::~FFmpegDemuxerFactory() {}
-
-static void DemuxerInitDone(const DemuxerFactory::BuildCallback& cb,
- const scoped_refptr<FFmpegDemuxer>& demuxer,
- PipelineStatus status) {
- cb.Run(status, demuxer);
-}
-
-void FFmpegDemuxerFactory::Build(const std::string& url,
- const BuildCallback& cb) {
- GURL gurl = GURL(url);
- bool local_source = !gurl.SchemeIs("http") && !gurl.SchemeIs("https");
- scoped_refptr<FFmpegDemuxer> demuxer = new FFmpegDemuxer(loop_, local_source);
-
- demuxer->Initialize(
- data_source_,
- base::Bind(&DemuxerInitDone, cb, demuxer));
-}
-
-} // namespace media
diff --git a/media/filters/ffmpeg_demuxer_factory.h b/media/filters/ffmpeg_demuxer_factory.h
deleted file mode 100644
index 6a9463f..0000000
--- a/media/filters/ffmpeg_demuxer_factory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implements the DemuxerFactory interface using FFmpegDemuxer.
-
-#ifndef MEDIA_FILTERS_FFMPEG_DEMUXER_FACTORY_H_
-#define MEDIA_FILTERS_FFMPEG_DEMUXER_FACTORY_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "media/base/demuxer_factory.h"
-
-class MessageLoop;
-
-namespace media {
-
-class MEDIA_EXPORT FFmpegDemuxerFactory : public DemuxerFactory {
- public:
- FFmpegDemuxerFactory(const scoped_refptr<DataSource>& data_source,
- MessageLoop* loop);
- virtual ~FFmpegDemuxerFactory();
-
- // DemuxerFactory methods.
- virtual void Build(const std::string& url, const BuildCallback& cb) OVERRIDE;
-
- private:
- scoped_refptr<DataSource> data_source_;
- MessageLoop* loop_; // Unowned.
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(FFmpegDemuxerFactory);
-};
-
-} // namespace media
-
-#endif // MEDIA_FILTERS_FFMPEG_DEMUXER_FACTORY_H_
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index 3189e08..520b59b 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -41,19 +41,7 @@ MATCHER(IsEndOfStreamBuffer,
class FFmpegDemuxerTest : public testing::Test {
protected:
- FFmpegDemuxerTest() {
- // Create an FFmpegDemuxer with local data source.
- demuxer_ = new FFmpegDemuxer(&message_loop_, true);
- demuxer_->disable_first_seek_hack_for_testing();
-
- // Inject a filter host and message loop and prepare a data source.
- demuxer_->set_host(&host_);
-
- EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber());
- EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber());
- EXPECT_CALL(host_, SetCurrentReadPosition(_))
- .WillRepeatedly(SaveArg<0>(&current_read_position_));
- }
+ FFmpegDemuxerTest() {}
virtual ~FFmpegDemuxerTest() {
if (demuxer_) {
@@ -67,34 +55,33 @@ class FFmpegDemuxerTest : public testing::Test {
demuxer_ = NULL;
}
- scoped_refptr<FileDataSource> CreateDataSource(const std::string& name) {
- return CreateDataSource(name, false);
+ void CreateDemuxer(const std::string& name) {
+ CreateDemuxer(name, false);
}
- scoped_refptr<FileDataSource> CreateDataSource(const std::string& name,
- bool disable_file_size) {
- FilePath file_path;
- EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
+ void CreateDemuxer(const std::string& name, bool disable_file_size) {
+ CHECK(!demuxer_);
- file_path = file_path.Append(FILE_PATH_LITERAL("media"))
- .Append(FILE_PATH_LITERAL("test"))
- .Append(FILE_PATH_LITERAL("data"))
- .AppendASCII(name);
+ EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber());
+ EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber());
+ EXPECT_CALL(host_, SetCurrentReadPosition(_))
+ .WillRepeatedly(SaveArg<0>(&current_read_position_));
- scoped_refptr<FileDataSource> data_source = new FileDataSource(
- disable_file_size);
+ CreateDataSource(name, disable_file_size);
- EXPECT_EQ(PIPELINE_OK, data_source->Initialize(file_path.MaybeAsASCII()));
+ // Create an FFmpegDemuxer with local data source.
+ demuxer_ = new FFmpegDemuxer(&message_loop_, data_source_, true);
+ demuxer_->disable_first_seek_hack_for_testing();
- return data_source.get();
+ // Inject a filter host and message loop and prepare a data source.
+ demuxer_->set_host(&host_);
}
MOCK_METHOD1(CheckPoint, void(int v));
- // Initializes FFmpegDemuxer.
- void InitializeDemuxer(const scoped_refptr<DataSource>& data_source) {
+ void InitializeDemuxer() {
EXPECT_CALL(host_, SetDuration(_));
- demuxer_->Initialize(data_source, NewExpectedStatusCB(PIPELINE_OK));
+ demuxer_->Initialize(NewExpectedStatusCB(PIPELINE_OK));
message_loop_.RunAllPending();
}
@@ -120,9 +107,8 @@ class FFmpegDemuxerTest : public testing::Test {
// returns true if the bitrate is valid, false otherwise.
bool VideoHasValidBitrate(
const std::string& file_name, bool disable_file_size) {
- scoped_refptr<FileDataSource> data_source =
- CreateDataSource(file_name, disable_file_size);
- InitializeDemuxer(data_source);
+ CreateDemuxer(file_name, disable_file_size);
+ InitializeDemuxer();
return demuxer_->GetBitrate() > 0;
}
@@ -133,6 +119,7 @@ class FFmpegDemuxerTest : public testing::Test {
}
// Fixture members.
+ scoped_refptr<FileDataSource> data_source_;
scoped_refptr<FFmpegDemuxer> demuxer_;
StrictMock<MockDemuxerHost> host_;
MessageLoop message_loop_;
@@ -140,14 +127,29 @@ class FFmpegDemuxerTest : public testing::Test {
int64 current_read_position_;
private:
+ void CreateDataSource(const std::string& name, bool disable_file_size) {
+ CHECK(!data_source_);
+
+ FilePath file_path;
+ EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
+
+ file_path = file_path.Append(FILE_PATH_LITERAL("media"))
+ .Append(FILE_PATH_LITERAL("test"))
+ .Append(FILE_PATH_LITERAL("data"))
+ .AppendASCII(name);
+
+ data_source_ = new FileDataSource(disable_file_size);
+ EXPECT_EQ(PIPELINE_OK, data_source_->Initialize(file_path.MaybeAsASCII()));
+ }
+
DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest);
};
TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
// Simulate avformat_open_input() failing.
+ CreateDemuxer("ten_byte_file"),
EXPECT_CALL(host_, SetCurrentReadPosition(_));
- demuxer_->Initialize(CreateDataSource("ten_byte_file"),
- NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
+ demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN));
message_loop_.RunAllPending();
}
@@ -156,31 +158,32 @@ TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
// avformat_open_input(), but has avformat_find_stream_info() fail.
//
//TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) {
+// CreateDemuxer("find_stream_info_fail.webm");
// demuxer_->Initialize(
-// CreateDataSource("find_stream_info_fail.webm"),
// NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE));
// message_loop_.RunAllPending();
//}
TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) {
// Open a file with no streams whatsoever.
+ CreateDemuxer("no_streams.webm");
EXPECT_CALL(host_, SetCurrentReadPosition(_));
demuxer_->Initialize(
- CreateDataSource("no_streams.webm"),
NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
message_loop_.RunAllPending();
}
TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) {
// Open a file containing streams but none of which are audio/video streams.
+ CreateDemuxer("no_audio_video.webm");
demuxer_->Initialize(
- CreateDataSource("no_audio_video.webm"),
NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
message_loop_.RunAllPending();
}
TEST_F(FFmpegDemuxerTest, Initialize_Successful) {
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// Video stream should be present.
scoped_refptr<DemuxerStream> stream =
@@ -230,7 +233,8 @@ TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) {
// Stream #4: Audio (16-bit signed little endian PCM)
//
// We should only pick the first audio/video streams we come across.
- InitializeDemuxer(CreateDataSource("bear-320x240-multitrack.webm"));
+ CreateDemuxer("bear-320x240-multitrack.webm");
+ InitializeDemuxer();
// Video stream should be VP8.
scoped_refptr<DemuxerStream> stream =
@@ -251,7 +255,8 @@ TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) {
TEST_F(FFmpegDemuxerTest, Read_Audio) {
// We test that on a successful audio packet read.
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// Attempt a read from the audio stream and run the message loop until done.
scoped_refptr<DemuxerStream> audio =
@@ -271,7 +276,8 @@ TEST_F(FFmpegDemuxerTest, Read_Audio) {
TEST_F(FFmpegDemuxerTest, Read_Video) {
// We test that on a successful video packet read.
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// Attempt a read from the video stream and run the message loop until done.
scoped_refptr<DemuxerStream> video =
@@ -292,7 +298,8 @@ TEST_F(FFmpegDemuxerTest, Read_Video) {
TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) {
// Test the start time is the first timestamp of the video and audio stream.
- InitializeDemuxer(CreateDataSource("nonzero-start-time.webm"));
+ CreateDemuxer("nonzero-start-time.webm");
+ InitializeDemuxer();
// Attempt a read from the video stream and run the message loop until done.
scoped_refptr<DemuxerStream> video =
@@ -323,7 +330,8 @@ TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) {
TEST_F(FFmpegDemuxerTest, Read_EndOfStream) {
// Verify that end of stream buffers are created.
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// We should now expect an end of stream buffer.
scoped_refptr<DemuxerStream> audio =
@@ -356,7 +364,8 @@ TEST_F(FFmpegDemuxerTest, Read_EndOfStream) {
TEST_F(FFmpegDemuxerTest, Seek) {
// We're testing that the demuxer frees all queued packets when it receives
// a Seek().
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// Get our streams.
scoped_refptr<DemuxerStream> video =
@@ -434,7 +443,8 @@ class MockReadCB : public base::RefCountedThreadSafe<MockReadCB> {
TEST_F(FFmpegDemuxerTest, Stop) {
// Tests that calling Read() on a stopped demuxer stream immediately deletes
// the callback.
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// Get our stream.
scoped_refptr<DemuxerStream> audio =
@@ -470,7 +480,8 @@ TEST_F(FFmpegDemuxerTest, Stop) {
// This test verifies that DemuxerStream::Read() does not use an invalid demuxer
// pointer (no crash occurs) and calls the callback with an EndOfStream buffer.
TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) {
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// Get our stream.
scoped_refptr<DemuxerStream> audio =
@@ -513,7 +524,8 @@ TEST_F(FFmpegDemuxerTest, DisableAudioStream) {
// 1. Initialize the demuxer with audio and video stream.
// 2. Send a "disable audio stream" message to the demuxer.
// 3. Demuxer will free audio packets even if audio stream was initialized.
- InitializeDemuxer(CreateDataSource("bear-320x240.webm"));
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
// Submit a "disable audio stream" message to the demuxer.
demuxer_->OnAudioRendererDisabled();
@@ -548,8 +560,9 @@ TEST_F(FFmpegDemuxerTest, DisableAudioStream) {
class MockFFmpegDemuxer : public FFmpegDemuxer {
public:
- explicit MockFFmpegDemuxer(MessageLoop* message_loop)
- : FFmpegDemuxer(message_loop, true) {
+ MockFFmpegDemuxer(MessageLoop* message_loop,
+ const scoped_refptr<DataSource>& data_source)
+ : FFmpegDemuxer(message_loop, data_source, true) {
}
virtual ~MockFFmpegDemuxer() {}
@@ -575,10 +588,8 @@ TEST_F(FFmpegDemuxerTest, ProtocolRead) {
// Creates a demuxer.
scoped_refptr<MockFFmpegDemuxer> demuxer(
- new MockFFmpegDemuxer(&message_loop_));
- ASSERT_TRUE(demuxer);
+ new MockFFmpegDemuxer(&message_loop_, data_source));
demuxer->set_host(&host_);
- demuxer->data_source_ = data_source;
uint8 kBuffer[1];
InSequence s;
@@ -643,8 +654,8 @@ TEST_F(FFmpegDemuxerTest, GetBitrate_UnsetInContainer_NoFileSize) {
}
TEST_F(FFmpegDemuxerTest, ProtocolGetSetPosition) {
- scoped_refptr<DataSource> data_source = CreateDataSource("bear-320x240.webm");
- InitializeDemuxer(data_source);
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
InSequence s;
@@ -663,29 +674,30 @@ TEST_F(FFmpegDemuxerTest, ProtocolGetSetPosition) {
}
TEST_F(FFmpegDemuxerTest, ProtocolGetSize) {
- scoped_refptr<DataSource> data_source = CreateDataSource("bear-320x240.webm");
- InitializeDemuxer(data_source);
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
int64 data_source_size = 0;
int64 demuxer_size = 0;
- EXPECT_TRUE(data_source->GetSize(&data_source_size));
+ EXPECT_TRUE(data_source_->GetSize(&data_source_size));
EXPECT_TRUE(demuxer_->GetSize(&demuxer_size));
EXPECT_NE(0, data_source_size);
EXPECT_EQ(data_source_size, demuxer_size);
}
TEST_F(FFmpegDemuxerTest, ProtocolIsStreaming) {
- scoped_refptr<DataSource> data_source = CreateDataSource("bear-320x240.webm");
- InitializeDemuxer(data_source);
+ CreateDemuxer("bear-320x240.webm");
+ InitializeDemuxer();
- EXPECT_FALSE(data_source->IsStreaming());
+ EXPECT_FALSE(data_source_->IsStreaming());
EXPECT_FALSE(demuxer_->IsStreaming());
}
// Verify that seek works properly when the WebM cues data is at the start of
// the file instead of at the end.
TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) {
- InitializeDemuxer(CreateDataSource("bear-320x240-cues-in-front.webm"));
+ CreateDemuxer("bear-320x240-cues-in-front.webm");
+ InitializeDemuxer();
// Get our streams.
scoped_refptr<DemuxerStream> video =
diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc
index b84cfc0..cfcbf87 100644
--- a/media/filters/pipeline_integration_test.cc
+++ b/media/filters/pipeline_integration_test.cc
@@ -85,7 +85,7 @@ class PipelineIntegrationTest
public:
void StartPipelineWithMediaSource(MockMediaSource& source) {
pipeline_->Start(
- CreateFilterCollection(&source), source.url(),
+ CreateFilterCollection(&source),
base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTest::OnError, base::Unretained(this)),
NetworkEventCB(), QuitOnStatusCB(PIPELINE_OK));
diff --git a/media/filters/pipeline_integration_test_base.cc b/media/filters/pipeline_integration_test_base.cc
index 558e1ec..6fcead0 100644
--- a/media/filters/pipeline_integration_test_base.cc
+++ b/media/filters/pipeline_integration_test_base.cc
@@ -6,9 +6,9 @@
#include "base/bind.h"
#include "media/base/media_log.h"
-#include "media/filters/chunk_demuxer_factory.h"
+#include "media/filters/chunk_demuxer.h"
#include "media/filters/ffmpeg_audio_decoder.h"
-#include "media/filters/ffmpeg_demuxer_factory.h"
+#include "media/filters/ffmpeg_demuxer.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "media/filters/file_data_source.h"
#include "media/filters/null_audio_renderer.h"
@@ -81,7 +81,6 @@ bool PipelineIntegrationTestBase::Start(const std::string& url,
PipelineStatus expected_status) {
pipeline_->Start(
CreateFilterCollection(url),
- url,
base::Bind(&PipelineIntegrationTestBase::OnEnded, base::Unretained(this)),
base::Bind(&PipelineIntegrationTestBase::OnError, base::Unretained(this)),
NetworkEventCB(),
@@ -147,22 +146,21 @@ scoped_ptr<FilterCollection>
PipelineIntegrationTestBase::CreateFilterCollection(const std::string& url) {
scoped_refptr<FileDataSource> data_source = new FileDataSource();
CHECK_EQ(PIPELINE_OK, data_source->Initialize(url));
- return CreateFilterCollection(scoped_ptr<DemuxerFactory>(
- new FFmpegDemuxerFactory(data_source, &message_loop_)));
+ return CreateFilterCollection(new FFmpegDemuxer(
+ &message_loop_, data_source, false));
}
scoped_ptr<FilterCollection>
PipelineIntegrationTestBase::CreateFilterCollection(
ChunkDemuxerClient* client) {
- return CreateFilterCollection(scoped_ptr<DemuxerFactory>(
- new ChunkDemuxerFactory(client)));
+ return CreateFilterCollection(new ChunkDemuxer(client));
}
scoped_ptr<FilterCollection>
PipelineIntegrationTestBase::CreateFilterCollection(
- scoped_ptr<DemuxerFactory> demuxer_factory) {
+ const scoped_refptr<Demuxer>& demuxer) {
scoped_ptr<FilterCollection> collection(new FilterCollection());
- collection->SetDemuxerFactory(demuxer_factory.Pass());
+ collection->SetDemuxer(demuxer);
collection->AddAudioDecoder(new FFmpegAudioDecoder(
base::Bind(&MessageLoopFactory::GetMessageLoop,
base::Unretained(message_loop_factory_.get()),
diff --git a/media/filters/pipeline_integration_test_base.h b/media/filters/pipeline_integration_test_base.h
index 4b486d2..df7937a 100644
--- a/media/filters/pipeline_integration_test_base.h
+++ b/media/filters/pipeline_integration_test_base.h
@@ -68,7 +68,7 @@ class PipelineIntegrationTestBase {
void OnError(PipelineStatus status);
void QuitAfterCurrentTimeTask(const base::TimeDelta& quit_time);
scoped_ptr<FilterCollection> CreateFilterCollection(
- scoped_ptr<DemuxerFactory> demuxer_factory);
+ const scoped_refptr<Demuxer>& demuxer);
void OnVideoRendererPaint();
MOCK_METHOD1(OnSetOpaque, void(bool));
diff --git a/media/media.gyp b/media/media.gyp
index a11e2d0..29a7774 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -130,8 +130,6 @@
'base/decrypt_config.h',
'base/demuxer.cc',
'base/demuxer.h',
- 'base/demuxer_factory.cc',
- 'base/demuxer_factory.h',
'base/demuxer_stream.cc',
'base/demuxer_stream.h',
'base/djb2.cc',
@@ -189,18 +187,12 @@
'filters/chunk_demuxer.cc',
'filters/chunk_demuxer.h',
'filters/chunk_demuxer_client.h',
- 'filters/chunk_demuxer_factory.cc',
- 'filters/chunk_demuxer_factory.h',
'filters/dummy_demuxer.cc',
'filters/dummy_demuxer.h',
- 'filters/dummy_demuxer_factory.cc',
- 'filters/dummy_demuxer_factory.h',
'filters/ffmpeg_audio_decoder.cc',
'filters/ffmpeg_audio_decoder.h',
'filters/ffmpeg_demuxer.cc',
'filters/ffmpeg_demuxer.h',
- 'filters/ffmpeg_demuxer_factory.cc',
- 'filters/ffmpeg_demuxer_factory.h',
'filters/ffmpeg_h264_bitstream_converter.cc',
'filters/ffmpeg_h264_bitstream_converter.h',
'filters/ffmpeg_glue.cc',
@@ -292,14 +284,10 @@
'filters/chunk_demuxer.cc',
'filters/chunk_demuxer.h',
'filters/chunk_demuxer_client.h',
- 'filters/chunk_demuxer_factory.cc',
- 'filters/chunk_demuxer_factory.h',
'filters/ffmpeg_audio_decoder.cc',
'filters/ffmpeg_audio_decoder.h',
'filters/ffmpeg_demuxer.cc',
'filters/ffmpeg_demuxer.h',
- 'filters/ffmpeg_demuxer_factory.cc',
- 'filters/ffmpeg_demuxer_factory.h',
'filters/ffmpeg_h264_bitstream_converter.cc',
'filters/ffmpeg_h264_bitstream_converter.h',
'filters/ffmpeg_glue.cc',
diff --git a/media/tools/player_wtl/movie.cc b/media/tools/player_wtl/movie.cc
index a506bdf..4e3c9ab 100644
--- a/media/tools/player_wtl/movie.cc
+++ b/media/tools/player_wtl/movie.cc
@@ -14,14 +14,14 @@
#include "media/base/message_loop_factory.h"
#include "media/base/pipeline.h"
#include "media/filters/ffmpeg_audio_decoder.h"
-#include "media/filters/ffmpeg_demuxer_factory.h"
+#include "media/filters/ffmpeg_demuxer.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "media/filters/file_data_source.h"
#include "media/filters/null_audio_renderer.h"
#include "media/filters/video_renderer_base.h"
using media::FFmpegAudioDecoder;
-using media::FFmpegDemuxerFactory;
+using media::FFmpegDemuxer;
using media::FFmpegVideoDecoder;
using media::FileDataSource;
using media::FilterCollection;
@@ -78,8 +78,8 @@ bool Movie::Open(const wchar_t* url, VideoRendererBase* video_renderer) {
// Create filter collection.
scoped_ptr<FilterCollection> collection(new FilterCollection());
- collection->SetDemuxerFactory(scoped_ptr<DemuxerFactory>(
- new FFmpegDemuxerFactory(data_source, pipeline_loop)));
+ collection->SetDemuxer(new FFmpegDemuxer(
+ pipeline_loop, data_source, true));
collection->AddAudioDecoder(new FFmpegAudioDecoder(
base::Bind(&MessageLoopFactory::GetMessageLoop,
base::Unretained(message_loop_factory_.get()),
@@ -97,7 +97,6 @@ bool Movie::Open(const wchar_t* url, VideoRendererBase* video_renderer) {
media::PipelineStatusNotification note;
pipeline_->Start(
collection.Pass(),
- url_utf8,
media::PipelineStatusCB(),
media::PipelineStatusCB(),
media::NetworkEventCB(),
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index e2ea311..467d92f 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -24,7 +24,7 @@
#include "media/base/pipeline.h"
#include "media/base/video_frame.h"
#include "media/filters/ffmpeg_audio_decoder.h"
-#include "media/filters/ffmpeg_demuxer_factory.h"
+#include "media/filters/ffmpeg_demuxer.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "media/filters/file_data_source.h"
#include "media/filters/null_audio_renderer.h"
@@ -109,8 +109,8 @@ bool InitPipeline(MessageLoop* message_loop,
// Create our filter factories.
scoped_ptr<media::FilterCollection> collection(
new media::FilterCollection());
- collection->SetDemuxerFactory(scoped_ptr<media::DemuxerFactory>(
- new media::FFmpegDemuxerFactory(data_source, message_loop)));
+ collection->SetDemuxer(new media::FFmpegDemuxer(
+ message_loop, data_source, true));
collection->AddAudioDecoder(new media::FFmpegAudioDecoder(
base::Bind(&media::MessageLoopFactory::GetMessageLoop,
base::Unretained(message_loop_factory),
@@ -133,7 +133,7 @@ bool InitPipeline(MessageLoop* message_loop,
*pipeline = new media::Pipeline(message_loop, new media::MediaLog());
media::PipelineStatusNotification note;
(*pipeline)->Start(
- collection.Pass(), "", media::PipelineStatusCB(),
+ collection.Pass(), media::PipelineStatusCB(),
media::PipelineStatusCB(), media::NetworkEventCB(),
note.Callback());
diff --git a/media/tools/seek_tester/seek_tester.cc b/media/tools/seek_tester/seek_tester.cc
index 17b03ea..b3d3e09 100644
--- a/media/tools/seek_tester/seek_tester.cc
+++ b/media/tools/seek_tester/seek_tester.cc
@@ -51,8 +51,8 @@ int main(int argc, char** argv) {
MessageLoop loop;
media::PipelineStatusCB quitter = base::Bind(&QuitMessageLoop, &loop);
scoped_refptr<media::FFmpegDemuxer> demuxer(
- new media::FFmpegDemuxer(&loop, true));
- demuxer->Initialize(file_data_source, quitter);
+ new media::FFmpegDemuxer(&loop, file_data_source, true));
+ demuxer->Initialize(quitter);
loop.Run();
demuxer->Seek(base::TimeDelta::FromMilliseconds(seek_target_ms), quitter);
diff --git a/webkit/media/filter_helpers.cc b/webkit/media/filter_helpers.cc
index f665f84..d1499a5 100644
--- a/webkit/media/filter_helpers.cc
+++ b/webkit/media/filter_helpers.cc
@@ -7,10 +7,10 @@
#include "base/bind.h"
#include "media/base/filter_collection.h"
#include "media/base/message_loop_factory.h"
-#include "media/filters/chunk_demuxer_factory.h"
-#include "media/filters/dummy_demuxer_factory.h"
+#include "media/filters/chunk_demuxer.h"
+#include "media/filters/dummy_demuxer.h"
#include "media/filters/ffmpeg_audio_decoder.h"
-#include "media/filters/ffmpeg_demuxer_factory.h"
+#include "media/filters/ffmpeg_demuxer.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "webkit/media/media_stream_client.h"
@@ -60,9 +60,9 @@ bool BuildMediaStreamCollection(const WebKit::WebURL& url,
// that the MediaStream represents a local webcam. This will need to
// change in the future when GetVideoDecoder is no longer hardcoded to
// only return CaptureVideoDecoders.
- scoped_ptr<media::DemuxerFactory> demuxer_factory(
- new media::DummyDemuxerFactory(true, false, true));
- filter_collection->SetDemuxerFactory(demuxer_factory.Pass());
+ //
+ // See http://crbug.com/120426 for details.
+ filter_collection->SetDemuxer(new media::DummyDemuxer(true, false, true));
return true;
}
@@ -77,9 +77,7 @@ bool BuildMediaSourceCollection(
if (media_source_url.isEmpty() || url != media_source_url)
return false;
- scoped_ptr<media::DemuxerFactory> demuxer_factory(
- new media::ChunkDemuxerFactory(client));
- filter_collection->SetDemuxerFactory(demuxer_factory.Pass());
+ filter_collection->SetDemuxer(new media::ChunkDemuxer(client));
AddDefaultDecodersToCollection(message_loop_factory, filter_collection,
video_decoder);
@@ -88,13 +86,14 @@ bool BuildMediaSourceCollection(
void BuildDefaultCollection(
const scoped_refptr<media::DataSource>& data_source,
+ bool local_source,
media::MessageLoopFactory* message_loop_factory,
media::FilterCollection* filter_collection,
scoped_refptr<media::FFmpegVideoDecoder>* video_decoder) {
- scoped_ptr<media::DemuxerFactory> demuxer_factory(
- new media::FFmpegDemuxerFactory(
- data_source, message_loop_factory->GetMessageLoop("PipelineThread")));
- filter_collection->SetDemuxerFactory(demuxer_factory.Pass());
+ filter_collection->SetDemuxer(new media::FFmpegDemuxer(
+ message_loop_factory->GetMessageLoop("PipelineThread"),
+ data_source,
+ local_source));
AddDefaultDecodersToCollection(message_loop_factory, filter_collection,
video_decoder);
diff --git a/webkit/media/filter_helpers.h b/webkit/media/filter_helpers.h
index f34da86..cdea330 100644
--- a/webkit/media/filter_helpers.h
+++ b/webkit/media/filter_helpers.h
@@ -45,9 +45,16 @@ bool BuildMediaSourceCollection(
media::FilterCollection* filter_collection,
scoped_refptr<media::FFmpegVideoDecoder>* video_decoder);
-// Builds the required filters for handling regular URLs, adds them to
-// |filter_collection| and fills |video_decoder|.
-void BuildDefaultCollection(const scoped_refptr<media::DataSource>& data_source,
+// Builds the required filters for handling regular URLs and adds them to
+// |filter_collection| and fills |video_decoder| returning true if successful.
+//
+// |local_source| refers to whether the data being fetched requires network
+// access.
+//
+// TODO(scherkus): a data source should be able to tell us this.
+void BuildDefaultCollection(
+ const scoped_refptr<media::DataSource>& data_source,
+ bool local_source,
media::MessageLoopFactory* message_loop_factory,
media::FilterCollection* filter_collection,
scoped_refptr<media::FFmpegVideoDecoder>* video_decoder);
diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc
index 6283c65..146f2839 100644
--- a/webkit/media/webmediaplayer_impl.cc
+++ b/webkit/media/webmediaplayer_impl.cc
@@ -221,7 +221,7 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url) {
if (BuildMediaStreamCollection(url, media_stream_client_,
message_loop_factory_.get(),
filter_collection_.get())) {
- StartPipeline(gurl);
+ StartPipeline();
return;
}
@@ -231,8 +231,8 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url) {
message_loop_factory_.get(),
filter_collection_.get(),
&video_decoder)) {
- StartPipeline(gurl);
proxy_->set_video_decoder(video_decoder);
+ StartPipeline();
return;
}
@@ -827,20 +827,24 @@ void WebMediaPlayerImpl::DataSourceInitialized(
return;
}
+ // TODO(scherkus): this is leftover from removing DemuxerFactory -- instead
+ // our DataSource should report this information. See http://crbug.com/120426
+ bool local_source = !gurl.SchemeIs("http") && !gurl.SchemeIs("https");
+
scoped_refptr<media::FFmpegVideoDecoder> video_decoder;
BuildDefaultCollection(proxy_->data_source(),
+ local_source,
message_loop_factory_.get(),
filter_collection_.get(),
&video_decoder);
proxy_->set_video_decoder(video_decoder);
- StartPipeline(gurl);
+ StartPipeline();
}
-void WebMediaPlayerImpl::StartPipeline(const GURL& gurl) {
+void WebMediaPlayerImpl::StartPipeline() {
started_ = true;
pipeline_->Start(
filter_collection_.Pass(),
- gurl.spec(),
base::Bind(&WebMediaPlayerProxy::PipelineEndedCallback, proxy_.get()),
base::Bind(&WebMediaPlayerProxy::PipelineErrorCallback, proxy_.get()),
base::Bind(&WebMediaPlayerProxy::NetworkEventCallback, proxy_.get()),
diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h
index bb96828..fc803a3 100644
--- a/webkit/media/webmediaplayer_impl.h
+++ b/webkit/media/webmediaplayer_impl.h
@@ -205,7 +205,7 @@ class WebMediaPlayerImpl
void DataSourceInitialized(const GURL& gurl, media::PipelineStatus status);
// Finishes starting the pipeline due to a call to load().
- void StartPipeline(const GURL& gurl);
+ void StartPipeline();
// Helpers that set the network/ready state and notifies the client if
// they've changed.