diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-18 09:30:32 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-18 09:30:32 +0000 |
commit | d399866c2fe77410afed5be486f2b72581823bed (patch) | |
tree | b7da4bc8b767ed87053ce974642598db1d1a6b4a /media | |
parent | 12bb3e11aac582a23034e3538a689e9a3a28da86 (diff) | |
download | chromium_src-d399866c2fe77410afed5be486f2b72581823bed.zip chromium_src-d399866c2fe77410afed5be486f2b72581823bed.tar.gz chromium_src-d399866c2fe77410afed5be486f2b72581823bed.tar.bz2 |
Fold media::PipelineImpl into media::Pipeline as there is only one implementation of the interface.
Three years ago I thought that having a separate interface would be A Good Thing. Needless to say there has never been a case where having an interface defintion of Pipeline came in handy as all clients create and access PipelineImpl objects directly.
Review URL: http://codereview.chromium.org/9243025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118082 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/filter_host.h | 8 | ||||
-rw-r--r-- | media/base/media_log.cc | 35 | ||||
-rw-r--r-- | media/base/media_log.h | 6 | ||||
-rw-r--r-- | media/base/media_log_event.h | 6 | ||||
-rw-r--r-- | media/base/pipeline.cc (renamed from media/base/pipeline_impl.cc) | 303 | ||||
-rw-r--r-- | media/base/pipeline.h | 536 | ||||
-rw-r--r-- | media/base/pipeline_impl.h | 518 | ||||
-rw-r--r-- | media/base/pipeline_unittest.cc (renamed from media/base/pipeline_impl_unittest.cc) | 59 | ||||
-rw-r--r-- | media/filters/ffmpeg_audio_decoder.cc | 3 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 3 | ||||
-rw-r--r-- | media/filters/gpu_video_decoder.cc | 3 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test.cc | 7 | ||||
-rw-r--r-- | media/filters/video_renderer_base.cc | 1 | ||||
-rw-r--r-- | media/media.gyp | 5 | ||||
-rw-r--r-- | media/tools/player_wtl/movie.cc | 6 | ||||
-rw-r--r-- | media/tools/player_wtl/movie.h | 6 | ||||
-rw-r--r-- | media/tools/player_wtl/player_wtl.cc | 4 | ||||
-rw-r--r-- | media/tools/player_x11/player_x11.cc | 10 |
18 files changed, 729 insertions, 790 deletions
diff --git a/media/base/filter_host.h b/media/base/filter_host.h index 864bc99..4719618 100644 --- a/media/base/filter_host.h +++ b/media/base/filter_host.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -17,8 +17,10 @@ #ifndef MEDIA_BASE_FILTER_HOST_H_ #define MEDIA_BASE_FILTER_HOST_H_ -#include "media/base/filters.h" -#include "media/base/pipeline.h" +#include "base/time.h" +#include "media/base/media_export.h" +#include "media/base/pipeline_status.h" +#include "ui/gfx/size.h" namespace media { diff --git a/media/base/media_log.cc b/media/base/media_log.cc index 43d9278..d223b51 100644 --- a/media/base/media_log.cc +++ b/media/base/media_log.cc @@ -11,6 +11,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" #include "base/values.h" namespace media { @@ -65,37 +66,37 @@ const char* MediaLog::EventTypeToString(MediaLogEvent::Type type) { return NULL; } -const char* MediaLog::PipelineStateToString(PipelineImpl::State state) { +const char* MediaLog::PipelineStateToString(Pipeline::State state) { switch (state) { - case PipelineImpl::kCreated: + case Pipeline::kCreated: return "created"; - case PipelineImpl::kInitDemuxer: + case Pipeline::kInitDemuxer: return "initDemuxer"; - case PipelineImpl::kInitAudioDecoder: + case Pipeline::kInitAudioDecoder: return "initAudioDecoder"; - case PipelineImpl::kInitAudioRenderer: + case Pipeline::kInitAudioRenderer: return "initAudioRenderer"; - case PipelineImpl::kInitVideoDecoder: + case Pipeline::kInitVideoDecoder: return "initVideoDecoder"; - case PipelineImpl::kInitVideoRenderer: + case Pipeline::kInitVideoRenderer: return "initVideoRenderer"; - case PipelineImpl::kPausing: + case Pipeline::kPausing: return "pausing"; - case PipelineImpl::kSeeking: + case Pipeline::kSeeking: return "seeking"; - case PipelineImpl::kFlushing: + case Pipeline::kFlushing: return "flushing"; - case PipelineImpl::kStarting: + case Pipeline::kStarting: return "starting"; - case PipelineImpl::kStarted: + case Pipeline::kStarted: return "started"; - case PipelineImpl::kEnded: + case Pipeline::kEnded: return "ended"; - case PipelineImpl::kStopping: + case Pipeline::kStopping: return "stopping"; - case PipelineImpl::kStopped: + case Pipeline::kStopped: return "stopped"; - case PipelineImpl::kError: + case Pipeline::kError: return "error"; } NOTREACHED(); @@ -199,7 +200,7 @@ scoped_ptr<MediaLogEvent> MediaLog::CreateSeekEvent(float seconds) { } scoped_ptr<MediaLogEvent> MediaLog::CreatePipelineStateChangedEvent( - PipelineImpl::State state) { + Pipeline::State state) { scoped_ptr<MediaLogEvent> event( CreateEvent(MediaLogEvent::PIPELINE_STATE_CHANGED)); event->params.SetString("pipeline_state", PipelineStateToString(state)); diff --git a/media/base/media_log.h b/media/base/media_log.h index 236c533..9b87361b 100644 --- a/media/base/media_log.h +++ b/media/base/media_log.h @@ -10,7 +10,7 @@ #include "base/synchronization/lock.h" #include "media/base/media_export.h" #include "media/base/media_log_event.h" -#include "media/base/pipeline_impl.h" +#include "media/base/pipeline.h" #include "media/base/pipeline_status.h" namespace media { @@ -19,7 +19,7 @@ class MEDIA_EXPORT MediaLog : public base::RefCountedThreadSafe<MediaLog> { public: // Convert various enums to strings. static const char* EventTypeToString(MediaLogEvent::Type type); - static const char* PipelineStateToString(PipelineImpl::State); + static const char* PipelineStateToString(Pipeline::State); static const char* PipelineStatusToString(PipelineStatus); MediaLog(); @@ -39,7 +39,7 @@ class MEDIA_EXPORT MediaLog : public base::RefCountedThreadSafe<MediaLog> { scoped_ptr<MediaLogEvent> CreateLoadEvent(const std::string& url); scoped_ptr<MediaLogEvent> CreateSeekEvent(float seconds); scoped_ptr<MediaLogEvent> CreatePipelineStateChangedEvent( - PipelineImpl::State state); + Pipeline::State state); scoped_ptr<MediaLogEvent> CreatePipelineErrorEvent(PipelineStatus error); scoped_ptr<MediaLogEvent> CreateVideoSizeSetEvent( size_t width, size_t height); diff --git a/media/base/media_log_event.h b/media/base/media_log_event.h index 384a2e3..4167c893 100644 --- a/media/base/media_log_event.h +++ b/media/base/media_log_event.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,7 +18,7 @@ struct MediaLogEvent { WEBMEDIAPLAYER_CREATED, WEBMEDIAPLAYER_DESTROYED, - // A PipelineImpl is being created or destroyed. + // A Pipeline is being created or destroyed. // params: none. PIPELINE_CREATED, PIPELINE_DESTROYED, @@ -36,7 +36,7 @@ struct MediaLogEvent { PLAY, PAUSE, - // The state of PipelineImpl has changed. + // The state of Pipeline has changed. // params: "pipeline_state": <string name of the state>. PIPELINE_STATE_CHANGED, diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline.cc index 307976e..2eeefff 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline.cc @@ -1,11 +1,8 @@ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// -// TODO(scherkus): clean up PipelineImpl... too many crazy function names, -// potential deadlocks, etc... -#include "media/base/pipeline_impl.h" +#include "media/base/pipeline.h" #include <algorithm> @@ -13,10 +10,12 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/metrics/histogram.h" +#include "base/message_loop.h" #include "base/stl_util.h" #include "base/string_util.h" #include "base/synchronization/condition_variable.h" #include "media/base/clock.h" +#include "media/base/composite_filter.h" #include "media/base/filter_collection.h" #include "media/base/media_log.h" @@ -55,14 +54,14 @@ media::PipelineStatus PipelineStatusNotification::status() { return status_; } -class PipelineImpl::PipelineInitState { +class Pipeline::PipelineInitState { public: scoped_refptr<AudioDecoder> audio_decoder_; scoped_refptr<VideoDecoder> video_decoder_; scoped_refptr<CompositeFilter> composite_; }; -PipelineImpl::PipelineImpl(MessageLoop* message_loop, MediaLog* media_log) +Pipeline::Pipeline(MessageLoop* message_loop, MediaLog* media_log) : message_loop_(message_loop), media_log_(media_log), clock_(new Clock(&base::Time::Now)), @@ -77,7 +76,7 @@ PipelineImpl::PipelineImpl(MessageLoop* message_loop, MediaLog* media_log) media_log_->CreateEvent(MediaLogEvent::PIPELINE_CREATED)); } -PipelineImpl::~PipelineImpl() { +Pipeline::~Pipeline() { base::AutoLock auto_lock(lock_); DCHECK(!running_) << "Stop() must complete before destroying object"; DCHECK(!stop_pending_); @@ -87,7 +86,7 @@ PipelineImpl::~PipelineImpl() { media_log_->CreateEvent(MediaLogEvent::PIPELINE_DESTROYED)); } -void PipelineImpl::Init(const PipelineStatusCB& ended_callback, +void Pipeline::Init(const PipelineStatusCB& ended_callback, const PipelineStatusCB& error_callback, const NetworkEventCB& network_callback) { DCHECK(!IsRunning()) @@ -98,7 +97,7 @@ void PipelineImpl::Init(const PipelineStatusCB& ended_callback, } // Creates the PipelineInternal and calls it's start method. -bool PipelineImpl::Start(scoped_ptr<FilterCollection> collection, +bool Pipeline::Start(scoped_ptr<FilterCollection> collection, const std::string& url, const PipelineStatusCB& start_callback) { base::AutoLock auto_lock(lock_); @@ -114,16 +113,13 @@ bool PipelineImpl::Start(scoped_ptr<FilterCollection> collection, // Kick off initialization! running_ = true; - message_loop_->PostTask( - FROM_HERE, - base::Bind(&PipelineImpl::StartTask, this, - base::Passed(&collection), - url, - start_callback)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::StartTask, this, base::Passed(&collection), + url, start_callback)); return true; } -void PipelineImpl::Stop(const PipelineStatusCB& stop_callback) { +void Pipeline::Stop(const PipelineStatusCB& stop_callback) { base::AutoLock auto_lock(lock_); if (!running_) { VLOG(1) << "Media pipeline has already stopped"; @@ -136,11 +132,11 @@ void PipelineImpl::Stop(const PipelineStatusCB& stop_callback) { } // Stop the pipeline, which will set |running_| to false on our behalf. - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::StopTask, this, stop_callback)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::StopTask, this, stop_callback)); } -void PipelineImpl::Seek(base::TimeDelta time, +void Pipeline::Seek(base::TimeDelta time, const PipelineStatusCB& seek_callback) { base::AutoLock auto_lock(lock_); if (!running_) { @@ -150,16 +146,16 @@ void PipelineImpl::Seek(base::TimeDelta time, download_rate_monitor_.Stop(); - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::SeekTask, this, time, seek_callback)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::SeekTask, this, time, seek_callback)); } -bool PipelineImpl::IsRunning() const { +bool Pipeline::IsRunning() const { base::AutoLock auto_lock(lock_); return running_; } -bool PipelineImpl::IsInitialized() const { +bool Pipeline::IsInitialized() const { // TODO(scherkus): perhaps replace this with a bool that is set/get under the // lock, because this is breaching the contract that |state_| is only accessed // on |message_loop_|. @@ -177,22 +173,22 @@ bool PipelineImpl::IsInitialized() const { } } -bool PipelineImpl::HasAudio() const { +bool Pipeline::HasAudio() const { base::AutoLock auto_lock(lock_); return has_audio_; } -bool PipelineImpl::HasVideo() const { +bool Pipeline::HasVideo() const { base::AutoLock auto_lock(lock_); return has_video_; } -float PipelineImpl::GetPlaybackRate() const { +float Pipeline::GetPlaybackRate() const { base::AutoLock auto_lock(lock_); return playback_rate_; } -void PipelineImpl::SetPlaybackRate(float playback_rate) { +void Pipeline::SetPlaybackRate(float playback_rate) { if (playback_rate < 0.0f) return; @@ -200,16 +196,16 @@ void PipelineImpl::SetPlaybackRate(float playback_rate) { playback_rate_ = playback_rate; if (running_ && !tearing_down_) { message_loop_->PostTask(FROM_HERE, base::Bind( - &PipelineImpl::PlaybackRateChangedTask, this, playback_rate)); + &Pipeline::PlaybackRateChangedTask, this, playback_rate)); } } -float PipelineImpl::GetVolume() const { +float Pipeline::GetVolume() const { base::AutoLock auto_lock(lock_); return volume_; } -void PipelineImpl::SetVolume(float volume) { +void Pipeline::SetVolume(float volume) { if (volume < 0.0f || volume > 1.0f) return; @@ -217,30 +213,30 @@ void PipelineImpl::SetVolume(float volume) { volume_ = volume; if (running_ && !tearing_down_) { message_loop_->PostTask(FROM_HERE, base::Bind( - &PipelineImpl::VolumeChangedTask, this, volume)); + &Pipeline::VolumeChangedTask, this, volume)); } } -Preload PipelineImpl::GetPreload() const { +Preload Pipeline::GetPreload() const { base::AutoLock auto_lock(lock_); return preload_; } -void PipelineImpl::SetPreload(Preload preload) { +void Pipeline::SetPreload(Preload preload) { base::AutoLock auto_lock(lock_); preload_ = preload; if (running_ && !tearing_down_) { message_loop_->PostTask(FROM_HERE, base::Bind( - &PipelineImpl::PreloadChangedTask, this, preload)); + &Pipeline::PreloadChangedTask, this, preload)); } } -base::TimeDelta PipelineImpl::GetCurrentTime() const { +base::TimeDelta Pipeline::GetCurrentTime() const { base::AutoLock auto_lock(lock_); return GetCurrentTime_Locked(); } -base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { +base::TimeDelta Pipeline::GetCurrentTime_Locked() const { lock_.AssertAcquired(); base::TimeDelta elapsed = clock_->Elapsed(); if (elapsed > duration_) @@ -249,7 +245,7 @@ base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { return elapsed; } -base::TimeDelta PipelineImpl::GetBufferedTime() { +base::TimeDelta Pipeline::GetBufferedTime() { base::AutoLock auto_lock(lock_); // If media is fully loaded, then return duration. @@ -288,47 +284,47 @@ base::TimeDelta PipelineImpl::GetBufferedTime() { return max_buffered_time_; } -base::TimeDelta PipelineImpl::GetMediaDuration() const { +base::TimeDelta Pipeline::GetMediaDuration() const { base::AutoLock auto_lock(lock_); return duration_; } -int64 PipelineImpl::GetBufferedBytes() const { +int64 Pipeline::GetBufferedBytes() const { base::AutoLock auto_lock(lock_); return buffered_bytes_; } -int64 PipelineImpl::GetTotalBytes() const { +int64 Pipeline::GetTotalBytes() const { base::AutoLock auto_lock(lock_); return total_bytes_; } -void PipelineImpl::GetNaturalVideoSize(gfx::Size* out_size) const { +void Pipeline::GetNaturalVideoSize(gfx::Size* out_size) const { CHECK(out_size); base::AutoLock auto_lock(lock_); *out_size = natural_size_; } -bool PipelineImpl::IsStreaming() const { +bool Pipeline::IsStreaming() const { base::AutoLock auto_lock(lock_); return streaming_; } -bool PipelineImpl::IsLocalSource() const { +bool Pipeline::IsLocalSource() const { base::AutoLock auto_lock(lock_); return local_source_; } -PipelineStatistics PipelineImpl::GetStatistics() const { +PipelineStatistics Pipeline::GetStatistics() const { base::AutoLock auto_lock(lock_); return statistics_; } -void PipelineImpl::SetClockForTesting(Clock* clock) { +void Pipeline::SetClockForTesting(Clock* clock) { clock_.reset(clock); } -void PipelineImpl::SetCurrentReadPosition(int64 offset) { +void Pipeline::SetCurrentReadPosition(int64 offset) { base::AutoLock auto_lock(lock_); // The current read position should never be ahead of the buffered byte @@ -342,7 +338,7 @@ void PipelineImpl::SetCurrentReadPosition(int64 offset) { current_bytes_ = offset; } -void PipelineImpl::ResetState() { +void Pipeline::ResetState() { base::AutoLock auto_lock(lock_); const base::TimeDelta kZero; running_ = false; @@ -371,7 +367,7 @@ void PipelineImpl::ResetState() { download_rate_monitor_.Reset(); } -void PipelineImpl::SetState(State next_state) { +void Pipeline::SetState(State next_state) { if (state_ != kStarted && next_state == kStarted && !creation_time_.is_null()) { UMA_HISTOGRAM_TIMES( @@ -382,27 +378,27 @@ void PipelineImpl::SetState(State next_state) { media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(next_state)); } -bool PipelineImpl::IsPipelineOk() { +bool Pipeline::IsPipelineOk() { base::AutoLock auto_lock(lock_); return status_ == PIPELINE_OK; } -bool PipelineImpl::IsPipelineStopped() { +bool Pipeline::IsPipelineStopped() { DCHECK_EQ(MessageLoop::current(), message_loop_); return state_ == kStopped || state_ == kError; } -bool PipelineImpl::IsPipelineTearingDown() { +bool Pipeline::IsPipelineTearingDown() { DCHECK_EQ(MessageLoop::current(), message_loop_); return tearing_down_; } -bool PipelineImpl::IsPipelineStopPending() { +bool Pipeline::IsPipelineStopPending() { DCHECK_EQ(MessageLoop::current(), message_loop_); return stop_pending_; } -bool PipelineImpl::IsPipelineSeeking() { +bool Pipeline::IsPipelineSeeking() { DCHECK_EQ(MessageLoop::current(), message_loop_); if (!seek_pending_) return false; @@ -412,7 +408,7 @@ bool PipelineImpl::IsPipelineSeeking() { return true; } -void PipelineImpl::FinishInitialization() { +void Pipeline::FinishInitialization() { DCHECK_EQ(MessageLoop::current(), message_loop_); // Execute the seek callback, if present. Note that this might be the // initial callback passed into Start(). @@ -423,7 +419,7 @@ void PipelineImpl::FinishInitialization() { } // static -bool PipelineImpl::TransientState(State state) { +bool Pipeline::TransientState(State state) { return state == kPausing || state == kFlushing || state == kSeeking || @@ -432,7 +428,7 @@ bool PipelineImpl::TransientState(State state) { } // static -PipelineImpl::State PipelineImpl::FindNextState(State current) { +Pipeline::State Pipeline::FindNextState(State current) { // TODO(scherkus): refactor InitializeTask() to make use of this function. if (current == kPausing) { return kFlushing; @@ -454,32 +450,32 @@ PipelineImpl::State PipelineImpl::FindNextState(State current) { } } -void PipelineImpl::OnDemuxerError(PipelineStatus error) { +void Pipeline::OnDemuxerError(PipelineStatus error) { SetError(error); } -void PipelineImpl::SetError(PipelineStatus error) { +void Pipeline::SetError(PipelineStatus error) { DCHECK(IsRunning()); DCHECK_NE(PIPELINE_OK, error); VLOG(1) << "Media pipeline error: " << error; - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::ErrorChangedTask, this, error)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::ErrorChangedTask, this, error)); media_log_->AddEvent(media_log_->CreatePipelineErrorEvent(error)); } -base::TimeDelta PipelineImpl::GetTime() const { +base::TimeDelta Pipeline::GetTime() const { DCHECK(IsRunning()); return GetCurrentTime(); } -base::TimeDelta PipelineImpl::GetDuration() const { +base::TimeDelta Pipeline::GetDuration() const { DCHECK(IsRunning()); return GetMediaDuration(); } -void PipelineImpl::SetTime(base::TimeDelta time) { +void Pipeline::SetTime(base::TimeDelta time) { DCHECK(IsRunning()); base::AutoLock auto_lock(lock_); @@ -495,7 +491,7 @@ void PipelineImpl::SetTime(base::TimeDelta time) { clock_->SetTime(time); } -void PipelineImpl::SetDuration(base::TimeDelta duration) { +void Pipeline::SetDuration(base::TimeDelta duration) { DCHECK(IsRunning()); media_log_->AddEvent( media_log_->CreateTimeEvent( @@ -506,13 +502,13 @@ void PipelineImpl::SetDuration(base::TimeDelta duration) { duration_ = duration; } -void PipelineImpl::SetBufferedTime(base::TimeDelta buffered_time) { +void Pipeline::SetBufferedTime(base::TimeDelta buffered_time) { DCHECK(IsRunning()); base::AutoLock auto_lock(lock_); buffered_time_ = buffered_time; } -void PipelineImpl::SetTotalBytes(int64 total_bytes) { +void Pipeline::SetTotalBytes(int64 total_bytes) { DCHECK(IsRunning()); media_log_->AddEvent( media_log_->CreateIntegerEvent( @@ -528,7 +524,7 @@ void PipelineImpl::SetTotalBytes(int64 total_bytes) { download_rate_monitor_.set_total_bytes(total_bytes_); } -void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { +void Pipeline::SetBufferedBytes(int64 buffered_bytes) { DCHECK(IsRunning()); base::AutoLock auto_lock(lock_); // See comments in SetCurrentReadPosition() about capping. @@ -538,7 +534,7 @@ void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { download_rate_monitor_.SetBufferedBytes(buffered_bytes, base::Time::Now()); } -void PipelineImpl::SetNaturalVideoSize(const gfx::Size& size) { +void Pipeline::SetNaturalVideoSize(const gfx::Size& size) { DCHECK(IsRunning()); media_log_->AddEvent(media_log_->CreateVideoSizeSetEvent( size.width(), size.height())); @@ -547,14 +543,14 @@ void PipelineImpl::SetNaturalVideoSize(const gfx::Size& size) { natural_size_ = size; } -void PipelineImpl::NotifyEnded() { +void Pipeline::NotifyEnded() { DCHECK(IsRunning()); - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::NotifyEndedTask, this)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::NotifyEndedTask, this)); media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::ENDED)); } -void PipelineImpl::SetNetworkActivity(bool is_downloading_data) { +void Pipeline::SetNetworkActivity(bool is_downloading_data) { DCHECK(IsRunning()); NetworkEvent type = DOWNLOAD_PAUSED; @@ -566,36 +562,35 @@ void PipelineImpl::SetNetworkActivity(bool is_downloading_data) { download_rate_monitor_.SetNetworkActivity(is_downloading_data); } - message_loop_->PostTask(FROM_HERE, - base::Bind( - &PipelineImpl::NotifyNetworkEventTask, this, type)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::NotifyNetworkEventTask, this, type)); media_log_->AddEvent( media_log_->CreateBooleanEvent( MediaLogEvent::NETWORK_ACTIVITY_SET, "is_downloading_data", is_downloading_data)); } -void PipelineImpl::DisableAudioRenderer() { +void Pipeline::DisableAudioRenderer() { DCHECK(IsRunning()); // Disable renderer on the message loop. - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::DisableAudioRendererTask, this)); + 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 PipelineImpl::OnFilterInitialize(PipelineStatus status) { +void Pipeline::OnFilterInitialize(PipelineStatus status) { // Continue the initialize task by proceeding to the next stage. - message_loop_->PostTask( - FROM_HERE, base::Bind(&PipelineImpl::InitializeTask, this, status)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::InitializeTask, this, status)); } // Called from any thread. -void PipelineImpl::OnFilterStateTransition() { - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::FilterStateTransitionTask, this)); +void Pipeline::OnFilterStateTransition() { + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::FilterStateTransitionTask, this)); } // Called from any thread. @@ -605,19 +600,19 @@ void PipelineImpl::OnFilterStateTransition() { // // TODO: Revisit this code when SetError() is removed from FilterHost and // all the Closures are converted to FilterStatusCB. -void PipelineImpl::OnFilterStateTransitionWithStatus(PipelineStatus status) { +void Pipeline::OnFilterStateTransitionWithStatus(PipelineStatus status) { if (status != PIPELINE_OK) SetError(status); OnFilterStateTransition(); } -void PipelineImpl::OnTeardownStateTransition() { - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::TeardownStateTransitionTask, this)); +void Pipeline::OnTeardownStateTransition() { + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::TeardownStateTransitionTask, this)); } // Called from any thread. -void PipelineImpl::OnUpdateStatistics(const PipelineStatistics& stats) { +void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { base::AutoLock auto_lock(lock_); statistics_.audio_bytes_decoded += stats.audio_bytes_decoded; statistics_.video_bytes_decoded += stats.video_bytes_decoded; @@ -626,7 +621,7 @@ void PipelineImpl::OnUpdateStatistics(const PipelineStatistics& stats) { media_log_->QueueStatisticsUpdatedEvent(statistics_); } -void PipelineImpl::StartTask(scoped_ptr<FilterCollection> filter_collection, +void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection, const std::string& url, const PipelineStatusCB& start_callback) { DCHECK_EQ(MessageLoop::current(), message_loop_); @@ -661,7 +656,7 @@ void PipelineImpl::StartTask(scoped_ptr<FilterCollection> filter_collection, // TODO(hclam): InitializeTask() is now starting the pipeline asynchronously. It // works like a big state change table. If we no longer need to start filters // in order, we need to get rid of all the state change. -void PipelineImpl::InitializeTask(PipelineStatus last_stage_status) { +void Pipeline::InitializeTask(PipelineStatus last_stage_status) { DCHECK_EQ(MessageLoop::current(), message_loop_); if (last_stage_status != PIPELINE_OK) { @@ -766,7 +761,7 @@ void PipelineImpl::InitializeTask(PipelineStatus last_stage_status) { // TODO(scherkus): beware! this can get posted multiple times since we post // Stop() tasks even if we've already stopped. Perhaps this should no-op for // additional calls, however most of this logic will be changing. -void PipelineImpl::StopTask(const PipelineStatusCB& stop_callback) { +void Pipeline::StopTask(const PipelineStatusCB& stop_callback) { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(!IsPipelineStopPending()); DCHECK_NE(state_, kStopped); @@ -798,7 +793,7 @@ void PipelineImpl::StopTask(const PipelineStatusCB& stop_callback) { } } -void PipelineImpl::ErrorChangedTask(PipelineStatus error) { +void Pipeline::ErrorChangedTask(PipelineStatus error) { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; @@ -819,11 +814,11 @@ void PipelineImpl::ErrorChangedTask(PipelineStatus error) { // |tearing_down_| is set early here to make sure that pending callbacks // don't modify the state before TeadDownPipeline() can run. tearing_down_ = true; - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::TearDownPipeline, this)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::TearDownPipeline, this)); } -void PipelineImpl::PlaybackRateChangedTask(float playback_rate) { +void Pipeline::PlaybackRateChangedTask(float playback_rate) { DCHECK_EQ(MessageLoop::current(), message_loop_); if (!running_ || tearing_down_) @@ -851,7 +846,7 @@ void PipelineImpl::PlaybackRateChangedTask(float playback_rate) { } } -void PipelineImpl::VolumeChangedTask(float volume) { +void Pipeline::VolumeChangedTask(float volume) { DCHECK_EQ(MessageLoop::current(), message_loop_); if (!running_ || tearing_down_) return; @@ -860,7 +855,7 @@ void PipelineImpl::VolumeChangedTask(float volume) { audio_renderer_->SetVolume(volume); } -void PipelineImpl::PreloadChangedTask(Preload preload) { +void Pipeline::PreloadChangedTask(Preload preload) { DCHECK_EQ(MessageLoop::current(), message_loop_); if (!running_ || tearing_down_) return; @@ -869,7 +864,7 @@ void PipelineImpl::PreloadChangedTask(Preload preload) { demuxer_->SetPreload(preload); } -void PipelineImpl::SeekTask(base::TimeDelta time, +void Pipeline::SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_callback) { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(!IsPipelineStopPending()); @@ -904,10 +899,10 @@ void PipelineImpl::SeekTask(base::TimeDelta time, clock_->Pause(); } pipeline_filter_->Pause( - base::Bind(&PipelineImpl::OnFilterStateTransition, this)); + base::Bind(&Pipeline::OnFilterStateTransition, this)); } -void PipelineImpl::NotifyEndedTask() { +void Pipeline::NotifyEndedTask() { DCHECK_EQ(MessageLoop::current(), message_loop_); // We can only end if we were actually playing. @@ -946,13 +941,13 @@ void PipelineImpl::NotifyEndedTask() { } } -void PipelineImpl::NotifyNetworkEventTask(NetworkEvent type) { +void Pipeline::NotifyNetworkEventTask(NetworkEvent type) { DCHECK_EQ(MessageLoop::current(), message_loop_); if (!network_callback_.is_null()) network_callback_.Run(type); } -void PipelineImpl::DisableAudioRendererTask() { +void Pipeline::DisableAudioRendererTask() { DCHECK_EQ(MessageLoop::current(), message_loop_); base::AutoLock auto_lock(lock_); @@ -973,7 +968,7 @@ void PipelineImpl::DisableAudioRendererTask() { StartClockIfWaitingForTimeUpdate_Locked(); } -void PipelineImpl::FilterStateTransitionTask() { +void Pipeline::FilterStateTransitionTask() { DCHECK_EQ(MessageLoop::current(), message_loop_); // No reason transitioning if we've errored or have stopped. @@ -1005,17 +1000,17 @@ void PipelineImpl::FilterStateTransitionTask() { if (TransientState(state_)) { if (state_ == kPausing) { pipeline_filter_->Pause( - base::Bind(&PipelineImpl::OnFilterStateTransition, this)); + base::Bind(&Pipeline::OnFilterStateTransition, this)); } else if (state_ == kFlushing) { pipeline_filter_->Flush( - base::Bind(&PipelineImpl::OnFilterStateTransition, this)); + base::Bind(&Pipeline::OnFilterStateTransition, this)); } else if (state_ == kSeeking) { DoSeek(seek_timestamp_); } else if (state_ == kStarting) { pipeline_filter_->Play( - base::Bind(&PipelineImpl::OnFilterStateTransition, this)); + base::Bind(&Pipeline::OnFilterStateTransition, this)); } else if (state_ == kStopping) { - DoStop(base::Bind(&PipelineImpl::OnFilterStateTransition, this)); + DoStop(base::Bind(&Pipeline::OnFilterStateTransition, this)); } else { NOTREACHED() << "Unexpected state: " << state_; } @@ -1050,7 +1045,7 @@ void PipelineImpl::FilterStateTransitionTask() { // Needs to be locked because most other calls to |download_rate_monitor_| // occur on the renderer thread. download_rate_monitor_.Start( - base::Bind(&PipelineImpl::OnCanPlayThrough, this), + base::Bind(&Pipeline::OnCanPlayThrough, this), bitrate, streaming_, local_source_); download_rate_monitor_.SetBufferedBytes(buffered_bytes_, base::Time::Now()); @@ -1063,7 +1058,7 @@ void PipelineImpl::FilterStateTransitionTask() { } } -void PipelineImpl::TeardownStateTransitionTask() { +void Pipeline::TeardownStateTransitionTask() { DCHECK(IsPipelineTearingDown()); switch (state_) { case kStopping: @@ -1073,11 +1068,11 @@ void PipelineImpl::TeardownStateTransitionTask() { case kPausing: SetState(kFlushing); pipeline_filter_->Flush( - base::Bind(&PipelineImpl::OnTeardownStateTransition, this)); + base::Bind(&Pipeline::OnTeardownStateTransition, this)); break; case kFlushing: SetState(kStopping); - DoStop(base::Bind(&PipelineImpl::OnTeardownStateTransition, this)); + DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); break; case kCreated: @@ -1099,7 +1094,7 @@ void PipelineImpl::TeardownStateTransitionTask() { }; } -void PipelineImpl::FinishDestroyingFiltersTask() { +void Pipeline::FinishDestroyingFiltersTask() { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(IsPipelineStopped()); @@ -1128,27 +1123,25 @@ void PipelineImpl::FinishDestroyingFiltersTask() { error_caused_teardown_ = false; } -bool PipelineImpl::PrepareFilter(scoped_refptr<Filter> filter) { +bool Pipeline::PrepareFilter(scoped_refptr<Filter> filter) { bool ret = pipeline_init_state_->composite_->AddFilter(filter.get()); if (!ret) SetError(PIPELINE_ERROR_INITIALIZATION_FAILED); return ret; } -void PipelineImpl::InitializeDemuxer() { +void Pipeline::InitializeDemuxer() { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(IsPipelineOk()); filter_collection_->GetDemuxerFactory()->Build( - url_, base::Bind(&PipelineImpl::OnDemuxerBuilt, this)); + url_, base::Bind(&Pipeline::OnDemuxerBuilt, this)); } -void PipelineImpl::OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer) { +void Pipeline::OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer) { if (MessageLoop::current() != message_loop_) { - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::OnDemuxerBuilt, this, - status, - make_scoped_refptr(demuxer))); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::OnDemuxerBuilt, this, status, make_scoped_refptr(demuxer))); return; } @@ -1175,7 +1168,7 @@ void PipelineImpl::OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer) { OnFilterInitialize(PIPELINE_OK); } -bool PipelineImpl::InitializeAudioDecoder( +bool Pipeline::InitializeAudioDecoder( const scoped_refptr<Demuxer>& demuxer) { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(IsPipelineOk()); @@ -1200,12 +1193,12 @@ bool PipelineImpl::InitializeAudioDecoder( pipeline_init_state_->audio_decoder_ = audio_decoder; audio_decoder->Initialize( stream, - base::Bind(&PipelineImpl::OnFilterInitialize, this, PIPELINE_OK), - base::Bind(&PipelineImpl::OnUpdateStatistics, this)); + base::Bind(&Pipeline::OnFilterInitialize, this, PIPELINE_OK), + base::Bind(&Pipeline::OnUpdateStatistics, this)); return true; } -bool PipelineImpl::InitializeVideoDecoder( +bool Pipeline::InitializeVideoDecoder( const scoped_refptr<Demuxer>& demuxer) { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(IsPipelineOk()); @@ -1232,12 +1225,12 @@ bool PipelineImpl::InitializeVideoDecoder( pipeline_init_state_->video_decoder_ = video_decoder_; video_decoder_->Initialize( stream, - base::Bind(&PipelineImpl::OnFilterInitialize, this), - base::Bind(&PipelineImpl::OnUpdateStatistics, this)); + base::Bind(&Pipeline::OnFilterInitialize, this), + base::Bind(&Pipeline::OnUpdateStatistics, this)); return true; } -bool PipelineImpl::InitializeAudioRenderer( +bool Pipeline::InitializeAudioRenderer( const scoped_refptr<AudioDecoder>& decoder) { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(IsPipelineOk()); @@ -1256,12 +1249,12 @@ bool PipelineImpl::InitializeAudioRenderer( audio_renderer_->Initialize( decoder, - base::Bind(&PipelineImpl::OnFilterInitialize, this, PIPELINE_OK), - base::Bind(&PipelineImpl::OnAudioUnderflow, this)); + base::Bind(&Pipeline::OnFilterInitialize, this, PIPELINE_OK), + base::Bind(&Pipeline::OnAudioUnderflow, this)); return true; } -bool PipelineImpl::InitializeVideoRenderer( +bool Pipeline::InitializeVideoRenderer( const scoped_refptr<VideoDecoder>& decoder) { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK(IsPipelineOk()); @@ -1280,12 +1273,12 @@ bool PipelineImpl::InitializeVideoRenderer( video_renderer_->Initialize( decoder, - base::Bind(&PipelineImpl::OnFilterInitialize, this, PIPELINE_OK), - base::Bind(&PipelineImpl::OnUpdateStatistics, this)); + base::Bind(&Pipeline::OnFilterInitialize, this, PIPELINE_OK), + base::Bind(&Pipeline::OnUpdateStatistics, this)); return true; } -void PipelineImpl::TearDownPipeline() { +void Pipeline::TearDownPipeline() { DCHECK_EQ(MessageLoop::current(), message_loop_); DCHECK_NE(kStopped, state_); @@ -1302,8 +1295,8 @@ void PipelineImpl::TearDownPipeline() { SetState(kStopped); // Need to put this in the message loop to make sure that it comes // after any pending callback tasks that are already queued. - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::FinishDestroyingFiltersTask, this)); + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::FinishDestroyingFiltersTask, this)); break; case kInitDemuxer: @@ -1317,7 +1310,7 @@ void PipelineImpl::TearDownPipeline() { filter_collection_.reset(); SetState(kStopping); - DoStop(base::Bind(&PipelineImpl::OnTeardownStateTransition, this)); + DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); FinishInitialization(); break; @@ -1327,7 +1320,7 @@ void PipelineImpl::TearDownPipeline() { case kFlushing: case kStarting: SetState(kStopping); - DoStop(base::Bind(&PipelineImpl::OnTeardownStateTransition, this)); + DoStop(base::Bind(&Pipeline::OnTeardownStateTransition, this)); if (seek_pending_) { seek_pending_ = false; @@ -1340,7 +1333,7 @@ void PipelineImpl::TearDownPipeline() { case kEnded: SetState(kPausing); pipeline_filter_->Pause( - base::Bind(&PipelineImpl::OnTeardownStateTransition, this)); + base::Bind(&Pipeline::OnTeardownStateTransition, this)); break; case kStopping: @@ -1352,20 +1345,20 @@ void PipelineImpl::TearDownPipeline() { }; } -void PipelineImpl::DoStop(const base::Closure& callback) { +void Pipeline::DoStop(const base::Closure& callback) { if (demuxer_) { demuxer_->Stop(base::Bind( - &PipelineImpl::OnDemuxerStopDone, this, callback)); + &Pipeline::OnDemuxerStopDone, this, callback)); return; } OnDemuxerStopDone(callback); } -void PipelineImpl::OnDemuxerStopDone(const base::Closure& callback) { +void Pipeline::OnDemuxerStopDone(const base::Closure& callback) { if (MessageLoop::current() != message_loop_) { message_loop_->PostTask(FROM_HERE, base::Bind( - &PipelineImpl::OnDemuxerStopDone, this, callback)); + &Pipeline::OnDemuxerStopDone, this, callback)); return; } @@ -1378,13 +1371,13 @@ void PipelineImpl::OnDemuxerStopDone(const base::Closure& callback) { } -void PipelineImpl::DoSeek(base::TimeDelta seek_timestamp) { +void Pipeline::DoSeek(base::TimeDelta seek_timestamp) { // TODO(acolwell) : We might be able to convert this if (demuxer_) into a // DCHECK(). Further investigation is needed to make sure this won't introduce // a bug. if (demuxer_) { demuxer_->Seek(seek_timestamp, - base::Bind(&PipelineImpl::OnDemuxerSeekDone, + base::Bind(&Pipeline::OnDemuxerSeekDone, this, seek_timestamp)); return; @@ -1393,16 +1386,16 @@ void PipelineImpl::DoSeek(base::TimeDelta seek_timestamp) { OnDemuxerSeekDone(seek_timestamp, PIPELINE_OK); } -void PipelineImpl::OnDemuxerSeekDone(base::TimeDelta seek_timestamp, +void Pipeline::OnDemuxerSeekDone(base::TimeDelta seek_timestamp, PipelineStatus status) { if (MessageLoop::current() != message_loop_) { message_loop_->PostTask(FROM_HERE, base::Bind( - &PipelineImpl::OnDemuxerSeekDone, this, seek_timestamp, status)); + &Pipeline::OnDemuxerSeekDone, this, seek_timestamp, status)); return; } PipelineStatusCB done_cb = - base::Bind(&PipelineImpl::OnFilterStateTransitionWithStatus, this); + base::Bind(&Pipeline::OnFilterStateTransitionWithStatus, this); if (status == PIPELINE_OK && pipeline_filter_) { pipeline_filter_->Seek(seek_timestamp, done_cb); @@ -1412,10 +1405,10 @@ void PipelineImpl::OnDemuxerSeekDone(base::TimeDelta seek_timestamp, done_cb.Run(status); } -void PipelineImpl::OnAudioUnderflow() { +void Pipeline::OnAudioUnderflow() { if (MessageLoop::current() != message_loop_) { message_loop_->PostTask(FROM_HERE, base::Bind( - &PipelineImpl::OnAudioUnderflow, this)); + &Pipeline::OnAudioUnderflow, this)); return; } @@ -1426,17 +1419,17 @@ void PipelineImpl::OnAudioUnderflow() { audio_renderer_->ResumeAfterUnderflow(true); } -void PipelineImpl::OnCanPlayThrough() { - message_loop_->PostTask(FROM_HERE, - base::Bind(&PipelineImpl::NotifyCanPlayThrough, this)); +void Pipeline::OnCanPlayThrough() { + message_loop_->PostTask(FROM_HERE, base::Bind( + &Pipeline::NotifyCanPlayThrough, this)); } -void PipelineImpl::NotifyCanPlayThrough() { +void Pipeline::NotifyCanPlayThrough() { DCHECK_EQ(MessageLoop::current(), message_loop_); NotifyNetworkEventTask(CAN_PLAY_THROUGH); } -void PipelineImpl::StartClockIfWaitingForTimeUpdate_Locked() { +void Pipeline::StartClockIfWaitingForTimeUpdate_Locked() { lock_.AssertAcquired(); if (!waiting_for_clock_update_) return; diff --git a/media/base/pipeline.h b/media/base/pipeline.h index 7d382d0..1c6e102 100644 --- a/media/base/pipeline.h +++ b/media/base/pipeline.h @@ -2,32 +2,46 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// The pipeline is the public API clients use for playing back media. Clients -// provide a filter collection containing the filters they want the pipeline to -// use to render media. - #ifndef MEDIA_BASE_PIPELINE_H_ #define MEDIA_BASE_PIPELINE_H_ #include <string> +#include "base/gtest_prod_util.h" +#include "base/synchronization/condition_variable.h" +#include "base/synchronization/lock.h" +#include "media/base/demuxer.h" +#include "media/base/download_rate_monitor.h" +#include "media/base/filter_host.h" #include "media/base/media_export.h" #include "media/base/pipeline_status.h" #include "media/base/preload.h" #include "ui/gfx/size.h" +class MessageLoop; + namespace base { class TimeDelta; } namespace media { +class AudioDecoder; +class AudioRenderer; +class Clock; +class Filter; +class FilterCollection; +class MediaLog; +class VideoDecoder; +class VideoRenderer; + +// TODO(scherkus): this should be moved alongside host interface defintions. struct PipelineStatistics { - PipelineStatistics() : - audio_bytes_decoded(0), - video_bytes_decoded(0), - video_frames_decoded(0), - video_frames_dropped(0) { + PipelineStatistics() + : audio_bytes_decoded(0), + video_bytes_decoded(0), + video_frames_decoded(0), + video_frames_dropped(0) { } uint32 audio_bytes_decoded; // Should be uint64? @@ -42,10 +56,77 @@ enum NetworkEvent { CAN_PLAY_THROUGH }; -class FilterCollection; +// Adapter for using asynchronous Pipeline methods in code that wants to run +// synchronously. To use, construct an instance of this class and pass the +// |Callback()| to the Pipeline method requiring a callback. Then Wait() for +// the callback to get fired and call status() to see what the callback's +// argument was. This object is for one-time use; call |Callback()| exactly +// once. +class MEDIA_EXPORT PipelineStatusNotification { + public: + PipelineStatusNotification(); + ~PipelineStatusNotification(); + + // See class-level comment for usage. + PipelineStatusCB Callback(); + void Wait(); + PipelineStatus status(); + + private: + void Notify(media::PipelineStatus status); -class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe<Pipeline> { + base::Lock lock_; + base::ConditionVariable cv_; + media::PipelineStatus status_; + bool notified_; + + DISALLOW_COPY_AND_ASSIGN(PipelineStatusNotification); +}; + +// Pipeline runs the media pipeline. Filters are created and called on the +// message loop injected into this object. Pipeline works like a state +// machine to perform asynchronous initialization, pausing, seeking and playing. +// +// Here's a state diagram that describes the lifetime of this object. +// +// [ *Created ] [ Stopped ] +// | Start() ^ +// V SetError() | +// [ InitXXX (for each filter) ] -------->[ Stopping (for each filter) ] +// | ^ +// V | if Stop +// [ Seeking (for each filter) ] <--------[ Flushing (for each filter) ] +// | if Seek ^ +// V | +// [ Starting (for each filter) ] | +// | | +// V Seek()/Stop() | +// [ Started ] -------------------------> [ Pausing (for each filter) ] +// | ^ +// | NotifyEnded() Seek()/Stop() | +// `-------------> [ Ended ] ---------------------' +// ^ SetError() +// | +// [ Any State Other Than InitXXX ] + +// +// Initialization is a series of state transitions from "Created" through each +// filter initialization state. When all filter initialization states have +// completed, we are implicitly in a "Paused" state. At that point we simulate +// a Seek() to the beginning of the media to give filters a chance to preroll. +// From then on the normal Seek() transitions are carried out and we start +// playing the media. +// +// If any error ever happens, this object will transition to the "Error" state +// from any state. If Stop() is ever called, this object will transition to +// "Stopped" state. +class MEDIA_EXPORT Pipeline + : public base::RefCountedThreadSafe<Pipeline>, + public FilterHost, + public DemuxerHost { public: + Pipeline(MessageLoop* message_loop, MediaLog* media_log); + // Callback that executes when a network event occurrs. // The parameter specifies the type of event that is being signaled. typedef base::Callback<void(NetworkEvent)> NetworkEventCB; @@ -54,9 +135,9 @@ class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe<Pipeline> { // |ended_callback| will be executed when the media reaches the end. // |error_callback_| will be executed upon an error in the pipeline. // |network_callback_| will be executed when there's a network event. - virtual void Init(const PipelineStatusCB& ended_callback, - const PipelineStatusCB& error_callback, - const NetworkEventCB& network_callback) = 0; + void Init(const PipelineStatusCB& ended_callback, + const PipelineStatusCB& error_callback, + const NetworkEventCB& network_callback); // Build a pipeline to render the given URL using the given filter collection // to construct a filter chain. Returns true if successful, false otherwise @@ -69,9 +150,9 @@ class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe<Pipeline> { // This method is asynchronous and can execute a callback when completed. // If the caller provides a |start_callback|, it will be called when the // pipeline initialization completes. - virtual bool Start(scoped_ptr<FilterCollection> filter_collection, - const std::string& url, - const PipelineStatusCB& start_callback) = 0; + bool Start(scoped_ptr<FilterCollection> filter_collection, + const std::string& url, + const PipelineStatusCB& start_callback); // Asynchronously stops the pipeline and resets it to an uninitialized state. // If provided, |stop_callback| will be executed when the pipeline has been @@ -83,98 +164,473 @@ class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe<Pipeline> { // // TODO(scherkus): ideally clients would destroy the pipeline after calling // Stop() and create a new pipeline as needed. - virtual void Stop(const PipelineStatusCB& stop_callback) = 0; + void Stop(const PipelineStatusCB& stop_callback); // Attempt to seek to the position specified by time. |seek_callback| will be // executed when the all filters in the pipeline have processed the seek. // // Clients are expected to call GetCurrentTime() to check whether the seek // succeeded. - virtual void Seek(base::TimeDelta time, - const PipelineStatusCB& seek_callback) = 0; + void Seek(base::TimeDelta time, const PipelineStatusCB& seek_callback); // Returns true if the pipeline has been started via Start(). If IsRunning() // returns true, it is expected that Stop() will be called before destroying // the pipeline. - virtual bool IsRunning() const = 0; + bool IsRunning() const; // Returns true if the pipeline has been started and fully initialized to a // point where playback controls will be respected. Note that it is possible // for a pipeline to be started but not initialized (i.e., an error occurred). - virtual bool IsInitialized() const = 0; + bool IsInitialized() const; // Returns true if the media has audio. - virtual bool HasAudio() const = 0; + bool HasAudio() const; // Returns true if the media has video. - virtual bool HasVideo() const = 0; + bool HasVideo() const; // Gets the current playback rate of the pipeline. When the pipeline is // started, the playback rate will be 0.0f. A rate of 1.0f indicates // that the pipeline is rendering the media at the standard rate. Valid // values for playback rate are >= 0.0f. - virtual float GetPlaybackRate() const = 0; + float GetPlaybackRate() const; // Attempt to adjust the playback rate. Setting a playback rate of 0.0f pauses // all rendering of the media. A rate of 1.0f indicates a normal playback // rate. Values for the playback rate must be greater than or equal to 0.0f. // // TODO(scherkus): What about maximum rate? Does HTML5 specify a max? - virtual void SetPlaybackRate(float playback_rate) = 0; + void SetPlaybackRate(float playback_rate); // Gets the current volume setting being used by the audio renderer. When // the pipeline is started, this value will be 1.0f. Valid values range // from 0.0f to 1.0f. - virtual float GetVolume() const = 0; + float GetVolume() const; // Attempt to set the volume of the audio renderer. Valid values for volume // range from 0.0f (muted) to 1.0f (full volume). This value affects all // channels proportionately for multi-channel audio streams. - virtual void SetVolume(float volume) = 0; + void SetVolume(float volume); // Set the preload value for the pipeline. - virtual void SetPreload(Preload preload) = 0; + void SetPreload(Preload preload); // Gets the current pipeline time. For a pipeline "time" progresses from 0 to // the end of the media. - virtual base::TimeDelta GetCurrentTime() const = 0; + base::TimeDelta GetCurrentTime() const; // Get the approximate amount of playable data buffered so far in micro- // seconds. - virtual base::TimeDelta GetBufferedTime() = 0; + base::TimeDelta GetBufferedTime(); // Get the duration of the media in microseconds. If the duration has not // been determined yet, then returns 0. - virtual base::TimeDelta GetMediaDuration() const = 0; + base::TimeDelta GetMediaDuration() const; // Get the total number of bytes that are buffered on the client and ready to // be played. - virtual int64 GetBufferedBytes() const = 0; + int64 GetBufferedBytes() const; // Get the total size of the media file. If the size has not yet been // determined or can not be determined, this value is 0. - virtual int64 GetTotalBytes() const = 0; + int64 GetTotalBytes() const; // Gets the natural size of the video output in pixel units. If there is no // video or the video has not been rendered yet, the width and height will // be 0. - virtual void GetNaturalVideoSize(gfx::Size* out_size) const = 0; + void GetNaturalVideoSize(gfx::Size* out_size) const; // If this method returns true, that means the data source is a streaming // data source. Seeking may not be possible. - virtual bool IsStreaming() const = 0; + bool IsStreaming() const; // If this method returns true, that means the data source is local and // the network is not needed. - virtual bool IsLocalSource() const = 0; + bool IsLocalSource() const; // Gets the current pipeline statistics. - virtual PipelineStatistics GetStatistics() const = 0; + PipelineStatistics GetStatistics() const; + + void SetClockForTesting(Clock* clock); + + private: + FRIEND_TEST_ALL_PREFIXES(PipelineTest, GetBufferedTime); + friend class MediaLog; - protected: // Only allow ourselves to be deleted by reference counting. friend class base::RefCountedThreadSafe<Pipeline>; - virtual ~Pipeline() {} + virtual ~Pipeline(); + + // Pipeline states, as described above. + enum State { + kCreated, + kInitDemuxer, + kInitAudioDecoder, + kInitAudioRenderer, + kInitVideoDecoder, + kInitVideoRenderer, + kPausing, + kSeeking, + kFlushing, + kStarting, + kStarted, + kEnded, + kStopping, + kStopped, + kError, + }; + + // Reset the state of the pipeline object to the initial state. This method + // is used by the constructor, and the Stop() method. + void ResetState(); + + // Updates |state_|. All state transitions should use this call. + void SetState(State next_state); + + // Simple method used to make sure the pipeline is running normally. + bool IsPipelineOk(); + + // Helper method to tell whether we are stopped or in error. + bool IsPipelineStopped(); + + // Helper method to tell whether we are in transition to stop state. + bool IsPipelineTearingDown(); + + // We could also be delayed by a transition during seek is performed. + bool IsPipelineStopPending(); + + // Helper method to tell whether we are in transition to seek state. + bool IsPipelineSeeking(); + + // Helper method to execute callback from Start() and reset + // |filter_collection_|. Called when initialization completes + // normally or when pipeline is stopped or error occurs during + // initialization. + void FinishInitialization(); + + // Returns true if the given state is one that transitions to a new state + // after iterating through each filter. + static bool TransientState(State state); + + // Given the current state, returns the next state. + State FindNextState(State current); + + // DataSourceHost (by way of DemuxerHost) implementation. + virtual void SetTotalBytes(int64 total_bytes) OVERRIDE; + virtual void SetBufferedBytes(int64 buffered_bytes) OVERRIDE; + virtual void SetNetworkActivity(bool is_downloading_data) OVERRIDE; + + // DemuxerHost implementaion. + virtual void SetDuration(base::TimeDelta duration) OVERRIDE; + virtual void SetBufferedTime(base::TimeDelta buffered_time) OVERRIDE; + virtual void SetCurrentReadPosition(int64 offset) OVERRIDE; + virtual void OnDemuxerError(PipelineStatus error) OVERRIDE; + + // FilterHost implementation. + virtual void SetError(PipelineStatus error) OVERRIDE; + virtual base::TimeDelta GetTime() const OVERRIDE; + virtual base::TimeDelta GetDuration() const OVERRIDE; + virtual void SetTime(base::TimeDelta time) OVERRIDE; + virtual void SetNaturalVideoSize(const gfx::Size& size) OVERRIDE; + virtual void NotifyEnded() OVERRIDE; + virtual void DisableAudioRenderer() OVERRIDE; + + // Callbacks executed by filters upon completing initialization. + void OnFilterInitialize(PipelineStatus status); + + // Callback executed by filters upon completing Play(), Pause(), or Stop(). + void OnFilterStateTransition(); + + // Callback executed by filters upon completing Seek(). + void OnFilterStateTransitionWithStatus(PipelineStatus status); + + // Callback executed by filters when completing teardown operations. + void OnTeardownStateTransition(); + + // Callback executed by filters to update statistics. + void OnUpdateStatistics(const PipelineStatistics& stats); + + // The following "task" methods correspond to the public methods, but these + // methods are run as the result of posting a task to the PipelineInternal's + // message loop. + void StartTask(scoped_ptr<FilterCollection> filter_collection, + const std::string& url, + const PipelineStatusCB& start_callback); + + // InitializeTask() performs initialization in multiple passes. It is executed + // as a result of calling Start() or InitializationComplete() that advances + // initialization to the next state. It works as a hub of state transition for + // initialization. One stage communicates its status to the next through + // |last_stage_status|. + void InitializeTask(PipelineStatus last_stage_status); + + // Stops and destroys all filters, placing the pipeline in the kStopped state. + void StopTask(const PipelineStatusCB& stop_callback); + + // Carries out stopping and destroying all filters, placing the pipeline in + // the kError state. + void ErrorChangedTask(PipelineStatus error); + + // Carries out notifying filters that the playback rate has changed. + void PlaybackRateChangedTask(float playback_rate); + + // Carries out notifying filters that the volume has changed. + void VolumeChangedTask(float volume); + + // Returns media preload value. + virtual Preload GetPreload() const; + + // Carries out notifying filters that the preload value has changed. + void PreloadChangedTask(Preload preload); + + // Carries out notifying filters that we are seeking to a new timestamp. + void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_callback); + + // Carries out handling a notification from a filter that it has ended. + void NotifyEndedTask(); + + // Carries out handling a notification of network event. + void NotifyNetworkEventTask(NetworkEvent type); + + // Carries out disabling the audio renderer. + void DisableAudioRendererTask(); + + // Carries out advancing to the next filter during Play()/Pause()/Seek(). + void FilterStateTransitionTask(); + + // Carries out advancing to the next teardown operation. + void TeardownStateTransitionTask(); + + // Carries out stopping filter threads, deleting filters, running + // appropriate callbacks, and setting the appropriate pipeline state + // depending on whether we performing Stop() or SetError(). + // Called after all filters have been stopped. + void FinishDestroyingFiltersTask(); + + // Internal methods used in the implementation of the pipeline thread. All + // of these methods are only called on the pipeline thread. + + // PrepareFilter() creates the filter's thread and injects a FilterHost and + // MessageLoop. + bool PrepareFilter(scoped_refptr<Filter> filter); + + // The following initialize methods are used to select a specific type of + // Filter object from FilterCollection and initialize it asynchronously. + void InitializeDemuxer(); + void OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer); + + // Returns true if the asynchronous action of creating decoder has started. + // Returns false if this method did nothing because the corresponding + // audio/video stream does not exist. + bool InitializeAudioDecoder(const scoped_refptr<Demuxer>& demuxer); + bool InitializeVideoDecoder(const scoped_refptr<Demuxer>& demuxer); + + // Initializes a renderer and connects it with decoder. Returns true if the + // asynchronous action of creating renderer has started. Returns + // false if this method did nothing because the corresponding audio/video + // stream does not exist. + bool InitializeAudioRenderer(const scoped_refptr<AudioDecoder>& decoder); + bool InitializeVideoRenderer(const scoped_refptr<VideoDecoder>& decoder); + + // Kicks off destroying filters. Called by StopTask() and ErrorChangedTask(). + // When we start to tear down the pipeline, we will consider two cases: + // 1. when pipeline has not been initialized, we will transit to stopping + // state first. + // 2. when pipeline has been initialized, we will first transit to pausing + // => flushing => stopping => stopped state. + // This will remove the race condition during stop between filters. + void TearDownPipeline(); + + // Compute the current time. Assumes that the lock has been acquired by the + // caller. + base::TimeDelta GetCurrentTime_Locked() const; + + // Initiates a Stop() on |demuxer_| & |pipeline_filter_|. |callback| + // is called once both objects have been stopped. + void DoStop(const base::Closure& callback); + + // Called when |demuxer_| has stopped. This method calls Stop() + // on |pipeline_filter_|. + void OnDemuxerStopDone(const base::Closure& callback); + + // Initiates a Seek() on the |demuxer_| & |pipeline_filter_|. + void DoSeek(base::TimeDelta seek_timestamp); + + // Called when |demuxer_| finishes seeking. If seeking was successful, + // then Seek() is called on |pipeline_filter_|. + void OnDemuxerSeekDone(base::TimeDelta seek_timestamp, + PipelineStatus status); + + void OnAudioUnderflow(); + + // Called when |download_rate_monitor_| believes that the media can + // be played through without needing to pause to buffer. + void OnCanPlayThrough(); + + // Carries out the notification that the media can be played through without + // needing to pause to buffer. + void NotifyCanPlayThrough(); + + void StartClockIfWaitingForTimeUpdate_Locked(); + + // Message loop used to execute pipeline tasks. + MessageLoop* message_loop_; + + // MediaLog to which to log events. + scoped_refptr<MediaLog> media_log_; + + // Lock used to serialize access for the following data members. + mutable base::Lock lock_; + + // Whether or not the pipeline is running. + bool running_; + + // Whether or not the pipeline is in transition for a seek operation. + bool seek_pending_; + + // Whether or not the pipeline is pending a stop operation. + bool stop_pending_; + + // Whether or not the pipeline is perform a stop operation. + bool tearing_down_; + + // Whether or not an error triggered the teardown. + bool error_caused_teardown_; + + // Whether or not a playback rate change should be done once seeking is done. + bool playback_rate_change_pending_; + + // Duration of the media in microseconds. Set by filters. + base::TimeDelta duration_; + + // Amount of available buffered data in microseconds. Set by filters. + base::TimeDelta buffered_time_; + + // Amount of available buffered data. Set by filters. + int64 buffered_bytes_; + + // Total size of the media. Set by filters. + int64 total_bytes_; + + // Video's natural width and height. Set by filters. + gfx::Size natural_size_; + + // Set by the demuxer to indicate whether the data source is a streaming + // source. + bool streaming_; + + // Indicates whether the data source is local, such as a local media file + // from disk or a local webcam stream. + bool local_source_; + + // Current volume level (from 0.0f to 1.0f). This value is set immediately + // via SetVolume() and a task is dispatched on the message loop to notify the + // filters. + float volume_; + + // Current value of preload attribute. This value is set immediately via + // SetPreload() and a task is dispatched on the message loop to notify the + // filters. + Preload preload_; + + // Current playback rate (>= 0.0f). This value is set immediately via + // SetPlaybackRate() and a task is dispatched on the message loop to notify + // the filters. + float playback_rate_; + + // Playback rate to set when the current seek has finished. + float pending_playback_rate_; + + // Reference clock. Keeps track of current playback time. Uses system + // clock and linear interpolation, but can have its time manually set + // 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_; + + // Status of the pipeline. Initialized to PIPELINE_OK which indicates that + // the pipeline is operating correctly. Any other value indicates that the + // pipeline is stopped or is stopping. Clients can call the Stop() method to + // reset the pipeline state, and restore this to PIPELINE_OK. + PipelineStatus status_; + + // Whether the media contains rendered audio and video streams. + bool has_audio_; + bool has_video_; + + // The following data members are only accessed by tasks posted to + // |message_loop_|. + + // Member that tracks the current state. + State state_; + + // For kSeeking we need to remember where we're seeking between filter + // replies. + base::TimeDelta seek_timestamp_; + + // For GetCurrentBytes()/SetCurrentBytes() we need to know what byte we are + // currently reading. + int64 current_bytes_; + + // Set to true in DisableAudioRendererTask(). + bool audio_disabled_; + + // Keep track of the maximum buffered position so the buffering appears + // smooth. + // TODO(vrk): This is a hack. + base::TimeDelta max_buffered_time_; + + // Filter collection as passed in by Start(). + scoped_ptr<FilterCollection> filter_collection_; + + // URL for the data source as passed in by Start(). + std::string url_; + + // Callbacks for various pipeline operations. + PipelineStatusCB seek_callback_; + PipelineStatusCB stop_callback_; + PipelineStatusCB ended_callback_; + PipelineStatusCB error_callback_; + NetworkEventCB network_callback_; + + // Reference to the filter(s) that constitute the pipeline. + scoped_refptr<Filter> pipeline_filter_; + + // Decoder reference used for signalling imminent shutdown. + // This is a HACK necessary because WebMediaPlayerImpl::Destroy() holds the + // renderer thread loop hostage for until PipelineImpl::Stop() calls its + // callback. http://crbug.com/110228 tracks removing this hack. + scoped_refptr<VideoDecoder> video_decoder_; + + // Renderer references used for setting the volume and determining + // when playback has finished. + scoped_refptr<AudioRenderer> audio_renderer_; + scoped_refptr<VideoRenderer> video_renderer_; + + // Demuxer reference used for setting the preload value. + scoped_refptr<Demuxer> demuxer_; + + // Helper class that stores filter references during pipeline + // initialization. + class PipelineInitState; + scoped_ptr<PipelineInitState> pipeline_init_state_; + + // Statistics. + PipelineStatistics statistics_; + // Time of pipeline creation; is non-zero only until the pipeline first + // reaches "kStarted", at which point it is used & zeroed out. + base::Time creation_time_; + + // Approximates the rate at which the media is being downloaded. + DownloadRateMonitor download_rate_monitor_; + + // True if the pipeline is actively downloading bytes, false otherwise. + bool is_downloading_data_; + + DISALLOW_COPY_AND_ASSIGN(Pipeline); }; } // namespace media diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h deleted file mode 100644 index 5b9ee4e..0000000 --- a/media/base/pipeline_impl.h +++ /dev/null @@ -1,518 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Implementation of Pipeline & PipelineStatusNotification (an async-to-sync -// callback adapter). - -#ifndef MEDIA_BASE_PIPELINE_IMPL_H_ -#define MEDIA_BASE_PIPELINE_IMPL_H_ - -#include <set> -#include <string> -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "base/synchronization/condition_variable.h" -#include "base/synchronization/lock.h" -#include "base/threading/thread.h" -#include "base/time.h" -#include "media/base/clock.h" -#include "media/base/composite_filter.h" -#include "media/base/demuxer.h" -#include "media/base/download_rate_monitor.h" -#include "media/base/filter_host.h" -#include "media/base/pipeline.h" -#include "ui/gfx/size.h" - -namespace media { - -class MediaLog; - -// Adapter for using asynchronous Pipeline methods in code that wants to run -// synchronously. To use, construct an instance of this class and pass the -// |Callback()| to the Pipeline method requiring a callback. Then Wait() for -// the callback to get fired and call status() to see what the callback's -// argument was. This object is for one-time use; call |Callback()| exactly -// once. -class MEDIA_EXPORT PipelineStatusNotification { - public: - PipelineStatusNotification(); - ~PipelineStatusNotification(); - - // See class-level comment for usage. - PipelineStatusCB Callback(); - void Wait(); - PipelineStatus status(); - - private: - void Notify(media::PipelineStatus status); - - base::Lock lock_; - base::ConditionVariable cv_; - media::PipelineStatus status_; - bool notified_; - - DISALLOW_COPY_AND_ASSIGN(PipelineStatusNotification); -}; - -// PipelineImpl runs the media pipeline. Filters are created and called on the -// message loop injected into this object. PipelineImpl works like a state -// machine to perform asynchronous initialization, pausing, seeking and playing. -// -// Here's a state diagram that describes the lifetime of this object. -// -// [ *Created ] [ Stopped ] -// | Start() ^ -// V SetError() | -// [ InitXXX (for each filter) ] -------->[ Stopping (for each filter) ] -// | ^ -// V | if Stop -// [ Seeking (for each filter) ] <--------[ Flushing (for each filter) ] -// | if Seek ^ -// V | -// [ Starting (for each filter) ] | -// | | -// V Seek()/Stop() | -// [ Started ] -------------------------> [ Pausing (for each filter) ] -// | ^ -// | NotifyEnded() Seek()/Stop() | -// `-------------> [ Ended ] ---------------------' -// ^ SetError() -// | -// [ Any State Other Than InitXXX ] - -// -// Initialization is a series of state transitions from "Created" through each -// filter initialization state. When all filter initialization states have -// completed, we are implicitly in a "Paused" state. At that point we simulate -// a Seek() to the beginning of the media to give filters a chance to preroll. -// From then on the normal Seek() transitions are carried out and we start -// playing the media. -// -// If any error ever happens, this object will transition to the "Error" state -// from any state. If Stop() is ever called, this object will transition to -// "Stopped" state. -class MEDIA_EXPORT PipelineImpl - : public Pipeline, - public FilterHost, - public DemuxerHost { - public: - explicit PipelineImpl(MessageLoop* message_loop, MediaLog* media_log); - - // Pipeline implementation. - virtual void Init(const PipelineStatusCB& ended_callback, - const PipelineStatusCB& error_callback, - const NetworkEventCB& network_callback) OVERRIDE; - virtual bool Start(scoped_ptr<FilterCollection> filter_collection, - const std::string& uri, - const PipelineStatusCB& start_callback) OVERRIDE; - virtual void Stop(const PipelineStatusCB& stop_callback) OVERRIDE; - virtual void Seek(base::TimeDelta time, - const PipelineStatusCB& seek_callback) OVERRIDE; - virtual bool IsRunning() const OVERRIDE; - virtual bool IsInitialized() const OVERRIDE; - virtual bool HasAudio() const OVERRIDE; - virtual bool HasVideo() const OVERRIDE; - virtual float GetPlaybackRate() const OVERRIDE; - virtual void SetPlaybackRate(float playback_rate) OVERRIDE; - virtual float GetVolume() const OVERRIDE; - virtual void SetVolume(float volume) OVERRIDE; - virtual void SetPreload(Preload preload) OVERRIDE; - virtual base::TimeDelta GetCurrentTime() const OVERRIDE; - virtual base::TimeDelta GetBufferedTime() OVERRIDE; - virtual base::TimeDelta GetMediaDuration() const OVERRIDE; - virtual int64 GetBufferedBytes() const OVERRIDE; - virtual int64 GetTotalBytes() const OVERRIDE; - virtual void GetNaturalVideoSize(gfx::Size* out_size) const OVERRIDE; - virtual bool IsStreaming() const OVERRIDE; - virtual bool IsLocalSource() const OVERRIDE; - virtual PipelineStatistics GetStatistics() const OVERRIDE; - - void SetClockForTesting(Clock* clock); - - private: - friend class MediaLog; - - // Pipeline states, as described above. - enum State { - kCreated, - kInitDemuxer, - kInitAudioDecoder, - kInitAudioRenderer, - kInitVideoDecoder, - kInitVideoRenderer, - kPausing, - kSeeking, - kFlushing, - kStarting, - kStarted, - kEnded, - kStopping, - kStopped, - kError, - }; - - virtual ~PipelineImpl(); - - // Reset the state of the pipeline object to the initial state. This method - // is used by the constructor, and the Stop() method. - void ResetState(); - - // Updates |state_|. All state transitions should use this call. - void SetState(State next_state); - - // Simple method used to make sure the pipeline is running normally. - bool IsPipelineOk(); - - // Helper method to tell whether we are stopped or in error. - bool IsPipelineStopped(); - - // Helper method to tell whether we are in transition to stop state. - bool IsPipelineTearingDown(); - - // We could also be delayed by a transition during seek is performed. - bool IsPipelineStopPending(); - - // Helper method to tell whether we are in transition to seek state. - bool IsPipelineSeeking(); - - // Helper method to execute callback from Start() and reset - // |filter_collection_|. Called when initialization completes - // normally or when pipeline is stopped or error occurs during - // initialization. - void FinishInitialization(); - - // Returns true if the given state is one that transitions to a new state - // after iterating through each filter. - static bool TransientState(State state); - - // Given the current state, returns the next state. - State FindNextState(State current); - - // DataSourceHost (by way of DemuxerHost) implementation. - virtual void SetTotalBytes(int64 total_bytes) OVERRIDE; - virtual void SetBufferedBytes(int64 buffered_bytes) OVERRIDE; - virtual void SetNetworkActivity(bool is_downloading_data) OVERRIDE; - - // DemuxerHost implementaion. - virtual void SetDuration(base::TimeDelta duration) OVERRIDE; - virtual void SetBufferedTime(base::TimeDelta buffered_time) OVERRIDE; - virtual void SetCurrentReadPosition(int64 offset) OVERRIDE; - virtual void OnDemuxerError(PipelineStatus error) OVERRIDE; - - // FilterHost implementation. - virtual void SetError(PipelineStatus error) OVERRIDE; - virtual base::TimeDelta GetTime() const OVERRIDE; - virtual base::TimeDelta GetDuration() const OVERRIDE; - virtual void SetTime(base::TimeDelta time) OVERRIDE; - virtual void SetNaturalVideoSize(const gfx::Size& size) OVERRIDE; - virtual void NotifyEnded() OVERRIDE; - virtual void DisableAudioRenderer() OVERRIDE; - - // Callbacks executed by filters upon completing initialization. - void OnFilterInitialize(PipelineStatus status); - - // Callback executed by filters upon completing Play(), Pause(), or Stop(). - void OnFilterStateTransition(); - - // Callback executed by filters upon completing Seek(). - void OnFilterStateTransitionWithStatus(PipelineStatus status); - - // Callback executed by filters when completing teardown operations. - void OnTeardownStateTransition(); - - // Callback executed by filters to update statistics. - void OnUpdateStatistics(const PipelineStatistics& stats); - - // The following "task" methods correspond to the public methods, but these - // methods are run as the result of posting a task to the PipelineInternal's - // message loop. - void StartTask(scoped_ptr<FilterCollection> filter_collection, - const std::string& url, - const PipelineStatusCB& start_callback); - - // InitializeTask() performs initialization in multiple passes. It is executed - // as a result of calling Start() or InitializationComplete() that advances - // initialization to the next state. It works as a hub of state transition for - // initialization. One stage communicates its status to the next through - // |last_stage_status|. - void InitializeTask(PipelineStatus last_stage_status); - - // Stops and destroys all filters, placing the pipeline in the kStopped state. - void StopTask(const PipelineStatusCB& stop_callback); - - // Carries out stopping and destroying all filters, placing the pipeline in - // the kError state. - void ErrorChangedTask(PipelineStatus error); - - // Carries out notifying filters that the playback rate has changed. - void PlaybackRateChangedTask(float playback_rate); - - // Carries out notifying filters that the volume has changed. - void VolumeChangedTask(float volume); - - // Returns media preload value. - virtual Preload GetPreload() const; - - // Carries out notifying filters that the preload value has changed. - void PreloadChangedTask(Preload preload); - - // Carries out notifying filters that we are seeking to a new timestamp. - void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_callback); - - // Carries out handling a notification from a filter that it has ended. - void NotifyEndedTask(); - - // Carries out handling a notification of network event. - void NotifyNetworkEventTask(NetworkEvent type); - - // Carries out disabling the audio renderer. - void DisableAudioRendererTask(); - - // Carries out advancing to the next filter during Play()/Pause()/Seek(). - void FilterStateTransitionTask(); - - // Carries out advancing to the next teardown operation. - void TeardownStateTransitionTask(); - - // Carries out stopping filter threads, deleting filters, running - // appropriate callbacks, and setting the appropriate pipeline state - // depending on whether we performing Stop() or SetError(). - // Called after all filters have been stopped. - void FinishDestroyingFiltersTask(); - - // Internal methods used in the implementation of the pipeline thread. All - // of these methods are only called on the pipeline thread. - - // PrepareFilter() creates the filter's thread and injects a FilterHost and - // MessageLoop. - bool PrepareFilter(scoped_refptr<Filter> filter); - - // The following initialize methods are used to select a specific type of - // Filter object from FilterCollection and initialize it asynchronously. - void InitializeDemuxer(); - void OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer); - - // Returns true if the asynchronous action of creating decoder has started. - // Returns false if this method did nothing because the corresponding - // audio/video stream does not exist. - bool InitializeAudioDecoder(const scoped_refptr<Demuxer>& demuxer); - bool InitializeVideoDecoder(const scoped_refptr<Demuxer>& demuxer); - - // Initializes a renderer and connects it with decoder. Returns true if the - // asynchronous action of creating renderer has started. Returns - // false if this method did nothing because the corresponding audio/video - // stream does not exist. - bool InitializeAudioRenderer(const scoped_refptr<AudioDecoder>& decoder); - bool InitializeVideoRenderer(const scoped_refptr<VideoDecoder>& decoder); - - // Kicks off destroying filters. Called by StopTask() and ErrorChangedTask(). - // When we start to tear down the pipeline, we will consider two cases: - // 1. when pipeline has not been initialized, we will transit to stopping - // state first. - // 2. when pipeline has been initialized, we will first transit to pausing - // => flushing => stopping => stopped state. - // This will remove the race condition during stop between filters. - void TearDownPipeline(); - - // Compute the current time. Assumes that the lock has been acquired by the - // caller. - base::TimeDelta GetCurrentTime_Locked() const; - - // Initiates a Stop() on |demuxer_| & |pipeline_filter_|. |callback| - // is called once both objects have been stopped. - void DoStop(const base::Closure& callback); - - // Called when |demuxer_| has stopped. This method calls Stop() - // on |pipeline_filter_|. - void OnDemuxerStopDone(const base::Closure& callback); - - // Initiates a Seek() on the |demuxer_| & |pipeline_filter_|. - void DoSeek(base::TimeDelta seek_timestamp); - - // Called when |demuxer_| finishes seeking. If seeking was successful, - // then Seek() is called on |pipeline_filter_|. - void OnDemuxerSeekDone(base::TimeDelta seek_timestamp, - PipelineStatus status); - - void OnAudioUnderflow(); - - // Called when |download_rate_monitor_| believes that the media can - // be played through without needing to pause to buffer. - void OnCanPlayThrough(); - - // Carries out the notification that the media can be played through without - // needing to pause to buffer. - void NotifyCanPlayThrough(); - - void StartClockIfWaitingForTimeUpdate_Locked(); - - // Message loop used to execute pipeline tasks. - MessageLoop* message_loop_; - - // MediaLog to which to log events. - scoped_refptr<MediaLog> media_log_; - - // Lock used to serialize access for the following data members. - mutable base::Lock lock_; - - // Whether or not the pipeline is running. - bool running_; - - // Whether or not the pipeline is in transition for a seek operation. - bool seek_pending_; - - // Whether or not the pipeline is pending a stop operation. - bool stop_pending_; - - // Whether or not the pipeline is perform a stop operation. - bool tearing_down_; - - // Whether or not an error triggered the teardown. - bool error_caused_teardown_; - - // Whether or not a playback rate change should be done once seeking is done. - bool playback_rate_change_pending_; - - // Duration of the media in microseconds. Set by filters. - base::TimeDelta duration_; - - // Amount of available buffered data in microseconds. Set by filters. - base::TimeDelta buffered_time_; - - // Amount of available buffered data. Set by filters. - int64 buffered_bytes_; - - // Total size of the media. Set by filters. - int64 total_bytes_; - - // Video's natural width and height. Set by filters. - gfx::Size natural_size_; - - // Set by the demuxer to indicate whether the data source is a streaming - // source. - bool streaming_; - - // Indicates whether the data source is local, such as a local media file - // from disk or a local webcam stream. - bool local_source_; - - // Current volume level (from 0.0f to 1.0f). This value is set immediately - // via SetVolume() and a task is dispatched on the message loop to notify the - // filters. - float volume_; - - // Current value of preload attribute. This value is set immediately via - // SetPreload() and a task is dispatched on the message loop to notify the - // filters. - Preload preload_; - - // Current playback rate (>= 0.0f). This value is set immediately via - // SetPlaybackRate() and a task is dispatched on the message loop to notify - // the filters. - float playback_rate_; - - // Playback rate to set when the current seek has finished. - float pending_playback_rate_; - - // Reference clock. Keeps track of current playback time. Uses system - // clock and linear interpolation, but can have its time manually set - // 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_; - - // Status of the pipeline. Initialized to PIPELINE_OK which indicates that - // the pipeline is operating correctly. Any other value indicates that the - // pipeline is stopped or is stopping. Clients can call the Stop() method to - // reset the pipeline state, and restore this to PIPELINE_OK. - PipelineStatus status_; - - // Whether the media contains rendered audio and video streams. - bool has_audio_; - bool has_video_; - - // The following data members are only accessed by tasks posted to - // |message_loop_|. - - // Member that tracks the current state. - State state_; - - // For kSeeking we need to remember where we're seeking between filter - // replies. - base::TimeDelta seek_timestamp_; - - // For GetCurrentBytes()/SetCurrentBytes() we need to know what byte we are - // currently reading. - int64 current_bytes_; - - // Set to true in DisableAudioRendererTask(). - bool audio_disabled_; - - // Keep track of the maximum buffered position so the buffering appears - // smooth. - // TODO(vrk): This is a hack. - base::TimeDelta max_buffered_time_; - - // Filter collection as passed in by Start(). - scoped_ptr<FilterCollection> filter_collection_; - - // URL for the data source as passed in by Start(). - std::string url_; - - // Callbacks for various pipeline operations. - PipelineStatusCB seek_callback_; - PipelineStatusCB stop_callback_; - PipelineStatusCB ended_callback_; - PipelineStatusCB error_callback_; - NetworkEventCB network_callback_; - - // Reference to the filter(s) that constitute the pipeline. - scoped_refptr<Filter> pipeline_filter_; - - // Decoder reference used for signalling imminent shutdown. - // This is a HACK necessary because WebMediaPlayerImpl::Destroy() holds the - // renderer thread loop hostage for until PipelineImpl::Stop() calls its - // callback. http://crbug.com/110228 tracks removing this hack. - scoped_refptr<VideoDecoder> video_decoder_; - - // Renderer references used for setting the volume and determining - // when playback has finished. - scoped_refptr<AudioRenderer> audio_renderer_; - scoped_refptr<VideoRenderer> video_renderer_; - - // Demuxer reference used for setting the preload value. - scoped_refptr<Demuxer> demuxer_; - - // Helper class that stores filter references during pipeline - // initialization. - class PipelineInitState; - scoped_ptr<PipelineInitState> pipeline_init_state_; - - // Statistics. - PipelineStatistics statistics_; - // Time of pipeline creation; is non-zero only until the pipeline first - // reaches "kStarted", at which point it is used & zeroed out. - base::Time creation_time_; - - // Approximates the rate at which the media is being downloaded. - DownloadRateMonitor download_rate_monitor_; - - // True if the pipeline is actively downloading bytes, false otherwise. - bool is_downloading_data_; - - FRIEND_TEST_ALL_PREFIXES(PipelineImplTest, GetBufferedTime); - - DISALLOW_COPY_AND_ASSIGN(PipelineImpl); -}; - -} // namespace media - -#endif // MEDIA_BASE_PIPELINE_IMPL_H_ diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_unittest.cc index 3ded0e7..58f028f 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_unittest.cc @@ -5,13 +5,14 @@ #include <string> #include "base/bind.h" -#include "base/callback.h" +#include "base/message_loop.h" #include "base/stl_util.h" #include "base/threading/simple_thread.h" +#include "media/base/clock.h" #include "media/base/filter_host.h" #include "media/base/filters.h" #include "media/base/media_log.h" -#include "media/base/pipeline_impl.h" +#include "media/base/pipeline.h" #include "media/base/mock_callback.h" #include "media/base/mock_filters.h" #include "testing/gtest/include/gtest/gtest.h" @@ -65,10 +66,10 @@ static void RunPipelineStatusOKCB(const PipelineStatusCB& cb) { // InitializationComplete(), which keeps the pipeline humming along. If // either filters don't call InitializationComplete() immediately or filter // initialization is moved to a separate thread this test will become flaky. -class PipelineImplTest : public ::testing::Test { +class PipelineTest : public ::testing::Test { public: - PipelineImplTest() - : pipeline_(new PipelineImpl(&message_loop_, new MediaLog())) { + PipelineTest() + : pipeline_(new Pipeline(&message_loop_, new MediaLog())) { pipeline_->Init( base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)), base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)), @@ -85,7 +86,7 @@ class PipelineImplTest : public ::testing::Test { .WillRepeatedly(Return(base::TimeDelta())); } - virtual ~PipelineImplTest() { + virtual ~PipelineTest() { if (!pipeline_->IsRunning()) { return; } @@ -266,18 +267,18 @@ class PipelineImplTest : public ::testing::Test { // Fixture members. StrictMock<CallbackHelper> callbacks_; MessageLoop message_loop_; - scoped_refptr<PipelineImpl> pipeline_; + scoped_refptr<Pipeline> pipeline_; scoped_ptr<media::MockFilterCollection> mocks_; scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream_; scoped_refptr<StrictMock<MockDemuxerStream> > video_stream_; private: - DISALLOW_COPY_AND_ASSIGN(PipelineImplTest); + DISALLOW_COPY_AND_ASSIGN(PipelineTest); }; // Test that playback controls methods no-op when the pipeline hasn't been // started. -TEST_F(PipelineImplTest, NotStarted) { +TEST_F(PipelineTest, NotStarted) { const base::TimeDelta kZero; // StrictMock<> will ensure these never get called, and valgrind will @@ -321,7 +322,7 @@ TEST_F(PipelineImplTest, NotStarted) { EXPECT_EQ(0, size.height()); } -TEST_F(PipelineImplTest, NeverInitializes) { +TEST_F(PipelineTest, NeverInitializes) { // This test hangs during initialization by never calling // InitializationComplete(). StrictMock<> will ensure that the callback is // never executed. @@ -343,7 +344,7 @@ TEST_F(PipelineImplTest, NeverInitializes) { EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); } -TEST_F(PipelineImplTest, RequiredFilterMissing) { +TEST_F(PipelineTest, RequiredFilterMissing) { EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_REQUIRED_FILTER_MISSING)); // Sets up expectations on the callback and initializes the pipeline. Called @@ -362,7 +363,7 @@ TEST_F(PipelineImplTest, RequiredFilterMissing) { EXPECT_FALSE(pipeline_->IsInitialized()); } -TEST_F(PipelineImplTest, URLNotFound) { +TEST_F(PipelineTest, URLNotFound) { // TODO(acolwell,fischman): Since OnStart() is getting called with an error // code already, OnError() doesn't also need to get called. Fix the pipeline // (and it's consumers!) so that OnError doesn't need to be called after @@ -373,7 +374,7 @@ TEST_F(PipelineImplTest, URLNotFound) { EXPECT_FALSE(pipeline_->IsInitialized()); } -TEST_F(PipelineImplTest, NoStreams) { +TEST_F(PipelineTest, NoStreams) { // Manually set these expectations because SetPlaybackRate() is not called if // we cannot fully initialize the pipeline. EXPECT_CALL(*mocks_->demuxer(), Stop(_)) @@ -385,7 +386,7 @@ TEST_F(PipelineImplTest, NoStreams) { EXPECT_FALSE(pipeline_->IsInitialized()); } -TEST_F(PipelineImplTest, AudioStream) { +TEST_F(PipelineTest, AudioStream) { CreateAudioStream(); MockDemuxerStreamVector streams; streams.push_back(audio_stream()); @@ -400,7 +401,7 @@ TEST_F(PipelineImplTest, AudioStream) { EXPECT_FALSE(pipeline_->HasVideo()); } -TEST_F(PipelineImplTest, VideoStream) { +TEST_F(PipelineTest, VideoStream) { CreateVideoStream(); MockDemuxerStreamVector streams; streams.push_back(video_stream()); @@ -415,7 +416,7 @@ TEST_F(PipelineImplTest, VideoStream) { EXPECT_TRUE(pipeline_->HasVideo()); } -TEST_F(PipelineImplTest, AudioVideoStream) { +TEST_F(PipelineTest, AudioVideoStream) { CreateAudioStream(); CreateVideoStream(); MockDemuxerStreamVector streams; @@ -434,7 +435,7 @@ TEST_F(PipelineImplTest, AudioVideoStream) { EXPECT_TRUE(pipeline_->HasVideo()); } -TEST_F(PipelineImplTest, Seek) { +TEST_F(PipelineTest, Seek) { CreateAudioStream(); CreateVideoStream(); MockDemuxerStreamVector streams; @@ -456,7 +457,7 @@ TEST_F(PipelineImplTest, Seek) { DoSeek(expected); } -TEST_F(PipelineImplTest, SetVolume) { +TEST_F(PipelineTest, SetVolume) { CreateAudioStream(); MockDemuxerStreamVector streams; streams.push_back(audio_stream()); @@ -474,7 +475,7 @@ TEST_F(PipelineImplTest, SetVolume) { pipeline_->SetVolume(expected); } -TEST_F(PipelineImplTest, Properties) { +TEST_F(PipelineTest, Properties) { CreateVideoStream(); MockDemuxerStreamVector streams; streams.push_back(video_stream()); @@ -497,7 +498,7 @@ TEST_F(PipelineImplTest, Properties) { pipeline_->GetBufferedTime().ToInternalValue()); } -TEST_F(PipelineImplTest, GetBufferedTime) { +TEST_F(PipelineTest, GetBufferedTime) { CreateVideoStream(); MockDemuxerStreamVector streams; streams.push_back(video_stream()); @@ -558,7 +559,7 @@ TEST_F(PipelineImplTest, GetBufferedTime) { pipeline_->GetBufferedTime().ToInternalValue()); } -TEST_F(PipelineImplTest, DisableAudioRenderer) { +TEST_F(PipelineTest, DisableAudioRenderer) { CreateAudioStream(); CreateVideoStream(); MockDemuxerStreamVector streams; @@ -599,7 +600,7 @@ TEST_F(PipelineImplTest, DisableAudioRenderer) { host->NotifyEnded(); } -TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) { +TEST_F(PipelineTest, DisableAudioRendererDuringInit) { CreateAudioStream(); CreateVideoStream(); MockDemuxerStreamVector streams; @@ -636,7 +637,7 @@ TEST_F(PipelineImplTest, DisableAudioRendererDuringInit) { host->NotifyEnded(); } -TEST_F(PipelineImplTest, EndedCallback) { +TEST_F(PipelineTest, EndedCallback) { CreateAudioStream(); CreateVideoStream(); MockDemuxerStreamVector streams; @@ -679,7 +680,7 @@ static base::Time StaticClockFunction() { return base::Time::FromInternalValue(g_static_clock_time); } -TEST_F(PipelineImplTest, AudioStreamShorterThanVideo) { +TEST_F(PipelineTest, AudioStreamShorterThanVideo) { base::TimeDelta duration = base::TimeDelta::FromSeconds(10); CreateAudioStream(); @@ -749,7 +750,7 @@ void SendReadErrorToCB(::testing::Unused, const FilterStatusCB& cb) { cb.Run(PIPELINE_ERROR_READ); } -TEST_F(PipelineImplTest, ErrorDuringSeek) { +TEST_F(PipelineTest, ErrorDuringSeek) { CreateAudioStream(); MockDemuxerStreamVector streams; streams.push_back(audio_stream()); @@ -783,7 +784,7 @@ TEST_F(PipelineImplTest, ErrorDuringSeek) { // Invoked function OnError. This asserts that the pipeline does not enqueue // non-teardown related tasks while tearing down. static void TestNoCallsAfterError( - PipelineImpl* pipeline, MessageLoop* message_loop, + Pipeline* pipeline, MessageLoop* message_loop, PipelineStatus /* status */) { CHECK(pipeline); CHECK(message_loop); @@ -800,7 +801,7 @@ static void TestNoCallsAfterError( message_loop->AssertIdle(); } -TEST_F(PipelineImplTest, NoMessageDuringTearDownFromError) { +TEST_F(PipelineTest, NoMessageDuringTearDownFromError) { CreateAudioStream(); MockDemuxerStreamVector streams; streams.push_back(audio_stream()); @@ -830,7 +831,7 @@ TEST_F(PipelineImplTest, NoMessageDuringTearDownFromError) { message_loop_.RunAllPending(); } -TEST_F(PipelineImplTest, StartTimeIsZero) { +TEST_F(PipelineTest, StartTimeIsZero) { CreateVideoStream(); MockDemuxerStreamVector streams; streams.push_back(video_stream()); @@ -848,7 +849,7 @@ TEST_F(PipelineImplTest, StartTimeIsZero) { EXPECT_EQ(base::TimeDelta(), pipeline_->GetCurrentTime()); } -TEST_F(PipelineImplTest, StartTimeIsNonZero) { +TEST_F(PipelineTest, StartTimeIsNonZero) { const base::TimeDelta kStartTime = base::TimeDelta::FromSeconds(4); const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); diff --git a/media/filters/ffmpeg_audio_decoder.cc b/media/filters/ffmpeg_audio_decoder.cc index 1e8cc60..71b32e5 100644 --- a/media/filters/ffmpeg_audio_decoder.cc +++ b/media/filters/ffmpeg_audio_decoder.cc @@ -9,6 +9,7 @@ #include "media/base/data_buffer.h" #include "media/base/demuxer.h" #include "media/base/filter_host.h" +#include "media/base/pipeline.h" #include "media/ffmpeg/ffmpeg_common.h" namespace media { @@ -113,7 +114,7 @@ void FFmpegAudioDecoder::DoInitialize( const AudioDecoderConfig& config = stream->audio_decoder_config(); stats_callback_ = stats_callback; - // TODO(scherkus): this check should go in PipelineImpl prior to creating + // TODO(scherkus): this check should go in Pipeline prior to creating // decoder objects. if (!config.IsValidConfig()) { DLOG(ERROR) << "Invalid audio stream -" diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index 213c09e..fc1236c 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc @@ -12,6 +12,7 @@ #include "media/base/filter_host.h" #include "media/base/limits.h" #include "media/base/media_switches.h" +#include "media/base/pipeline.h" #include "media/base/video_decoder_config.h" #include "media/base/video_frame.h" #include "media/base/video_util.h" @@ -85,7 +86,7 @@ void FFmpegVideoDecoder::Initialize(DemuxerStream* demuxer_stream, const VideoDecoderConfig& config = demuxer_stream->video_decoder_config(); - // TODO(scherkus): this check should go in PipelineImpl prior to creating + // TODO(scherkus): this check should go in Pipeline prior to creating // decoder objects. if (!config.IsValidConfig()) { DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString(); diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc index 3b7ea08..193ccd8 100644 --- a/media/filters/gpu_video_decoder.cc +++ b/media/filters/gpu_video_decoder.cc @@ -9,6 +9,7 @@ #include "base/stl_util.h" #include "media/base/demuxer_stream.h" #include "media/base/filter_host.h" +#include "media/base/pipeline.h" #include "media/base/video_decoder_config.h" #include "media/ffmpeg/ffmpeg_common.h" @@ -155,7 +156,7 @@ void GpuVideoDecoder::Initialize(DemuxerStream* demuxer_stream, } const VideoDecoderConfig& config = demuxer_stream->video_decoder_config(); - // TODO(scherkus): this check should go in PipelineImpl prior to creating + // TODO(scherkus): this check should go in Pipeline prior to creating // decoder objects. if (!config.IsValidConfig()) { DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString(); diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc index decadd4..f95fd34 100644 --- a/media/filters/pipeline_integration_test.cc +++ b/media/filters/pipeline_integration_test.cc @@ -3,10 +3,11 @@ // found in the LICENSE file. #include "base/bind.h" +#include "base/message_loop.h" #include "media/base/filter_collection.h" #include "media/base/media_log.h" #include "media/base/message_loop_factory_impl.h" -#include "media/base/pipeline_impl.h" +#include "media/base/pipeline.h" #include "media/base/test_data_util.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer_factory.h" @@ -21,7 +22,7 @@ using ::testing::AnyNumber; namespace media { -// Integration tests for PipelineImpl. Real demuxers, real decoders, and +// Integration tests for Pipeline. Real demuxers, real decoders, and // base renderer implementations are used to verify pipeline functionality. The // renderers used in these tests rely heavily on the AudioRendererBase & // VideoRendererBase implementations which contain a majority of the code used @@ -34,7 +35,7 @@ class PipelineIntegrationTest : public testing::Test { public: PipelineIntegrationTest() : message_loop_factory_(new MessageLoopFactoryImpl()), - pipeline_(new PipelineImpl(&message_loop_, new MediaLog())), + pipeline_(new Pipeline(&message_loop_, new MediaLog())), ended_(false) { pipeline_->Init( base::Bind(&PipelineIntegrationTest::OnEnded, base::Unretained(this)), diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc index 8248f88..df7350c 100644 --- a/media/filters/video_renderer_base.cc +++ b/media/filters/video_renderer_base.cc @@ -8,6 +8,7 @@ #include "media/base/buffers.h" #include "media/base/filter_host.h" #include "media/base/limits.h" +#include "media/base/pipeline.h" #include "media/base/video_frame.h" #include "media/filters/video_renderer_base.h" diff --git a/media/media.gyp b/media/media.gyp index 8bfe118..4d550df 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -148,9 +148,8 @@ 'base/message_loop_factory.h', 'base/message_loop_factory_impl.cc', 'base/message_loop_factory_impl.h', + 'base/pipeline.cc', 'base/pipeline.h', - 'base/pipeline_impl.cc', - 'base/pipeline_impl.h', 'base/pipeline_status.h', 'base/preload.h', 'base/pts_heap.cc', @@ -605,7 +604,7 @@ 'base/filter_collection_unittest.cc', 'base/h264_bitstream_converter_unittest.cc', 'base/mock_reader.h', - 'base/pipeline_impl_unittest.cc', + 'base/pipeline_unittest.cc', 'base/pts_heap_unittest.cc', 'base/pts_stream_unittest.cc', 'base/run_all_unittests.cc', diff --git a/media/tools/player_wtl/movie.cc b/media/tools/player_wtl/movie.cc index 44b20b2..f97f88a 100644 --- a/media/tools/player_wtl/movie.cc +++ b/media/tools/player_wtl/movie.cc @@ -11,7 +11,7 @@ #include "media/base/filter_collection.h" #include "media/base/media_log.h" #include "media/base/message_loop_factory_impl.h" -#include "media/base/pipeline_impl.h" +#include "media/base/pipeline.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer_factory.h" #include "media/filters/ffmpeg_video_decoder.h" @@ -25,7 +25,7 @@ using media::FFmpegDemuxerFactory; using media::FFmpegVideoDecoder; using media::FileDataSourceFactory; using media::FilterCollection; -using media::PipelineImpl; +using media::Pipeline; using media::ReferenceAudioRenderer; namespace media { @@ -68,7 +68,7 @@ bool Movie::Open(const wchar_t* url, VideoRendererBase* video_renderer) { MessageLoop* pipeline_loop = message_loop_factory_->GetMessageLoop("PipelineThread"); - pipeline_ = new PipelineImpl(pipeline_loop, new media::MediaLog()); + pipeline_ = new Pipeline(pipeline_loop, new media::MediaLog()); // Create filter collection. scoped_ptr<FilterCollection> collection(new FilterCollection()); diff --git a/media/tools/player_wtl/movie.h b/media/tools/player_wtl/movie.h index 0b407bf..f6a3c44 100644 --- a/media/tools/player_wtl/movie.h +++ b/media/tools/player_wtl/movie.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,7 +18,7 @@ template <typename T> struct DefaultSingletonTraits; namespace media { -class PipelineImpl; +class Pipeline; class VideoRendererBase; class Movie { @@ -83,7 +83,7 @@ class Movie { Movie(); virtual ~Movie(); - scoped_refptr<PipelineImpl> pipeline_; + scoped_refptr<Pipeline> pipeline_; scoped_ptr<media::MessageLoopFactory> message_loop_factory_; scoped_refptr<AudioManager> audio_manager_; diff --git a/media/tools/player_wtl/player_wtl.cc b/media/tools/player_wtl/player_wtl.cc index 7ae160a..7756042 100644 --- a/media/tools/player_wtl/player_wtl.cc +++ b/media/tools/player_wtl/player_wtl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,7 @@ #include "base/at_exit.h" #include "base/command_line.h" -#include "media/base/pipeline_impl.h" +#include "media/base/pipeline.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer.h" #include "media/filters/ffmpeg_video_decoder.h" diff --git a/media/tools/player_x11/player_x11.cc b/media/tools/player_x11/player_x11.cc index 11188db..f4b9fcc 100644 --- a/media/tools/player_x11/player_x11.cc +++ b/media/tools/player_x11/player_x11.cc @@ -21,7 +21,7 @@ #include "media/base/media_log.h" #include "media/base/media_switches.h" #include "media/base/message_loop_factory_impl.h" -#include "media/base/pipeline_impl.h" +#include "media/base/pipeline.h" #include "media/base/video_frame.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer_factory.h" @@ -100,7 +100,7 @@ bool InitPipeline(MessageLoop* message_loop, const char* filename, const PaintCB& paint_cb, bool enable_audio, - scoped_refptr<media::PipelineImpl>* pipeline, + scoped_refptr<media::Pipeline>* pipeline, MessageLoop* paint_message_loop, media::MessageLoopFactory* message_loop_factory) { // Load media libraries. @@ -135,7 +135,7 @@ bool InitPipeline(MessageLoop* message_loop, } // Create the pipeline and start it. - *pipeline = new media::PipelineImpl(message_loop, new media::MediaLog()); + *pipeline = new media::Pipeline(message_loop, new media::MediaLog()); media::PipelineStatusNotification note; (*pipeline)->Start(collection.Pass(), filename, note.Callback()); @@ -157,7 +157,7 @@ void TerminateHandler(int signal) { } void PeriodicalUpdate( - media::PipelineImpl* pipeline, + media::Pipeline* pipeline, MessageLoop* message_loop, bool audio_only) { if (!g_running) { @@ -267,7 +267,7 @@ int main(int argc, char** argv) { scoped_ptr<media::MessageLoopFactory> message_loop_factory( new media::MessageLoopFactoryImpl()); scoped_ptr<base::Thread> thread; - scoped_refptr<media::PipelineImpl> pipeline; + scoped_refptr<media::Pipeline> pipeline; MessageLoop message_loop; thread.reset(new base::Thread("PipelineThread")); thread->Start(); |