summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/audio/clockless_audio_sink.cc3
-rw-r--r--media/base/audio_renderer.h6
-rw-r--r--media/base/mock_filters.h1
-rw-r--r--media/base/pipeline.cc10
-rw-r--r--media/base/pipeline_unittest.cc11
-rw-r--r--media/filters/audio_renderer_impl.cc57
-rw-r--r--media/filters/audio_renderer_impl.h4
-rw-r--r--media/filters/audio_renderer_impl_unittest.cc66
8 files changed, 36 insertions, 122 deletions
diff --git a/media/audio/clockless_audio_sink.cc b/media/audio/clockless_audio_sink.cc
index 89f43bf..1c98574 100644
--- a/media/audio/clockless_audio_sink.cc
+++ b/media/audio/clockless_audio_sink.cc
@@ -78,7 +78,8 @@ void ClocklessAudioSink::Start() {
}
void ClocklessAudioSink::Stop() {
- Pause();
+ if (initialized_)
+ Pause();
}
void ClocklessAudioSink::Play() {
diff --git a/media/base/audio_renderer.h b/media/base/audio_renderer.h
index dc202be..3e7131c 100644
--- a/media/base/audio_renderer.h
+++ b/media/base/audio_renderer.h
@@ -23,6 +23,8 @@ class MEDIA_EXPORT AudioRenderer {
typedef base::Callback<void(base::TimeDelta, base::TimeDelta)> TimeCB;
AudioRenderer();
+
+ // Stop all operations and fire all pending callbacks.
virtual ~AudioRenderer();
// Initialize an AudioRenderer with |stream|, executing |init_cb| upon
@@ -60,10 +62,6 @@ class MEDIA_EXPORT AudioRenderer {
// Only valid to call after a successful Initialize() or Flush().
virtual void StartPlaying() = 0;
- // Stop all operations in preparation for being deleted, executing |callback|
- // when complete.
- virtual void Stop(const base::Closure& callback) = 0;
-
// Sets the output volume.
virtual void SetVolume(float volume) = 0;
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 06a6c1f..dd66e2f 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -149,7 +149,6 @@ class MockAudioRenderer : public AudioRenderer {
const PipelineStatusCB& error_cb));
MOCK_METHOD0(GetTimeSource, TimeSource*());
MOCK_METHOD1(Flush, void(const base::Closure& callback));
- MOCK_METHOD1(Stop, void(const base::Closure& callback));
MOCK_METHOD0(StartPlaying, void());
MOCK_METHOD1(SetVolume, void(float volume));
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index efe91f6..f238d66 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -494,6 +494,9 @@ void Pipeline::DoSeek(
void Pipeline::DoStop(const PipelineStatusCB& done_cb) {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(!pending_callbacks_.get());
+
+ audio_renderer_.reset();
+
SerialRunner::Queue bound_fns;
if (demuxer_) {
@@ -501,11 +504,6 @@ void Pipeline::DoStop(const PipelineStatusCB& done_cb) {
&Demuxer::Stop, base::Unretained(demuxer_)));
}
- if (audio_renderer_) {
- bound_fns.Push(base::Bind(
- &AudioRenderer::Stop, base::Unretained(audio_renderer_.get())));
- }
-
if (video_renderer_) {
bound_fns.Push(base::Bind(
&VideoRenderer::Stop, base::Unretained(video_renderer_.get())));
@@ -522,6 +520,7 @@ void Pipeline::DoStop(const PipelineStatusCB& done_cb) {
void Pipeline::OnStopCompleted(PipelineStatus status) {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, kStopping);
+ DCHECK(!audio_renderer_);
{
base::AutoLock l(lock_);
running_ = false;
@@ -530,7 +529,6 @@ void Pipeline::OnStopCompleted(PipelineStatus status) {
SetState(kStopped);
pending_callbacks_.reset();
filter_collection_.reset();
- audio_renderer_.reset();
video_renderer_.reset();
text_renderer_.reset();
demuxer_ = NULL;
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 6fdb4b3a..42db189 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -312,9 +312,6 @@ class PipelineTest : public ::testing::Test {
if (demuxer_)
EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
- if (audio_stream_)
- EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
-
if (video_stream_)
EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
}
@@ -687,8 +684,6 @@ TEST_F(PipelineTest, ErrorDuringSeek) {
.WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_NOTHING),
RunClosure<0>()));
- EXPECT_CALL(*audio_renderer_, Stop(_))
- .WillOnce(RunClosure<0>());
EXPECT_CALL(*demuxer_, Seek(seek_time, _))
.WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
@@ -743,8 +738,6 @@ TEST_F(PipelineTest, NoMessageDuringTearDownFromError) {
.WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_NOTHING),
RunClosure<0>()));
- EXPECT_CALL(*audio_renderer_, Stop(_))
- .WillOnce(RunClosure<0>());
EXPECT_CALL(*demuxer_, Seek(seek_time, _))
.WillOnce(RunCallback<1>(PIPELINE_ERROR_READ));
@@ -966,7 +959,6 @@ class PipelineTeardownTest : public PipelineTest {
}
EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
- EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
return status;
}
@@ -987,7 +979,6 @@ class PipelineTeardownTest : public PipelineTest {
}
EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
- EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
return status;
}
@@ -1023,7 +1014,6 @@ class PipelineTeardownTest : public PipelineTest {
PipelineStatus status = SetSeekExpectations(state, stop_or_error);
EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
- EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
EXPECT_CALL(callbacks_, OnSeek(status));
@@ -1094,7 +1084,6 @@ class PipelineTeardownTest : public PipelineTest {
InSequence s;
EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>());
- EXPECT_CALL(*audio_renderer_, Stop(_)).WillOnce(RunClosure<0>());
EXPECT_CALL(*video_renderer_, Stop(_)).WillOnce(RunClosure<0>());
switch (stop_or_error) {
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index cfdf016..44536de 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -67,9 +67,15 @@ AudioRendererImpl::AudioRendererImpl(
}
AudioRendererImpl::~AudioRendererImpl() {
- // Stop() should have been called and |algorithm_| should have been destroyed.
- DCHECK(state_ == kUninitialized || state_ == kStopped);
- DCHECK(!algorithm_.get());
+ DVLOG(1) << __FUNCTION__;
+ DCHECK(task_runner_->BelongsToCurrentThread());
+
+ // If Render() is in progress, this call will wait for Render() to finish.
+ // After this call, the |sink_| will not call back into |this| anymore.
+ sink_->Stop();
+
+ if (!init_cb_.is_null())
+ base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
}
void AudioRendererImpl::StartTicking() {
@@ -189,8 +195,6 @@ void AudioRendererImpl::ResetDecoderDone() {
DCHECK(task_runner_->BelongsToCurrentThread());
{
base::AutoLock auto_lock(lock_);
- if (state_ == kStopped)
- return;
DCHECK_EQ(state_, kFlushed);
DCHECK(!flush_cb_.is_null());
@@ -214,37 +218,6 @@ void AudioRendererImpl::ResetDecoderDone() {
task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
}
-void AudioRendererImpl::Stop(const base::Closure& callback) {
- DVLOG(1) << __FUNCTION__;
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(!callback.is_null());
-
- // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
- // task-running guards that check |state_| with DCHECK().
-
- {
- base::AutoLock auto_lock(lock_);
-
- if (state_ == kStopped) {
- task_runner_->PostTask(FROM_HERE, callback);
- return;
- }
-
- ChangeState_Locked(kStopped);
- algorithm_.reset();
- time_cb_.Reset();
- flush_cb_.Reset();
- }
-
- if (sink_) {
- sink_->Stop();
- sink_ = NULL;
- }
-
- audio_buffer_stream_.reset();
- task_runner_->PostTask(FROM_HERE, callback);
-}
-
void AudioRendererImpl::StartPlaying() {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
@@ -334,11 +307,6 @@ void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
base::AutoLock auto_lock(lock_);
- if (state_ == kStopped) {
- base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
- return;
- }
-
if (!success) {
state_ = kUninitialized;
base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
@@ -469,7 +437,7 @@ bool AudioRendererImpl::HandleSplicerBuffer_Locked(
return true;
}
- if (state_ != kUninitialized && state_ != kStopped)
+ if (state_ != kUninitialized)
algorithm_->EnqueueBuffer(buffer);
}
@@ -491,9 +459,6 @@ bool AudioRendererImpl::HandleSplicerBuffer_Locked(
return false;
}
return true;
-
- case kStopped:
- return false;
}
return false;
}
@@ -523,7 +488,6 @@ bool AudioRendererImpl::CanRead_Locked() {
case kInitializing:
case kFlushing:
case kFlushed:
- case kStopped:
return false;
case kPlaying:
@@ -690,7 +654,6 @@ void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) {
case kFlushed:
case kPlaying:
- case kStopped:
if (status != PIPELINE_OK)
error_cb_.Run(status);
return;
diff --git a/media/filters/audio_renderer_impl.h b/media/filters/audio_renderer_impl.h
index 28d62ab..837dd73 100644
--- a/media/filters/audio_renderer_impl.h
+++ b/media/filters/audio_renderer_impl.h
@@ -84,7 +84,6 @@ class MEDIA_EXPORT AudioRendererImpl
const PipelineStatusCB& error_cb) OVERRIDE;
virtual TimeSource* GetTimeSource() OVERRIDE;
virtual void Flush(const base::Closure& callback) OVERRIDE;
- virtual void Stop(const base::Closure& callback) OVERRIDE;
virtual void StartPlaying() OVERRIDE;
virtual void SetVolume(float volume) OVERRIDE;
@@ -113,8 +112,7 @@ class MEDIA_EXPORT AudioRendererImpl
kInitializing,
kFlushing,
kFlushed,
- kPlaying,
- kStopped,
+ kPlaying
};
// Callback from the audio decoder delivering decoded audio samples.
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc
index 5aae0af..54850c8 100644
--- a/media/filters/audio_renderer_impl_unittest.cc
+++ b/media/filters/audio_renderer_impl_unittest.cc
@@ -59,7 +59,6 @@ class AudioRendererImplTest : public ::testing::Test {
// Give the decoder some non-garbage media properties.
AudioRendererImplTest()
: hardware_config_(AudioParameters(), AudioParameters()),
- needs_stop_(true),
demuxer_stream_(DemuxerStream::AUDIO),
decoder_(new MockAudioDecoder()),
last_time_update_(kNoTimestamp()),
@@ -103,11 +102,6 @@ class AudioRendererImplTest : public ::testing::Test {
virtual ~AudioRendererImplTest() {
SCOPED_TRACE("~AudioRendererImplTest()");
- if (needs_stop_) {
- WaitableMessageLoopEvent event;
- renderer_->Stop(event.GetClosure());
- event.RunAndWait();
- }
}
void ExpectUnsupportedAudioDecoder() {
@@ -161,38 +155,31 @@ class AudioRendererImplTest : public ::testing::Test {
EXPECT_TRUE(decode_cb_.is_null());
}
- void InitializeAndStop() {
+ void InitializeAndDestroy() {
EXPECT_CALL(*decoder_, Initialize(_, _, _))
- .WillOnce(DoAll(SaveArg<2>(&output_cb_),
- RunCallback<1>(PIPELINE_OK)));
+ .WillOnce(RunCallback<1>(PIPELINE_OK));
WaitableMessageLoopEvent event;
InitializeRenderer(event.GetPipelineStatusCB());
- // Stop before we let the MessageLoop run, this simulates an interleaving
- // in which we end up calling Stop() while the OnDecoderSelected callback
- // is in flight.
- renderer_->Stop(NewExpectedClosure());
+ // Destroy the |renderer_| before we let the MessageLoop run, this simulates
+ // an interleaving in which we end up destroying the |renderer_| while the
+ // OnDecoderSelected callback is in flight.
+ renderer_.reset();
event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
- EXPECT_EQ(renderer_->state_, AudioRendererImpl::kStopped);
}
- void InitializeAndStopDuringDecoderInit() {
+ void InitializeAndDestroyDuringDecoderInit() {
EXPECT_CALL(*decoder_, Initialize(_, _, _))
- .WillOnce(DoAll(SaveArg<2>(&output_cb_),
- EnterPendingDecoderInitStateAction(this)));
+ .WillOnce(EnterPendingDecoderInitStateAction(this));
WaitableMessageLoopEvent event;
InitializeRenderer(event.GetPipelineStatusCB());
-
base::RunLoop().RunUntilIdle();
DCHECK(!init_decoder_cb_.is_null());
- renderer_->Stop(NewExpectedClosure());
- base::ResetAndReturn(&init_decoder_cb_).Run(PIPELINE_OK);
-
+ renderer_.reset();
event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
- EXPECT_EQ(renderer_->state_, AudioRendererImpl::kStopped);
}
void EnterPendingDecoderInitState(PipelineStatusCB cb) {
@@ -355,16 +342,9 @@ class AudioRendererImplTest : public ::testing::Test {
scoped_refptr<FakeAudioRendererSink> sink_;
AudioHardwareConfig hardware_config_;
- // Whether or not the test needs the destructor to call Stop() on
- // |renderer_| at destruction.
- bool needs_stop_;
-
private:
void DecodeDecoder(const scoped_refptr<DecoderBuffer>& buffer,
const AudioDecoder::DecodeCB& decode_cb) {
- // We shouldn't ever call Read() after Stop():
- EXPECT_TRUE(stop_decoder_cb_.is_null());
-
// TODO(scherkus): Make this a DCHECK after threading semantics are fixed.
if (base::MessageLoop::current() != &message_loop_) {
message_loop_.PostTask(FROM_HERE, base::Bind(
@@ -421,7 +401,6 @@ class AudioRendererImplTest : public ::testing::Test {
// Run during DecodeDecoder() to unblock WaitForPendingRead().
base::Closure wait_for_pending_decode_cb_;
- base::Closure stop_decoder_cb_;
PipelineStatusCB init_decoder_cb_;
base::TimeDelta last_time_update_;
@@ -569,7 +548,7 @@ TEST_F(AudioRendererImplTest, PendingRead_Flush) {
Preroll(1000, PIPELINE_OK);
}
-TEST_F(AudioRendererImplTest, PendingRead_Stop) {
+TEST_F(AudioRendererImplTest, PendingRead_Destroy) {
Initialize();
Preroll();
@@ -583,18 +562,10 @@ TEST_F(AudioRendererImplTest, PendingRead_Stop) {
EXPECT_TRUE(IsReadPending());
- WaitableMessageLoopEvent stop_event;
- renderer_->Stop(stop_event.GetClosure());
- needs_stop_ = false;
-
- SatisfyPendingRead(InputFrames(256));
-
- stop_event.RunAndWait();
-
- EXPECT_FALSE(IsReadPending());
+ renderer_.reset();
}
-TEST_F(AudioRendererImplTest, PendingFlush_Stop) {
+TEST_F(AudioRendererImplTest, PendingFlush_Destroy) {
Initialize();
Preroll();
@@ -615,18 +586,15 @@ TEST_F(AudioRendererImplTest, PendingFlush_Stop) {
EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
SatisfyPendingRead(InputFrames(256));
- WaitableMessageLoopEvent event;
- renderer_->Stop(event.GetClosure());
- event.RunAndWait();
- needs_stop_ = false;
+ renderer_.reset();
}
-TEST_F(AudioRendererImplTest, InitializeThenStop) {
- InitializeAndStop();
+TEST_F(AudioRendererImplTest, InitializeThenDestroy) {
+ InitializeAndDestroy();
}
-TEST_F(AudioRendererImplTest, InitializeThenStopDuringDecoderInit) {
- InitializeAndStopDuringDecoderInit();
+TEST_F(AudioRendererImplTest, InitializeThenDestroyDuringDecoderInit) {
+ InitializeAndDestroyDuringDecoderInit();
}
TEST_F(AudioRendererImplTest, ConfigChangeDrainsConverter) {