summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/renderer/media/audio_renderer_impl_unittest.cc1
-rw-r--r--chrome/renderer/render_view.cc7
-rw-r--r--media/base/composite_filter.cc76
-rw-r--r--media/base/composite_filter.h33
-rw-r--r--media/base/composite_filter_unittest.cc32
-rw-r--r--media/base/filters.cc45
-rw-r--r--media/base/filters.h26
-rw-r--r--media/base/message_loop_factory.cc11
-rw-r--r--media/base/message_loop_factory.h34
-rw-r--r--media/base/message_loop_factory_impl.cc51
-rw-r--r--media/base/message_loop_factory_impl.h38
-rw-r--r--media/base/mock_filters.cc16
-rw-r--r--media/base/mock_filters.h7
-rw-r--r--media/filters/decoder_base.h37
-rw-r--r--media/filters/decoder_base_unittest.cc6
-rw-r--r--media/filters/ffmpeg_audio_decoder.cc5
-rw-r--r--media/filters/ffmpeg_audio_decoder.h8
-rw-r--r--media/filters/ffmpeg_demuxer.cc34
-rw-r--r--media/filters/ffmpeg_demuxer.h7
-rw-r--r--media/filters/ffmpeg_demuxer_unittest.cc11
-rw-r--r--media/filters/ffmpeg_video_decoder.cc58
-rw-r--r--media/filters/ffmpeg_video_decoder.h4
-rw-r--r--media/filters/ffmpeg_video_decoder_unittest.cc8
-rw-r--r--media/filters/omx_video_decoder.cc44
-rw-r--r--media/filters/omx_video_decoder.h5
-rw-r--r--media/media.gyp4
-rw-r--r--media/tools/player_wtl/movie.cc21
-rw-r--r--media/tools/player_wtl/movie.h4
-rw-r--r--media/tools/player_wtl/view.h1
-rw-r--r--media/tools/player_x11/player_x11.cc25
-rw-r--r--media/tools/player_x11/x11_video_renderer.h2
-rw-r--r--webkit/glue/webmediaplayer_impl.cc24
-rw-r--r--webkit/glue/webmediaplayer_impl.h7
-rw-r--r--webkit/support/webkit_support.cc8
-rw-r--r--webkit/tools/test_shell/test_webview_delegate.cc8
35 files changed, 361 insertions, 347 deletions
diff --git a/chrome/renderer/media/audio_renderer_impl_unittest.cc b/chrome/renderer/media/audio_renderer_impl_unittest.cc
index b5f80e6..249c987 100644
--- a/chrome/renderer/media/audio_renderer_impl_unittest.cc
+++ b/chrome/renderer/media/audio_renderer_impl_unittest.cc
@@ -46,7 +46,6 @@ class AudioRendererImplTest : public ::testing::Test {
// Create and initialize audio renderer.
renderer_ = new AudioRendererImpl(filter_);
renderer_->set_host(&host_);
- renderer_->set_message_loop(message_loop_.get());
renderer_->Initialize(decoder_, media::NewExpectedCallback());
// Run pending tasks and simulate responding with a created audio stream.
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 9395eca..f16ae6f 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -106,6 +106,7 @@
#include "grit/renderer_resources.h"
#include "media/base/filter_collection.h"
#include "media/base/media_switches.h"
+#include "media/base/message_loop_factory_impl.h"
#include "net/base/data_url.h"
#include "net/base/escape.h"
#include "net/base/net_errors.h"
@@ -2811,6 +2812,8 @@ WebSharedWorker* RenderView::createSharedWorker(
WebMediaPlayer* RenderView::createMediaPlayer(
WebFrame* frame, WebMediaPlayerClient* client) {
+ scoped_ptr<media::MessageLoopFactory> message_loop_factory(
+ new media::MessageLoopFactoryImpl());
scoped_ptr<media::FilterCollection> collection(
new media::FilterCollection());
@@ -2846,7 +2849,9 @@ WebMediaPlayer* RenderView::createMediaPlayer(
video_renderer = renderer;
scoped_ptr<webkit_glue::WebMediaPlayerImpl> result(
- new webkit_glue::WebMediaPlayerImpl(client, collection.release()));
+ new webkit_glue::WebMediaPlayerImpl(client,
+ collection.release(),
+ message_loop_factory.release()));
if (!result->Initialize(frame,
cmd_line->HasSwitch(switches::kSimpleDataSource),
video_renderer)) {
diff --git a/media/base/composite_filter.cc b/media/base/composite_filter.cc
index 94665fd..41eb31c 100644
--- a/media/base/composite_filter.cc
+++ b/media/base/composite_filter.cc
@@ -4,6 +4,7 @@
#include "media/base/composite_filter.h"
+#include "base/message_loop.h"
#include "base/stl_util-inl.h"
#include "media/base/callback.h"
@@ -40,46 +41,21 @@ class CompositeFilter::FilterHostImpl : public FilterHost {
DISALLOW_COPY_AND_ASSIGN(FilterHostImpl);
};
-CompositeFilter::CompositeFilter(MessageLoop* message_loop) {
- Init(message_loop, NULL);
-}
-
-CompositeFilter::CompositeFilter(MessageLoop* message_loop,
- ThreadFactoryFunction thread_factory) {
- DCHECK(thread_factory);
- Init(message_loop, thread_factory);
-}
-
-void CompositeFilter::Init(MessageLoop* message_loop,
- ThreadFactoryFunction thread_factory) {
+CompositeFilter::CompositeFilter(MessageLoop* message_loop)
+ : state_(kCreated),
+ sequence_index_(0),
+ message_loop_(message_loop),
+ error_(PIPELINE_OK) {
DCHECK(message_loop);
- message_loop_ = message_loop;
- thread_factory_ = thread_factory;
runnable_factory_.reset(
new ScopedRunnableMethodFactory<CompositeFilter>(this));
-
- if (!thread_factory_) {
- thread_factory_ = &CompositeFilter::DefaultThreadFactory;
- }
-
- state_ = kCreated;
- sequence_index_ = 0;
- error_ = PIPELINE_OK;
}
CompositeFilter::~CompositeFilter() {
DCHECK_EQ(message_loop_, MessageLoop::current());
DCHECK(state_ == kCreated || state_ == kStopped);
- // Stop every running filter thread.
- for (FilterThreadVector::iterator iter = filter_threads_.begin();
- iter != filter_threads_.end();
- ++iter) {
- (*iter)->Stop();
- }
-
filters_.clear();
- STLDeleteElements(&filter_threads_);
}
bool CompositeFilter::AddFilter(scoped_refptr<Filter> filter) {
@@ -87,19 +63,6 @@ bool CompositeFilter::AddFilter(scoped_refptr<Filter> filter) {
if (!filter.get() || state_ != kCreated || !host())
return false;
- // Create a dedicated thread for this filter if applicable.
- if (filter->requires_message_loop()) {
- scoped_ptr<base::Thread> thread(
- thread_factory_(filter->message_loop_name()));
-
- if (!thread.get() || !thread->Start()) {
- return false;
- }
-
- filter->set_message_loop(thread->message_loop());
- filter_threads_.push_back(thread.release());
- }
-
// Register ourselves as the filter's host.
filter->set_host(host_impl_.get());
filters_.push_back(make_scoped_refptr(filter.get()));
@@ -121,22 +84,6 @@ FilterHost* CompositeFilter::host() {
return host_impl_.get() ? host_impl_->host() : NULL;
}
-bool CompositeFilter::requires_message_loop() const {
- return false;
-}
-
-const char* CompositeFilter::message_loop_name() const {
- return "CompositeFilter";
-}
-
-void CompositeFilter::set_message_loop(MessageLoop* message_loop) {
- NOTREACHED() << "Message loop should not be set.";
-}
-
-MessageLoop* CompositeFilter::message_loop() {
- return NULL;
-}
-
void CompositeFilter::Play(FilterCallback* play_callback) {
DCHECK_EQ(message_loop_, MessageLoop::current());
scoped_ptr<FilterCallback> callback(play_callback);
@@ -278,11 +225,6 @@ void CompositeFilter::OnAudioRendererDisabled() {
}
}
-base::Thread* CompositeFilter::DefaultThreadFactory(
- const char* thread_name) {
- return new base::Thread(thread_name);
-}
-
void CompositeFilter::ChangeState(State new_state) {
DCHECK_EQ(message_loop_, MessageLoop::current());
state_ = new_state;
@@ -529,9 +471,9 @@ void CompositeFilter::SetError(PipelineError error) {
}
CompositeFilter::FilterHostImpl::FilterHostImpl(CompositeFilter* parent,
- FilterHost* host) :
- parent_(parent),
- host_(host) {
+ FilterHost* host)
+ : parent_(parent),
+ host_(host) {
}
FilterHost* CompositeFilter::FilterHostImpl::host() {
diff --git a/media/base/composite_filter.h b/media/base/composite_filter.h
index c1bd8c0..daac421 100644
--- a/media/base/composite_filter.h
+++ b/media/base/composite_filter.h
@@ -5,39 +5,29 @@
#ifndef MEDIA_BASE_COMPOSITE_FILTER_H_
#define MEDIA_BASE_COMPOSITE_FILTER_H_
-#include "base/threading/thread.h"
+#include "base/task.h"
#include "media/base/filter_host.h"
#include "media/base/filters.h"
+class MessageLoop;
+
namespace media {
class CompositeFilter : public Filter {
public:
- typedef base::Thread* (*ThreadFactoryFunction)(const char* thread_name);
-
- CompositeFilter(MessageLoop* message_loop);
-
- // Constructor that allows the default thread creation strategy to be
- // overridden.
- CompositeFilter(MessageLoop* message_loop,
- ThreadFactoryFunction thread_factory);
+ explicit CompositeFilter(MessageLoop* message_loop);
// Adds a filter to the composite. This is only allowed after set_host()
// is called and before the first state changing operation such as Play(),
// Flush(), Stop(), or Seek(). True is returned if the filter was successfully
// added to the composite. False is returned if the filter couldn't be added
- // because the composite is in the wrong state or the filter needed a thread
- // and the composite was unable to create one.
+ // because the composite is in the wrong state.
bool AddFilter(scoped_refptr<Filter> filter);
// media::Filter methods.
virtual const char* major_mime_type() const;
virtual void set_host(FilterHost* host);
virtual FilterHost* host();
- virtual bool requires_message_loop() const;
- virtual const char* message_loop_name() const;
- virtual void set_message_loop(MessageLoop* message_loop);
- virtual MessageLoop* message_loop();
virtual void Play(FilterCallback* play_callback);
virtual void Pause(FilterCallback* pause_callback);
virtual void Flush(FilterCallback* flush_callback);
@@ -49,9 +39,6 @@ class CompositeFilter : public Filter {
protected:
virtual ~CompositeFilter();
- /// Default thread factory strategy.
- static base::Thread* DefaultThreadFactory(const char* thread_name);
-
void SetError(PipelineError error);
private:
@@ -75,9 +62,6 @@ class CompositeFilter : public Filter {
kError
};
- // Initialization method called by constructors.
- void Init(MessageLoop* message_loop, ThreadFactoryFunction thread_factory);
-
// Transition to a new state.
void ChangeState(State new_state);
@@ -124,17 +108,10 @@ class CompositeFilter : public Filter {
// to the host of this filter.
bool CanForwardError();
- // Vector of threads owned by the composite and used by filters in |filters_|.
- typedef std::vector<base::Thread*> FilterThreadVector;
- FilterThreadVector filter_threads_;
-
// Vector of the filters added to the composite.
typedef std::vector<scoped_refptr<Filter> > FilterVector;
FilterVector filters_;
- // Factory function used to create filter threads.
- ThreadFactoryFunction thread_factory_;
-
// Callback for the pending request.
scoped_ptr<FilterCallback> callback_;
diff --git a/media/base/composite_filter_unittest.cc b/media/base/composite_filter_unittest.cc
index 4ce96c1..0be2185 100644
--- a/media/base/composite_filter_unittest.cc
+++ b/media/base/composite_filter_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/message_loop.h"
#include "media/base/composite_filter.h"
#include "media/base/mock_callback.h"
#include "media/base/mock_filter_host.h"
@@ -297,56 +298,29 @@ void CompositeFilterTest::RunFilter2Callback() {
delete callback;
}
-static base::Thread* NullThreadFactory(const char* thread_name) {
- return NULL;
-}
-
// Test AddFilter() failure cases.
TEST_F(CompositeFilterTest, TestAddFilterFailCases) {
// Test adding a null pointer.
EXPECT_FALSE(composite_->AddFilter(NULL));
- scoped_refptr<StrictMock<MockFilter> > filter =
- new StrictMock<MockFilter>(true);
+ scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
EXPECT_EQ(NULL, filter->host());
- EXPECT_EQ(NULL, filter->message_loop());
// Test failing because set_host() hasn't been called yet.
EXPECT_FALSE(composite_->AddFilter(filter));
-
- // Test thread creation failure.
- composite_ = new CompositeFilter(&message_loop_, &NullThreadFactory);
- composite_->set_host(mock_filter_host_.get());
- EXPECT_FALSE(composite_->AddFilter(filter));
- EXPECT_EQ(NULL, filter->host());
- EXPECT_EQ(NULL, filter->message_loop());
}
// Test successful AddFilter() cases.
TEST_F(CompositeFilterTest, TestAddFilter) {
composite_->set_host(mock_filter_host_.get());
- // Add a filter that doesn't require a message loop.
+ // Add a filter.
scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
EXPECT_EQ(NULL, filter->host());
- EXPECT_EQ(NULL, filter->message_loop());
EXPECT_TRUE(composite_->AddFilter(filter));
EXPECT_TRUE(filter->host() != NULL);
- EXPECT_EQ(NULL, filter->message_loop());
-
- // Add a filter that requires a message loop.
- scoped_refptr<StrictMock<MockFilter> > filter_2 =
- new StrictMock<MockFilter>(true);
-
- EXPECT_EQ(NULL, filter_2->host());
- EXPECT_EQ(NULL, filter_2->message_loop());
-
- EXPECT_TRUE(composite_->AddFilter(filter_2));
-
- EXPECT_TRUE(filter_2->host() != NULL);
- EXPECT_TRUE(filter_2->message_loop() != NULL);
}
TEST_F(CompositeFilterTest, TestPlay) {
diff --git a/media/base/filters.cc b/media/base/filters.cc
index d3d3bcb..eff50b4 100644
--- a/media/base/filters.cc
+++ b/media/base/filters.cc
@@ -5,11 +5,10 @@
#include "media/base/filters.h"
#include "base/logging.h"
-#include "base/message_loop.h"
namespace media {
-Filter::Filter() : host_(NULL), message_loop_(NULL) {}
+Filter::Filter() : host_(NULL) {}
Filter::~Filter() {}
@@ -27,24 +26,6 @@ FilterHost* Filter::host() {
return host_;
}
-bool Filter::requires_message_loop() const {
- return false;
-}
-
-const char* Filter::message_loop_name() const {
- return "FilterThread";
-}
-
-void Filter::set_message_loop(MessageLoop* message_loop) {
- DCHECK(message_loop);
- DCHECK(!message_loop_);
- message_loop_ = message_loop;
-}
-
-MessageLoop* Filter::message_loop() {
- return message_loop_;
-}
-
void Filter::Play(FilterCallback* callback) {
DCHECK(callback);
if (callback) {
@@ -93,26 +74,10 @@ bool DataSource::IsUrlSupported(const std::string& url) {
return true;
}
-bool Demuxer::requires_message_loop() const {
- return true;
-}
-
-const char* Demuxer::message_loop_name() const {
- return "DemuxerThread";
-}
-
const char* AudioDecoder::major_mime_type() const {
return mime_type::kMajorTypeAudio;
}
-bool AudioDecoder::requires_message_loop() const {
- return true;
-}
-
-const char* AudioDecoder::message_loop_name() const {
- return "AudioDecoderThread";
-}
-
const char* AudioRenderer::major_mime_type() const {
return mime_type::kMajorTypeAudio;
}
@@ -121,14 +86,6 @@ const char* VideoDecoder::major_mime_type() const {
return mime_type::kMajorTypeVideo;
}
-bool VideoDecoder::requires_message_loop() const {
- return true;
-}
-
-const char* VideoDecoder::message_loop_name() const {
- return "VideoDecoderThread";
-}
-
const char* VideoRenderer::major_mime_type() const {
return mime_type::kMajorTypeVideo;
}
diff --git a/media/base/filters.h b/media/base/filters.h
index 49fa347..84c466d 100644
--- a/media/base/filters.h
+++ b/media/base/filters.h
@@ -33,8 +33,6 @@
#include "media/base/media_format.h"
#include "media/base/video_frame.h"
-class MessageLoop;
-
namespace media {
class Buffer;
@@ -61,20 +59,6 @@ class Filter : public base::RefCountedThreadSafe<Filter> {
virtual FilterHost* host();
- // Indicates whether this filter requires a message loop to operate.
- virtual bool requires_message_loop() const;
-
- // The name to associate with this filter's message loop.
- virtual const char* message_loop_name() const;
-
- // Sets the private member |message_loop_|, which is used by filters for
- // processing asynchronous tasks and maintaining synchronized access to
- // internal data members. The message loop should be running and exceed the
- // lifetime of the filter.
- virtual void set_message_loop(MessageLoop* message_loop);
-
- virtual MessageLoop* message_loop();
-
// The pipeline has resumed playback. Filters can continue requesting reads.
// Filters may implement this method if they need to respond to this call.
// TODO(boliu): Check that callback is not NULL in subclasses.
@@ -114,11 +98,9 @@ class Filter : public base::RefCountedThreadSafe<Filter> {
virtual ~Filter();
FilterHost* host() const { return host_; }
- MessageLoop* message_loop() const { return message_loop_; }
private:
FilterHost* host_;
- MessageLoop* message_loop_;
DISALLOW_COPY_AND_ASSIGN(Filter);
};
@@ -154,9 +136,6 @@ class DataSource : public Filter {
class Demuxer : public Filter {
public:
- virtual bool requires_message_loop() const;
- virtual const char* message_loop_name() const;
-
// Initialize a Demuxer with the given DataSource, executing the callback upon
// completion.
virtual void Initialize(DataSource* data_source,
@@ -211,9 +190,6 @@ class DemuxerStream : public base::RefCountedThreadSafe<DemuxerStream> {
class VideoDecoder : public Filter {
public:
virtual const char* major_mime_type() const;
- virtual bool requires_message_loop() const;
- virtual const char* message_loop_name() const;
-
// Initialize a VideoDecoder with the given DemuxerStream, executing the
// callback upon completion.
@@ -256,8 +232,6 @@ class VideoDecoder : public Filter {
class AudioDecoder : public Filter {
public:
virtual const char* major_mime_type() const;
- virtual bool requires_message_loop() const;
- virtual const char* message_loop_name() const;
// Initialize a AudioDecoder with the given DemuxerStream, executing the
// callback upon completion.
diff --git a/media/base/message_loop_factory.cc b/media/base/message_loop_factory.cc
new file mode 100644
index 0000000..e5b1d33
--- /dev/null
+++ b/media/base/message_loop_factory.cc
@@ -0,0 +1,11 @@
+// Copyright (c) 2011 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/message_loop_factory.h"
+
+namespace media {
+
+MessageLoopFactory::~MessageLoopFactory() {}
+
+} // namespace media
diff --git a/media/base/message_loop_factory.h b/media/base/message_loop_factory.h
new file mode 100644
index 0000000..dacfab2
--- /dev/null
+++ b/media/base/message_loop_factory.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2011 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_MESSAGE_LOOP_FACTORY_H_
+#define MEDIA_BASE_MESSAGE_LOOP_FACTORY_H_
+
+#include <string>
+
+#include "base/scoped_ptr.h"
+
+class MessageLoop;
+
+namespace media {
+
+// Factory object that manages named MessageLoops.
+class MessageLoopFactory {
+ public:
+ // Get the message loop associated with |name|. A new MessageLoop
+ // is created if the factory doesn't have one associated with |name|.
+ // NULL is returned if |name| is an empty string, or a new
+ // MessageLoop needs to be created and a failure occurs during the
+ // creation process.
+ virtual MessageLoop* GetMessageLoop(const std::string& name) = 0;
+
+ protected:
+ // Only allow scoped_ptr<> to delete factory.
+ friend class scoped_ptr<MessageLoopFactory>;
+ virtual ~MessageLoopFactory();
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_MESSAGE_LOOP_FACTORY_H_
diff --git a/media/base/message_loop_factory_impl.cc b/media/base/message_loop_factory_impl.cc
new file mode 100644
index 0000000..bcf3bf8
--- /dev/null
+++ b/media/base/message_loop_factory_impl.cc
@@ -0,0 +1,51 @@
+// Copyright (c) 2011 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/message_loop_factory_impl.h"
+
+namespace media {
+
+MessageLoopFactoryImpl::MessageLoopFactoryImpl() {}
+
+MessageLoopFactoryImpl::~MessageLoopFactoryImpl() {
+ AutoLock auto_lock(lock_);
+
+ for (ThreadMap::iterator iter = thread_map_.begin();
+ iter != thread_map_.end();
+ ++iter) {
+ base::Thread* thread = (*iter).second;
+
+ if (thread) {
+ thread->Stop();
+ delete thread;
+ }
+ }
+ thread_map_.clear();
+}
+
+// MessageLoopFactory methods.
+MessageLoop* MessageLoopFactoryImpl::GetMessageLoop(const std::string& name) {
+ if (name.empty()) {
+ return NULL;
+ }
+
+ AutoLock auto_lock(lock_);
+
+ ThreadMap::iterator it = thread_map_.find(name);
+ if (it != thread_map_.end())
+ return (*it).second->message_loop();
+
+ scoped_ptr<base::Thread> thread(new base::Thread(name.c_str()));
+
+ if (thread->Start()) {
+ MessageLoop* message_loop = thread->message_loop();
+ thread_map_[name] = thread.release();
+ return message_loop;
+ }
+
+ LOG(ERROR) << "Failed to start '" << name << "' thread!";
+ return NULL;
+}
+
+} // namespace media
diff --git a/media/base/message_loop_factory_impl.h b/media/base/message_loop_factory_impl.h
new file mode 100644
index 0000000..1c8a61a
--- /dev/null
+++ b/media/base/message_loop_factory_impl.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2011 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_MESSAGE_LOOP_FACTORY_IMPL_H_
+#define MEDIA_BASE_MESSAGE_LOOP_FACTORY_IMPL_H_
+
+#include <map>
+#include <string>
+
+#include "base/threading/thread.h"
+#include "media/base/message_loop_factory.h"
+
+namespace media {
+
+class MessageLoopFactoryImpl : public MessageLoopFactory {
+ public:
+ MessageLoopFactoryImpl();
+
+ // MessageLoopFactory methods.
+ virtual MessageLoop* GetMessageLoop(const std::string& name);
+
+ protected:
+ virtual ~MessageLoopFactoryImpl();
+
+ private:
+ // Lock used to serialize access for the following data members.
+ Lock lock_;
+
+ typedef std::map<std::string, base::Thread*> ThreadMap;
+ ThreadMap thread_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageLoopFactoryImpl);
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_MESSAGE_LOOP_FACTORY_IMPL_H_
diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc
index 90df69b..8aa5458 100644
--- a/media/base/mock_filters.cc
+++ b/media/base/mock_filters.cc
@@ -74,23 +74,9 @@ void RunStopFilterCallback(FilterCallback* callback) {
delete callback;
}
-MockFilter::MockFilter() :
- requires_message_loop_(false) {
-}
-
-MockFilter::MockFilter(bool requires_message_loop) :
- requires_message_loop_(requires_message_loop) {
+MockFilter::MockFilter() {
}
MockFilter::~MockFilter() {}
-bool MockFilter::requires_message_loop() const {
- return requires_message_loop_;
-}
-
-const char* MockFilter::message_loop_name() const {
- return "MockFilter";
-}
-
-
} // namespace media
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 45c1e29..3439597 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -46,12 +46,8 @@ class Destroyable : public MockClass {
class MockFilter : public Filter {
public:
MockFilter();
- MockFilter(bool requires_message_loop);
// Filter implementation.
- virtual bool requires_message_loop() const;
- virtual const char* message_loop_name() const;
-
MOCK_METHOD1(Play, void(FilterCallback* callback));
MOCK_METHOD1(Pause, void(FilterCallback* callback));
MOCK_METHOD1(Flush, void(FilterCallback* callback));
@@ -64,9 +60,6 @@ class MockFilter : public Filter {
virtual ~MockFilter();
private:
-
- bool requires_message_loop_;
-
DISALLOW_COPY_AND_ASSIGN(MockFilter);
};
diff --git a/media/filters/decoder_base.h b/media/filters/decoder_base.h
index f8b26ab..7ddd16e 100644
--- a/media/filters/decoder_base.h
+++ b/media/filters/decoder_base.h
@@ -26,17 +26,16 @@ namespace media {
template <class Decoder, class Output>
class DecoderBase : public Decoder {
public:
-
// Filter implementation.
virtual void Stop(FilterCallback* callback) {
- this->message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &DecoderBase::StopTask, callback));
}
virtual void Seek(base::TimeDelta time,
FilterCallback* callback) {
- this->message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &DecoderBase::SeekTask, time, callback));
}
@@ -44,7 +43,7 @@ class DecoderBase : public Decoder {
// Decoder implementation.
virtual void Initialize(DemuxerStream* demuxer_stream,
FilterCallback* callback) {
- this->message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this,
&DecoderBase::InitializeTask,
@@ -58,13 +57,14 @@ class DecoderBase : public Decoder {
// Note that this class is only used by the audio decoder, this will
// eventually be merged into FFmpegAudioDecoder.
virtual void ProduceAudioSamples(scoped_refptr<Output> output) {
- this->message_loop()->PostTask(FROM_HERE,
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &DecoderBase::ReadTask, output));
}
protected:
- DecoderBase()
- : pending_reads_(0),
+ explicit DecoderBase(MessageLoop* message_loop)
+ : message_loop_(message_loop),
+ pending_reads_(0),
pending_requests_(0),
state_(kUninitialized) {
}
@@ -78,7 +78,7 @@ class DecoderBase : public Decoder {
// It places an output buffer in the result queue. It must be called from
// within the OnDecode method.
void EnqueueResult(Output* output) {
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
if (!IsStopped()) {
result_queue_.push_back(output);
}
@@ -136,6 +136,9 @@ class DecoderBase : public Decoder {
}
}
+ // Provide access to subclasses.
+ MessageLoop* message_loop() { return message_loop_; }
+
private:
bool IsStopped() { return state_ == kStopped; }
@@ -146,12 +149,12 @@ class DecoderBase : public Decoder {
// TODO(scherkus): change the callback format to pass a scoped_refptr<> or
// better yet see if we can get away with not using reference counting.
scoped_refptr<Buffer> buffer_ref = buffer;
- this->message_loop()->PostTask(FROM_HERE,
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &DecoderBase::ReadCompleteTask, buffer_ref));
}
void StopTask(FilterCallback* callback) {
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
// Delegate to the subclass first.
DoStop(NewRunnableMethod(this, &DecoderBase::OnStopComplete, callback));
@@ -169,7 +172,7 @@ class DecoderBase : public Decoder {
}
void SeekTask(base::TimeDelta time, FilterCallback* callback) {
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed";
DCHECK_EQ(0u, pending_requests_) << "Pending requests should be empty";
@@ -190,7 +193,7 @@ class DecoderBase : public Decoder {
}
void InitializeTask(DemuxerStream* demuxer_stream, FilterCallback* callback) {
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
CHECK(kUninitialized == state_);
CHECK(!demuxer_stream_);
demuxer_stream_ = demuxer_stream;
@@ -208,7 +211,7 @@ class DecoderBase : public Decoder {
scoped_ptr<bool> success_deleter(success);
AutoCallbackRunner done_runner(done_cb);
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
// Delegate to subclass first.
if (!*success) {
this->host()->SetError(PIPELINE_ERROR_DECODE);
@@ -220,7 +223,7 @@ class DecoderBase : public Decoder {
}
void ReadTask(scoped_refptr<Output> output) {
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
// TODO(scherkus): should reply with a null operation (empty buffer).
if (IsStopped())
@@ -239,7 +242,7 @@ class DecoderBase : public Decoder {
}
void ReadCompleteTask(scoped_refptr<Buffer> buffer) {
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK_GT(pending_reads_, 0u);
--pending_reads_;
if (IsStopped()) {
@@ -255,7 +258,7 @@ class DecoderBase : public Decoder {
//
// Return true if one read request is fulfilled.
bool FulfillPendingRead() {
- DCHECK_EQ(MessageLoop::current(), this->message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
if (!pending_requests_ || result_queue_.empty()) {
return false;
}
@@ -274,6 +277,8 @@ class DecoderBase : public Decoder {
return true;
}
+ MessageLoop* message_loop_;
+
// Tracks the number of asynchronous reads issued to |demuxer_stream_|.
// Using size_t since it is always compared against deque::size().
size_t pending_reads_;
diff --git a/media/filters/decoder_base_unittest.cc b/media/filters/decoder_base_unittest.cc
index 2fefb56..661ba4e 100644
--- a/media/filters/decoder_base_unittest.cc
+++ b/media/filters/decoder_base_unittest.cc
@@ -62,7 +62,8 @@ class MockDecoderCallback {
class MockDecoderImpl : public media::DecoderBase<
MockDecoder, MockDecoderOutput> {
public:
- MockDecoderImpl() {
+ explicit MockDecoderImpl(MessageLoop* message_loop)
+ : media::DecoderBase<MockDecoder, MockDecoderOutput>(message_loop) {
media_format_.SetAsString(media::MediaFormat::kMimeType, "mock");
}
@@ -117,12 +118,11 @@ ACTION(CompleteDemuxRequest) {
// \ ReadCallback() -> client
TEST(DecoderBaseTest, FlowControl) {
MessageLoop message_loop;
- scoped_refptr<MockDecoderImpl> decoder(new MockDecoderImpl());
+ scoped_refptr<MockDecoderImpl> decoder(new MockDecoderImpl(&message_loop));
MockDecoderCallback read_callback;
decoder->set_consume_audio_samples_callback(
NewCallback(&read_callback, &MockDecoderCallback::OnReadComplete));
scoped_refptr<MockDemuxerStream> demuxer_stream(new MockDemuxerStream());
- decoder->set_message_loop(&message_loop);
// Initailize.
EXPECT_CALL(*decoder, DoInitialize(NotNull(), NotNull(), NotNull()))
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index 2e8e9ad..030149a 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -27,8 +27,9 @@ namespace media {
const size_t FFmpegAudioDecoder::kOutputBufferSize =
AVCODEC_MAX_AUDIO_FRAME_SIZE;
-FFmpegAudioDecoder::FFmpegAudioDecoder()
- : codec_context_(NULL),
+FFmpegAudioDecoder::FFmpegAudioDecoder(MessageLoop* message_loop)
+ : DecoderBase<AudioDecoder, Buffer>(message_loop),
+ codec_context_(NULL),
estimated_next_timestamp_(kNoTimestamp) {
}
diff --git a/media/filters/ffmpeg_audio_decoder.h b/media/filters/ffmpeg_audio_decoder.h
index 0a7a915..20bc22e 100644
--- a/media/filters/ffmpeg_audio_decoder.h
+++ b/media/filters/ffmpeg_audio_decoder.h
@@ -1,6 +1,6 @@
-// Copyright (c) 2009 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.
+// Copyright (c) 2009 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_FFMPEG_AUDIO_DECODER_H_
#define MEDIA_FILTERS_FFMPEG_AUDIO_DECODER_H_
@@ -16,7 +16,7 @@ class ScopedPtrAVFree;
class FFmpegAudioDecoder : public DecoderBase<AudioDecoder, Buffer> {
public:
- FFmpegAudioDecoder();
+ explicit FFmpegAudioDecoder(MessageLoop* message_loop);
virtual ~FFmpegAudioDecoder();
protected:
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index 7c4f763..17248c6 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -239,12 +239,14 @@ base::TimeDelta FFmpegDemuxerStream::ConvertStreamTimestamp(
//
// FFmpegDemuxer
//
-FFmpegDemuxer::FFmpegDemuxer()
- : format_context_(NULL),
+FFmpegDemuxer::FFmpegDemuxer(MessageLoop* message_loop)
+ : message_loop_(message_loop),
+ format_context_(NULL),
read_event_(false, false),
read_has_failed_(false),
last_read_bytes_(0),
read_position_(0) {
+ DCHECK(message_loop_);
}
FFmpegDemuxer::~FFmpegDemuxer() {
@@ -279,13 +281,13 @@ FFmpegDemuxer::~FFmpegDemuxer() {
}
void FFmpegDemuxer::PostDemuxTask() {
- message_loop()->PostTask(FROM_HERE,
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &FFmpegDemuxer::DemuxTask));
}
void FFmpegDemuxer::Stop(FilterCallback* callback) {
// Post a task to notify the streams to stop as well.
- message_loop()->PostTask(FROM_HERE,
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &FFmpegDemuxer::StopTask, callback));
// Then wakes up the thread from reading.
@@ -297,18 +299,18 @@ void FFmpegDemuxer::Seek(base::TimeDelta time, FilterCallback* callback) {
// operation is completed and filters behind the demuxer is good to issue
// more reads, but we are posting a task here, which makes the seek operation
// asynchronous, should change how seek works to make it fully asynchronous.
- message_loop()->PostTask(FROM_HERE,
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &FFmpegDemuxer::SeekTask, time, callback));
}
void FFmpegDemuxer::OnAudioRendererDisabled() {
- message_loop()->PostTask(FROM_HERE,
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &FFmpegDemuxer::DisableAudioStreamTask));
}
void FFmpegDemuxer::Initialize(DataSource* data_source,
FilterCallback* callback) {
- message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this,
&FFmpegDemuxer::InitializeTask,
@@ -391,9 +393,13 @@ bool FFmpegDemuxer::IsStreaming() {
return data_source_->IsStreaming();
}
+MessageLoop* FFmpegDemuxer::message_loop() {
+ return message_loop_;
+}
+
void FFmpegDemuxer::InitializeTask(DataSource* data_source,
FilterCallback* callback) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
scoped_ptr<FilterCallback> c(callback);
data_source_ = data_source;
@@ -477,7 +483,7 @@ void FFmpegDemuxer::InitializeTask(DataSource* data_source,
}
void FFmpegDemuxer::SeekTask(base::TimeDelta time, FilterCallback* callback) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
scoped_ptr<FilterCallback> c(callback);
// Tell streams to flush buffers due to seeking.
@@ -504,7 +510,7 @@ void FFmpegDemuxer::SeekTask(base::TimeDelta time, FilterCallback* callback) {
}
void FFmpegDemuxer::DemuxTask() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
// Make sure we have work to do before demuxing.
if (!StreamsHavePendingReads()) {
@@ -556,7 +562,7 @@ void FFmpegDemuxer::DemuxTask() {
}
void FFmpegDemuxer::StopTask(FilterCallback* callback) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
StreamVector::iterator iter;
for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
(*iter)->Stop();
@@ -568,7 +574,7 @@ void FFmpegDemuxer::StopTask(FilterCallback* callback) {
}
void FFmpegDemuxer::DisableAudioStreamTask() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
StreamVector::iterator iter;
for (size_t i = 0; i < packet_streams_.size(); ++i) {
@@ -586,7 +592,7 @@ void FFmpegDemuxer::DisableAudioStreamTask() {
}
bool FFmpegDemuxer::StreamsHavePendingReads() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
StreamVector::iterator iter;
for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
if ((*iter)->HasPendingReads()) {
@@ -597,7 +603,7 @@ bool FFmpegDemuxer::StreamsHavePendingReads() {
}
void FFmpegDemuxer::StreamHasEnded() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
StreamVector::iterator iter;
for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
AVPacket* packet = new AVPacket();
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h
index e5355203..2123563 100644
--- a/media/filters/ffmpeg_demuxer.h
+++ b/media/filters/ffmpeg_demuxer.h
@@ -121,7 +121,7 @@ class FFmpegDemuxerStream : public DemuxerStream, public AVStreamProvider {
class FFmpegDemuxer : public Demuxer,
public FFmpegURLProtocol {
public:
- FFmpegDemuxer();
+ explicit FFmpegDemuxer(MessageLoop* message_loop);
virtual ~FFmpegDemuxer();
// Posts a task to perform additional demuxing.
@@ -144,6 +144,9 @@ class FFmpegDemuxer : public Demuxer,
virtual bool GetSize(int64* size_out);
virtual bool IsStreaming();
+ // Provide access to FFmpegDemuxerStream.
+ MessageLoop* message_loop();
+
private:
// Only allow a factory to create this class.
friend class MockFFmpegDemuxer;
@@ -187,6 +190,8 @@ class FFmpegDemuxer : public Demuxer,
// Signal that read has completed, and |size| bytes have been read.
virtual void SignalReadCompleted(size_t size);
+ MessageLoop* message_loop_;
+
// FFmpeg context handle.
AVFormatContext* format_context_;
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index 0bb21c0..5ba6fd3 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -65,12 +65,11 @@ class FFmpegDemuxerTest : public testing::Test {
FFmpegDemuxerTest() {
// Create an FFmpegDemuxer.
- demuxer_ = new FFmpegDemuxer();
+ demuxer_ = new FFmpegDemuxer(&message_loop_);
DCHECK(demuxer_);
// Inject a filter host and message loop and prepare a data source.
demuxer_->set_host(&host_);
- demuxer_->set_message_loop(&message_loop_);
data_source_ = new StrictMock<MockDataSource>();
// Initialize FFmpeg fixtures.
@@ -619,7 +618,9 @@ TEST_F(FFmpegDemuxerTest, DisableAudioStream) {
class MockFFmpegDemuxer : public FFmpegDemuxer {
public:
- MockFFmpegDemuxer() {}
+ explicit MockFFmpegDemuxer(MessageLoop* message_loop)
+ : FFmpegDemuxer(message_loop) {
+ }
virtual ~MockFFmpegDemuxer() {}
MOCK_METHOD0(WaitForRead, size_t());
@@ -638,10 +639,10 @@ void RunCallback(size_t size, DataSource::ReadCallback* callback) {
TEST_F(FFmpegDemuxerTest, ProtocolRead) {
// Creates a demuxer.
- scoped_refptr<MockFFmpegDemuxer> demuxer(new MockFFmpegDemuxer());
+ scoped_refptr<MockFFmpegDemuxer> demuxer(
+ new MockFFmpegDemuxer(&message_loop_));
ASSERT_TRUE(demuxer);
demuxer->set_host(&host_);
- demuxer->set_message_loop(&message_loop_);
demuxer->data_source_ = data_source_;
uint8 kBuffer[1];
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index bdaee8c..13b26b2 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -21,8 +21,10 @@
namespace media {
-FFmpegVideoDecoder::FFmpegVideoDecoder(VideoDecodeContext* decode_context)
- : width_(0),
+FFmpegVideoDecoder::FFmpegVideoDecoder(MessageLoop* message_loop,
+ VideoDecodeContext* decode_context)
+ : message_loop_(message_loop),
+ width_(0),
height_(0),
time_base_(new AVRational()),
state_(kUnInitialized),
@@ -36,8 +38,8 @@ FFmpegVideoDecoder::~FFmpegVideoDecoder() {
void FFmpegVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this,
&FFmpegVideoDecoder::Initialize,
@@ -46,7 +48,7 @@ void FFmpegVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(!demuxer_stream_);
DCHECK(!initialize_callback_.get());
@@ -98,11 +100,11 @@ void FFmpegVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
config.width = width_;
config.height = height_;
state_ = kInitializing;
- decode_engine_->Initialize(message_loop(), this, NULL, config);
+ decode_engine_->Initialize(message_loop_, this, NULL, config);
}
void FFmpegVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(initialize_callback_.get());
info_ = info; // Save a copy.
@@ -128,15 +130,15 @@ void FFmpegVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) {
}
void FFmpegVideoDecoder::Stop(FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(FROM_HERE,
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
&FFmpegVideoDecoder::Stop,
callback));
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(!uninitialize_callback_.get());
uninitialize_callback_.reset(callback);
@@ -147,7 +149,7 @@ void FFmpegVideoDecoder::Stop(FilterCallback* callback) {
}
void FFmpegVideoDecoder::OnUninitializeComplete() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(uninitialize_callback_.get());
AutoCallbackRunner done_runner(uninitialize_callback_.release());
@@ -157,8 +159,8 @@ void FFmpegVideoDecoder::OnUninitializeComplete() {
}
void FFmpegVideoDecoder::Pause(FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(FROM_HERE,
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
&FFmpegVideoDecoder::Pause,
callback));
@@ -170,15 +172,15 @@ void FFmpegVideoDecoder::Pause(FilterCallback* callback) {
}
void FFmpegVideoDecoder::Flush(FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(FROM_HERE,
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
&FFmpegVideoDecoder::Flush,
callback));
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(!flush_callback_.get());
state_ = kFlushing;
@@ -191,7 +193,7 @@ void FFmpegVideoDecoder::Flush(FilterCallback* callback) {
}
void FFmpegVideoDecoder::OnFlushComplete() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(flush_callback_.get());
AutoCallbackRunner done_runner(flush_callback_.release());
@@ -206,8 +208,8 @@ void FFmpegVideoDecoder::OnFlushComplete() {
void FFmpegVideoDecoder::Seek(base::TimeDelta time,
FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(FROM_HERE,
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
&FFmpegVideoDecoder::Seek,
time,
@@ -215,7 +217,7 @@ void FFmpegVideoDecoder::Seek(base::TimeDelta time,
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(!seek_callback_.get());
seek_callback_.reset(callback);
@@ -223,7 +225,7 @@ void FFmpegVideoDecoder::Seek(base::TimeDelta time,
}
void FFmpegVideoDecoder::OnSeekComplete() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(seek_callback_.get());
AutoCallbackRunner done_runner(seek_callback_.release());
@@ -239,7 +241,7 @@ void FFmpegVideoDecoder::OnFormatChange(VideoStreamInfo stream_info) {
void FFmpegVideoDecoder::OnReadComplete(Buffer* buffer_in) {
scoped_refptr<Buffer> buffer(buffer_in);
- message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this,
&FFmpegVideoDecoder::OnReadCompleteTask,
@@ -247,7 +249,7 @@ void FFmpegVideoDecoder::OnReadComplete(Buffer* buffer_in) {
}
void FFmpegVideoDecoder::OnReadCompleteTask(scoped_refptr<Buffer> buffer) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK_NE(state_, kStopped); // because of Flush() before Stop().
// During decode, because reads are issued asynchronously, it is possible to
@@ -301,15 +303,15 @@ const MediaFormat& FFmpegVideoDecoder::media_format() {
void FFmpegVideoDecoder::ProduceVideoFrame(
scoped_refptr<VideoFrame> video_frame) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this,
&FFmpegVideoDecoder::ProduceVideoFrame, video_frame));
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
// Synchronized flushing before stop should prevent this.
DCHECK_NE(state_, kStopped);
@@ -330,7 +332,7 @@ void FFmpegVideoDecoder::ProduceVideoFrame(
void FFmpegVideoDecoder::ConsumeVideoFrame(
scoped_refptr<VideoFrame> video_frame) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK_NE(state_, kStopped);
if (video_frame.get()) {
@@ -365,7 +367,7 @@ void FFmpegVideoDecoder::ConsumeVideoFrame(
void FFmpegVideoDecoder::ProduceVideoSample(
scoped_refptr<Buffer> buffer) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK_NE(state_, kStopped);
demuxer_stream_->Read(
diff --git a/media/filters/ffmpeg_video_decoder.h b/media/filters/ffmpeg_video_decoder.h
index 76e60e8..82e5a8c 100644
--- a/media/filters/ffmpeg_video_decoder.h
+++ b/media/filters/ffmpeg_video_decoder.h
@@ -25,7 +25,8 @@ class VideoDecodeEngine;
class FFmpegVideoDecoder : public VideoDecoder,
public VideoDecodeEngine::EventHandler {
public:
- explicit FFmpegVideoDecoder(VideoDecodeContext* decode_context);
+ FFmpegVideoDecoder(MessageLoop* message_loop,
+ VideoDecodeContext* decode_context);
virtual ~FFmpegVideoDecoder();
// Filter implementation.
@@ -109,6 +110,7 @@ class FFmpegVideoDecoder : public VideoDecoder,
// the provided engine.
virtual void SetVideoDecodeEngineForTest(VideoDecodeEngine* engine);
+ MessageLoop* message_loop_;
size_t width_;
size_t height_;
MediaFormat media_format_;
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc
index 3db54c0..128e531 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -71,8 +71,9 @@ class MockVideoDecodeEngine : public VideoDecodeEngine {
// Class that just mocks the private functions.
class DecoderPrivateMock : public FFmpegVideoDecoder {
public:
- explicit DecoderPrivateMock(VideoDecodeContext* context)
- : FFmpegVideoDecoder(context) {
+ DecoderPrivateMock(MessageLoop* message_loop,
+ VideoDecodeContext* context)
+ : FFmpegVideoDecoder(message_loop, context) {
}
// change access qualifier for test: used in actions.
@@ -125,7 +126,7 @@ class FFmpegVideoDecoderTest : public testing::Test {
// Create an FFmpegVideoDecoder, and MockVideoDecodeEngine.
//
// TODO(ajwong): Break the test's dependency on FFmpegVideoDecoder.
- decoder_ = new DecoderPrivateMock(NULL);
+ decoder_ = new DecoderPrivateMock(&message_loop_, NULL);
renderer_ = new MockVideoRenderer();
engine_ = new StrictMock<MockVideoDecodeEngine>();
@@ -133,7 +134,6 @@ class FFmpegVideoDecoderTest : public testing::Test {
// Inject mocks and prepare a demuxer stream.
decoder_->set_host(&host_);
- decoder_->set_message_loop(&message_loop_);
decoder_->SetVideoDecodeEngineForTest(engine_);
demuxer_ = new StrictMock<MockFFmpegDemuxerStream>();
diff --git a/media/filters/omx_video_decoder.cc b/media/filters/omx_video_decoder.cc
index 15ba4f1..3a31bf7 100644
--- a/media/filters/omx_video_decoder.cc
+++ b/media/filters/omx_video_decoder.cc
@@ -16,8 +16,10 @@
namespace media {
OmxVideoDecoder::OmxVideoDecoder(
+ MessageLoop* message_loop,
VideoDecodeContext* context)
- : decode_engine_(new OmxVideoDecodeEngine()),
+ : message_loop_(message_loop),
+ decode_engine_(new OmxVideoDecodeEngine()),
decode_context_(context),
width_(0), height_(0) {
DCHECK(decode_engine_.get());
@@ -30,8 +32,8 @@ OmxVideoDecoder::~OmxVideoDecoder() {
void OmxVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this,
&OmxVideoDecoder::Initialize,
@@ -40,7 +42,7 @@ void OmxVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
return;
}
- DCHECK_EQ(message_loop(), MessageLoop::current());
+ DCHECK_EQ(message_loop_, MessageLoop::current());
DCHECK(!demuxer_stream_);
DCHECK(!initialize_callback_.get());
@@ -88,11 +90,11 @@ void OmxVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
config.opaque_context = NULL;
config.width = width_;
config.height = height_;
- decode_engine_->Initialize(message_loop(), this, NULL, config);
+ decode_engine_->Initialize(message_loop_, this, NULL, config);
}
void OmxVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(initialize_callback_.get());
info_ = info; // Save a copy.
@@ -115,15 +117,15 @@ void OmxVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) {
}
void OmxVideoDecoder::Stop(FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(FROM_HERE,
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
&OmxVideoDecoder::Stop,
callback));
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(!uninitialize_callback_.get());
uninitialize_callback_.reset(callback);
@@ -131,7 +133,7 @@ void OmxVideoDecoder::Stop(FilterCallback* callback) {
}
void OmxVideoDecoder::OnUninitializeComplete() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(uninitialize_callback_.get());
AutoCallbackRunner done_runner(uninitialize_callback_.release());
@@ -140,15 +142,15 @@ void OmxVideoDecoder::OnUninitializeComplete() {
}
void OmxVideoDecoder::Flush(FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(FROM_HERE,
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
&OmxVideoDecoder::Flush,
callback));
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(!flush_callback_.get());
flush_callback_.reset(callback);
@@ -165,8 +167,8 @@ void OmxVideoDecoder::OnFlushComplete() {
void OmxVideoDecoder::Seek(base::TimeDelta time,
FilterCallback* callback) {
- if (MessageLoop::current() != message_loop()) {
- message_loop()->PostTask(FROM_HERE,
+ if (MessageLoop::current() != message_loop_) {
+ message_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
&OmxVideoDecoder::Seek,
time,
@@ -174,7 +176,7 @@ void OmxVideoDecoder::Seek(base::TimeDelta time,
return;
}
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(!seek_callback_.get());
seek_callback_.reset(callback);
@@ -182,7 +184,7 @@ void OmxVideoDecoder::Seek(base::TimeDelta time,
}
void OmxVideoDecoder::OnSeekComplete() {
- DCHECK_EQ(MessageLoop::current(), message_loop());
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
DCHECK(seek_callback_.get());
AutoCallbackRunner done_runner(seek_callback_.release());
@@ -196,20 +198,20 @@ void OmxVideoDecoder::OnFormatChange(VideoStreamInfo stream_info) {
}
void OmxVideoDecoder::ProduceVideoSample(scoped_refptr<Buffer> buffer) {
- DCHECK_EQ(message_loop(), MessageLoop::current());
+ DCHECK_EQ(message_loop_, MessageLoop::current());
// Issue more demux.
demuxer_stream_->Read(NewCallback(this, &OmxVideoDecoder::DemuxCompleteTask));
}
void OmxVideoDecoder::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) {
- DCHECK_EQ(message_loop(), MessageLoop::current());
+ DCHECK_EQ(message_loop_, MessageLoop::current());
VideoFrameReady(frame);
}
void OmxVideoDecoder::ProduceVideoFrame(scoped_refptr<VideoFrame> frame) {
DCHECK(decode_engine_.get());
- message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(decode_engine_.get(),
&VideoDecodeEngine::ProduceVideoFrame, frame));
@@ -228,7 +230,7 @@ void OmxVideoDecoder::DemuxCompleteTask(Buffer* buffer) {
// We simply delicate the buffer to the right message loop.
scoped_refptr<Buffer> ref_buffer = buffer;
DCHECK(decode_engine_.get());
- message_loop()->PostTask(
+ message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(decode_engine_.get(),
&VideoDecodeEngine::ConsumeVideoSample, ref_buffer));
diff --git a/media/filters/omx_video_decoder.h b/media/filters/omx_video_decoder.h
index 7eb8504..ddec99f 100644
--- a/media/filters/omx_video_decoder.h
+++ b/media/filters/omx_video_decoder.h
@@ -23,7 +23,8 @@ class VideoFrame;
class OmxVideoDecoder : public VideoDecoder,
public VideoDecodeEngine::EventHandler {
public:
- explicit OmxVideoDecoder(VideoDecodeContext* decode_context);
+ OmxVideoDecoder(MessageLoop* message_loop,
+ VideoDecodeContext* decode_context);
virtual ~OmxVideoDecoder();
// Filter implementations.
@@ -50,6 +51,8 @@ class OmxVideoDecoder : public VideoDecoder,
// scoped_refptr.
void DemuxCompleteTask(Buffer* buffer);
+ MessageLoop* message_loop_;
+
// Pointer to the demuxer stream that will feed us compressed buffers.
scoped_refptr<DemuxerStream> demuxer_stream_;
scoped_ptr<VideoDecodeEngine> decode_engine_;
diff --git a/media/media.gyp b/media/media.gyp
index 259a7a1..660898b 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -94,6 +94,10 @@
'base/media_switches.cc',
'base/media_switches.h',
'base/media_win.cc',
+ 'base/message_loop_factory.cc',
+ 'base/message_loop_factory.h',
+ 'base/message_loop_factory_impl.cc',
+ 'base/message_loop_factory_impl.h',
'base/pipeline.h',
'base/pipeline_impl.cc',
'base/pipeline_impl.h',
diff --git a/media/tools/player_wtl/movie.cc b/media/tools/player_wtl/movie.cc
index 2efd715..fe73490 100644
--- a/media/tools/player_wtl/movie.cc
+++ b/media/tools/player_wtl/movie.cc
@@ -8,6 +8,7 @@
#include "base/threading/platform_thread.h"
#include "base/utf_string_conversions.h"
#include "media/base/filter_collection.h"
+#include "media/base/message_loop_factory_impl.h"
#include "media/base/pipeline_impl.h"
#include "media/filters/audio_renderer_impl.h"
#include "media/filters/ffmpeg_audio_decoder.h"
@@ -60,12 +61,17 @@ bool Movie::Open(const wchar_t* url, WtlVideoRenderer* video_renderer) {
Close();
}
+ message_loop_factory_.reset(new media::MessageLoopFactoryImpl());
+
// Create filter collection.
scoped_ptr<FilterCollection> collection(new FilterCollection());
collection->AddDataSource(new FileDataSource());
- collection->AddAudioDecoder(new FFmpegAudioDecoder());
- collection->AddDemuxer(new FFmpegDemuxer());
- collection->AddVideoDecoder(new FFmpegVideoDecoder(NULL));
+ collection->AddAudioDecoder(new FFmpegAudioDecoder(
+ message_loop_factory_->GetMessageLoop("AudioDecoderThread")));
+ collection->AddDemuxer(new FFmpegDemuxer(
+ message_loop_factory_->GetMessageLoop("DemuxThread")));
+ collection->AddVideoDecoder(new FFmpegVideoDecoder(
+ message_loop_factory_->GetMessageLoop("VideoDecoderThread"), NULL));
if (enable_audio_) {
collection->AddAudioRenderer(new AudioRendererImpl());
@@ -74,9 +80,8 @@ bool Movie::Open(const wchar_t* url, WtlVideoRenderer* video_renderer) {
}
collection->AddVideoRenderer(video_renderer);
- thread_.reset(new base::Thread("PipelineThread"));
- thread_->Start();
- pipeline_ = new PipelineImpl(thread_->message_loop());
+ pipeline_ = new PipelineImpl(
+ message_loop_factory_->GetMessageLoop("PipelineThread"));
// Create and start our pipeline.
pipeline_->Start(collection.release(), WideToUTF8(std::wstring(url)), NULL);
@@ -168,10 +173,10 @@ bool Movie::GetDumpYuvFileEnable() {
void Movie::Close() {
if (pipeline_) {
pipeline_->Stop(NULL);
- thread_->Stop();
pipeline_ = NULL;
- thread_.reset();
}
+
+ message_loop_factory_.reset();
}
} // namespace media
diff --git a/media/tools/player_wtl/movie.h b/media/tools/player_wtl/movie.h
index ea81b09..00708f9 100644
--- a/media/tools/player_wtl/movie.h
+++ b/media/tools/player_wtl/movie.h
@@ -11,7 +11,7 @@
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
-#include "base/threading/thread.h"
+#include "media/base/message_loop_factory.h"
template <typename T> struct DefaultSingletonTraits;
class WtlVideoRenderer;
@@ -83,7 +83,7 @@ class Movie {
virtual ~Movie();
scoped_refptr<PipelineImpl> pipeline_;
- scoped_ptr<base::Thread> thread_;
+ scoped_ptr<media::MessageLoopFactory> message_loop_factory_;
bool enable_audio_;
bool enable_draw_;
diff --git a/media/tools/player_wtl/view.h b/media/tools/player_wtl/view.h
index cbb0a48..5273cd5 100644
--- a/media/tools/player_wtl/view.h
+++ b/media/tools/player_wtl/view.h
@@ -9,6 +9,7 @@
#include <process.h>
#include <string.h>
+#include "base/logging.h"
#include "media/base/video_frame.h"
#include "media/base/yuv_convert.h"
#include "media/tools/player_wtl/movie.h"
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index df9bd619..2e75994 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -17,6 +17,7 @@
#include "media/base/filter_collection.h"
#include "media/base/media.h"
#include "media/base/media_switches.h"
+#include "media/base/message_loop_factory_impl.h"
#include "media/base/pipeline_impl.h"
#include "media/filters/audio_renderer_impl.h"
#include "media/filters/ffmpeg_audio_decoder.h"
@@ -83,7 +84,8 @@ bool InitX11() {
bool InitPipeline(MessageLoop* message_loop,
const char* filename, bool enable_audio,
scoped_refptr<media::PipelineImpl>* pipeline,
- MessageLoop* paint_message_loop) {
+ MessageLoop* paint_message_loop,
+ media::MessageLoopFactory* message_loop_factory) {
// Initialize OpenMAX.
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableOpenMax) &&
@@ -102,13 +104,19 @@ bool InitPipeline(MessageLoop* message_loop,
scoped_ptr<media::FilterCollection> collection(
new media::FilterCollection());
collection->AddDataSource(new media::FileDataSource());
- collection->AddDemuxer(new media::FFmpegDemuxer());
- collection->AddAudioDecoder(new media::FFmpegAudioDecoder());
+ collection->AddDemuxer(new media::FFmpegDemuxer(
+ message_loop_factory->GetMessageLoop("DemuxThread")));
+ collection->AddAudioDecoder(new media::FFmpegAudioDecoder(
+ message_loop_factory->GetMessageLoop("AudioDecoderThread")));
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableOpenMax)) {
- collection->AddVideoDecoder(new media::OmxVideoDecoder(NULL));
+ collection->AddVideoDecoder(new media::OmxVideoDecoder(
+ message_loop_factory->GetMessageLoop("VideoDecoderThread"),
+ NULL));
} else {
- collection->AddVideoDecoder(new media::FFmpegVideoDecoder(NULL));
+ collection->AddVideoDecoder(new media::FFmpegVideoDecoder(
+ message_loop_factory->GetMessageLoop("VideoDecoderThread"),
+ NULL));
}
collection->AddVideoRenderer(new Renderer(g_display,
g_window,
@@ -244,13 +252,16 @@ int main(int argc, char** argv) {
// Initialize the pipeline thread and the pipeline.
base::AtExitManager at_exit;
+ scoped_ptr<media::MessageLoopFactory> message_loop_factory(
+ new media::MessageLoopFactoryImpl());
scoped_ptr<base::Thread> thread;
scoped_refptr<media::PipelineImpl> pipeline;
MessageLoop message_loop;
thread.reset(new base::Thread("PipelineThread"));
thread->Start();
if (InitPipeline(thread->message_loop(), filename.c_str(),
- enable_audio, &pipeline, &message_loop)) {
+ enable_audio, &pipeline, &message_loop,
+ message_loop_factory.get())) {
// Main loop of the application.
g_running = true;
@@ -266,6 +277,8 @@ int main(int argc, char** argv) {
}
// Cleanup tasks.
+ message_loop_factory.reset();
+
thread->Stop();
XDestroyWindow(g_display, g_window);
XCloseDisplay(g_display);
diff --git a/media/tools/player_x11/x11_video_renderer.h b/media/tools/player_x11/x11_video_renderer.h
index 0129b60..fd5c12e 100644
--- a/media/tools/player_x11/x11_video_renderer.h
+++ b/media/tools/player_x11/x11_video_renderer.h
@@ -11,6 +11,8 @@
#include "media/base/filters.h"
#include "media/filters/video_renderer_base.h"
+class MessageLoop;
+
class X11VideoRenderer : public media::VideoRendererBase {
public:
X11VideoRenderer(Display* display, Window window, MessageLoop* message_loop);
diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc
index 005c7cf..3bfb6a9 100644
--- a/webkit/glue/webmediaplayer_impl.cc
+++ b/webkit/glue/webmediaplayer_impl.cc
@@ -225,13 +225,14 @@ void WebMediaPlayerImpl::Proxy::PutCurrentFrame(
WebMediaPlayerImpl::WebMediaPlayerImpl(
WebKit::WebMediaPlayerClient* client,
- media::FilterCollection* collection)
+ media::FilterCollection* collection,
+ media::MessageLoopFactory* message_loop_factory)
: network_state_(WebKit::WebMediaPlayer::Empty),
ready_state_(WebKit::WebMediaPlayer::HaveNothing),
main_loop_(NULL),
filter_collection_(collection),
pipeline_(NULL),
- pipeline_thread_("PipelineThread"),
+ message_loop_factory_(message_loop_factory),
paused_(true),
seeking_(false),
playback_rate_(0.0f),
@@ -247,13 +248,14 @@ bool WebMediaPlayerImpl::Initialize(
WebKit::WebFrame* frame,
bool use_simple_data_source,
scoped_refptr<WebVideoRenderer> web_video_renderer) {
- // Create the pipeline and its thread.
- if (!pipeline_thread_.Start()) {
+ MessageLoop* pipeline_message_loop =
+ message_loop_factory_->GetMessageLoop("PipelineThread");
+ if (!pipeline_message_loop) {
NOTREACHED() << "Could not start PipelineThread";
return false;
}
- pipeline_ = new media::PipelineImpl(pipeline_thread_.message_loop());
+ pipeline_ = new media::PipelineImpl(pipeline_message_loop);
// Also we want to be notified of |main_loop_| destruction.
main_loop_->AddDestructionObserver(this);
@@ -290,9 +292,12 @@ bool WebMediaPlayerImpl::Initialize(
}
// Add in the default filter factories.
- filter_collection_->AddDemuxer(new media::FFmpegDemuxer());
- filter_collection_->AddAudioDecoder(new media::FFmpegAudioDecoder());
- filter_collection_->AddVideoDecoder(new media::FFmpegVideoDecoder(NULL));
+ filter_collection_->AddDemuxer(new media::FFmpegDemuxer(
+ message_loop_factory_->GetMessageLoop("DemuxThread")));
+ filter_collection_->AddAudioDecoder(new media::FFmpegAudioDecoder(
+ message_loop_factory_->GetMessageLoop("AudioDecoderThread")));
+ filter_collection_->AddVideoDecoder(new media::FFmpegVideoDecoder(
+ message_loop_factory_->GetMessageLoop("VideoDecoderThread"), NULL));
filter_collection_->AddAudioRenderer(new media::NullAudioRenderer());
return true;
@@ -794,9 +799,10 @@ void WebMediaPlayerImpl::Destroy() {
pipeline_->Stop(NewCallback(this,
&WebMediaPlayerImpl::PipelineStoppedCallback));
pipeline_stopped_.Wait();
- pipeline_thread_.Stop();
}
+ message_loop_factory_.reset();
+
// And then detach the proxy, it may live on the render thread for a little
// longer until all the tasks are finished.
if (proxy_) {
diff --git a/webkit/glue/webmediaplayer_impl.h b/webkit/glue/webmediaplayer_impl.h
index abb1c60..9f2db64 100644
--- a/webkit/glue/webmediaplayer_impl.h
+++ b/webkit/glue/webmediaplayer_impl.h
@@ -62,6 +62,7 @@
#include "gfx/rect.h"
#include "gfx/size.h"
#include "media/base/filters.h"
+#include "media/base/message_loop_factory.h"
#include "media/base/pipeline.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/WebMediaPlayer.h"
@@ -175,7 +176,8 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer,
//
// Callers must call |Initialize()| before they can use the object.
WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client,
- media::FilterCollection* collection);
+ media::FilterCollection* collection,
+ media::MessageLoopFactory* message_loop_factory);
virtual ~WebMediaPlayerImpl();
// Finalizes initialization of the object.
@@ -288,7 +290,8 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer,
// The actual pipeline and the thread it runs on.
scoped_refptr<media::Pipeline> pipeline_;
- base::Thread pipeline_thread_;
+
+ scoped_ptr<media::MessageLoopFactory> message_loop_factory_;
// Playback state.
//
diff --git a/webkit/support/webkit_support.cc b/webkit/support/webkit_support.cc
index 8a76c1f..f043c82 100644
--- a/webkit/support/webkit_support.cc
+++ b/webkit/support/webkit_support.cc
@@ -26,6 +26,7 @@
#include "base/weak_ptr.h"
#include "grit/webkit_chromium_resources.h"
#include "media/base/filter_collection.h"
+#include "media/base/message_loop_factory_impl.h"
#include "net/base/escape.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
@@ -266,6 +267,9 @@ WebPlugin* CreateWebPlugin(WebFrame* frame,
WebKit::WebMediaPlayer* CreateMediaPlayer(WebFrame* frame,
WebMediaPlayerClient* client) {
+ scoped_ptr<media::MessageLoopFactory> message_loop_factory(
+ new media::MessageLoopFactoryImpl());
+
scoped_ptr<media::FilterCollection> collection(
new media::FilterCollection());
@@ -274,7 +278,9 @@ WebKit::WebMediaPlayer* CreateMediaPlayer(WebFrame* frame,
collection->AddVideoRenderer(video_renderer);
scoped_ptr<webkit_glue::WebMediaPlayerImpl> result(
- new webkit_glue::WebMediaPlayerImpl(client, collection.release()));
+ new webkit_glue::WebMediaPlayerImpl(client,
+ collection.release(),
+ message_loop_factory.release()));
if (!result->Initialize(frame, false, video_renderer)) {
return NULL;
}
diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc
index 305fa1f..0d61350 100644
--- a/webkit/tools/test_shell/test_webview_delegate.cc
+++ b/webkit/tools/test_shell/test_webview_delegate.cc
@@ -19,6 +19,7 @@
#include "gfx/native_widget_types.h"
#include "gfx/point.h"
#include "media/base/filter_collection.h"
+#include "media/base/message_loop_factory_impl.h"
#include "net/base/net_errors.h"
#include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h"
#include "third_party/WebKit/WebKit/chromium/public/WebConsoleMessage.h"
@@ -732,6 +733,9 @@ WebWorker* TestWebViewDelegate::createWorker(WebFrame* frame,
WebMediaPlayer* TestWebViewDelegate::createMediaPlayer(
WebFrame* frame, WebMediaPlayerClient* client) {
+ scoped_ptr<media::MessageLoopFactory> message_loop_factory(
+ new media::MessageLoopFactoryImpl());
+
scoped_ptr<media::FilterCollection> collection(
new media::FilterCollection());
@@ -740,7 +744,9 @@ WebMediaPlayer* TestWebViewDelegate::createMediaPlayer(
collection->AddVideoRenderer(video_renderer);
scoped_ptr<webkit_glue::WebMediaPlayerImpl> result(
- new webkit_glue::WebMediaPlayerImpl(client, collection.release()));
+ new webkit_glue::WebMediaPlayerImpl(client,
+ collection.release(),
+ message_loop_factory.release()));
if (!result->Initialize(frame, false, video_renderer)) {
return NULL;
}