diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-20 06:01:16 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-20 06:01:16 +0000 |
commit | ff6256104abc7e766684f28ef4c42b945fd3225e (patch) | |
tree | 6ef0af0880affb4deb5139d594d787797be10eef /media/base/pipeline.cc | |
parent | 35daebe09bf03548ca99e58bc6ebb57d5b7a520d (diff) | |
download | chromium_src-ff6256104abc7e766684f28ef4c42b945fd3225e.zip chromium_src-ff6256104abc7e766684f28ef4c42b945fd3225e.tar.gz chromium_src-ff6256104abc7e766684f28ef4c42b945fd3225e.tar.bz2 |
Move AudioRenderer out of Filter heirarchy.
BUG=108341
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10753021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147619 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base/pipeline.cc')
-rw-r--r-- | media/base/pipeline.cc | 186 |
1 files changed, 104 insertions, 82 deletions
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc index 2b26541..1000747 100644 --- a/media/base/pipeline.cc +++ b/media/base/pipeline.cc @@ -17,6 +17,7 @@ #include "base/synchronization/condition_variable.h" #include "media/base/audio_decoder.h" #include "media/base/audio_renderer.h" +#include "media/base/callback_util.h" #include "media/base/clock.h" #include "media/base/composite_filter.h" #include "media/base/filter_collection.h" @@ -64,7 +65,6 @@ media::PipelineStatus PipelineStatusNotification::status() { struct Pipeline::PipelineInitState { scoped_refptr<AudioDecoder> audio_decoder; scoped_refptr<VideoDecoder> video_decoder; - scoped_refptr<AudioRenderer> audio_renderer; scoped_refptr<VideoRenderer> video_renderer; scoped_refptr<CompositeFilter> composite; }; @@ -317,6 +317,7 @@ bool Pipeline::IsPipelineSeeking() { } void Pipeline::ReportStatus(const PipelineStatusCB& cb, PipelineStatus status) { + DCHECK(message_loop_->BelongsToCurrentThread()); if (cb.is_null()) return; cb.Run(status); @@ -390,6 +391,14 @@ TimeDelta Pipeline::GetDuration() const { return GetMediaDuration(); } +void Pipeline::OnAudioDisabled() { + DCHECK(IsRunning()); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::AudioDisabledTask, this)); + media_log_->AddEvent( + media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); +} + void Pipeline::OnAudioTimeUpdate(TimeDelta time, TimeDelta max_time) { DCHECK(time <= max_time); DCHECK(IsRunning()); @@ -460,6 +469,61 @@ TimeDelta Pipeline::TimeForByteOffset_Locked(int64 byte_offset) const { return time_offset; } +void Pipeline::DoPause(const base::Closure& done_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); + + if (audio_renderer_) + closures->push(base::Bind(&AudioRenderer::Pause, audio_renderer_)); + + if (pipeline_filter_) + closures->push(base::Bind(&Filter::Pause, pipeline_filter_)); + + RunInSeries(closures.Pass(), done_cb); +} + +void Pipeline::DoFlush(const base::Closure& done_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); + + if (audio_renderer_) + closures->push(base::Bind(&AudioRenderer::Flush, audio_renderer_)); + + if (pipeline_filter_) + closures->push(base::Bind(&Filter::Flush, pipeline_filter_)); + + RunInParallel(closures.Pass(), done_cb); +} + +void Pipeline::DoPlay(const base::Closure& done_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); + + if (audio_renderer_) + closures->push(base::Bind(&AudioRenderer::Play, audio_renderer_)); + + if (pipeline_filter_) + closures->push(base::Bind(&Filter::Play, pipeline_filter_)); + + RunInSeries(closures.Pass(), done_cb); +} + +void Pipeline::DoStop(const base::Closure& done_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + scoped_ptr<std::queue<ClosureFunc> > closures(new std::queue<ClosureFunc>); + + if (demuxer_) + closures->push(base::Bind(&Demuxer::Stop, demuxer_)); + + if (audio_renderer_) + closures->push(base::Bind(&AudioRenderer::Stop, audio_renderer_)); + + if (pipeline_filter_) + closures->push(base::Bind(&Filter::Stop, pipeline_filter_)); + + RunInSeries(closures.Pass(), done_cb); +} + void Pipeline::AddBufferedByteRange(int64 start, int64 end) { DCHECK(IsRunning()); base::AutoLock auto_lock(lock_); @@ -491,16 +555,6 @@ void Pipeline::NotifyEnded() { media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); } -void Pipeline::DisableAudioRenderer() { - DCHECK(IsRunning()); - - // Disable renderer on the message loop. - message_loop_->PostTask(FROM_HERE, base::Bind( - &Pipeline::DisableAudioRendererTask, this)); - media_log_->AddEvent( - media_log_->CreateEvent(MediaLogEvent::AUDIO_RENDERER_DISABLED)); -} - // Called from any thread. void Pipeline::OnFilterInitialize(PipelineStatus status) { // Continue the initialize task by proceeding to the next stage. @@ -658,12 +712,13 @@ void Pipeline::InitializeTask(PipelineStatus last_stage_status) { PlaybackRateChangedTask(GetPlaybackRate()); VolumeChangedTask(GetVolume()); - // Fire a seek request to get the renderers to preroll. We don't need to - // tell the demuxer to seek since it should already be at the start. + // Fire a seek request to get the renderers to preroll. We can skip a seek + // here as the demuxer should be at the start of the stream. seek_pending_ = true; SetState(kSeeking); seek_timestamp_ = demuxer_->GetStartTime(); - OnDemuxerSeekDone(seek_timestamp_, PIPELINE_OK); + DoSeek(seek_timestamp_, true, + base::Bind(&Pipeline::OnFilterStateTransitionWithStatus, this)); } } @@ -752,9 +807,11 @@ void Pipeline::PlaybackRateChangedTask(float playback_rate) { // hasn't completed yet, the playback rate will be set when initialization // completes. if (pipeline_filter_) { - DCHECK(demuxer_); demuxer_->SetPlaybackRate(playback_rate); pipeline_filter_->SetPlaybackRate(playback_rate); + + if (audio_renderer_) + audio_renderer_->SetPlaybackRate(playback_rate_); } } @@ -800,8 +857,7 @@ void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) { if (clock_->IsPlaying()) clock_->Pause(); } - pipeline_filter_->Pause( - base::Bind(&Pipeline::OnFilterStateTransition, this)); + DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this)); } void Pipeline::NotifyEndedTask() { @@ -841,7 +897,7 @@ void Pipeline::NotifyEndedTask() { ReportStatus(ended_cb_, status_); } -void Pipeline::DisableAudioRendererTask() { +void Pipeline::AudioDisabledTask() { DCHECK(message_loop_->BelongsToCurrentThread()); base::AutoLock auto_lock(lock_); @@ -888,16 +944,14 @@ void Pipeline::FilterStateTransitionTask() { // Carry out the action for the current state. if (TransientState(state_)) { if (state_ == kPausing) { - pipeline_filter_->Pause( - base::Bind(&Pipeline::OnFilterStateTransition, this)); + DoPause(base::Bind(&Pipeline::OnFilterStateTransition, this)); } else if (state_ == kFlushing) { - pipeline_filter_->Flush( - base::Bind(&Pipeline::OnFilterStateTransition, this)); + DoFlush(base::Bind(&Pipeline::OnFilterStateTransition, this)); } else if (state_ == kSeeking) { - DoSeek(seek_timestamp_); + DoSeek(seek_timestamp_, false, + base::Bind(&Pipeline::OnFilterStateTransitionWithStatus, this)); } else if (state_ == kStarting) { - pipeline_filter_->Play( - base::Bind(&Pipeline::OnFilterStateTransition, this)); + DoPlay(base::Bind(&Pipeline::OnFilterStateTransition, this)); } else if (state_ == kStopping) { DoStop(base::Bind(&Pipeline::OnFilterStateTransition, this)); } else { @@ -943,8 +997,7 @@ void Pipeline::TeardownStateTransitionTask() { break; case kPausing: SetState(kFlushing); - pipeline_filter_->Flush( - base::Bind(&Pipeline::OnTeardownStateTransition, this)); + DoFlush(base::Bind(&Pipeline::OnTeardownStateTransition, this)); break; case kFlushing: SetState(kStopping); @@ -1092,23 +1145,20 @@ bool Pipeline::InitializeAudioRenderer( if (!decoder) return false; - filter_collection_->SelectAudioRenderer( - &pipeline_init_state_->audio_renderer); - if (!pipeline_init_state_->audio_renderer) { + filter_collection_->SelectAudioRenderer(&audio_renderer_); + if (!audio_renderer_) { SetError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING); return false; } - pipeline_init_state_->composite->AddFilter( - pipeline_init_state_->audio_renderer); - - pipeline_init_state_->audio_renderer->Initialize( + audio_renderer_->Initialize( decoder, base::Bind(&Pipeline::OnFilterInitialize, this), base::Bind(&Pipeline::OnAudioUnderflow, this), - base::Bind(&Pipeline::OnAudioTimeUpdate, this)); - - audio_renderer_ = pipeline_init_state_->audio_renderer; + base::Bind(&Pipeline::OnAudioTimeUpdate, this), + base::Bind(&Pipeline::NotifyEnded, this), + base::Bind(&Pipeline::OnAudioDisabled, this), + base::Bind(&Pipeline::SetError, this)); return true; } @@ -1194,8 +1244,7 @@ void Pipeline::TearDownPipeline() { case kStarted: case kEnded: SetState(kPausing); - pipeline_filter_->Pause( - base::Bind(&Pipeline::OnTeardownStateTransition, this)); + DoPause(base::Bind(&Pipeline::OnTeardownStateTransition, this)); break; case kStopping: @@ -1207,53 +1256,26 @@ void Pipeline::TearDownPipeline() { }; } -void Pipeline::DoStop(const base::Closure& callback) { - if (demuxer_) { - demuxer_->Stop(base::Bind( - &Pipeline::OnDemuxerStopDone, this, callback)); - return; - } - - OnDemuxerStopDone(callback); -} - -void Pipeline::OnDemuxerStopDone(const base::Closure& callback) { - if (!message_loop_->BelongsToCurrentThread()) { - message_loop_->PostTask(FROM_HERE, base::Bind( - &Pipeline::OnDemuxerStopDone, this, callback)); - return; - } - - if (pipeline_filter_) { - pipeline_filter_->Stop(callback); - return; - } - - callback.Run(); -} - -void Pipeline::DoSeek(TimeDelta seek_timestamp) { - demuxer_->Seek(seek_timestamp, base::Bind( - &Pipeline::OnDemuxerSeekDone, this, seek_timestamp)); -} +void Pipeline::DoSeek(base::TimeDelta seek_timestamp, + bool skip_demuxer_seek, + const PipelineStatusCB& done_cb) { + DCHECK(message_loop_->BelongsToCurrentThread()); + scoped_ptr<std::queue<PipelineStatusCBFunc> > status_cbs( + new std::queue<PipelineStatusCBFunc>()); -void Pipeline::OnDemuxerSeekDone(TimeDelta seek_timestamp, - PipelineStatus status) { - if (!message_loop_->BelongsToCurrentThread()) { - message_loop_->PostTask(FROM_HERE, base::Bind( - &Pipeline::OnDemuxerSeekDone, this, seek_timestamp, status)); - return; - } + if (!skip_demuxer_seek) + status_cbs->push(base::Bind(&Demuxer::Seek, demuxer_, seek_timestamp)); - PipelineStatusCB done_cb = - base::Bind(&Pipeline::OnFilterStateTransitionWithStatus, this); + if (audio_renderer_) + status_cbs->push(base::Bind( + &AudioRenderer::Seek, audio_renderer_, seek_timestamp)); - if (status == PIPELINE_OK && pipeline_filter_) { - pipeline_filter_->Seek(seek_timestamp, done_cb); - return; - } + if (pipeline_filter_) + status_cbs->push(base::Bind( + &Filter::Seek, pipeline_filter_, seek_timestamp)); - ReportStatus(done_cb, status); + RunInSeriesWithStatus(status_cbs.Pass(), base::Bind( + &Pipeline::ReportStatus, this, done_cb)); } void Pipeline::OnAudioUnderflow() { |