diff options
-rw-r--r-- | media/cdm/ppapi/ffmpeg_cdm_audio_decoder.cc | 29 | ||||
-rw-r--r-- | media/cdm/ppapi/ffmpeg_cdm_audio_decoder.h | 7 | ||||
-rw-r--r-- | media/cdm/ppapi/ffmpeg_cdm_video_decoder.cc | 33 | ||||
-rw-r--r-- | media/cdm/ppapi/ffmpeg_cdm_video_decoder.h | 8 | ||||
-rw-r--r-- | media/ffmpeg/ffmpeg_common.h | 22 | ||||
-rw-r--r-- | media/filters/audio_file_reader.cc | 8 | ||||
-rw-r--r-- | media/filters/ffmpeg_audio_decoder.cc | 34 | ||||
-rw-r--r-- | media/filters/ffmpeg_audio_decoder.h | 7 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 32 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.h | 7 |
10 files changed, 92 insertions, 95 deletions
diff --git a/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.cc b/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.cc index ed619b2..1e66736 100644 --- a/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.cc +++ b/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.cc @@ -12,6 +12,7 @@ #include "media/base/buffers.h" #include "media/base/data_buffer.h" #include "media/base/limits.h" +#include "media/ffmpeg/ffmpeg_common.h" // Include FFmpeg header files. extern "C" { @@ -82,8 +83,6 @@ static void CdmAudioDecoderConfigToAVCodecContext( FFmpegCdmAudioDecoder::FFmpegCdmAudioDecoder(cdm::Host* host) : is_initialized_(false), host_(host), - codec_context_(NULL), - av_frame_(NULL), bits_per_channel_(0), samples_per_second_(0), channels_(0), @@ -111,15 +110,15 @@ bool FFmpegCdmAudioDecoder::Initialize(const cdm::AudioDecoderConfig& config) { } // Initialize AVCodecContext structure. - codec_context_ = avcodec_alloc_context3(NULL); - CdmAudioDecoderConfigToAVCodecContext(config, codec_context_); + codec_context_.reset(avcodec_alloc_context3(NULL)); + CdmAudioDecoderConfigToAVCodecContext(config, codec_context_.get()); // MP3 decodes to S16P which we don't support, tell it to use S16 instead. if (codec_context_->sample_fmt == AV_SAMPLE_FMT_S16P) codec_context_->request_sample_fmt = AV_SAMPLE_FMT_S16; AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); - if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { + if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) { DLOG(ERROR) << "Could not initialize audio decoder: " << codec_context_->codec_id; return false; @@ -146,7 +145,7 @@ bool FFmpegCdmAudioDecoder::Initialize(const cdm::AudioDecoderConfig& config) { } // Success! - av_frame_ = avcodec_alloc_frame(); + av_frame_.reset(avcodec_alloc_frame()); bits_per_channel_ = config.bits_per_channel; samples_per_second_ = config.samples_per_second; bytes_per_frame_ = codec_context_->channels * bits_per_channel_ / 8; @@ -171,7 +170,7 @@ void FFmpegCdmAudioDecoder::Deinitialize() { void FFmpegCdmAudioDecoder::Reset() { DVLOG(1) << "Reset()"; - avcodec_flush_buffers(codec_context_); + avcodec_flush_buffers(codec_context_.get()); ResetTimestampState(); } @@ -233,11 +232,11 @@ cdm::Status FFmpegCdmAudioDecoder::DecodeBuffer( // skipping end of stream packets since they have a size of zero. do { // Reset frame to default values. - avcodec_get_frame_defaults(av_frame_); + avcodec_get_frame_defaults(av_frame_.get()); int frame_decoded = 0; int result = avcodec_decode_audio4( - codec_context_, av_frame_, &frame_decoded, &packet); + codec_context_.get(), av_frame_.get(), &frame_decoded, &packet); if (result < 0) { DCHECK(!is_end_of_stream) @@ -391,16 +390,8 @@ void FFmpegCdmAudioDecoder::ResetTimestampState() { void FFmpegCdmAudioDecoder::ReleaseFFmpegResources() { DVLOG(1) << "ReleaseFFmpegResources()"; - if (codec_context_) { - av_free(codec_context_->extradata); - avcodec_close(codec_context_); - av_free(codec_context_); - codec_context_ = NULL; - } - if (av_frame_) { - av_free(av_frame_); - av_frame_ = NULL; - } + codec_context_.reset(); + av_frame_.reset(); } void FFmpegCdmAudioDecoder::SerializeInt64(int64 value) { diff --git a/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.h b/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.h index 1b4fb8f..50fe4d4 100644 --- a/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.h +++ b/media/cdm/ppapi/ffmpeg_cdm_audio_decoder.h @@ -19,10 +19,11 @@ struct AVFrame; namespace media { class AudioBus; class AudioTimestampHelper; +class ScopedPtrAVFreeContext; +class ScopedPtrAVFreeFrame; } namespace media { - // TODO(xhwang): This class is partially cloned from FFmpegAudioDecoder. When // FFmpegAudioDecoder is updated, it's a pain to keep this class in sync with // FFmpegAudioDecoder. We need a long term sustainable solution for this. See @@ -63,8 +64,8 @@ class FFmpegCdmAudioDecoder { cdm::Host* const host_; // FFmpeg structures owned by this object. - AVCodecContext* codec_context_; - AVFrame* av_frame_; + scoped_ptr_malloc<AVCodecContext, ScopedPtrAVFreeContext> codec_context_; + scoped_ptr_malloc<AVFrame, ScopedPtrAVFreeFrame> av_frame_; // Audio format. int bits_per_channel_; diff --git a/media/cdm/ppapi/ffmpeg_cdm_video_decoder.cc b/media/cdm/ppapi/ffmpeg_cdm_video_decoder.cc index 9a2439d..515db04 100644 --- a/media/cdm/ppapi/ffmpeg_cdm_video_decoder.cc +++ b/media/cdm/ppapi/ffmpeg_cdm_video_decoder.cc @@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "media/base/buffers.h" #include "media/base/limits.h" +#include "media/ffmpeg/ffmpeg_common.h" // Include FFmpeg header files. extern "C" { @@ -128,9 +129,7 @@ static void CopyPlane(const uint8_t* source, } FFmpegCdmVideoDecoder::FFmpegCdmVideoDecoder(cdm::Host* host) - : codec_context_(NULL), - av_frame_(NULL), - is_initialized_(false), + : is_initialized_(false), host_(host) { } @@ -152,8 +151,8 @@ bool FFmpegCdmVideoDecoder::Initialize(const cdm::VideoDecoderConfig& config) { } // Initialize AVCodecContext structure. - codec_context_ = avcodec_alloc_context3(NULL); - CdmVideoDecoderConfigToAVCodecContext(config, codec_context_); + codec_context_.reset(avcodec_alloc_context3(NULL)); + CdmVideoDecoderConfigToAVCodecContext(config, codec_context_.get()); // Enable motion vector search (potentially slow), strong deblocking filter // for damaged macroblocks, and set our error detection sensitivity. @@ -170,12 +169,12 @@ bool FFmpegCdmVideoDecoder::Initialize(const cdm::VideoDecoderConfig& config) { } int status; - if ((status = avcodec_open2(codec_context_, codec, NULL)) < 0) { + if ((status = avcodec_open2(codec_context_.get(), codec, NULL)) < 0) { LOG(ERROR) << "Initialize(): avcodec_open2 failed: " << status; return false; } - av_frame_ = avcodec_alloc_frame(); + av_frame_.reset(avcodec_alloc_frame()); is_initialized_ = true; return true; @@ -189,7 +188,7 @@ void FFmpegCdmVideoDecoder::Deinitialize() { void FFmpegCdmVideoDecoder::Reset() { DVLOG(1) << "Reset()"; - avcodec_flush_buffers(codec_context_); + avcodec_flush_buffers(codec_context_.get()); } // static @@ -223,15 +222,15 @@ cdm::Status FFmpegCdmVideoDecoder::DecodeFrame( codec_context_->reordered_opaque = timestamp; // Reset frame to default values. - avcodec_get_frame_defaults(av_frame_); + avcodec_get_frame_defaults(av_frame_.get()); // This is for codecs not using get_buffer to initialize // |av_frame_->reordered_opaque| av_frame_->reordered_opaque = codec_context_->reordered_opaque; int frame_decoded = 0; - int result = avcodec_decode_video2(codec_context_, - av_frame_, + int result = avcodec_decode_video2(codec_context_.get(), + av_frame_.get(), &frame_decoded, &packet); // Log the problem when we can't decode a video frame and exit early. @@ -329,16 +328,8 @@ bool FFmpegCdmVideoDecoder::CopyAvFrameTo(cdm::VideoFrame* cdm_video_frame) { void FFmpegCdmVideoDecoder::ReleaseFFmpegResources() { DVLOG(1) << "ReleaseFFmpegResources()"; - if (codec_context_) { - av_free(codec_context_->extradata); - avcodec_close(codec_context_); - av_free(codec_context_); - codec_context_ = NULL; - } - if (av_frame_) { - av_free(av_frame_); - av_frame_ = NULL; - } + codec_context_.reset(); + av_frame_.reset(); } } // namespace media diff --git a/media/cdm/ppapi/ffmpeg_cdm_video_decoder.h b/media/cdm/ppapi/ffmpeg_cdm_video_decoder.h index 17e2b57..06a3967 100644 --- a/media/cdm/ppapi/ffmpeg_cdm_video_decoder.h +++ b/media/cdm/ppapi/ffmpeg_cdm_video_decoder.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "media/cdm/ppapi/api/content_decryption_module.h" #include "media/cdm/ppapi/cdm_video_decoder.h" @@ -15,6 +16,9 @@ struct AVFrame; namespace media { +class ScopedPtrAVFreeContext; +class ScopedPtrAVFreeFrame; + class FFmpegCdmVideoDecoder : public CdmVideoDecoder { public: explicit FFmpegCdmVideoDecoder(cdm::Host* host); @@ -43,8 +47,8 @@ class FFmpegCdmVideoDecoder : public CdmVideoDecoder { void ReleaseFFmpegResources(); // FFmpeg structures owned by this object. - AVCodecContext* codec_context_; - AVFrame* av_frame_; + scoped_ptr_malloc<AVCodecContext, ScopedPtrAVFreeContext> codec_context_; + scoped_ptr_malloc<AVFrame, ScopedPtrAVFreeFrame> av_frame_; bool is_initialized_; diff --git a/media/ffmpeg/ffmpeg_common.h b/media/ffmpeg/ffmpeg_common.h index ccd2aa5..39626ac 100644 --- a/media/ffmpeg/ffmpeg_common.h +++ b/media/ffmpeg/ffmpeg_common.h @@ -58,6 +58,28 @@ class ScopedPtrAVFreePacket { } }; +// Frees an AVCodecContext object in a class that can be passed as a Deleter +// argument to scoped_ptr_malloc. +class ScopedPtrAVFreeContext { + public: + inline void operator()(void* x) const { + AVCodecContext* codec_context = static_cast<AVCodecContext*>(x); + av_free(codec_context->extradata); + avcodec_close(codec_context); + av_free(codec_context); + } +}; + +// Frees an AVFrame object in a class that can be passed as a Deleter argument +// to scoped_ptr_malloc. +class ScopedPtrAVFreeFrame { + public: + inline void operator()(void* x) const { + AVFrame* frame = static_cast<AVFrame*>(x); + av_frame_free(&frame); + } +}; + // Converts an int64 timestamp in |time_base| units to a base::TimeDelta. // For example if |timestamp| equals 11025 and |time_base| equals {1, 44100} // then the return value will be a base::TimeDelta for 0.25 seconds since that diff --git a/media/filters/audio_file_reader.cc b/media/filters/audio_file_reader.cc index ba1d551..5969991 100644 --- a/media/filters/audio_file_reader.cc +++ b/media/filters/audio_file_reader.cc @@ -114,10 +114,10 @@ bool AudioFileReader::Open() { } void AudioFileReader::Close() { - if (codec_context_) { - avcodec_close(codec_context_); - codec_context_ = NULL; - } + // |codec_context_| is a stream inside glue_->format_context(), so it is + // closed when |glue_| is disposed. + glue_.reset(); + codec_context_ = NULL; } int AudioFileReader::Read(AudioBus* audio_bus) { diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc index f922e98..cdeeeea 100644 --- a/media/filters/ffmpeg_audio_decoder.cc +++ b/media/filters/ffmpeg_audio_decoder.cc @@ -73,15 +73,13 @@ FFmpegAudioDecoder::FFmpegAudioDecoder( : message_loop_(message_loop), weak_factory_(this), demuxer_stream_(NULL), - codec_context_(NULL), bytes_per_channel_(0), channel_layout_(CHANNEL_LAYOUT_NONE), channels_(0), samples_per_second_(0), av_sample_format_(0), last_input_timestamp_(kNoTimestamp()), - output_frames_to_drop_(0), - av_frame_(NULL) { + output_frames_to_drop_(0) { } void FFmpegAudioDecoder::Initialize( @@ -150,7 +148,7 @@ void FFmpegAudioDecoder::Reset(const base::Closure& closure) { DCHECK(message_loop_->BelongsToCurrentThread()); base::Closure reset_cb = BindToCurrentLoop(closure); - avcodec_flush_buffers(codec_context_); + avcodec_flush_buffers(codec_context_.get()); ResetTimestampState(); queued_audio_.clear(); reset_cb.Run(); @@ -334,7 +332,7 @@ bool FFmpegAudioDecoder::ConfigureDecoder() { return false; } - if (codec_context_ && + if (codec_context_.get() && (bytes_per_channel_ != config.bytes_per_channel() || channel_layout_ != config.channel_layout() || samples_per_second_ != config.samples_per_second())) { @@ -352,22 +350,22 @@ bool FFmpegAudioDecoder::ConfigureDecoder() { ReleaseFFmpegResources(); // Initialize AVCodecContext structure. - codec_context_ = avcodec_alloc_context3(NULL); - AudioDecoderConfigToAVCodecContext(config, codec_context_); + codec_context_.reset(avcodec_alloc_context3(NULL)); + AudioDecoderConfigToAVCodecContext(config, codec_context_.get()); codec_context_->opaque = this; codec_context_->get_buffer2 = GetAudioBufferImpl; codec_context_->refcounted_frames = 1; AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); - if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { + if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) { DLOG(ERROR) << "Could not initialize audio decoder: " << codec_context_->codec_id; return false; } // Success! - av_frame_ = avcodec_alloc_frame(); + av_frame_.reset(avcodec_alloc_frame()); channel_layout_ = config.channel_layout(); samples_per_second_ = config.samples_per_second(); output_timestamp_helper_.reset( @@ -391,14 +389,8 @@ bool FFmpegAudioDecoder::ConfigureDecoder() { } void FFmpegAudioDecoder::ReleaseFFmpegResources() { - if (codec_context_) { - av_free(codec_context_->extradata); - avcodec_close(codec_context_); - av_free(codec_context_); - } - - if (av_frame_) - av_frame_free(&av_frame_); + codec_context_.reset(); + av_frame_.reset(); } void FFmpegAudioDecoder::ResetTimestampState() { @@ -427,7 +419,7 @@ void FFmpegAudioDecoder::RunDecodeLoop( do { int frame_decoded = 0; int result = avcodec_decode_audio4( - codec_context_, av_frame_, &frame_decoded, &packet); + codec_context_.get(), av_frame_.get(), &frame_decoded, &packet); if (result < 0) { DCHECK(!input->end_of_stream()) @@ -467,7 +459,7 @@ void FFmpegAudioDecoder::RunDecodeLoop( scoped_refptr<AudioBuffer> output; int decoded_frames = 0; int original_frames = 0; - int channels = DetermineChannels(av_frame_); + int channels = DetermineChannels(av_frame_.get()); if (frame_decoded) { if (av_frame_->sample_rate != samples_per_second_ || channels != channels_ || @@ -483,7 +475,7 @@ void FFmpegAudioDecoder::RunDecodeLoop( // This is an unrecoverable error, so bail out. QueuedAudioBuffer queue_entry = { kDecodeError, NULL }; queued_audio_.push_back(queue_entry); - av_frame_unref(av_frame_); + av_frame_unref(av_frame_.get()); break; } @@ -506,7 +498,7 @@ void FFmpegAudioDecoder::RunDecodeLoop( } decoded_frames = output->frame_count(); - av_frame_unref(av_frame_); + av_frame_unref(av_frame_.get()); } // WARNING: |av_frame_| no longer has valid data at this point. diff --git a/media/filters/ffmpeg_audio_decoder.h b/media/filters/ffmpeg_audio_decoder.h index 7ea8615..40103b8 100644 --- a/media/filters/ffmpeg_audio_decoder.h +++ b/media/filters/ffmpeg_audio_decoder.h @@ -8,6 +8,7 @@ #include <list> #include "base/callback.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "media/base/audio_decoder.h" @@ -26,6 +27,8 @@ namespace media { class AudioTimestampHelper; class DecoderBuffer; struct QueuedAudioBuffer; +class ScopedPtrAVFreeContext; +class ScopedPtrAVFreeFrame; class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder { public: @@ -66,7 +69,7 @@ class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder { DemuxerStream* demuxer_stream_; StatisticsCB statistics_cb_; - AVCodecContext* codec_context_; + scoped_ptr_malloc<AVCodecContext, ScopedPtrAVFreeContext> codec_context_; // Decoded audio format. int bytes_per_channel_; @@ -86,7 +89,7 @@ class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder { int output_frames_to_drop_; // Holds decoded audio. - AVFrame* av_frame_; + scoped_ptr_malloc<AVFrame, ScopedPtrAVFreeFrame> av_frame_; ReadCB read_cb_; diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index d03648c..5dfb344 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc @@ -58,9 +58,7 @@ FFmpegVideoDecoder::FFmpegVideoDecoder( const scoped_refptr<base::MessageLoopProxy>& message_loop) : message_loop_(message_loop), weak_factory_(this), - state_(kUninitialized), - codec_context_(NULL), - av_frame_(NULL) { + state_(kUninitialized) { } int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, @@ -189,7 +187,7 @@ void FFmpegVideoDecoder::Reset(const base::Closure& closure) { void FFmpegVideoDecoder::DoReset() { DCHECK(decode_cb_.is_null()); - avcodec_flush_buffers(codec_context_); + avcodec_flush_buffers(codec_context_.get()); state_ = kNormal; base::ResetAndReturn(&reset_cb_).Run(); } @@ -290,7 +288,7 @@ bool FFmpegVideoDecoder::FFmpegDecode( DCHECK(video_frame); // Reset frame to default values. - avcodec_get_frame_defaults(av_frame_); + avcodec_get_frame_defaults(av_frame_.get()); // Create a packet for input data. // Due to FFmpeg API changes we no longer have const read-only pointers. @@ -312,8 +310,8 @@ bool FFmpegVideoDecoder::FFmpegDecode( } int frame_decoded = 0; - int result = avcodec_decode_video2(codec_context_, - av_frame_, + int result = avcodec_decode_video2(codec_context_.get(), + av_frame_.get(), &frame_decoded, &packet); // Log the problem if we can't decode a video frame and exit early. @@ -356,16 +354,8 @@ bool FFmpegVideoDecoder::FFmpegDecode( } void FFmpegVideoDecoder::ReleaseFFmpegResources() { - if (codec_context_) { - av_free(codec_context_->extradata); - avcodec_close(codec_context_); - av_free(codec_context_); - codec_context_ = NULL; - } - if (av_frame_) { - av_free(av_frame_); - av_frame_ = NULL; - } + codec_context_.reset(); + av_frame_.reset(); } bool FFmpegVideoDecoder::ConfigureDecoder() { @@ -373,8 +363,8 @@ bool FFmpegVideoDecoder::ConfigureDecoder() { ReleaseFFmpegResources(); // Initialize AVCodecContext structure. - codec_context_ = avcodec_alloc_context3(NULL); - VideoDecoderConfigToAVCodecContext(config_, codec_context_); + codec_context_.reset(avcodec_alloc_context3(NULL)); + VideoDecoderConfigToAVCodecContext(config_, codec_context_.get()); // Enable motion vector search (potentially slow), strong deblocking filter // for damaged macroblocks, and set our error detection sensitivity. @@ -386,12 +376,12 @@ bool FFmpegVideoDecoder::ConfigureDecoder() { codec_context_->release_buffer = ReleaseVideoBufferImpl; AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); - if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { + if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) { ReleaseFFmpegResources(); return false; } - av_frame_ = avcodec_alloc_frame(); + av_frame_.reset(avcodec_alloc_frame()); return true; } diff --git a/media/filters/ffmpeg_video_decoder.h b/media/filters/ffmpeg_video_decoder.h index 1f03226..9df5fa9 100644 --- a/media/filters/ffmpeg_video_decoder.h +++ b/media/filters/ffmpeg_video_decoder.h @@ -8,6 +8,7 @@ #include <list> #include "base/callback.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "media/base/video_decoder.h" #include "media/base/video_decoder_config.h" @@ -22,6 +23,8 @@ class MessageLoopProxy; namespace media { class DecoderBuffer; +class ScopedPtrAVFreeContext; +class ScopedPtrAVFreeFrame; class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder { public: @@ -77,8 +80,8 @@ class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder { base::Closure reset_cb_; // FFmpeg structures owned by this object. - AVCodecContext* codec_context_; - AVFrame* av_frame_; + scoped_ptr_malloc<AVCodecContext, ScopedPtrAVFreeContext> codec_context_; + scoped_ptr_malloc<AVFrame, ScopedPtrAVFreeFrame> av_frame_; VideoDecoderConfig config_; |