summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/base/clock.cc24
-rw-r--r--media/base/clock.h7
-rw-r--r--media/base/pipeline.cc51
-rw-r--r--media/base/pipeline.h17
-rw-r--r--media/base/pipeline_unittest.cc19
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);