Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1371)

Unified Diff: media/filters/ffmpeg_demuxer.cc

Issue 151192: Cleanup resources allocated by FFmpeg to avoid memory and threads leaks... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/ffmpeg_demuxer.cc
===================================================================
--- media/filters/ffmpeg_demuxer.cc (revision 19853)
+++ media/filters/ffmpeg_demuxer.cc (working copy)
@@ -215,16 +215,40 @@
// FFmpegDemuxer
//
FFmpegDemuxer::FFmpegDemuxer()
- : thread_id_(NULL) {
+ : format_context_(NULL),
+ thread_id_(NULL) {
}
FFmpegDemuxer::~FFmpegDemuxer() {
- DCHECK(!format_context_.get());
- // TODO(scherkus): I believe we need to use av_close_input_file() here
- // instead of scoped_ptr_malloc calling av_free().
- //
- // Note that av_close_input_file() doesn't close the codecs so we need to
- // figure out who's responsible for closing the them.
+ // In this destructor, we clean up resources held by FFmpeg. It is ugly to
+ // close the codec contexts here because the corresponding codecs are opened
+ // in the decoder filters. By reaching this point, all filters should have
+ // stopped, so this is the only safe place to do the global clean up.
+ // TODO(hclam): close the codecs in the corresponding decoders.
+ AutoLock auto_lock(FFmpegLock::get()->lock());
+ if (!format_context_)
+ return;
+
+ // Iterate each stream and destroy each one of them.
+ int streams = format_context_->nb_streams;
+ for (int i = 0; i < streams; ++i) {
+ AVStream* stream = format_context_->streams[i];
+
+ // The conditions for calling avcodec_close():
+ // 1. AVStream is alive.
+ // 2. AVCodecContext in AVStream is alive.
+ // 3. AVCodec in AVCodecContext is alive.
+ // Notice that closing a codec context without prior avcodec_open() will
+ // result in a crash in FFmpeg.
+ if (stream && stream->codec && stream->codec->codec) {
+ stream->discard = AVDISCARD_ALL;
+ avcodec_close(stream->codec);
+ }
+ }
+
+ // Then finally cleanup the format context.
+ av_close_input_file(format_context_);
+ format_context_ = NULL;
}
void FFmpegDemuxer::PostDemuxTask() {
@@ -281,7 +305,7 @@
std::string key = FFmpegGlue::get()->AddDataSource(data_source);
// Open FFmpeg AVFormatContext.
- DCHECK(!format_context_.get());
+ DCHECK(!format_context_);
AVFormatContext* context = NULL;
int result = av_open_input_file(&context, key.c_str(), NULL, 0, NULL);
@@ -293,16 +317,15 @@
return;
}
- // Assign to our scoped_ptr_malloc.
DCHECK(context);
- format_context_.reset(context);
+ format_context_ = context;
// Serialize calls to av_find_stream_info().
{
AutoLock auto_lock(FFmpegLock::get()->lock());
// Fully initialize AVFormatContext by parsing the stream a little.
- result = av_find_stream_info(format_context_.get());
+ result = av_find_stream_info(format_context_);
if (result < 0) {
host_->Error(DEMUXER_ERROR_COULD_NOT_PARSE);
return;
@@ -350,7 +373,7 @@
flags |= AVSEEK_FLAG_BACKWARD;
}
- if (av_seek_frame(format_context_.get(), -1, time.InMicroseconds(),
+ if (av_seek_frame(format_context_, -1, time.InMicroseconds(),
flags) < 0) {
// TODO(scherkus): signal error.
NOTIMPLEMENTED();
@@ -367,7 +390,7 @@
// Allocate and read an AVPacket from the media.
scoped_ptr<AVPacket> packet(new AVPacket());
- int result = av_read_frame(format_context_.get(), packet.get());
+ int result = av_read_frame(format_context_, packet.get());
if (result < 0) {
// If we have reached the end of stream, tell the downstream filters about
// the event.
@@ -420,9 +443,6 @@
for (iter = streams_.begin(); iter != streams_.end(); ++iter) {
(*iter)->Stop();
}
-
- // Free our AVFormatContext.
- format_context_.reset();
}
bool FFmpegDemuxer::StreamsHavePendingReads() {
« no previous file with comments | « media/filters/ffmpeg_demuxer.h ('k') | media/filters/ffmpeg_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698