diff options
-rw-r--r-- | media/base/clock.cc | 24 | ||||
-rw-r--r-- | media/base/clock.h | 7 | ||||
-rw-r--r-- | media/base/pipeline.cc | 51 | ||||
-rw-r--r-- | media/base/pipeline.h | 17 | ||||
-rw-r--r-- | media/base/pipeline_unittest.cc | 19 |
5 files changed, 56 insertions, 62 deletions
diff --git a/media/base/clock.cc b/media/base/clock.cc index ea95483..3dc49e9 100644 --- a/media/base/clock.cc +++ b/media/base/clock.cc @@ -12,9 +12,14 @@ namespace media { -Clock::Clock(base::TickClock* clock) : clock_(clock) { +Clock::Clock(base::TickClock* clock) + : clock_(clock), + playing_(false), + underflow_(false), + playback_rate_(1.0f), + max_time_(kNoTimestamp()), + duration_(kNoTimestamp()) { DCHECK(clock_); - Reset(); } Clock::~Clock() {} @@ -103,11 +108,6 @@ base::TimeDelta Clock::ClampToValidTimeRange(base::TimeDelta time) const { return std::max(std::min(time, duration_), base::TimeDelta()); } -void Clock::EndOfStream() { - Pause(); - SetTime(Duration(), Duration()); -} - base::TimeDelta Clock::Duration() const { if (duration_ == kNoTimestamp()) return base::TimeDelta(); @@ -127,14 +127,4 @@ base::TimeDelta Clock::EstimatedElapsedTime() { return ClampToValidTimeRange(ElapsedViaProvidedTime(clock_->NowTicks())); } -void Clock::Reset() { - playing_ = false; - playback_rate_ = 1.0f; - max_time_ = kNoTimestamp(); - duration_ = kNoTimestamp(); - media_time_ = base::TimeDelta(); - reference_ = base::TimeTicks(); - underflow_ = false; -} - } // namespace media diff --git a/media/base/clock.h b/media/base/clock.h index 01449be..fbd7ca1 100644 --- a/media/base/clock.h +++ b/media/base/clock.h @@ -70,13 +70,6 @@ class MEDIA_EXPORT Clock { // exactly once. void SetDuration(base::TimeDelta duration); - // Resets clock to an uninitialized state. - void Reset(); - - // Notifies the clock that the end of stream has been reached. The clock state - // is updated accordingly. - void EndOfStream(); - // Returns the duration of the clock, or 0 if not set. base::TimeDelta Duration() const; diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc index e177e18..5cfc144 100644 --- a/media/base/pipeline.cc +++ b/media/base/pipeline.cc @@ -42,7 +42,7 @@ Pipeline::Pipeline( volume_(1.0f), playback_rate_(0.0f), clock_(new Clock(&default_tick_clock_)), - waiting_for_clock_update_(false), + clock_state_(CLOCK_PAUSED), status_(PIPELINE_OK), state_(kCreated), audio_ended_(false), @@ -297,8 +297,10 @@ void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { DCHECK(IsRunning()); base::AutoLock auto_lock(lock_); - if (waiting_for_clock_update_ && time < clock_->Elapsed()) + if (clock_state_ == CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE && + time < clock_->Elapsed()) { return; + } // TODO(scherkus): |state_| should only be accessed on pipeline thread, see // http://crbug.com/137973 @@ -321,7 +323,7 @@ void Pipeline::OnVideoTimeUpdate(TimeDelta max_time) { if (state_ == kSeeking) return; - DCHECK(!waiting_for_clock_update_); + DCHECK_NE(clock_state_, CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE); clock_->SetMaxTime(max_time); } @@ -753,12 +755,8 @@ void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) { // Kick off seeking! { - if (audio_renderer_) - audio_renderer_->StopRendering(); - base::AutoLock auto_lock(lock_); - if (clock_->IsPlaying()) - clock_->Pause(); + PauseClockAndStopRendering_Locked(); clock_->SetTime(seek_timestamp, seek_timestamp); } DoSeek(seek_timestamp, base::Bind( @@ -822,7 +820,8 @@ void Pipeline::RunEndedCallbackIfNeeded() { { base::AutoLock auto_lock(lock_); - clock_->EndOfStream(); + PauseClockAndStopRendering_Locked(); + clock_->SetTime(clock_->Duration(), clock_->Duration()); } DCHECK_EQ(status_, PIPELINE_OK); @@ -931,27 +930,25 @@ void Pipeline::StartWaitingForEnoughData() { DCHECK_EQ(state_, kPlaying); DCHECK(WaitingForEnoughData()); - if (audio_renderer_) - audio_renderer_->StopRendering(); - base::AutoLock auto_lock(lock_); - clock_->Pause(); + PauseClockAndStopRendering_Locked(); } void Pipeline::StartPlayback() { DVLOG(1) << __FUNCTION__; DCHECK_EQ(state_, kPlaying); + DCHECK_EQ(clock_state_, CLOCK_PAUSED); DCHECK(!WaitingForEnoughData()); if (audio_renderer_) { // We use audio stream to update the clock. So if there is such a // stream, we pause the clock until we receive a valid timestamp. base::AutoLock auto_lock(lock_); - waiting_for_clock_update_ = true; + clock_state_ = CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE; audio_renderer_->StartRendering(); } else { base::AutoLock auto_lock(lock_); - DCHECK(!waiting_for_clock_update_); + clock_state_ = CLOCK_PLAYING; clock_->SetMaxTime(clock_->Duration()); clock_->Play(); } @@ -961,12 +958,32 @@ void Pipeline::StartPlayback() { base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); } +void Pipeline::PauseClockAndStopRendering_Locked() { + lock_.AssertAcquired(); + switch (clock_state_) { + case CLOCK_PAUSED: + return; + + case CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE: + audio_renderer_->StopRendering(); + break; + + case CLOCK_PLAYING: + if (audio_renderer_) + audio_renderer_->StopRendering(); + clock_->Pause(); + break; + } + + clock_state_ = CLOCK_PAUSED; +} + void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { lock_.AssertAcquired(); - if (!waiting_for_clock_update_) + if (clock_state_ != CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE) return; - waiting_for_clock_update_ = false; + clock_state_ = CLOCK_PLAYING; clock_->Play(); } diff --git a/media/base/pipeline.h b/media/base/pipeline.h index 06bffba..b40cd3c 100644 --- a/media/base/pipeline.h +++ b/media/base/pipeline.h @@ -326,6 +326,7 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost { void StartWaitingForEnoughData(); void StartPlayback(); + void PauseClockAndStopRendering_Locked(); void StartClockIfWaitingForTimeUpdate_Locked(); // Task runner used to execute pipeline tasks. @@ -365,10 +366,18 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost { // by filters. scoped_ptr<Clock> clock_; - // If this value is set to true, then |clock_| is paused and we are waiting - // for an update of the clock greater than or equal to the elapsed time to - // start the clock. - bool waiting_for_clock_update_; + enum ClockState { + // Audio (if present) is not rendering. Clock isn't playing. + CLOCK_PAUSED, + + // Audio (if present) is rendering. Clock isn't playing. + CLOCK_WAITING_FOR_AUDIO_TIME_UPDATE, + + // Audio (if present) is rendering. Clock is playing. + CLOCK_PLAYING, + }; + + ClockState clock_state_; // Status of the pipeline. Initialized to PIPELINE_OK which indicates that // the pipeline is operating correctly. Any other value indicates that the diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc index e1f1e56..45cc73ba3 100644 --- a/media/base/pipeline_unittest.cc +++ b/media/base/pipeline_unittest.cc @@ -596,6 +596,7 @@ TEST_F(PipelineTest, EndedCallback) { pipeline_->OnVideoRendererEnded(); message_loop_.RunUntilIdle(); + EXPECT_CALL(*audio_renderer_, StopRendering()); EXPECT_CALL(callbacks_, OnEnded()); text_stream()->SendEosNotification(); message_loop_.RunUntilIdle(); @@ -645,6 +646,7 @@ TEST_F(PipelineTest, AudioStreamShorterThanVideo) { EXPECT_GT(pipeline_->GetMediaTime().ToInternalValue(), start_time); // Signal end of video stream and make sure OnEnded() callback occurs. + EXPECT_CALL(*audio_renderer_, StopRendering()); EXPECT_CALL(callbacks_, OnEnded()); pipeline_->OnVideoRendererEnded(); } @@ -858,7 +860,6 @@ class PipelineTeardownTest : public PipelineTest { kInitDemuxer, kInitAudioRenderer, kInitVideoRenderer, - kPausing, kFlushing, kSeeking, kPrerolling, @@ -882,7 +883,6 @@ class PipelineTeardownTest : public PipelineTest { DoInitialize(state, stop_or_error); break; - case kPausing: case kFlushing: case kSeeking: case kPrerolling: @@ -1035,19 +1035,6 @@ class PipelineTeardownTest : public PipelineTest { base::Closure stop_cb = base::Bind( &CallbackHelper::OnStop, base::Unretained(&callbacks_)); - if (state == kPausing) { - if (stop_or_error == kStop) { - EXPECT_CALL(*audio_renderer_, StopRendering()) - .WillOnce(Stop(pipeline_.get(), stop_cb)); - } else { - status = PIPELINE_ERROR_READ; - EXPECT_CALL(*audio_renderer_, StopRendering()) - .WillOnce(SetError(pipeline_.get(), status)); - } - - return status; - } - EXPECT_CALL(*audio_renderer_, StopRendering()); if (state == kFlushing) { @@ -1152,7 +1139,6 @@ class PipelineTeardownTest : public PipelineTest { INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer); INSTANTIATE_TEARDOWN_TEST(Stop, InitAudioRenderer); INSTANTIATE_TEARDOWN_TEST(Stop, InitVideoRenderer); -INSTANTIATE_TEARDOWN_TEST(Stop, Pausing); INSTANTIATE_TEARDOWN_TEST(Stop, Flushing); INSTANTIATE_TEARDOWN_TEST(Stop, Seeking); INSTANTIATE_TEARDOWN_TEST(Stop, Prerolling); @@ -1161,7 +1147,6 @@ INSTANTIATE_TEARDOWN_TEST(Stop, Playing); INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); INSTANTIATE_TEARDOWN_TEST(Error, InitAudioRenderer); INSTANTIATE_TEARDOWN_TEST(Error, InitVideoRenderer); -INSTANTIATE_TEARDOWN_TEST(Error, Pausing); INSTANTIATE_TEARDOWN_TEST(Error, Flushing); INSTANTIATE_TEARDOWN_TEST(Error, Seeking); INSTANTIATE_TEARDOWN_TEST(Error, Prerolling); |