Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(346)

Unified Diff: media/base/pipeline.cc

Issue 10834236: Replace Pipeline::kEnded state and HasEnded() methods with renderer-specific bools. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/pipeline.cc
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index 470f1868e734b483ea57375a7cd4fad05735712b..e99b70afca32a9165d88f57db3af63ef167193e7 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -88,6 +88,8 @@ Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log)
has_video_(false),
state_(kCreated),
seek_timestamp_(kNoTimestamp()),
+ audio_ended_(false),
+ video_ended_(false),
audio_disabled_(false),
creation_time_(base::Time::Now()) {
media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
@@ -151,7 +153,6 @@ bool Pipeline::IsInitialized() const {
case kSeeking:
case kStarting:
case kStarted:
- case kEnded:
return true;
default:
return false;
@@ -527,11 +528,18 @@ void Pipeline::OnNaturalVideoSizeChanged(const gfx::Size& size) {
natural_size_ = size;
}
-void Pipeline::OnRendererEnded() {
- DCHECK(IsRunning());
+void Pipeline::OnAudioRendererEnded() {
+ // Force post to process ended messages after current execution frame.
+ message_loop_->PostTask(FROM_HERE, base::Bind(
+ &Pipeline::DoAudioRendererEnded, this));
+ media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::AUDIO_ENDED));
+}
+
+void Pipeline::OnVideoRendererEnded() {
+ // Force post to process ended messages after current execution frame.
message_loop_->PostTask(FROM_HERE, base::Bind(
- &Pipeline::OnRendererEndedTask, this));
- media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED));
+ &Pipeline::DoVideoRendererEnded, this));
+ media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::VIDEO_ENDED));
}
// Called from any thread.
@@ -796,7 +804,7 @@ void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) {
DCHECK(!IsPipelineStopPending());
// Suppress seeking if we're not fully started.
- if (state_ != kStarted && state_ != kEnded) {
+ if (state_ != kStarted) {
// TODO(scherkus): should we run the callback? I'm tempted to say the API
// will only execute the first Seek() request.
DVLOG(1) << "Media pipeline has not started, ignoring seek to "
@@ -809,12 +817,14 @@ void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) {
// We'll need to pause every filter before seeking. The state transition
// is as follows:
- // kStarted/kEnded
+ // kStarted
// kPausing (for each filter)
// kSeeking (for each filter)
// kStarting (for each filter)
// kStarted
SetState(kPausing);
+ audio_ended_ = false;
+ video_ended_ = false;
seek_timestamp_ = std::max(time, demuxer_->GetStartTime());
seek_cb_ = seek_cb;
@@ -827,35 +837,46 @@ void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) {
DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this));
}
-void Pipeline::OnRendererEndedTask() {
+void Pipeline::DoAudioRendererEnded() {
DCHECK(message_loop_->BelongsToCurrentThread());
- // We can only end if we were actually playing.
- if (state_ != kStarted) {
+ if (state_ != kStarted)
return;
- }
- DCHECK(audio_renderer_ || video_renderer_);
+ DCHECK(!audio_ended_);
+ audio_ended_ = true;
- // Make sure every extant renderer has ended.
- if (audio_renderer_ && !audio_disabled_) {
- if (!audio_renderer_->HasEnded()) {
- return;
- }
-
- // Start clock since there is no more audio to
- // trigger clock updates.
+ // Start clock since there is no more audio to trigger clock updates.
+ if (!audio_disabled_) {
base::AutoLock auto_lock(lock_);
clock_->SetMaxTime(clock_->Duration());
StartClockIfWaitingForTimeUpdate_Locked();
}
- if (video_renderer_ && !video_renderer_->HasEnded()) {
+ RunEndedCallbackIfNeeded();
+}
+
+void Pipeline::DoVideoRendererEnded() {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
+ if (state_ != kStarted)
+ return;
+
+ DCHECK(!video_ended_);
+ video_ended_ = true;
+
+ RunEndedCallbackIfNeeded();
+}
+
+void Pipeline::RunEndedCallbackIfNeeded() {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
+ if (audio_renderer_ && !audio_ended_ && !audio_disabled_)
+ return;
+
+ if (video_renderer_ && !video_ended_)
return;
- }
- // Transition to ended, executing the callback if present.
- SetState(kEnded);
{
base::AutoLock auto_lock(lock_);
clock_->EndOfStream();
@@ -990,7 +1011,6 @@ void Pipeline::TeardownStateTransitionTask() {
case kStarting:
case kStopped:
case kStarted:
- case kEnded:
NOTREACHED() << "Unexpected state for teardown: " << state_;
break;
// default: intentionally left out to force new states to cause compiler
@@ -1132,7 +1152,7 @@ bool Pipeline::InitializeAudioRenderer(
base::Bind(&Pipeline::OnFilterInitialize, this),
base::Bind(&Pipeline::OnAudioUnderflow, this),
base::Bind(&Pipeline::OnAudioTimeUpdate, this),
- base::Bind(&Pipeline::OnRendererEnded, this),
+ base::Bind(&Pipeline::OnAudioRendererEnded, this),
base::Bind(&Pipeline::OnAudioDisabled, this),
base::Bind(&Pipeline::SetError, this));
return true;
@@ -1158,7 +1178,7 @@ bool Pipeline::InitializeVideoRenderer(
base::Bind(&Pipeline::OnUpdateStatistics, this),
base::Bind(&Pipeline::OnVideoTimeUpdate, this),
base::Bind(&Pipeline::OnNaturalVideoSizeChanged, this),
- base::Bind(&Pipeline::OnRendererEnded, this),
+ base::Bind(&Pipeline::OnVideoRendererEnded, this),
base::Bind(&Pipeline::SetError, this),
base::Bind(&Pipeline::GetMediaTime, this),
base::Bind(&Pipeline::GetMediaDuration, this));
@@ -1219,7 +1239,6 @@ void Pipeline::TearDownPipeline() {
break;
case kStarted:
- case kEnded:
SetState(kPausing);
DoPause(base::Bind(&Pipeline::OnTeardownStateTransition, this));
break;
« no previous file with comments | « media/base/pipeline.h ('k') | media/base/pipeline_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698