diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-17 08:32:52 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-17 08:32:52 +0000 |
commit | 4beec40bbd48c2f04b194f0f82d70fa07485811f (patch) | |
tree | d47bd9e75d0335b096489c0c2682edb2913e53f1 /media | |
parent | 317b66eb10f6361698c03b3e6e25c15e123ff185 (diff) | |
download | chromium_src-4beec40bbd48c2f04b194f0f82d70fa07485811f.zip chromium_src-4beec40bbd48c2f04b194f0f82d70fa07485811f.tar.gz chromium_src-4beec40bbd48c2f04b194f0f82d70fa07485811f.tar.bz2 |
Fold DecoderStream::Stop() into the dtor.
BUG=349211
TEST=Existing tests pass.
Review URL: https://codereview.chromium.org/393313004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283713 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/filters/audio_renderer_impl.cc | 23 | ||||
-rw-r--r-- | media/filters/audio_renderer_impl.h | 3 | ||||
-rw-r--r-- | media/filters/decoder_stream.cc | 100 | ||||
-rw-r--r-- | media/filters/decoder_stream.h | 15 | ||||
-rw-r--r-- | media/filters/video_frame_stream_unittest.cc | 94 | ||||
-rw-r--r-- | media/filters/video_renderer_impl.cc | 19 | ||||
-rw-r--r-- | media/filters/video_renderer_impl.h | 3 |
7 files changed, 95 insertions, 162 deletions
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc index e6937fc..bbe0d78 100644 --- a/media/filters/audio_renderer_impl.cc +++ b/media/filters/audio_renderer_impl.cc @@ -48,9 +48,9 @@ AudioRendererImpl::AudioRendererImpl( AudioHardwareConfig* hardware_config) : task_runner_(task_runner), sink_(sink), - audio_buffer_stream_(task_runner, - decoders.Pass(), - set_decryptor_ready_cb), + audio_buffer_stream_(new AudioBufferStream(task_runner, + decoders.Pass(), + set_decryptor_ready_cb)), hardware_config_(hardware_config), state_(kUninitialized), buffering_state_(BUFFERING_HAVE_NOTHING), @@ -60,9 +60,9 @@ AudioRendererImpl::AudioRendererImpl( received_end_of_stream_(false), rendered_end_of_stream_(false), weak_factory_(this) { - audio_buffer_stream_.set_splice_observer(base::Bind( + audio_buffer_stream_->set_splice_observer(base::Bind( &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); - audio_buffer_stream_.set_config_change_observer(base::Bind( + audio_buffer_stream_->set_config_change_observer(base::Bind( &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); } @@ -155,8 +155,8 @@ void AudioRendererImpl::DoFlush_Locked() { DCHECK(!pending_read_); DCHECK_EQ(state_, kFlushed); - audio_buffer_stream_.Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, - weak_factory_.GetWeakPtr())); + audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, + weak_factory_.GetWeakPtr())); } void AudioRendererImpl::ResetDecoderDone() { @@ -215,7 +215,8 @@ void AudioRendererImpl::Stop(const base::Closure& callback) { sink_ = NULL; } - audio_buffer_stream_.Stop(callback); + audio_buffer_stream_.reset(); + task_runner_->PostTask(FROM_HERE, callback); } void AudioRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { @@ -296,7 +297,7 @@ void AudioRendererImpl::Initialize(DemuxerStream* stream, audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); - audio_buffer_stream_.Initialize( + audio_buffer_stream_->Initialize( stream, false, statistics_cb, @@ -486,8 +487,8 @@ void AudioRendererImpl::AttemptRead_Locked() { return; pending_read_ = true; - audio_buffer_stream_.Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, - weak_factory_.GetWeakPtr())); + audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, + weak_factory_.GetWeakPtr())); } bool AudioRendererImpl::CanRead_Locked() { diff --git a/media/filters/audio_renderer_impl.h b/media/filters/audio_renderer_impl.h index cc06fa3..5f6ebdd 100644 --- a/media/filters/audio_renderer_impl.h +++ b/media/filters/audio_renderer_impl.h @@ -22,6 +22,7 @@ #include <deque> #include "base/gtest_prod_util.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "media/base/audio_decoder.h" @@ -197,7 +198,7 @@ class MEDIA_EXPORT AudioRendererImpl // may deadlock between |task_runner_| and the audio callback thread. scoped_refptr<media::AudioRendererSink> sink_; - AudioBufferStream audio_buffer_stream_; + scoped_ptr<AudioBufferStream> audio_buffer_stream_; // Interface to the hardware audio params. const AudioHardwareConfig* const hardware_config_; diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc index f8714f2..66c64d3 100644 --- a/media/filters/decoder_stream.cc +++ b/media/filters/decoder_stream.cc @@ -56,7 +56,30 @@ DecoderStream<StreamType>::DecoderStream( template <DemuxerStream::Type StreamType> DecoderStream<StreamType>::~DecoderStream() { - DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_STOPPED) << state_; + FUNCTION_DVLOG(2); + DCHECK(task_runner_->BelongsToCurrentThread()); + + // TODO(xhwang): Fold DecoderSelector::Abort() into the dtor. + if (state_ == STATE_INITIALIZING) + decoder_selector_->Abort(); + + if (!init_cb_.is_null()) { + task_runner_->PostTask(FROM_HERE, + base::Bind(base::ResetAndReturn(&init_cb_), false)); + } + if (!read_cb_.is_null()) { + task_runner_->PostTask(FROM_HERE, base::Bind( + base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); + } + if (!reset_cb_.is_null()) + task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); + + if (decrypting_demuxer_stream_) + decrypting_demuxer_stream_->Stop(); + + stream_ = NULL; + decoder_.reset(); + decrypting_demuxer_stream_.reset(); } template <DemuxerStream::Type StreamType> @@ -89,13 +112,12 @@ template <DemuxerStream::Type StreamType> void DecoderStream<StreamType>::Read(const ReadCB& read_cb) { FUNCTION_DVLOG(2); DCHECK(task_runner_->BelongsToCurrentThread()); - DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING && - state_ != STATE_STOPPED) << state_; + DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_INITIALIZING) + << state_; // No two reads in the flight at any time. DCHECK(read_cb_.is_null()); // No read during resetting or stopping process. DCHECK(reset_cb_.is_null()); - DCHECK(stop_cb_.is_null()); if (state_ == STATE_ERROR) { task_runner_->PostTask( @@ -125,9 +147,8 @@ template <DemuxerStream::Type StreamType> void DecoderStream<StreamType>::Reset(const base::Closure& closure) { FUNCTION_DVLOG(2); DCHECK(task_runner_->BelongsToCurrentThread()); - DCHECK(state_ != STATE_UNINITIALIZED && state_ != STATE_STOPPED) << state_; + DCHECK(state_ != STATE_UNINITIALIZED)<< state_; DCHECK(reset_cb_.is_null()); - DCHECK(stop_cb_.is_null()); reset_cb_ = closure; @@ -160,45 +181,6 @@ void DecoderStream<StreamType>::Reset(const base::Closure& closure) { } template <DemuxerStream::Type StreamType> -void DecoderStream<StreamType>::Stop(const base::Closure& closure) { - FUNCTION_DVLOG(2); - DCHECK(task_runner_->BelongsToCurrentThread()); - DCHECK_NE(state_, STATE_STOPPED) << state_; - DCHECK(stop_cb_.is_null()); - - // TODO(xhwang): This is the only asynchronousness in DecoderStream::Stop(). - // Fix this so that we can merge the stopping code into the dtor. - if (state_ == STATE_INITIALIZING) { - stop_cb_ = closure; - decoder_selector_->Abort(); - return; - } - - DCHECK(init_cb_.is_null()); - - // All pending callbacks will be dropped. - weak_factory_.InvalidateWeakPtrs(); - - // Post callbacks to prevent reentrance into this object. - if (!read_cb_.is_null()) { - task_runner_->PostTask(FROM_HERE, base::Bind( - base::ResetAndReturn(&read_cb_), ABORTED, scoped_refptr<Output>())); - } - if (!reset_cb_.is_null()) - task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&reset_cb_)); - - if (decrypting_demuxer_stream_) - decrypting_demuxer_stream_->Stop(); - - stream_ = NULL; - decoder_.reset(); - decrypting_demuxer_stream_.reset(); - - state_ = STATE_STOPPED; - task_runner_->PostTask(FROM_HERE, closure); -} - -template <DemuxerStream::Type StreamType> bool DecoderStream<StreamType>::CanReadWithoutStalling() const { DCHECK(task_runner_->BelongsToCurrentThread()); return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling(); @@ -251,19 +233,14 @@ void DecoderStream<StreamType>::OnDecoderSelected( state_ = STATE_UNINITIALIZED; StreamTraits::FinishInitialization( base::ResetAndReturn(&init_cb_), selected_decoder.get(), stream_); - } else { - state_ = STATE_NORMAL; - decoder_ = selected_decoder.Pass(); - decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); - StreamTraits::FinishInitialization( - base::ResetAndReturn(&init_cb_), decoder_.get(), stream_); - } - - // Stop() called during initialization. - if (!stop_cb_.is_null()) { - Stop(base::ResetAndReturn(&stop_cb_)); return; } + + state_ = STATE_NORMAL; + decoder_ = selected_decoder.Pass(); + decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); + StreamTraits::FinishInitialization( + base::ResetAndReturn(&init_cb_), decoder_.get(), stream_); } template <DemuxerStream::Type StreamType> @@ -281,7 +258,6 @@ void DecoderStream<StreamType>::Decode( DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_; DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests()); DCHECK(reset_cb_.is_null()); - DCHECK(stop_cb_.is_null()); DCHECK(buffer); int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); @@ -308,7 +284,6 @@ void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) << state_; - DCHECK(stop_cb_.is_null()); DCHECK_GT(pending_decode_requests_, 0); --pending_decode_requests_; @@ -403,7 +378,6 @@ void DecoderStream<StreamType>::ReadFromDemuxerStream() { DCHECK_EQ(state_, STATE_NORMAL) << state_; DCHECK(CanDecodeMore()); DCHECK(reset_cb_.is_null()); - DCHECK(stop_cb_.is_null()); state_ = STATE_PENDING_DEMUXER_READ; stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, @@ -418,15 +392,13 @@ void DecoderStream<StreamType>::OnBufferReady( << (buffer ? buffer->AsHumanReadableString() : "NULL"); DCHECK(task_runner_->BelongsToCurrentThread()); - DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || - state_ == STATE_STOPPED) + DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) << state_; DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; - DCHECK(stop_cb_.is_null()); // Decoding has been stopped (e.g due to an error). if (state_ != STATE_PENDING_DEMUXER_READ) { - DCHECK(state_ == STATE_ERROR || state_ == STATE_STOPPED); + DCHECK(state_ == STATE_ERROR); DCHECK(read_cb_.is_null()); return; } @@ -507,7 +479,6 @@ void DecoderStream<StreamType>::OnDecoderReinitialized(PipelineStatus status) { FUNCTION_DVLOG(2); DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, STATE_REINITIALIZING_DECODER) << state_; - DCHECK(stop_cb_.is_null()); // ReinitializeDecoder() can be called in two cases: // 1, Flushing decoder finished (see OnDecodeOutputReady()). @@ -555,7 +526,6 @@ void DecoderStream<StreamType>::OnDecoderReset() { // before the reset callback is fired. DCHECK(read_cb_.is_null()); DCHECK(!reset_cb_.is_null()); - DCHECK(stop_cb_.is_null()); if (state_ != STATE_FLUSHING_DECODER) { state_ = STATE_NORMAL; diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h index 32c1a28..c077a18 100644 --- a/media/filters/decoder_stream.h +++ b/media/filters/decoder_stream.h @@ -65,23 +65,16 @@ class MEDIA_EXPORT DecoderStream { // Reads a decoded Output and returns it via the |read_cb|. Note that // |read_cb| is always called asynchronously. This method should only be // called after initialization has succeeded and must not be called during - // any pending Reset() and/or Stop(). + // pending Reset(). void Read(const ReadCB& read_cb); // Resets the decoder, flushes all decoded outputs and/or internal buffers, // fires any existing pending read callback and calls |closure| on completion. // Note that |closure| is always called asynchronously. This method should // only be called after initialization has succeeded and must not be called - // during any pending Reset() and/or Stop(). + // during pending Reset(). void Reset(const base::Closure& closure); - // Stops the decoder, fires any existing pending read callback or reset - // callback and calls |closure| on completion. Note that |closure| is always - // called asynchronously. The DecoderStream cannot be used anymore after - // it is stopped. This method can be called at any time but not during another - // pending Stop(). - void Stop(const base::Closure& closure); - // Returns true if the decoder currently has the ability to decode and return // an Output. // TODO(rileya): Remove the need for this by refactoring Decoder queueing @@ -117,12 +110,11 @@ class MEDIA_EXPORT DecoderStream { enum State { STATE_UNINITIALIZED, STATE_INITIALIZING, - STATE_NORMAL, // Includes idle, pending decoder decode/reset/stop. + STATE_NORMAL, // Includes idle, pending decoder decode/reset. STATE_FLUSHING_DECODER, STATE_PENDING_DEMUXER_READ, STATE_REINITIALIZING_DECODER, STATE_END_OF_STREAM, // End of stream reached; returns EOS on all reads. - STATE_STOPPED, STATE_ERROR }; @@ -174,7 +166,6 @@ class MEDIA_EXPORT DecoderStream { ReadCB read_cb_; base::Closure reset_cb_; - base::Closure stop_cb_; DemuxerStream* stream_; bool low_delay_; diff --git a/media/filters/video_frame_stream_unittest.cc b/media/filters/video_frame_stream_unittest.cc index f249404..492e7cf 100644 --- a/media/filters/video_frame_stream_unittest.cc +++ b/media/filters/video_frame_stream_unittest.cc @@ -76,14 +76,19 @@ class VideoFrameStreamTest } ~VideoFrameStreamTest() { + // Check that the pipeline statistics callback was fired correctly. + if (decoder_) + EXPECT_EQ(decoder_->total_bytes_decoded(), total_bytes_decoded_); + + is_initialized_ = false; + decoder_ = NULL; + video_frame_stream_.reset(); + message_loop_.RunUntilIdle(); + DCHECK(!pending_initialize_); DCHECK(!pending_read_); DCHECK(!pending_reset_); DCHECK(!pending_stop_); - - if (is_initialized_) - Stop(); - EXPECT_FALSE(is_initialized_); } MOCK_METHOD1(OnNewSpliceBuffer, void(base::TimeDelta)); @@ -157,16 +162,6 @@ class VideoFrameStreamTest pending_reset_ = false; } - void OnStopped() { - DCHECK(!pending_initialize_); - DCHECK(!pending_read_); - DCHECK(!pending_reset_); - DCHECK(pending_stop_); - pending_stop_ = false; - is_initialized_ = false; - decoder_ = NULL; - } - void ReadOneFrame() { frame_read_ = NULL; pending_read_ = true; @@ -270,7 +265,7 @@ class VideoFrameStreamTest break; // These two cases are only interesting to test during - // VideoFrameStream::Stop(). There's no need to satisfy a callback. + // VideoFrameStream destruction. There's no need to satisfy a callback. case SET_DECRYPTOR: case DECRYPTOR_NO_KEY: NOTREACHED(); @@ -315,15 +310,6 @@ class VideoFrameStreamTest SatisfyPendingCallback(DECODER_RESET); } - void 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_; scoped_ptr<VideoFrameStream> video_frame_stream_; @@ -577,118 +563,98 @@ TEST_P(VideoFrameStreamTest, Reset_DuringNoKeyRead) { Reset(); } -TEST_P(VideoFrameStreamTest, Stop_BeforeInitialization) { - pending_stop_ = true; - video_frame_stream_->Stop( - base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this))); - message_loop_.RunUntilIdle(); +// In the following Destroy_* tests, |video_frame_stream_| is destroyed in +// VideoFrameStreamTest dtor. + +TEST_P(VideoFrameStreamTest, Destroy_BeforeInitialization) { } -TEST_P(VideoFrameStreamTest, Stop_DuringSetDecryptor) { +TEST_P(VideoFrameStreamTest, Destroy_DuringSetDecryptor) { if (!GetParam().is_encrypted) { DVLOG(1) << "SetDecryptor test only runs when the stream is encrytped."; return; } EnterPendingState(SET_DECRYPTOR); - pending_stop_ = true; - video_frame_stream_->Stop( - base::Bind(&VideoFrameStreamTest::OnStopped, base::Unretained(this))); - message_loop_.RunUntilIdle(); } -TEST_P(VideoFrameStreamTest, Stop_DuringInitialization) { +TEST_P(VideoFrameStreamTest, Destroy_DuringInitialization) { EnterPendingState(DECODER_INIT); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_AfterInitialization) { +TEST_P(VideoFrameStreamTest, Destroy_AfterInitialization) { Initialize(); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_DuringReinitialization) { +TEST_P(VideoFrameStreamTest, Destroy_DuringReinitialization) { Initialize(); EnterPendingState(DECODER_REINIT); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_AfterReinitialization) { +TEST_P(VideoFrameStreamTest, Destroy_AfterReinitialization) { Initialize(); EnterPendingState(DECODER_REINIT); SatisfyPendingCallback(DECODER_REINIT); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_Normal) { +TEST_P(VideoFrameStreamTest, Destroy_DuringDemuxerRead_Normal) { Initialize(); EnterPendingState(DEMUXER_READ_NORMAL); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_DuringDemuxerRead_ConfigChange) { +TEST_P(VideoFrameStreamTest, Destroy_DuringDemuxerRead_ConfigChange) { Initialize(); EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_DuringNormalDecoderDecode) { +TEST_P(VideoFrameStreamTest, Destroy_DuringNormalDecoderDecode) { Initialize(); EnterPendingState(DECODER_DECODE); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_AfterNormalRead) { +TEST_P(VideoFrameStreamTest, Destroy_AfterNormalRead) { Initialize(); Read(); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_AfterConfigChangeRead) { +TEST_P(VideoFrameStreamTest, Destroy_AfterConfigChangeRead) { Initialize(); EnterPendingState(DEMUXER_READ_CONFIG_CHANGE); SatisfyPendingCallback(DEMUXER_READ_CONFIG_CHANGE); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_DuringNoKeyRead) { +TEST_P(VideoFrameStreamTest, Destroy_DuringNoKeyRead) { Initialize(); EnterPendingState(DECRYPTOR_NO_KEY); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_DuringReset) { +TEST_P(VideoFrameStreamTest, Destroy_DuringReset) { Initialize(); EnterPendingState(DECODER_RESET); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_AfterReset) { +TEST_P(VideoFrameStreamTest, Destroy_AfterReset) { Initialize(); Reset(); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_DuringRead_DuringReset) { +TEST_P(VideoFrameStreamTest, Destroy_DuringRead_DuringReset) { Initialize(); EnterPendingState(DECODER_DECODE); EnterPendingState(DECODER_RESET); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_AfterRead_DuringReset) { +TEST_P(VideoFrameStreamTest, Destroy_AfterRead_DuringReset) { Initialize(); EnterPendingState(DECODER_DECODE); EnterPendingState(DECODER_RESET); SatisfyPendingCallback(DECODER_DECODE); - Stop(); } -TEST_P(VideoFrameStreamTest, Stop_AfterRead_AfterReset) { +TEST_P(VideoFrameStreamTest, Destroy_AfterRead_AfterReset) { Initialize(); Read(); Reset(); - Stop(); } TEST_P(VideoFrameStreamTest, DecoderErrorWhenReading) { diff --git a/media/filters/video_renderer_impl.cc b/media/filters/video_renderer_impl.cc index 1cbf1bc..a544bac 100644 --- a/media/filters/video_renderer_impl.cc +++ b/media/filters/video_renderer_impl.cc @@ -25,7 +25,9 @@ VideoRendererImpl::VideoRendererImpl( const PaintCB& paint_cb, bool drop_frames) : task_runner_(task_runner), - video_frame_stream_(task_runner, decoders.Pass(), set_decryptor_ready_cb), + video_frame_stream_(new VideoFrameStream(task_runner, + decoders.Pass(), + set_decryptor_ready_cb)), low_delay_(false), received_end_of_stream_(false), rendered_end_of_stream_(false), @@ -66,7 +68,7 @@ void VideoRendererImpl::Flush(const base::Closure& callback) { received_end_of_stream_ = false; rendered_end_of_stream_ = false; - video_frame_stream_.Reset( + video_frame_stream_->Reset( base::Bind(&VideoRendererImpl::OnVideoFrameStreamResetDone, weak_factory_.GetWeakPtr())); } @@ -75,7 +77,7 @@ void VideoRendererImpl::Stop(const base::Closure& callback) { DCHECK(task_runner_->BelongsToCurrentThread()); base::AutoLock auto_lock(lock_); if (state_ == kUninitialized || state_ == kStopped) { - callback.Run(); + task_runner_->PostTask(FROM_HERE, callback); return; } @@ -102,7 +104,8 @@ void VideoRendererImpl::Stop(const base::Closure& callback) { base::PlatformThread::Join(thread_to_join); } - video_frame_stream_.Stop(callback); + video_frame_stream_.reset(); + task_runner_->PostTask(FROM_HERE, callback); } void VideoRendererImpl::StartPlayingFrom(base::TimeDelta timestamp) { @@ -153,7 +156,7 @@ void VideoRendererImpl::Initialize(DemuxerStream* stream, get_duration_cb_ = get_duration_cb; state_ = kInitializing; - video_frame_stream_.Initialize( + video_frame_stream_->Initialize( stream, low_delay, statistics_cb, @@ -360,7 +363,7 @@ void VideoRendererImpl::FrameReady(VideoFrameStream::Status status, bool VideoRendererImpl::HaveEnoughData_Locked() { DCHECK_EQ(state_, kPlaying); return received_end_of_stream_ || - !video_frame_stream_.CanReadWithoutStalling() || + !video_frame_stream_->CanReadWithoutStalling() || ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames) || (low_delay_ && ready_frames_.size() > 0); } @@ -440,8 +443,8 @@ void VideoRendererImpl::AttemptRead_Locked() { switch (state_) { case kPlaying: pending_read_ = true; - video_frame_stream_.Read(base::Bind(&VideoRendererImpl::FrameReady, - weak_factory_.GetWeakPtr())); + video_frame_stream_->Read(base::Bind(&VideoRendererImpl::FrameReady, + weak_factory_.GetWeakPtr())); return; case kUninitialized: diff --git a/media/filters/video_renderer_impl.h b/media/filters/video_renderer_impl.h index 0f142be..06262da 100644 --- a/media/filters/video_renderer_impl.h +++ b/media/filters/video_renderer_impl.h @@ -8,6 +8,7 @@ #include <deque> #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "base/synchronization/condition_variable.h" @@ -123,7 +124,7 @@ class MEDIA_EXPORT VideoRendererImpl base::Lock lock_; // Provides video frames to VideoRendererImpl. - VideoFrameStream video_frame_stream_; + scoped_ptr<VideoFrameStream> video_frame_stream_; // Flag indicating low-delay mode. bool low_delay_; |