diff options
author | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-07 19:12:21 +0000 |
---|---|---|
committer | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-07 19:12:21 +0000 |
commit | 85110e96f98b4dca5f1afbdcd570b7ce8b641211 (patch) | |
tree | 258107578f49509ed6e18ed86ddba18555802e9d /media | |
parent | 9522ddf3c862eb128b815af9ef205ab9fadb703e (diff) | |
download | chromium_src-85110e96f98b4dca5f1afbdcd570b7ce8b641211.zip chromium_src-85110e96f98b4dca5f1afbdcd570b7ce8b641211.tar.gz chromium_src-85110e96f98b4dca5f1afbdcd570b7ce8b641211.tar.bz2 |
Fix hangs & crashes in teardown-during-Seek.
Hangs:
- AudioRendererImpl: Don't hold lock_ in the call to Join() b/c OnStop wants to
acquire the lock before exiting.
- FFmpegDemuxerStream::Stop: signal EOS to waiting read callbacks (instead of
silently dropping them on the floor) so decoders can exit instead of stalling
(and causing renderers to stall).
Crashes:
- CompositeFilter::Stop: clear out the Seek callback when Stopping.
- FFmpegVideoDecoder::ProduceVideoFrame: early-return if already stopped (racing
with webkit repaints makes this necessary).
Also fixed a bunch of mis-indentation where I saw it.
BUG=98975,98948,98955,96861
TEST=trybots, manual
Review URL: http://codereview.chromium.org/8184003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104540 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/composite_filter.cc | 7 | ||||
-rw-r--r-- | media/filters/ffmpeg_demuxer.cc | 19 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 6 | ||||
-rw-r--r-- | media/filters/video_renderer_base.cc | 5 |
4 files changed, 23 insertions, 14 deletions
diff --git a/media/base/composite_filter.cc b/media/base/composite_filter.cc index 1716f3a..f613f36 100644 --- a/media/base/composite_filter.cc +++ b/media/base/composite_filter.cc @@ -173,6 +173,11 @@ void CompositeFilter::Stop(const base::Closure& stop_callback) { return; } + if (!status_cb_.is_null()) { + DCHECK_EQ(state_, kStopWhileSeekPending); + status_cb_.Reset(); + } + callback_ = stop_callback; if (state_ == kStopPending) { StartSerialCallSequence(); @@ -268,7 +273,6 @@ void CompositeFilter::CallFilter(scoped_refptr<Filter>& filter, base::Bind(&CompositeFilter::OnStatusCB, this, callback)); break; default: - ChangeState(kError); DispatchPendingCallback(PIPELINE_ERROR_INVALID_STATE); } @@ -429,7 +433,6 @@ void CompositeFilter::OnStatusCB(const base::Closure& callback, SetError(status); callback.Run(); - } void CompositeFilter::SetError(PipelineStatus error) { diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index 56981e4..f59c665 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc @@ -10,6 +10,7 @@ #include "base/stl_util.h" #include "base/string_util.h" #include "base/time.h" +#include "media/base/data_buffer.h" #include "media/base/filter_host.h" #include "media/base/limits.h" #include "media/base/media_switches.h" @@ -139,6 +140,10 @@ void FFmpegDemuxerStream::Stop() { DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); base::AutoLock auto_lock(lock_); buffer_queue_.clear(); + for (ReadQueue::iterator it = read_queue_.begin(); + it != read_queue_.end(); ++it) { + it->Run(new DataBuffer(0)); + } read_queue_.clear(); stopped_ = true; } @@ -289,13 +294,13 @@ FFmpegDemuxer::~FFmpegDemuxer() { void FFmpegDemuxer::PostDemuxTask() { message_loop_->PostTask(FROM_HERE, - base::Bind(&FFmpegDemuxer::DemuxTask, this)); + base::Bind(&FFmpegDemuxer::DemuxTask, this)); } void FFmpegDemuxer::Stop(const base::Closure& callback) { // Post a task to notify the streams to stop as well. message_loop_->PostTask(FROM_HERE, - base::Bind(&FFmpegDemuxer::StopTask, this, callback)); + base::Bind(&FFmpegDemuxer::StopTask, this, callback)); // Then wakes up the thread from reading. SignalReadCompleted(DataSource::kReadError); @@ -303,7 +308,7 @@ void FFmpegDemuxer::Stop(const base::Closure& callback) { void FFmpegDemuxer::Seek(base::TimeDelta time, const FilterStatusCB& cb) { message_loop_->PostTask(FROM_HERE, - base::Bind(&FFmpegDemuxer::SeekTask, this, time, cb)); + base::Bind(&FFmpegDemuxer::SeekTask, this, time, cb)); } void FFmpegDemuxer::SetPlaybackRate(float playback_rate) { @@ -317,8 +322,8 @@ void FFmpegDemuxer::SetPreload(Preload preload) { } void FFmpegDemuxer::OnAudioRendererDisabled() { - message_loop_->PostTask(FROM_HERE, - base::Bind(&FFmpegDemuxer::DisableAudioStreamTask, this)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &FFmpegDemuxer::DisableAudioStreamTask, this)); } void FFmpegDemuxer::set_host(FilterHost* filter_host) { @@ -473,7 +478,7 @@ void FFmpegDemuxer::InitializeTask(DataSource* data_source, AVStream* stream = format_context_->streams[i]; // WebM is currently strictly VP8 and Vorbis. if (kDemuxerIsWebm && (stream->codec->codec_id != CODEC_ID_VP8 && - stream->codec->codec_id != CODEC_ID_VORBIS)) { + stream->codec->codec_id != CODEC_ID_VORBIS)) { packet_streams_.push_back(NULL); continue; } @@ -487,7 +492,7 @@ void FFmpegDemuxer::InitializeTask(DataSource* data_source, if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) { const base::TimeDelta first_dts = ConvertFromTimeBase( - stream->time_base, stream->first_dts); + stream->time_base, stream->first_dts); if (start_time_ == kNoTimestamp || first_dts < start_time_) start_time_ = first_dts; } diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index d41b796..d540227 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc @@ -255,8 +255,10 @@ void FFmpegVideoDecoder::OnReadCompleteTask(scoped_refptr<Buffer> buffer) { void FFmpegVideoDecoder::ProduceVideoFrame( scoped_refptr<VideoFrame> video_frame) { if (MessageLoop::current() != message_loop_) { - message_loop_->PostTask(FROM_HERE, base::Bind( - &FFmpegVideoDecoder::ProduceVideoFrame, this, video_frame)); + if (state_ != kStopped) { + message_loop_->PostTask(FROM_HERE, base::Bind( + &FFmpegVideoDecoder::ProduceVideoFrame, this, video_frame)); + } return; } diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc index ee95161..8334cd1 100644 --- a/media/filters/video_renderer_base.cc +++ b/media/filters/video_renderer_base.cc @@ -38,7 +38,7 @@ VideoRendererBase::VideoRendererBase() VideoRendererBase::~VideoRendererBase() { base::AutoLock auto_lock(lock_); - DCHECK(state_ == kUninitialized || state_ == kStopped); + DCHECK(state_ == kUninitialized || state_ == kStopped) << state_; } void VideoRendererBase::Play(const base::Closure& callback) { @@ -95,7 +95,7 @@ void VideoRendererBase::SetPlaybackRate(float playback_rate) { playback_rate_ = playback_rate; } -void VideoRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) { +void VideoRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) { bool run_callback = false; { @@ -112,7 +112,6 @@ void VideoRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) { if (state_ == kPrerolled) { // Already get enough buffers from decoder. run_callback = true; - } else { // Otherwise we are either kFlushed or kSeeking, but without enough // buffers we should save the callback function and call it later. |