summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 00:25:37 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 00:25:37 +0000
commit212ea326e8afca40eb8280b4061e2dce893aaed8 (patch)
tree04ebc1fc43ffcaf0ad7d82e998f7bca327ddd917 /media
parentfccac67e992a922758da05cbdf405deea9a7c9d1 (diff)
downloadchromium_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.cc10
-rw-r--r--media/filters/ffmpeg_common.cc10
-rw-r--r--media/filters/ffmpeg_common.h22
-rw-r--r--media/filters/ffmpeg_demuxer.cc20
-rw-r--r--media/filters/ffmpeg_video_decoder.cc13
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;
}