summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-31 19:59:18 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-31 19:59:18 +0000
commitb9eda9ecf8c1ac85da9b75820589163fbc7e3878 (patch)
treea0976ff7b315571efecfab8e603432ddac8df642 /media
parent2adc7517e8116924439cb6a67bd53a222c9f8072 (diff)
downloadchromium_src-b9eda9ecf8c1ac85da9b75820589163fbc7e3878.zip
chromium_src-b9eda9ecf8c1ac85da9b75820589163fbc7e3878.tar.gz
chromium_src-b9eda9ecf8c1ac85da9b75820589163fbc7e3878.tar.bz2
Make {Audio|Video}Decoder::Stop() synchronous.
Currently all AudioDecoder and VideoDecoders can Stop() synchronously already. Even for those aync decoders (e.g. Decrypting*Decoder, GpuVideoDecoder) that relies on IPC to work, they have to Stop() synchronously becuase the render main thread is blocked during the pipeline teardown process, which prevents IPC through render main thread from working. This CL make Stop() on AudioDecoder and VideoDecoder synchronous, which removes a lot of unnecessary complicated code. BUG=349211 TEST=All tests updated and pass. Review URL: https://codereview.chromium.org/213983002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260619 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/audio_decoder.h6
-rw-r--r--media/base/mock_filters.h4
-rw-r--r--media/base/video_decoder.h6
-rw-r--r--media/filters/audio_decoder_selector_unittest.cc30
-rw-r--r--media/filters/audio_renderer_impl_unittest.cc123
-rw-r--r--media/filters/decoder_selector.cc4
-rw-r--r--media/filters/decoder_stream.cc20
-rw-r--r--media/filters/decoder_stream.h1
-rw-r--r--media/filters/decrypting_audio_decoder.cc3
-rw-r--r--media/filters/decrypting_audio_decoder.h2
-rw-r--r--media/filters/decrypting_audio_decoder_unittest.cc2
-rw-r--r--media/filters/decrypting_video_decoder.cc3
-rw-r--r--media/filters/decrypting_video_decoder.h2
-rw-r--r--media/filters/decrypting_video_decoder_unittest.cc2
-rw-r--r--media/filters/fake_video_decoder.cc51
-rw-r--r--media/filters/fake_video_decoder.h18
-rw-r--r--media/filters/fake_video_decoder_unittest.cc105
-rw-r--r--media/filters/ffmpeg_audio_decoder.cc3
-rw-r--r--media/filters/ffmpeg_audio_decoder.h2
-rw-r--r--media/filters/ffmpeg_audio_decoder_unittest.cc21
-rw-r--r--media/filters/ffmpeg_video_decoder.cc25
-rw-r--r--media/filters/ffmpeg_video_decoder.h7
-rw-r--r--media/filters/ffmpeg_video_decoder_unittest.cc2
-rw-r--r--media/filters/gpu_video_decoder.cc3
-rw-r--r--media/filters/gpu_video_decoder.h2
-rw-r--r--media/filters/opus_audio_decoder.cc3
-rw-r--r--media/filters/opus_audio_decoder.h5
-rw-r--r--media/filters/video_decoder_selector_unittest.cc25
-rw-r--r--media/filters/video_frame_stream_unittest.cc90
-rw-r--r--media/filters/video_renderer_impl_unittest.cc6
-rw-r--r--media/filters/vpx_video_decoder.cc33
-rw-r--r--media/filters/vpx_video_decoder.h7
32 files changed, 168 insertions, 448 deletions
diff --git a/media/base/audio_decoder.h b/media/base/audio_decoder.h
index b1ee2cd..5c5e294 100644
--- a/media/base/audio_decoder.h
+++ b/media/base/audio_decoder.h
@@ -65,9 +65,9 @@ class MEDIA_EXPORT AudioDecoder {
// Stops decoder, fires any pending callbacks and sets the decoder to an
// uninitialized state. An AudioDecoder cannot be re-initialized after it has
// been stopped.
- // Note that if Initialize() has been called, Stop() must be called and
- // complete before deleting the decoder.
- virtual void Stop(const base::Closure& closure) = 0;
+ // Note that if Initialize() is pending or has finished successfully, Stop()
+ // must be called before destructing the decoder.
+ virtual void Stop() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(AudioDecoder);
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 0392d11..f25d9731 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -79,7 +79,7 @@ class MockVideoDecoder : public VideoDecoder {
MOCK_METHOD2(Decode, void(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB&));
MOCK_METHOD1(Reset, void(const base::Closure&));
- MOCK_METHOD1(Stop, void(const base::Closure&));
+ MOCK_METHOD0(Stop, void());
MOCK_CONST_METHOD0(HasAlpha, bool());
private:
@@ -98,7 +98,7 @@ class MockAudioDecoder : public AudioDecoder {
void(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB&));
MOCK_METHOD1(Reset, void(const base::Closure&));
- MOCK_METHOD1(Stop, void(const base::Closure&));
+ MOCK_METHOD0(Stop, void());
private:
DISALLOW_COPY_AND_ASSIGN(MockAudioDecoder);
diff --git a/media/base/video_decoder.h b/media/base/video_decoder.h
index c54974c..5b6664a 100644
--- a/media/base/video_decoder.h
+++ b/media/base/video_decoder.h
@@ -75,9 +75,9 @@ class MEDIA_EXPORT VideoDecoder {
// Stops decoder, fires any pending callbacks and sets the decoder to an
// uninitialized state. A VideoDecoder cannot be re-initialized after it has
// been stopped.
- // Note that if Initialize() has been called, Stop() must be called and
- // complete before deleting the decoder.
- virtual void Stop(const base::Closure& closure) = 0;
+ // Note that if Initialize() is pending or has finished successfully, Stop()
+ // must be called before destructing the decoder.
+ virtual void Stop() = 0;
// Returns true if the output format has an alpha channel. Most formats do not
// have alpha so the default is false. Override and return true for decoders
diff --git a/media/filters/audio_decoder_selector_unittest.cc b/media/filters/audio_decoder_selector_unittest.cc
index 6255d3e..2fe53c7 100644
--- a/media/filters/audio_decoder_selector_unittest.cc
+++ b/media/filters/audio_decoder_selector_unittest.cc
@@ -42,17 +42,11 @@ class AudioDecoderSelectorTest : public ::testing::Test {
decoder_2_(new StrictMock<MockAudioDecoder>()) {
all_decoders_.push_back(decoder_1_);
all_decoders_.push_back(decoder_2_);
-
- EXPECT_CALL(*decoder_1_, Stop(_))
- .WillRepeatedly(RunClosure<0>());
- EXPECT_CALL(*decoder_2_, Stop(_))
- .WillRepeatedly(RunClosure<0>());
}
~AudioDecoderSelectorTest() {
- if (selected_decoder_) {
- selected_decoder_->Stop(NewExpectedClosure());
- }
+ if (selected_decoder_)
+ selected_decoder_->Stop();
message_loop_.RunUntilIdle();
}
@@ -61,9 +55,8 @@ class AudioDecoderSelectorTest : public ::testing::Test {
MOCK_METHOD2(OnDecoderSelected,
void(AudioDecoder*, DecryptingDemuxerStream*));
- void MockOnDecoderSelected(
- scoped_ptr<AudioDecoder> decoder,
- scoped_ptr<DecryptingDemuxerStream> stream) {
+ void MockOnDecoderSelected(scoped_ptr<AudioDecoder> decoder,
+ scoped_ptr<DecryptingDemuxerStream> stream) {
OnDecoderSelected(decoder.get(), stream.get());
selected_decoder_ = decoder.Pass();
}
@@ -152,6 +145,11 @@ class AudioDecoderSelectorTest : public ::testing::Test {
DISALLOW_COPY_AND_ASSIGN(AudioDecoderSelectorTest);
};
+// Note:
+// In all the tests, Stop() is expected to be called on a decoder if a decoder:
+// - is pending initialization and DecoderSelector::Abort() is called, or
+// - has been successfully initialized.
+
// The stream is not encrypted but we have no clear decoder. No decoder can be
// selected.
TEST_F(AudioDecoderSelectorTest, ClearStream_NoDecryptor_NoClearDecoder) {
@@ -172,6 +170,7 @@ TEST_F(AudioDecoderSelectorTest, ClearStream_NoDecryptor_OneClearDecoder) {
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoder();
}
@@ -182,6 +181,7 @@ TEST_F(AudioDecoderSelectorTest,
InitializeDecoderSelector(kNoDecryptor, 1);
EXPECT_CALL(*decoder_1_, Initialize(_, _));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoderAndAbort();
}
@@ -197,6 +197,7 @@ TEST_F(AudioDecoderSelectorTest, ClearStream_NoDecryptor_MultipleClearDecoder) {
EXPECT_CALL(*decoder_2_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, IsNull()));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoder();
}
@@ -209,6 +210,7 @@ TEST_F(AudioDecoderSelectorTest,
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
EXPECT_CALL(*decoder_2_, Initialize(_, _));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoderAndAbort();
}
@@ -222,6 +224,7 @@ TEST_F(AudioDecoderSelectorTest, ClearStream_HasDecryptor) {
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoder();
}
@@ -231,6 +234,7 @@ TEST_F(AudioDecoderSelectorTest, Abort_ClearStream_HasDecryptor) {
InitializeDecoderSelector(kDecryptOnly, 1);
EXPECT_CALL(*decoder_1_, Initialize(_, _));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoderAndAbort();
}
@@ -273,6 +277,7 @@ TEST_F(AudioDecoderSelectorTest, EncryptedStream_DecryptOnly_OneClearDecoder) {
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, NotNull()));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoder();
}
@@ -283,6 +288,7 @@ TEST_F(AudioDecoderSelectorTest,
InitializeDecoderSelector(kDecryptOnly, 1);
EXPECT_CALL(*decoder_1_, Initialize(_, _));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoderAndAbort();
}
@@ -300,6 +306,7 @@ TEST_F(AudioDecoderSelectorTest,
EXPECT_CALL(*decoder_2_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, NotNull()));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoder();
}
@@ -312,6 +319,7 @@ TEST_F(AudioDecoderSelectorTest,
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
EXPECT_CALL(*decoder_2_, Initialize(_, _));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoderAndAbort();
}
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc
index 7cccdfc..7894c28 100644
--- a/media/filters/audio_renderer_impl_unittest.cc
+++ b/media/filters/audio_renderer_impl_unittest.cc
@@ -69,13 +69,9 @@ class AudioRendererImplTest : public ::testing::Test {
// Used to save callbacks and run them at a later time.
EXPECT_CALL(*decoder_, Decode(_, _))
.WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder));
-
EXPECT_CALL(*decoder_, Reset(_))
.WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder));
- EXPECT_CALL(*decoder_, Stop(_))
- .WillRepeatedly(Invoke(this, &AudioRendererImplTest::StopDecoder));
-
// Mock out demuxer reads
EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly(
RunCallback<0>(DemuxerStream::kOk, DecoderBuffer::CreateEOSBuffer()));
@@ -123,22 +119,10 @@ class AudioRendererImplTest : public ::testing::Test {
CHECK(current_time <= max_time);
}
- void Initialize() {
- EXPECT_CALL(*decoder_, Initialize(_, _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
- InitializeWithStatus(PIPELINE_OK);
-
- next_timestamp_.reset(new AudioTimestampHelper(
- hardware_config_.GetOutputConfig().sample_rate()));
- }
-
- void InitializeWithStatus(PipelineStatus expected) {
- SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected));
-
- WaitableMessageLoopEvent event;
+ void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) {
renderer_->Initialize(
&demuxer_stream_,
- event.GetPipelineStatusCB(),
+ pipeline_status_cb,
base::Bind(&AudioRendererImplTest::OnStatistics,
base::Unretained(this)),
base::Bind(&AudioRendererImplTest::OnUnderflow,
@@ -150,6 +134,23 @@ class AudioRendererImplTest : public ::testing::Test {
base::Unretained(this)),
base::Bind(&AudioRendererImplTest::OnError,
base::Unretained(this)));
+ }
+
+ void Initialize() {
+ EXPECT_CALL(*decoder_, Initialize(_, _))
+ .WillOnce(RunCallback<1>(PIPELINE_OK));
+ EXPECT_CALL(*decoder_, Stop());
+ InitializeWithStatus(PIPELINE_OK);
+
+ next_timestamp_.reset(new AudioTimestampHelper(
+ hardware_config_.GetOutputConfig().sample_rate()));
+ }
+
+ void InitializeWithStatus(PipelineStatus expected) {
+ SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected));
+
+ WaitableMessageLoopEvent event;
+ InitializeRenderer(event.GetPipelineStatusCB());
event.RunAndWaitForStatus(expected);
// We should have no reads.
@@ -159,21 +160,11 @@ class AudioRendererImplTest : public ::testing::Test {
void InitializeAndStop() {
EXPECT_CALL(*decoder_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
+ EXPECT_CALL(*decoder_, Stop());
+
WaitableMessageLoopEvent event;
- renderer_->Initialize(
- &demuxer_stream_,
- event.GetPipelineStatusCB(),
- base::Bind(&AudioRendererImplTest::OnStatistics,
- base::Unretained(this)),
- base::Bind(&AudioRendererImplTest::OnUnderflow,
- base::Unretained(this)),
- base::Bind(&AudioRendererImplTest::OnAudioTimeCallback,
- base::Unretained(this)),
- ended_event_.GetClosure(),
- base::Bind(&AudioRendererImplTest::OnDisabled,
- base::Unretained(this)),
- base::Bind(&AudioRendererImplTest::OnError,
- base::Unretained(this)));
+ 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.
@@ -185,21 +176,10 @@ class AudioRendererImplTest : public ::testing::Test {
void InitializeAndStopDuringDecoderInit() {
EXPECT_CALL(*decoder_, Initialize(_, _))
.WillOnce(EnterPendingDecoderInitStateAction(this));
+ EXPECT_CALL(*decoder_, Stop());
+
WaitableMessageLoopEvent event;
- renderer_->Initialize(
- &demuxer_stream_,
- event.GetPipelineStatusCB(),
- base::Bind(&AudioRendererImplTest::OnStatistics,
- base::Unretained(this)),
- base::Bind(&AudioRendererImplTest::OnUnderflow,
- base::Unretained(this)),
- base::Bind(&AudioRendererImplTest::OnAudioTimeCallback,
- base::Unretained(this)),
- ended_event_.GetClosure(),
- base::Bind(&AudioRendererImplTest::OnDisabled,
- base::Unretained(this)),
- base::Bind(&AudioRendererImplTest::OnError,
- base::Unretained(this)));
+ InitializeRenderer(event.GetPipelineStatusCB());
base::RunLoop().RunUntilIdle();
DCHECK(!init_decoder_cb_.is_null());
@@ -260,9 +240,7 @@ class AudioRendererImplTest : public ::testing::Test {
void Seek() {
Pause();
-
Flush();
-
Preroll();
}
@@ -437,16 +415,6 @@ class AudioRendererImplTest : public ::testing::Test {
time_ += time;
}
- void HoldStopDecoderCB() {
- EXPECT_CALL(*decoder_, Stop(_)).WillRepeatedly(
- Invoke(this, &AudioRendererImplTest::StopDecoderHoldCB));
- }
-
- void DispatchHeldStopDecoderCB() {
- base::ResetAndReturn(&stop_decoder_cb_).Run();
- }
-
-
// Fixture members.
base::MessageLoop message_loop_;
scoped_ptr<AudioRendererImpl> renderer_;
@@ -491,14 +459,6 @@ class AudioRendererImplTest : public ::testing::Test {
message_loop_.PostTask(FROM_HERE, reset_cb);
}
- void StopDecoder(const base::Closure& stop_cb) {
- message_loop_.PostTask(FROM_HERE, stop_cb);
- }
-
- void StopDecoderHoldCB(const base::Closure& stop_cb) {
- stop_decoder_cb_ = stop_cb;
- }
-
void DeliverBuffer(AudioDecoder::Status status,
const scoped_refptr<AudioBuffer>& buffer) {
CHECK(!decode_cb_.is_null());
@@ -939,37 +899,6 @@ TEST_F(AudioRendererImplTest, PendingFlush_Stop) {
needs_stop_ = false;
}
-TEST_F(AudioRendererImplTest, PendingStop_Read) {
- // This reproduces crbug.com/335181, basically an extra Read() call to the
- // decoder can sneak into the gap between Stop() and its callback being run,
- // which is potentially problematic if we wait until that callback runs to
- // set the 'kStopped' state on the AudioRendererImpl.
-
- Initialize();
-
- Preroll();
- Play();
-
- // Delay calling the callback passed to AudioDecoder::Stop()
- HoldStopDecoderCB();
-
- // This will post at least one call to ARI::AttemptRead.
- ConsumeAllBufferedData();
-
- WaitableMessageLoopEvent stop_event;
- renderer_->Stop(stop_event.GetClosure());
- needs_stop_ = false;
-
- // Now, after stopping, but before the callback is run, let some pending
- // AttemptRead()'s go through... the AudioRendererImpl should ignore them,
- // since the Stop() should have put us into the kStopped state.
- base::RunLoop().RunUntilIdle();
-
- // Now let the stop callback run.
- DispatchHeldStopDecoderCB();
- stop_event.RunAndWait();
-}
-
TEST_F(AudioRendererImplTest, InitializeThenStop) {
InitializeAndStop();
}
diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc
index 94559ff..7698101 100644
--- a/media/filters/decoder_selector.cc
+++ b/media/filters/decoder_selector.cc
@@ -123,8 +123,8 @@ void DecoderSelector<StreamType>::Abort() {
if (decoder_) {
// |decrypted_stream_| is either NULL or already initialized. We don't
// need to Stop() |decrypted_stream_| in either case.
- decoder_->Stop(base::Bind(&DecoderSelector<StreamType>::ReturnNullDecoder,
- weak_ptr_factory_.GetWeakPtr()));
+ decoder_->Stop();
+ ReturnNullDecoder();
return;
}
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
index 2863d22..350e47f 100644
--- a/media/filters/decoder_stream.cc
+++ b/media/filters/decoder_stream.cc
@@ -503,26 +503,14 @@ void DecoderStream<StreamType>::StopDecoder() {
DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
DCHECK(!stop_cb_.is_null());
- decoder_->Stop(base::Bind(&DecoderStream<StreamType>::OnDecoderStopped,
- weak_factory_.GetWeakPtr()));
-}
-
-template <DemuxerStream::Type StreamType>
-void DecoderStream<StreamType>::OnDecoderStopped() {
- FUNCTION_DVLOG(2);
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_;
- // If Stop() was called during pending read/reset, read/reset callback should
- // be fired before the stop callback is fired.
- DCHECK(read_cb_.is_null());
- DCHECK(reset_cb_.is_null());
- DCHECK(!stop_cb_.is_null());
-
state_ = STATE_STOPPED;
+ decoder_->Stop();
stream_ = NULL;
decoder_.reset();
decrypting_demuxer_stream_.reset();
- base::ResetAndReturn(&stop_cb_).Run();
+ // Post |stop_cb_| because pending |read_cb_| and/or |reset_cb_| are also
+ // posted in Stop().
+ task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
}
template class DecoderStream<DemuxerStream::VIDEO>;
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h
index cc44885..acc8265 100644
--- a/media/filters/decoder_stream.h
+++ b/media/filters/decoder_stream.h
@@ -161,7 +161,6 @@ class MEDIA_EXPORT DecoderStream {
void OnDecoderReset();
void StopDecoder();
- void OnDecoderStopped();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc
index 7336f21..8f9b479 100644
--- a/media/filters/decrypting_audio_decoder.cc
+++ b/media/filters/decrypting_audio_decoder.cc
@@ -156,7 +156,7 @@ void DecryptingAudioDecoder::Reset(const base::Closure& closure) {
DoReset();
}
-void DecryptingAudioDecoder::Stop(const base::Closure& closure) {
+void DecryptingAudioDecoder::Stop() {
DVLOG(2) << "Stop() - state: " << state_;
DCHECK(task_runner_->BelongsToCurrentThread());
@@ -179,7 +179,6 @@ void DecryptingAudioDecoder::Stop(const base::Closure& closure) {
base::ResetAndReturn(&reset_cb_).Run();
state_ = kStopped;
- task_runner_->PostTask(FROM_HERE, closure);
}
DecryptingAudioDecoder::~DecryptingAudioDecoder() {
diff --git a/media/filters/decrypting_audio_decoder.h b/media/filters/decrypting_audio_decoder.h
index 562faa0..547aeb5 100644
--- a/media/filters/decrypting_audio_decoder.h
+++ b/media/filters/decrypting_audio_decoder.h
@@ -49,7 +49,7 @@ class MEDIA_EXPORT DecryptingAudioDecoder : public AudioDecoder {
const DecodeCB& decode_cb) OVERRIDE;
virtual scoped_refptr<AudioBuffer> GetDecodeOutput() OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
private:
// For a detailed state diagram please see this link: http://goo.gl/8jAok
diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc
index c711cbd..add52b9 100644
--- a/media/filters/decrypting_audio_decoder_unittest.cc
+++ b/media/filters/decrypting_audio_decoder_unittest.cc
@@ -249,7 +249,7 @@ class DecryptingAudioDecoderTest : public testing::Test {
.WillRepeatedly(InvokeWithoutArgs(
this, &DecryptingAudioDecoderTest::AbortAllPendingCBs));
- decoder_->Stop(NewExpectedClosure());
+ decoder_->Stop();
message_loop_.RunUntilIdle();
}
diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc
index 7e5efec..839f40d 100644
--- a/media/filters/decrypting_video_decoder.cc
+++ b/media/filters/decrypting_video_decoder.cc
@@ -122,7 +122,7 @@ void DecryptingVideoDecoder::Reset(const base::Closure& closure) {
DoReset();
}
-void DecryptingVideoDecoder::Stop(const base::Closure& closure) {
+void DecryptingVideoDecoder::Stop() {
DCHECK(task_runner_->BelongsToCurrentThread());
DVLOG(2) << "Stop() - state: " << state_;
@@ -149,7 +149,6 @@ void DecryptingVideoDecoder::Stop(const base::Closure& closure) {
base::ResetAndReturn(&reset_cb_).Run();
state_ = kStopped;
- BindToCurrentLoop(closure).Run();
}
DecryptingVideoDecoder::~DecryptingVideoDecoder() {
diff --git a/media/filters/decrypting_video_decoder.h b/media/filters/decrypting_video_decoder.h
index 89c72c2..6fe60a9c 100644
--- a/media/filters/decrypting_video_decoder.h
+++ b/media/filters/decrypting_video_decoder.h
@@ -37,7 +37,7 @@ class MEDIA_EXPORT DecryptingVideoDecoder : public VideoDecoder {
virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB& decode_cb) OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
private:
// For a detailed state diagram please see this link: http://goo.gl/8jAok
diff --git a/media/filters/decrypting_video_decoder_unittest.cc b/media/filters/decrypting_video_decoder_unittest.cc
index a01c8c0..6fcd8ac 100644
--- a/media/filters/decrypting_video_decoder_unittest.cc
+++ b/media/filters/decrypting_video_decoder_unittest.cc
@@ -203,7 +203,7 @@ class DecryptingVideoDecoderTest : public testing::Test {
.WillRepeatedly(InvokeWithoutArgs(
this, &DecryptingVideoDecoderTest::AbortAllPendingCBs));
- decoder_->Stop(NewExpectedClosure());
+ decoder_->Stop();
message_loop_.RunUntilIdle();
}
diff --git a/media/filters/fake_video_decoder.cc b/media/filters/fake_video_decoder.cc
index 56d1484..0f17199 100644
--- a/media/filters/fake_video_decoder.cc
+++ b/media/filters/fake_video_decoder.cc
@@ -95,15 +95,18 @@ void FakeVideoDecoder::Reset(const base::Closure& closure) {
DoReset();
}
-void FakeVideoDecoder::Stop(const base::Closure& closure) {
+void FakeVideoDecoder::Stop() {
DCHECK(task_runner_->BelongsToCurrentThread());
- stop_cb_.SetCallback(BindToCurrentLoop(closure));
- // Defer the stop if an init, a decode or a reset is pending.
- if (!init_cb_.IsNull() || !decode_cb_.IsNull() || !reset_cb_.IsNull())
- return;
+ if (!init_cb_.IsNull())
+ SatisfyInit();
+ if (!decode_cb_.IsNull())
+ SatisfyDecode();
+ if (!reset_cb_.IsNull())
+ SatisfyReset();
- DoStop();
+ decoded_frames_.clear();
+ state_ = UNINITIALIZED;
}
scoped_refptr<VideoFrame> FakeVideoDecoder::GetDecodeOutput() {
@@ -120,7 +123,7 @@ void FakeVideoDecoder::HoldNextInit() {
init_cb_.HoldCallback();
}
-void FakeVideoDecoder::HoldNextRead() {
+void FakeVideoDecoder::HoldNextDecode() {
DCHECK(task_runner_->BelongsToCurrentThread());
decode_cb_.HoldCallback();
}
@@ -130,47 +133,26 @@ void FakeVideoDecoder::HoldNextReset() {
reset_cb_.HoldCallback();
}
-void FakeVideoDecoder::HoldNextStop() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- stop_cb_.HoldCallback();
-}
-
void FakeVideoDecoder::SatisfyInit() {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(decode_cb_.IsNull());
DCHECK(reset_cb_.IsNull());
init_cb_.RunHeldCallback();
-
- if (!stop_cb_.IsNull())
- DoStop();
}
-void FakeVideoDecoder::SatisfyRead() {
+void FakeVideoDecoder::SatisfyDecode() {
DCHECK(task_runner_->BelongsToCurrentThread());
decode_cb_.RunHeldCallback();
if (!reset_cb_.IsNull())
DoReset();
-
- if (reset_cb_.IsNull() && !stop_cb_.IsNull())
- DoStop();
}
void FakeVideoDecoder::SatisfyReset() {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(decode_cb_.IsNull());
reset_cb_.RunHeldCallback();
-
- if (!stop_cb_.IsNull())
- DoStop();
-}
-
-void FakeVideoDecoder::SatisfyStop() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(decode_cb_.IsNull());
- DCHECK(reset_cb_.IsNull());
- stop_cb_.RunHeldCallback();
}
void FakeVideoDecoder::DoReset() {
@@ -182,17 +164,6 @@ void FakeVideoDecoder::DoReset() {
reset_cb_.RunOrHold();
}
-void FakeVideoDecoder::DoStop() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(decode_cb_.IsNull());
- DCHECK(reset_cb_.IsNull());
- DCHECK(!stop_cb_.IsNull());
-
- state_ = UNINITIALIZED;
- decoded_frames_.clear();
- stop_cb_.RunOrHold();
-}
-
void FakeVideoDecoder::OnFrameDecoded(
int buffer_size,
const DecodeCB& decode_cb,
diff --git a/media/filters/fake_video_decoder.h b/media/filters/fake_video_decoder.h
index 3da6989..e4038d3 100644
--- a/media/filters/fake_video_decoder.h
+++ b/media/filters/fake_video_decoder.h
@@ -40,21 +40,19 @@ class FakeVideoDecoder : public VideoDecoder {
virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB& decode_cb) OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
virtual scoped_refptr<VideoFrame> GetDecodeOutput() OVERRIDE;
- // Holds the next init/read/reset/stop callback from firing.
+ // Holds the next init/decode/reset callback from firing.
void HoldNextInit();
- void HoldNextRead();
+ void HoldNextDecode();
void HoldNextReset();
- void HoldNextStop();
- // Satisfies the pending init/read/reset/stop callback, which must be ready
- // to fire when these methods are called.
+ // Satisfies the pending init/decode/reset callback, which must be ready to
+ // fire when these methods are called.
void SatisfyInit();
- void SatisfyRead();
+ void SatisfyDecode();
void SatisfyReset();
- void SatisfyStop();
int total_bytes_decoded() const { return total_bytes_decoded_; }
@@ -66,12 +64,11 @@ class FakeVideoDecoder : public VideoDecoder {
// Callback for updating |total_bytes_decoded_|.
void OnFrameDecoded(int buffer_size,
- const DecodeCB& read_cb,
+ const DecodeCB& decode_cb,
Status status,
const scoped_refptr<VideoFrame>& video_frame);
void DoReset();
- void DoStop();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -84,7 +81,6 @@ class FakeVideoDecoder : public VideoDecoder {
CallbackHolder<PipelineStatusCB> init_cb_;
CallbackHolder<DecodeCB> decode_cb_;
CallbackHolder<base::Closure> reset_cb_;
- CallbackHolder<base::Closure> stop_cb_;
VideoDecoderConfig current_config_;
diff --git a/media/filters/fake_video_decoder_unittest.cc b/media/filters/fake_video_decoder_unittest.cc
index ce0cfce..4f50b45 100644
--- a/media/filters/fake_video_decoder_unittest.cc
+++ b/media/filters/fake_video_decoder_unittest.cc
@@ -26,11 +26,10 @@ class FakeVideoDecoderTest : public testing::Test {
num_decoded_frames_(0),
decode_status_(VideoDecoder::kNotEnoughData),
is_decode_pending_(false),
- is_reset_pending_(false),
- is_stop_pending_(false) {}
+ is_reset_pending_(false) {}
virtual ~FakeVideoDecoderTest() {
- StopAndExpect(OK);
+ Stop();
}
void InitializeWithConfig(const VideoDecoderConfig& config) {
@@ -145,13 +144,13 @@ class FakeVideoDecoderTest : public testing::Test {
void EnterPendingReadState() {
// Pass the initial NOT_ENOUGH_DATA stage.
ReadOneFrame();
- decoder_->HoldNextRead();
+ decoder_->HoldNextDecode();
ReadOneFrame();
ExpectReadResult(PENDING);
}
void SatisfyReadAndExpect(CallbackResult result) {
- decoder_->SatisfyRead();
+ decoder_->SatisfyDecode();
message_loop_.RunUntilIdle();
ExpectReadResult(result);
}
@@ -198,42 +197,13 @@ class FakeVideoDecoderTest : public testing::Test {
ExpectResetResult(OK);
}
- // Callback for VideoDecoder::Stop().
- void OnDecoderStopped() {
- DCHECK(is_stop_pending_);
- is_stop_pending_ = false;
- }
-
- void ExpectStopResult(CallbackResult result) {
- switch (result) {
- case PENDING:
- EXPECT_TRUE(is_stop_pending_);
- break;
- case OK:
- EXPECT_FALSE(is_stop_pending_);
- break;
- default:
- NOTREACHED();
- }
- }
-
- void StopAndExpect(CallbackResult result) {
- is_stop_pending_ = true;
- decoder_->Stop(base::Bind(&FakeVideoDecoderTest::OnDecoderStopped,
- base::Unretained(this)));
+ void Stop() {
+ decoder_->Stop();
message_loop_.RunUntilIdle();
- ExpectStopResult(result);
- }
-
- void EnterPendingStopState() {
- decoder_->HoldNextStop();
- StopAndExpect(PENDING);
- }
- void SatisfyStop() {
- decoder_->SatisfyStop();
- message_loop_.RunUntilIdle();
- ExpectStopResult(OK);
+ // All pending callbacks must have been fired.
+ DCHECK(!is_decode_pending_);
+ DCHECK(!is_reset_pending_);
}
base::MessageLoop message_loop_;
@@ -249,7 +219,6 @@ class FakeVideoDecoderTest : public testing::Test {
scoped_refptr<VideoFrame> frame_decoded_;
bool is_decode_pending_;
bool is_reset_pending_;
- bool is_stop_pending_;
private:
DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
@@ -286,7 +255,7 @@ TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) {
TEST_F(FakeVideoDecoderTest, Read_Pending_NotEnoughData) {
Initialize();
- decoder_->HoldNextRead();
+ decoder_->HoldNextDecode();
ReadOneFrame();
ExpectReadResult(PENDING);
SatisfyReadAndExpect(NOT_ENOUGH_DATA);
@@ -347,75 +316,31 @@ TEST_F(FakeVideoDecoderTest, Stop) {
Initialize();
ReadOneFrame();
ExpectReadResult(OK);
- StopAndExpect(OK);
+ Stop();
}
TEST_F(FakeVideoDecoderTest, Stop_DuringPendingInitialization) {
EnterPendingInitState();
- EnterPendingStopState();
- SatisfyInit();
- SatisfyStop();
+ Stop();
}
TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) {
Initialize();
EnterPendingReadState();
- StopAndExpect(PENDING);
- SatisfyRead();
- ExpectStopResult(OK);
+ Stop();
}
TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) {
Initialize();
EnterPendingResetState();
- StopAndExpect(PENDING);
- SatisfyReset();
- ExpectStopResult(OK);
+ Stop();
}
TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
Initialize();
EnterPendingReadState();
EnterPendingResetState();
- StopAndExpect(PENDING);
- SatisfyRead();
- SatisfyReset();
- ExpectStopResult(OK);
-}
-
-TEST_F(FakeVideoDecoderTest, Stop_Pending) {
- Initialize();
- decoder_->HoldNextStop();
- StopAndExpect(PENDING);
- decoder_->SatisfyStop();
- message_loop_.RunUntilIdle();
- ExpectStopResult(OK);
-}
-
-TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingRead) {
- Initialize();
- EnterPendingReadState();
- EnterPendingStopState();
- SatisfyRead();
- SatisfyStop();
-}
-
-TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReset) {
- Initialize();
- EnterPendingResetState();
- EnterPendingStopState();
- SatisfyReset();
- SatisfyStop();
-}
-
-TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReadAndPendingReset) {
- Initialize();
- EnterPendingReadState();
- EnterPendingResetState();
- EnterPendingStopState();
- SatisfyRead();
- SatisfyReset();
- SatisfyStop();
+ Stop();
}
TEST_F(FakeVideoDecoderTest, GetDecodeOutput) {
diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc
index 3cb69c0..45f8dd4 100644
--- a/media/filters/ffmpeg_audio_decoder.cc
+++ b/media/filters/ffmpeg_audio_decoder.cc
@@ -203,9 +203,8 @@ void FFmpegAudioDecoder::Reset(const base::Closure& closure) {
task_runner_->PostTask(FROM_HERE, closure);
}
-void FFmpegAudioDecoder::Stop(const base::Closure& closure) {
+void FFmpegAudioDecoder::Stop() {
DCHECK(task_runner_->BelongsToCurrentThread());
- base::ScopedClosureRunner runner(BindToCurrentLoop(closure));
if (state_ == kUninitialized)
return;
diff --git a/media/filters/ffmpeg_audio_decoder.h b/media/filters/ffmpeg_audio_decoder.h
index 32fddb8..59e4629 100644
--- a/media/filters/ffmpeg_audio_decoder.h
+++ b/media/filters/ffmpeg_audio_decoder.h
@@ -40,7 +40,7 @@ class MEDIA_EXPORT FFmpegAudioDecoder : public AudioDecoder {
const DecodeCB& decode_cb) OVERRIDE;
virtual scoped_refptr<AudioBuffer> GetDecodeOutput() OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
private:
enum DecoderState {
diff --git a/media/filters/ffmpeg_audio_decoder_unittest.cc b/media/filters/ffmpeg_audio_decoder_unittest.cc
index ee09669..60d1f40 100644
--- a/media/filters/ffmpeg_audio_decoder_unittest.cc
+++ b/media/filters/ffmpeg_audio_decoder_unittest.cc
@@ -28,8 +28,7 @@ class FFmpegAudioDecoderTest : public testing::Test {
FFmpegAudioDecoderTest()
: decoder_(new FFmpegAudioDecoder(message_loop_.message_loop_proxy())),
pending_decode_(false),
- pending_reset_(false),
- pending_stop_(false) {
+ pending_reset_(false) {
FFmpegGlue::InitializeFFmpeg();
vorbis_extradata_ = ReadTestDataFile("vorbis-extradata");
@@ -58,7 +57,6 @@ class FFmpegAudioDecoderTest : public testing::Test {
virtual ~FFmpegAudioDecoderTest() {
EXPECT_FALSE(pending_decode_);
EXPECT_FALSE(pending_reset_);
- EXPECT_FALSE(pending_stop_);
}
void Initialize() {
@@ -96,9 +94,7 @@ class FFmpegAudioDecoderTest : public testing::Test {
}
void Stop() {
- pending_stop_ = true;
- decoder_->Stop(base::Bind(
- &FFmpegAudioDecoderTest::StopFinished, base::Unretained(this)));
+ decoder_->Stop();
base::RunLoop().RunUntilIdle();
}
@@ -116,7 +112,7 @@ class FFmpegAudioDecoderTest : public testing::Test {
decoded_audio_.push_back(buffer);
// If we hit a NULL buffer or have a pending reset, we expect an abort.
- if (buffer.get() == NULL || pending_stop_ || pending_reset_) {
+ if (buffer.get() == NULL || pending_reset_) {
EXPECT_TRUE(buffer.get() == NULL);
EXPECT_EQ(status, AudioDecoder::kAborted);
return;
@@ -125,15 +121,6 @@ class FFmpegAudioDecoderTest : public testing::Test {
EXPECT_EQ(status, AudioDecoder::kOk);
}
- void StopFinished() {
- EXPECT_TRUE(pending_stop_);
- // Stop should always finish after Decode and Reset.
- EXPECT_FALSE(pending_decode_);
- EXPECT_FALSE(pending_reset_);
-
- pending_stop_ = false;
- }
-
void ResetFinished() {
EXPECT_TRUE(pending_reset_);
// Reset should always finish after Decode.
@@ -158,7 +145,6 @@ class FFmpegAudioDecoderTest : public testing::Test {
scoped_ptr<FFmpegAudioDecoder> decoder_;
bool pending_decode_;
bool pending_reset_;
- bool pending_stop_;
scoped_refptr<DecoderBuffer> vorbis_extradata_;
@@ -212,7 +198,6 @@ TEST_F(FFmpegAudioDecoderTest, PendingDecode_Stop) {
Decode();
Stop();
SatisfyPendingDecode();
- Stop();
}
TEST_F(FFmpegAudioDecoderTest, PendingDecode_Reset) {
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc
index d52bc71..53ee437 100644
--- a/media/filters/ffmpeg_video_decoder.cc
+++ b/media/filters/ffmpeg_video_decoder.cc
@@ -127,7 +127,6 @@ void FFmpegVideoDecoder::Initialize(const VideoDecoderConfig& config,
const PipelineStatusCB& status_cb) {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(decode_cb_.is_null());
- DCHECK(reset_cb_.is_null());
DCHECK(!config.is_encrypted());
FFmpegGlue::InitializeFFmpeg();
@@ -169,38 +168,19 @@ void FFmpegVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
void FFmpegVideoDecoder::Reset(const base::Closure& closure) {
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(reset_cb_.is_null());
- reset_cb_ = BindToCurrentLoop(closure);
-
- // Defer the reset if a decode is pending.
- if (!decode_cb_.is_null())
- return;
-
- DoReset();
-}
-
-void FFmpegVideoDecoder::DoReset() {
DCHECK(decode_cb_.is_null());
avcodec_flush_buffers(codec_context_.get());
state_ = kNormal;
- base::ResetAndReturn(&reset_cb_).Run();
+ task_runner_->PostTask(FROM_HERE, closure);
}
-void FFmpegVideoDecoder::Stop(const base::Closure& closure) {
+void FFmpegVideoDecoder::Stop() {
DCHECK(task_runner_->BelongsToCurrentThread());
- base::ScopedClosureRunner runner(BindToCurrentLoop(closure));
if (state_ == kUninitialized)
return;
- if (!decode_cb_.is_null()) {
- base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
- // Reset is pending only when decode is pending.
- if (!reset_cb_.is_null())
- base::ResetAndReturn(&reset_cb_).Run();
- }
-
ReleaseFFmpegResources();
state_ = kUninitialized;
}
@@ -217,7 +197,6 @@ void FFmpegVideoDecoder::DecodeBuffer(
DCHECK_NE(state_, kUninitialized);
DCHECK_NE(state_, kDecodeFinished);
DCHECK_NE(state_, kError);
- DCHECK(reset_cb_.is_null());
DCHECK(!decode_cb_.is_null());
DCHECK(buffer);
diff --git a/media/filters/ffmpeg_video_decoder.h b/media/filters/ffmpeg_video_decoder.h
index 4ccc2e4..0785d15 100644
--- a/media/filters/ffmpeg_video_decoder.h
+++ b/media/filters/ffmpeg_video_decoder.h
@@ -37,7 +37,7 @@ class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB& decode_cb) OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
// Callback called from within FFmpeg to allocate a buffer based on
// the dimensions of |codec_context|. See AVCodecContext.get_buffer
@@ -66,15 +66,12 @@ class MEDIA_EXPORT FFmpegVideoDecoder : public VideoDecoder {
// and resets them to NULL.
void ReleaseFFmpegResources();
- // Reset decoder and call |reset_cb_|.
- void DoReset();
-
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
DecoderState state_;
+ // TODO(xhwang): Merge DecodeBuffer() into Decode() and remove this.
DecodeCB decode_cb_;
- base::Closure reset_cb_;
// FFmpeg structures owned by this object.
scoped_ptr<AVCodecContext, ScopedPtrAVFreeContext> codec_context_;
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc
index 2ce067c..f156a9f 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -86,7 +86,7 @@ class FFmpegVideoDecoderTest : public testing::Test {
}
void Stop() {
- decoder_->Stop(NewExpectedClosure());
+ decoder_->Stop();
message_loop_.RunUntilIdle();
}
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc
index ba6e636..1ce5ba0 100644
--- a/media/filters/gpu_video_decoder.cc
+++ b/media/filters/gpu_video_decoder.cc
@@ -104,7 +104,7 @@ void GpuVideoDecoder::Reset(const base::Closure& closure) {
vda_->Reset();
}
-void GpuVideoDecoder::Stop(const base::Closure& closure) {
+void GpuVideoDecoder::Stop() {
DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
if (vda_)
DestroyVDA();
@@ -112,7 +112,6 @@ void GpuVideoDecoder::Stop(const base::Closure& closure) {
EnqueueFrameAndTriggerFrameDelivery(VideoFrame::CreateEOSFrame());
if (!pending_reset_cb_.is_null())
base::ResetAndReturn(&pending_reset_cb_).Run();
- BindToCurrentLoop(closure).Run();
}
static bool IsCodedSizeSupported(const gfx::Size& coded_size) {
diff --git a/media/filters/gpu_video_decoder.h b/media/filters/gpu_video_decoder.h
index 6e05f63..41742e9 100644
--- a/media/filters/gpu_video_decoder.h
+++ b/media/filters/gpu_video_decoder.h
@@ -47,7 +47,7 @@ class MEDIA_EXPORT GpuVideoDecoder
virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB& decode_cb) OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
virtual bool HasAlpha() const OVERRIDE;
virtual bool NeedsBitstreamConversion() const OVERRIDE;
virtual bool CanReadWithoutStalling() const OVERRIDE;
diff --git a/media/filters/opus_audio_decoder.cc b/media/filters/opus_audio_decoder.cc
index 3fd28f4..5afc024 100644
--- a/media/filters/opus_audio_decoder.cc
+++ b/media/filters/opus_audio_decoder.cc
@@ -287,13 +287,12 @@ void OpusAudioDecoder::Reset(const base::Closure& closure) {
task_runner_->PostTask(FROM_HERE, closure);
}
-void OpusAudioDecoder::Stop(const base::Closure& closure) {
+void OpusAudioDecoder::Stop() {
DCHECK(task_runner_->BelongsToCurrentThread());
opus_multistream_decoder_ctl(opus_decoder_, OPUS_RESET_STATE);
ResetTimestampState();
CloseDecoder();
- task_runner_->PostTask(FROM_HERE, closure);
}
OpusAudioDecoder::~OpusAudioDecoder() {}
diff --git a/media/filters/opus_audio_decoder.h b/media/filters/opus_audio_decoder.h
index 5855719..2fad5a8 100644
--- a/media/filters/opus_audio_decoder.h
+++ b/media/filters/opus_audio_decoder.h
@@ -36,12 +36,9 @@ class MEDIA_EXPORT OpusAudioDecoder : public AudioDecoder {
virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB& decode_cb) OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
private:
- void DoReset();
- void DoStop();
-
// Reads from the demuxer stream with corresponding callback method.
void ReadFromDemuxerStream();
void DecodeBuffer(const scoped_refptr<DecoderBuffer>& input,
diff --git a/media/filters/video_decoder_selector_unittest.cc b/media/filters/video_decoder_selector_unittest.cc
index d7e945d..130c4e3 100644
--- a/media/filters/video_decoder_selector_unittest.cc
+++ b/media/filters/video_decoder_selector_unittest.cc
@@ -42,17 +42,11 @@ class VideoDecoderSelectorTest : public ::testing::Test {
decoder_2_(new StrictMock<MockVideoDecoder>()) {
all_decoders_.push_back(decoder_1_);
all_decoders_.push_back(decoder_2_);
-
- EXPECT_CALL(*decoder_1_, Stop(_))
- .WillRepeatedly(RunClosure<0>());
- EXPECT_CALL(*decoder_2_, Stop(_))
- .WillRepeatedly(RunClosure<0>());
}
~VideoDecoderSelectorTest() {
- if (selected_decoder_) {
- selected_decoder_->Stop(NewExpectedClosure());
- }
+ if (selected_decoder_)
+ selected_decoder_->Stop();
message_loop_.RunUntilIdle();
}
@@ -148,6 +142,11 @@ class VideoDecoderSelectorTest : public ::testing::Test {
DISALLOW_COPY_AND_ASSIGN(VideoDecoderSelectorTest);
};
+// Note:
+// In all the tests, Stop() is expected to be called on a decoder if a decoder:
+// - is pending initialization and DecoderSelector::Abort() is called, or
+// - has been successfully initialized.
+
// The stream is not encrypted but we have no clear decoder. No decoder can be
// selected.
TEST_F(VideoDecoderSelectorTest, ClearStream_NoDecryptor_NoClearDecoder) {
@@ -168,6 +167,7 @@ TEST_F(VideoDecoderSelectorTest, ClearStream_NoDecryptor_OneClearDecoder) {
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoder();
}
@@ -178,6 +178,7 @@ TEST_F(VideoDecoderSelectorTest,
InitializeDecoderSelector(kNoDecryptor, 1);
EXPECT_CALL(*decoder_1_, Initialize(_, _));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoderAndAbort();
}
@@ -193,6 +194,7 @@ TEST_F(VideoDecoderSelectorTest, ClearStream_NoDecryptor_MultipleClearDecoder) {
EXPECT_CALL(*decoder_2_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, IsNull()));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoder();
}
@@ -205,6 +207,7 @@ TEST_F(VideoDecoderSelectorTest,
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
EXPECT_CALL(*decoder_2_, Initialize(_, _));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoderAndAbort();
}
@@ -218,6 +221,7 @@ TEST_F(VideoDecoderSelectorTest, ClearStream_HasDecryptor) {
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, IsNull()));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoder();
}
@@ -227,6 +231,7 @@ TEST_F(VideoDecoderSelectorTest, Abort_ClearStream_HasDecryptor) {
InitializeDecoderSelector(kDecryptOnly, 1);
EXPECT_CALL(*decoder_1_, Initialize(_, _));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoderAndAbort();
}
@@ -269,6 +274,7 @@ TEST_F(VideoDecoderSelectorTest, EncryptedStream_DecryptOnly_OneClearDecoder) {
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_1_, NotNull()));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoder();
}
@@ -279,6 +285,7 @@ TEST_F(VideoDecoderSelectorTest,
InitializeDecoderSelector(kDecryptOnly, 1);
EXPECT_CALL(*decoder_1_, Initialize(_, _));
+ EXPECT_CALL(*decoder_1_, Stop());
SelectDecoderAndAbort();
}
@@ -296,6 +303,7 @@ TEST_F(VideoDecoderSelectorTest,
EXPECT_CALL(*decoder_2_, Initialize(_, _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
EXPECT_CALL(*this, OnDecoderSelected(decoder_2_, NotNull()));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoder();
}
@@ -308,6 +316,7 @@ TEST_F(VideoDecoderSelectorTest,
EXPECT_CALL(*decoder_1_, Initialize(_, _))
.WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
EXPECT_CALL(*decoder_2_, Initialize(_, _));
+ EXPECT_CALL(*decoder_2_, Stop());
SelectDecoderAndAbort();
}
diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc
index 52a439e..dc45638 100644
--- a/media/filters/video_frame_stream_unittest.cc
+++ b/media/filters/video_frame_stream_unittest.cc
@@ -148,6 +148,7 @@ class VideoFrameStreamTest
}
void OnStopped() {
+ DCHECK(!pending_initialize_);
DCHECK(!pending_read_);
DCHECK(!pending_reset_);
DCHECK(pending_stop_);
@@ -178,9 +179,8 @@ class VideoFrameStreamTest
DECRYPTOR_NO_KEY,
DECODER_INIT,
DECODER_REINIT,
- DECODER_READ,
- DECODER_RESET,
- DECODER_STOP
+ DECODER_DECODE,
+ DECODER_RESET
};
void EnterPendingState(PendingState state) {
@@ -223,8 +223,8 @@ class VideoFrameStreamTest
ReadUntilPending();
break;
- case DECODER_READ:
- decoder_->HoldNextRead();
+ case DECODER_DECODE:
+ decoder_->HoldNextDecode();
ReadUntilPending();
break;
@@ -236,16 +236,6 @@ class VideoFrameStreamTest
message_loop_.RunUntilIdle();
break;
- case DECODER_STOP:
- decoder_->HoldNextStop();
- // Check that the pipeline statistics callback was fired correctly.
- EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_);
- pending_stop_ = true;
- video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped,
- base::Unretained(this)));
- message_loop_.RunUntilIdle();
- break;
-
case NOT_PENDING:
NOTREACHED();
break;
@@ -275,19 +265,14 @@ class VideoFrameStreamTest
decoder_->SatisfyInit();
break;
- case DECODER_READ:
- decoder_->SatisfyRead();
+ case DECODER_DECODE:
+ decoder_->SatisfyDecode();
break;
case DECODER_RESET:
decoder_->SatisfyReset();
break;
- case DECODER_STOP:
- DCHECK(pending_stop_);
- decoder_->SatisfyStop();
- break;
-
case NOT_PENDING:
NOTREACHED();
break;
@@ -302,8 +287,8 @@ class VideoFrameStreamTest
}
void Read() {
- EnterPendingState(DECODER_READ);
- SatisfyPendingCallback(DECODER_READ);
+ EnterPendingState(DECODER_DECODE);
+ SatisfyPendingCallback(DECODER_DECODE);
}
void Reset() {
@@ -312,8 +297,12 @@ class VideoFrameStreamTest
}
void Stop() {
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DECODER_STOP);
+ // Check that the pipeline statistics callback was fired correctly.
+ EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_);
+ pending_stop_ = true;
+ video_frame_stream_->Stop(base::Bind(&VideoFrameStreamTest::OnStopped,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
}
base::MessageLoop message_loop_;
@@ -422,11 +411,11 @@ TEST_P(VideoFrameStreamTest, Reset_DuringDemuxerRead_ConfigChange) {
Read();
}
-TEST_P(VideoFrameStreamTest, Reset_DuringNormalDecoderRead) {
+TEST_P(VideoFrameStreamTest, Reset_DuringNormalDecoderDecode) {
Initialize();
- EnterPendingState(DECODER_READ);
+ EnterPendingState(DECODER_DECODE);
EnterPendingState(DECODER_RESET);
- SatisfyPendingCallback(DECODER_READ);
+ SatisfyPendingCallback(DECODER_DECODE);
SatisfyPendingCallback(DECODER_RESET);
Read();
}
@@ -474,9 +463,7 @@ TEST_P(VideoFrameStreamTest, Stop_DuringSetDecryptor) {
TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) {
EnterPendingState(DECODER_INIT);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DECODER_INIT);
- SatisfyPendingCallback(DECODER_STOP);
+ Stop();
}
TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) {
@@ -487,9 +474,7 @@ TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) {
TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) {
Initialize();
EnterPendingState(DECODER_REINIT);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DECODER_REINIT);
- SatisfyPendingCallback(DECODER_STOP);
+ Stop();
}
TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) {
@@ -502,25 +487,19 @@ TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) {
TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) {
Initialize();
EnterPendingState(DEMUXER_READ_NORMAL);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DEMUXER_READ_NORMAL);
- SatisfyPendingCallback(DECODER_STOP);
+ Stop();
}
TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) {
Initialize();
EnterPendingState(DEMUXER_READ_CONFIG_CHANGE);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE);
- SatisfyPendingCallback(DECODER_STOP);
+ Stop();
}
-TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderRead) {
+TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderDecode) {
Initialize();
- EnterPendingState(DECODER_READ);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DECODER_READ);
- SatisfyPendingCallback(DECODER_STOP);
+ EnterPendingState(DECODER_DECODE);
+ Stop();
}
TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) {
@@ -545,9 +524,7 @@ TEST_P(VideoFrameStreamTest, Stop_DuringNoKeyRead) {
TEST_P(VideoFrameStreamTest, Stop_DuringReset) {
Initialize();
EnterPendingState(DECODER_RESET);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DECODER_RESET);
- SatisfyPendingCallback(DECODER_STOP);
+ Stop();
}
TEST_P(VideoFrameStreamTest, Stop_AfterReset) {
@@ -558,22 +535,17 @@ TEST_P(VideoFrameStreamTest, Stop_AfterReset) {
TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) {
Initialize();
- EnterPendingState(DECODER_READ);
+ EnterPendingState(DECODER_DECODE);
EnterPendingState(DECODER_RESET);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DECODER_READ);
- SatisfyPendingCallback(DECODER_RESET);
- SatisfyPendingCallback(DECODER_STOP);
+ Stop();
}
TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) {
Initialize();
- EnterPendingState(DECODER_READ);
+ EnterPendingState(DECODER_DECODE);
EnterPendingState(DECODER_RESET);
- SatisfyPendingCallback(DECODER_READ);
- EnterPendingState(DECODER_STOP);
- SatisfyPendingCallback(DECODER_RESET);
- SatisfyPendingCallback(DECODER_STOP);
+ SatisfyPendingCallback(DECODER_DECODE);
+ Stop();
}
TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) {
diff --git a/media/filters/video_renderer_impl_unittest.cc b/media/filters/video_renderer_impl_unittest.cc
index b22549d..86fb17e 100644
--- a/media/filters/video_renderer_impl_unittest.cc
+++ b/media/filters/video_renderer_impl_unittest.cc
@@ -58,7 +58,7 @@ class VideoRendererImplTest : public ::testing::Test {
EXPECT_CALL(demuxer_stream_, Read(_))
.WillRepeatedly(RunCallback<0>(DemuxerStream::kOk,
DecoderBuffer::CreateEOSBuffer()));
- EXPECT_CALL(*decoder_, Stop(_))
+ EXPECT_CALL(*decoder_, Stop())
.WillRepeatedly(Invoke(this, &VideoRendererImplTest::StopRequested));
EXPECT_CALL(statistics_cb_object_, OnStatistics(_))
.Times(AnyNumber());
@@ -333,15 +333,13 @@ class VideoRendererImplTest : public ::testing::Test {
message_loop_.PostTask(FROM_HERE, callback);
}
- void StopRequested(const base::Closure& callback) {
+ void StopRequested() {
DCHECK_EQ(&message_loop_, base::MessageLoop::current());
decode_results_.clear();
if (!read_cb_.is_null()) {
QueueAbortedRead();
SatisfyPendingRead();
}
-
- message_loop_.PostTask(FROM_HERE, callback);
}
base::MessageLoop message_loop_;
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc
index ecef96c..69d137b 100644
--- a/media/filters/vpx_video_decoder.cc
+++ b/media/filters/vpx_video_decoder.cc
@@ -219,7 +219,6 @@ void VpxVideoDecoder::Initialize(const VideoDecoderConfig& config,
DCHECK(config.IsValidConfig());
DCHECK(!config.is_encrypted());
DCHECK(decode_cb_.is_null());
- DCHECK(reset_cb_.is_null());
if (!ConfigureDecoder(config)) {
status_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
@@ -329,29 +328,14 @@ void VpxVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
void VpxVideoDecoder::Reset(const base::Closure& closure) {
DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(reset_cb_.is_null());
- reset_cb_ = BindToCurrentLoop(closure);
-
- // Defer the reset if a decode is pending.
- if (!decode_cb_.is_null())
- return;
+ DCHECK(decode_cb_.is_null());
- DoReset();
+ state_ = kNormal;
+ task_runner_->PostTask(FROM_HERE, closure);
}
-void VpxVideoDecoder::Stop(const base::Closure& closure) {
+void VpxVideoDecoder::Stop() {
DCHECK(task_runner_->BelongsToCurrentThread());
- base::ScopedClosureRunner runner(BindToCurrentLoop(closure));
-
- if (state_ == kUninitialized)
- return;
-
- if (!decode_cb_.is_null()) {
- base::ResetAndReturn(&decode_cb_).Run(kAborted, NULL);
- // Reset is pending only when decode is pending.
- if (!reset_cb_.is_null())
- base::ResetAndReturn(&reset_cb_).Run();
- }
state_ = kUninitialized;
}
@@ -365,7 +349,6 @@ void VpxVideoDecoder::DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) {
DCHECK_NE(state_, kUninitialized);
DCHECK_NE(state_, kDecodeFinished);
DCHECK_NE(state_, kError);
- DCHECK(reset_cb_.is_null());
DCHECK(!decode_cb_.is_null());
DCHECK(buffer);
@@ -465,14 +448,6 @@ bool VpxVideoDecoder::VpxDecode(const scoped_refptr<DecoderBuffer>& buffer,
return true;
}
-void VpxVideoDecoder::DoReset() {
- DCHECK(decode_cb_.is_null());
-
- state_ = kNormal;
- reset_cb_.Run();
- reset_cb_.Reset();
-}
-
void VpxVideoDecoder::CopyVpxImageTo(const vpx_image* vpx_image,
const struct vpx_image* vpx_image_alpha,
scoped_refptr<VideoFrame>* video_frame) {
diff --git a/media/filters/vpx_video_decoder.h b/media/filters/vpx_video_decoder.h
index 0027219..91948944 100644
--- a/media/filters/vpx_video_decoder.h
+++ b/media/filters/vpx_video_decoder.h
@@ -37,7 +37,7 @@ class MEDIA_EXPORT VpxVideoDecoder : public VideoDecoder {
virtual void Decode(const scoped_refptr<DecoderBuffer>& buffer,
const DecodeCB& decode_cb) OVERRIDE;
virtual void Reset(const base::Closure& closure) OVERRIDE;
- virtual void Stop(const base::Closure& closure) OVERRIDE;
+ virtual void Stop() OVERRIDE;
virtual bool HasAlpha() const OVERRIDE;
private:
@@ -59,9 +59,6 @@ class MEDIA_EXPORT VpxVideoDecoder : public VideoDecoder {
bool VpxDecode(const scoped_refptr<DecoderBuffer>& buffer,
scoped_refptr<VideoFrame>* video_frame);
- // Reset decoder and call |reset_cb_|.
- void DoReset();
-
void CopyVpxImageTo(const vpx_image* vpx_image,
const struct vpx_image* vpx_image_alpha,
scoped_refptr<VideoFrame>* video_frame);
@@ -70,8 +67,8 @@ class MEDIA_EXPORT VpxVideoDecoder : public VideoDecoder {
DecoderState state_;
+ // TODO(xhwang): Merge DecodeBuffer() into Decode() and remove this.
DecodeCB decode_cb_;
- base::Closure reset_cb_;
VideoDecoderConfig config_;