diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 00:25:37 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 00:25:37 +0000 |
commit | 212ea326e8afca40eb8280b4061e2dce893aaed8 (patch) | |
tree | 04ebc1fc43ffcaf0ad7d82e998f7bca327ddd917 /media | |
parent | fccac67e992a922758da05cbdf405deea9a7c9d1 (diff) | |
download | chromium_src-212ea326e8afca40eb8280b4061e2dce893aaed8.zip chromium_src-212ea326e8afca40eb8280b4061e2dce893aaed8.tar.gz chromium_src-212ea326e8afca40eb8280b4061e2dce893aaed8.tar.bz2 |
Serialize calls to avcodec_open() and avcodec_close().
BUG=http://crbug.com/13907
TEST=some media layout tests should start passing consistently
Review URL: http://codereview.chromium.org/126243
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18570 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/filters/ffmpeg_audio_decoder.cc | 10 | ||||
-rw-r--r-- | media/filters/ffmpeg_common.cc | 10 | ||||
-rw-r--r-- | media/filters/ffmpeg_common.h | 22 | ||||
-rw-r--r-- | media/filters/ffmpeg_demuxer.cc | 20 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 13 |
5 files changed, 47 insertions, 28 deletions
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc index 0b27519..7462fa5 100644 --- a/media/filters/ffmpeg_audio_decoder.cc +++ b/media/filters/ffmpeg_audio_decoder.cc @@ -42,11 +42,13 @@ bool FFmpegAudioDecoder::OnInitialize(DemuxerStream* demuxer_stream) { DCHECK_GT(av_get_bits_per_sample_format(codec_context_->sample_fmt), 0); DCHECK_GT(codec_context_->sample_rate, 0); - // Grab the codec context from FFmpeg demuxer. + // Serialize calls to avcodec_open(). AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); - if (!codec || avcodec_open(codec_context_, codec) < 0) { - host_->Error(PIPELINE_ERROR_DECODE); - return false; + { + AutoLock auto_lock(FFmpegLock::get()->lock()); + if (!codec || avcodec_open(codec_context_, codec) < 0) { + return false; + } } // When calling avcodec_find_decoder(), |codec_context_| might be altered by diff --git a/media/filters/ffmpeg_common.cc b/media/filters/ffmpeg_common.cc index 6b05d55..d1c1103 100644 --- a/media/filters/ffmpeg_common.cc +++ b/media/filters/ffmpeg_common.cc @@ -6,6 +6,16 @@ namespace media { +FFmpegLock::FFmpegLock() { +} + +FFmpegLock::~FFmpegLock() { +} + +Lock& FFmpegLock::lock() { + return lock_; +} + namespace mime_type { const char kFFmpegAudio[] = "audio/x-ffmpeg"; diff --git a/media/filters/ffmpeg_common.h b/media/filters/ffmpeg_common.h index a11ab0f..5ccbae8 100644 --- a/media/filters/ffmpeg_common.h +++ b/media/filters/ffmpeg_common.h @@ -9,6 +9,7 @@ #include <cerrno> #include "base/compiler_specific.h" +#include "base/singleton.h" // Include FFmpeg header files. extern "C" { @@ -22,6 +23,26 @@ MSVC_POP_WARNING(); namespace media { +// FFmpegLock is used to serialize calls to avcodec_open(), avcodec_close(), +// and av_find_stream_info() for an entire process because for whatever reason +// it does Very Bad Things to other FFmpeg instances. +// +// TODO(scherkus): track down and upstream a fix to FFmpeg, if possible. +class FFmpegLock : public Singleton<FFmpegLock> { + public: + Lock& lock(); + + private: + // Only allow Singleton to create and delete FFmpegLock. + friend struct DefaultSingletonTraits<FFmpegLock>; + FFmpegLock(); + virtual ~FFmpegLock(); + + Lock lock_; + DISALLOW_COPY_AND_ASSIGN(FFmpegLock); +}; + + // Wraps FFmpeg's av_free() in a class that can be passed as a template argument // to scoped_ptr_malloc. class ScopedPtrAVFree { @@ -31,6 +52,7 @@ class ScopedPtrAVFree { } }; + // FFmpeg MIME types. namespace mime_type { diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index cab3af7..2e04b62 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc @@ -12,26 +12,6 @@ namespace media { -// FFmpegLock is used to serialize calls to av_find_stream_info() for an entire -// process because for whatever reason it does Very Bad Things to other demuxers -// also calling av_find_stream_info(). -// -// TODO(scherkus): track down and upstream a fix to FFmpeg. -class FFmpegLock : public Singleton<FFmpegLock> { - public: - Lock& lock() { return lock_; } - - private: - // Only allow Singleton to create and delete FFmpegLock. - friend struct DefaultSingletonTraits<FFmpegLock>; - FFmpegLock() {} - virtual ~FFmpegLock() {} - - Lock lock_; - DISALLOW_COPY_AND_ASSIGN(FFmpegLock); -}; - - // // AVPacketBuffer // diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index 4262068..4a943dd 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc @@ -61,11 +61,16 @@ bool FFmpegVideoDecoder::OnInitialize(DemuxerStream* demuxer_stream) { // for damaged macroblocks, and set our error detection sensitivity. codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; codec_context_->error_recognition = FF_ER_CAREFUL; + + // Serialize calls to avcodec_open(). AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); - if (!codec || - avcodec_thread_init(codec_context_, kDecodeThreads) < 0 || - avcodec_open(codec_context_, codec) < 0) { - return false; + { + AutoLock auto_lock(FFmpegLock::get()->lock()); + if (!codec || + avcodec_thread_init(codec_context_, kDecodeThreads) < 0 || + avcodec_open(codec_context_, codec) < 0) { + return false; + } } return true; } |