diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-11 20:02:13 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-11 20:02:13 +0000 |
commit | e24c547f7062bbef2d66548c30103ee9d48c1abf (patch) | |
tree | 6d397cb939762a0b687b34204e6e1dade9c63d72 /media | |
parent | 03ce3a031f0cd300b279b2334a8d70bcfa15aaff (diff) | |
download | chromium_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.cc | 14 | ||||
-rw-r--r-- | media/filters/ffmpeg_audio_decoder.h | 5 | ||||
-rw-r--r-- | media/filters/ffmpeg_audio_decoder_unittest.cc | 8 | ||||
-rw-r--r-- | media/filters/ffmpeg_decoder_unittest.h | 13 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 15 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.h | 6 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder_unittest.cc | 4 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test_base.cc | 8 | ||||
-rw-r--r-- | media/media.gyp | 1 | ||||
-rw-r--r-- | media/tools/player_wtl/movie.cc | 9 | ||||
-rw-r--r-- | media/tools/player_x11/player_x11.cc | 8 |
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( |