summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-11 20:02:13 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-11 20:02:13 +0000
commite24c547f7062bbef2d66548c30103ee9d48c1abf (patch)
tree6d397cb939762a0b687b34204e6e1dade9c63d72 /media
parent03ce3a031f0cd300b279b2334a8d70bcfa15aaff (diff)
downloadchromium_src-e24c547f7062bbef2d66548c30103ee9d48c1abf.zip
chromium_src-e24c547f7062bbef2d66548c30103ee9d48c1abf.tar.gz
chromium_src-e24c547f7062bbef2d66548c30103ee9d48c1abf.tar.bz2
Create video and audio decoder threads on demand.
Instead of creating these worker threads when the decoder objects are instantiated, we now do it when Initialize is called. Doing this avoids spinning a video decoder thread for an audio tag. BUG=114699,116873 TEST=Thread count in the renderer process goes up by 3 and not 4 when an audio element is created. Review URL: https://chromiumcodereview.appspot.com/9632024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126077 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/filters/ffmpeg_audio_decoder.cc14
-rw-r--r--media/filters/ffmpeg_audio_decoder.h5
-rw-r--r--media/filters/ffmpeg_audio_decoder_unittest.cc8
-rw-r--r--media/filters/ffmpeg_decoder_unittest.h13
-rw-r--r--media/filters/ffmpeg_video_decoder.cc15
-rw-r--r--media/filters/ffmpeg_video_decoder.h6
-rw-r--r--media/filters/ffmpeg_video_decoder_unittest.cc4
-rw-r--r--media/filters/pipeline_integration_test_base.cc8
-rw-r--r--media/media.gyp1
-rw-r--r--media/tools/player_wtl/movie.cc9
-rw-r--r--media/tools/player_x11/player_x11.cc8
11 files changed, 75 insertions, 16 deletions
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index b2578e5..97c67f6 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -45,8 +45,10 @@ static bool IsEndOfStream(int result, int decoded_size, Buffer* input) {
}
-FFmpegAudioDecoder::FFmpegAudioDecoder(MessageLoop* message_loop)
- : message_loop_(message_loop),
+FFmpegAudioDecoder::FFmpegAudioDecoder(
+ const base::Callback<MessageLoop*()>& message_loop_cb)
+ : message_loop_factory_cb_(message_loop_cb),
+ message_loop_(NULL),
codec_context_(NULL),
bits_per_channel_(0),
channel_layout_(CHANNEL_LAYOUT_NONE),
@@ -71,6 +73,14 @@ void FFmpegAudioDecoder::Initialize(
const scoped_refptr<DemuxerStream>& stream,
const PipelineStatusCB& pipeline_status_cb,
const StatisticsCB& statistics_cb) {
+ if (!message_loop_) {
+ message_loop_ = message_loop_factory_cb_.Run();
+ message_loop_factory_cb_.Reset();
+ } else {
+ // TODO(scherkus): initialization currently happens more than once in
+ // PipelineIntegrationTest.BasicPlayback.
+ LOG(ERROR) << "Initialize has already been called.";
+ }
message_loop_->PostTask(
FROM_HERE,
base::Bind(&FFmpegAudioDecoder::DoInitialize, this,
diff --git a/media/filters/ffmpeg_audio_decoder.h b/media/filters/ffmpeg_audio_decoder.h
index 68c1128..8654f1936 100644
--- a/media/filters/ffmpeg_audio_decoder.h
+++ b/media/filters/ffmpeg_audio_decoder.h
@@ -7,6 +7,7 @@
#include <list>
+#include "base/callback.h"
#include "base/message_loop.h"
#include "media/base/audio_decoder.h"
@@ -18,7 +19,7 @@ class DataBuffer;
class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder {
public:
- explicit FFmpegAudioDecoder(MessageLoop* message_loop);
+ FFmpegAudioDecoder(const base::Callback<MessageLoop*()>& message_loop_cb);
virtual ~FFmpegAudioDecoder();
// AudioDecoder implementation.
@@ -55,6 +56,8 @@ class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder {
// Delivers decoded samples to |read_cb_| and resets the callback.
void DeliverSamples(const scoped_refptr<Buffer>& samples);
+ // This is !is_null() iff Initialize() hasn't been called.
+ base::Callback<MessageLoop*()> message_loop_factory_cb_;
MessageLoop* message_loop_;
scoped_refptr<DemuxerStream> demuxer_stream_;
diff --git a/media/filters/ffmpeg_audio_decoder_unittest.cc b/media/filters/ffmpeg_audio_decoder_unittest.cc
index 0c7bed5..2c97058 100644
--- a/media/filters/ffmpeg_audio_decoder_unittest.cc
+++ b/media/filters/ffmpeg_audio_decoder_unittest.cc
@@ -13,6 +13,7 @@
#include "media/base/test_data_util.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_audio_decoder.h"
+#include "media/filters/ffmpeg_decoder_unittest.h"
#include "media/filters/ffmpeg_glue.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -25,11 +26,12 @@ namespace media {
ACTION_P(InvokeReadPacket, test) {
test->ReadPacket(arg0);
}
-
+
class FFmpegAudioDecoderTest : public testing::Test {
- public:
+ public:
FFmpegAudioDecoderTest()
- : decoder_(new FFmpegAudioDecoder(&message_loop_)),
+ : decoder_(new FFmpegAudioDecoder(base::Bind(&Identity<MessageLoop*>,
+ &message_loop_))),
demuxer_(new StrictMock<MockDemuxerStream>()) {
CHECK(FFmpegGlue::GetInstance());
diff --git a/media/filters/ffmpeg_decoder_unittest.h b/media/filters/ffmpeg_decoder_unittest.h
new file mode 100644
index 0000000..e558c30
--- /dev/null
+++ b/media/filters/ffmpeg_decoder_unittest.h
@@ -0,0 +1,13 @@
+// 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_FFMPEG_DECODER_UNITTEST_H_
+#define MEDIA_FILTERS_FFMPEG_DECODER_UNITTEST_H_
+
+namespace media {
+// Used to inject our message loop into the FFmpeg[Audio|Video|Decoder.
+template<class T> T Identity(T t) { return t; }
+} // namespace media
+
+#endif // MEDIA_FILTERS_FFMPEG_DECODER_UNITTEST_H_
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index f5eb500..0072b4c 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -51,8 +51,10 @@ static int GetThreadCount(CodecID codec_id) {
return decode_threads;
}
-FFmpegVideoDecoder::FFmpegVideoDecoder(MessageLoop* message_loop)
- : message_loop_(message_loop),
+FFmpegVideoDecoder::FFmpegVideoDecoder(
+ const base::Callback<MessageLoop*()>& message_loop_cb)
+ : message_loop_factory_cb_(message_loop_cb),
+ message_loop_(NULL),
state_(kUninitialized),
codec_context_(NULL),
av_frame_(NULL),
@@ -67,6 +69,15 @@ FFmpegVideoDecoder::~FFmpegVideoDecoder() {
void FFmpegVideoDecoder::Initialize(DemuxerStream* demuxer_stream,
const PipelineStatusCB& pipeline_status_cb,
const StatisticsCB& statistics_cb) {
+ if (!message_loop_) {
+ message_loop_ = message_loop_factory_cb_.Run();
+ message_loop_factory_cb_.Reset();
+ } else {
+ // TODO(scherkus): initialization currently happens more than once in
+ // PipelineIntegrationTest.BasicPlayback.
+ LOG(ERROR) << "Initialize has already been called.";
+ }
+
if (MessageLoop::current() != message_loop_) {
message_loop_->PostTask(FROM_HERE, base::Bind(
&FFmpegVideoDecoder::Initialize, this,
diff --git a/media/filters/ffmpeg_video_decoder.h b/media/filters/ffmpeg_video_decoder.h
index cd60c2e..9ff153f 100644
--- a/media/filters/ffmpeg_video_decoder.h
+++ b/media/filters/ffmpeg_video_decoder.h
@@ -7,6 +7,7 @@
#include <deque>
+#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/filters.h"
#include "media/crypto/aes_decryptor.h"
@@ -21,7 +22,7 @@ namespace media {
class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
public:
- explicit FFmpegVideoDecoder(MessageLoop* message_loop);
+ FFmpegVideoDecoder(const base::Callback<MessageLoop*()>& message_loop_cb);
virtual ~FFmpegVideoDecoder();
// Filter implementation.
@@ -68,6 +69,9 @@ class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
// the current state of |codec_context_|.
scoped_refptr<VideoFrame> AllocateVideoFrame();
+ // This is !is_null() iff Initialize() hasn't been called.
+ base::Callback<MessageLoop*()> message_loop_factory_cb_;
+
MessageLoop* message_loop_;
DecoderState state_;
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc
index 7818a94..580475ef 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -18,6 +18,7 @@
#include "media/base/test_data_util.h"
#include "media/base/video_frame.h"
#include "media/ffmpeg/ffmpeg_common.h"
+#include "media/filters/ffmpeg_decoder_unittest.h"
#include "media/filters/ffmpeg_glue.h"
#include "media/filters/ffmpeg_video_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -48,7 +49,8 @@ ACTION_P(ReturnBuffer, buffer) {
class FFmpegVideoDecoderTest : public testing::Test {
public:
FFmpegVideoDecoderTest()
- : decoder_(new FFmpegVideoDecoder(&message_loop_)),
+ : decoder_(new FFmpegVideoDecoder(base::Bind(&Identity<MessageLoop*>,
+ &message_loop_))),
demuxer_(new StrictMock<MockDemuxerStream>()),
read_cb_(base::Bind(&FFmpegVideoDecoderTest::FrameReady,
base::Unretained(this))) {
diff --git a/media/filters/pipeline_integration_test_base.cc b/media/filters/pipeline_integration_test_base.cc
index dd3cd5b..eeb5cb1 100644
--- a/media/filters/pipeline_integration_test_base.cc
+++ b/media/filters/pipeline_integration_test_base.cc
@@ -163,9 +163,13 @@ PipelineIntegrationTestBase::CreateFilterCollection(
scoped_ptr<FilterCollection> collection(new FilterCollection());
collection->SetDemuxerFactory(demuxer_factory.Pass());
collection->AddAudioDecoder(new FFmpegAudioDecoder(
- message_loop_factory_->GetMessageLoop("AudioDecoderThread")));
+ base::Bind(&MessageLoopFactory::GetMessageLoop,
+ base::Unretained(message_loop_factory_.get()),
+ "AudioDecoderThread")));
collection->AddVideoDecoder(new FFmpegVideoDecoder(
- message_loop_factory_->GetMessageLoop("VideoDecoderThread")));
+ base::Bind(&MessageLoopFactory::GetMessageLoop,
+ base::Unretained(message_loop_factory_.get()),
+ "VideoDecoderThread")));
collection->AddVideoRenderer(new VideoRendererBase(
base::Bind(&PipelineIntegrationTestBase::OnVideoRendererPaint,
base::Unretained(this)),
diff --git a/media/media.gyp b/media/media.gyp
index 30d85ed..f68e5e9 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -613,6 +613,7 @@
'filters/bitstream_converter_unittest.cc',
'filters/chunk_demuxer_unittest.cc',
'filters/ffmpeg_audio_decoder_unittest.cc',
+ 'filters/ffmpeg_decoder_unittest.h',
'filters/ffmpeg_demuxer_unittest.cc',
'filters/ffmpeg_glue_unittest.cc',
'filters/ffmpeg_h264_bitstream_converter_unittest.cc',
diff --git a/media/tools/player_wtl/movie.cc b/media/tools/player_wtl/movie.cc
index b2e7acc4..3e862dc 100644
--- a/media/tools/player_wtl/movie.cc
+++ b/media/tools/player_wtl/movie.cc
@@ -4,6 +4,7 @@
#include "media/tools/player_wtl/movie.h"
+#include "base/bind.h"
#include "base/memory/singleton.h"
#include "base/threading/platform_thread.h"
#include "base/utf_string_conversions.h"
@@ -80,9 +81,13 @@ bool Movie::Open(const wchar_t* url, VideoRendererBase* video_renderer) {
collection->SetDemuxerFactory(scoped_ptr<DemuxerFactory>(
new FFmpegDemuxerFactory(data_source, pipeline_loop)));
collection->AddAudioDecoder(new FFmpegAudioDecoder(
- message_loop_factory_->GetMessageLoop("AudioDecoderThread")));
+ base::Bind(&MessageLoopFactory::GetMessageLoop,
+ base::Unretained(message_loop_factory_.get()),
+ "AudioDecoderThread")));
collection->AddVideoDecoder(new FFmpegVideoDecoder(
- message_loop_factory_->GetMessageLoop("VideoDecoderThread")));
+ base::Bind(&MessageLoopFactory::GetMessageLoop,
+ base::Unretained(message_loop_factory_.get()),
+ "VideoDecoderThread")));
// TODO(vrk): Re-enabled audio. (crbug.com/112159)
collection->AddAudioRenderer(new media::NullAudioRenderer());
diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc
index e656b8e..5220fd5 100644
--- a/media/tools/player_x11/player_x11.cc
+++ b/media/tools/player_x11/player_x11.cc
@@ -124,9 +124,13 @@ bool InitPipeline(MessageLoop* message_loop,
collection->SetDemuxerFactory(scoped_ptr<media::DemuxerFactory>(
new media::FFmpegDemuxerFactory(data_source, message_loop)));
collection->AddAudioDecoder(new media::FFmpegAudioDecoder(
- message_loop_factory->GetMessageLoop("AudioDecoderThread")));
+ base::Bind(&media::MessageLoopFactory::GetMessageLoop,
+ base::Unretained(message_loop_factory),
+ "AudioDecoderThread")));
collection->AddVideoDecoder(new media::FFmpegVideoDecoder(
- message_loop_factory->GetMessageLoop("VideoDecoderThread")));
+ base::Bind(&media::MessageLoopFactory::GetMessageLoop,
+ base::Unretained(message_loop_factory),
+ "VideoDecoderThread")));
// Create our video renderer and save a reference to it for painting.
g_video_renderer = new media::VideoRendererBase(