summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-07 19:12:21 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-07 19:12:21 +0000
commit85110e96f98b4dca5f1afbdcd570b7ce8b641211 (patch)
tree258107578f49509ed6e18ed86ddba18555802e9d /media
parent9522ddf3c862eb128b815af9ef205ab9fadb703e (diff)
downloadchromium_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.cc7
-rw-r--r--media/filters/ffmpeg_demuxer.cc19
-rw-r--r--media/filters/ffmpeg_video_decoder.cc6
-rw-r--r--media/filters/video_renderer_base.cc5
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.