summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-18 09:30:32 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-18 09:30:32 +0000
commitd399866c2fe77410afed5be486f2b72581823bed (patch)
treeb7da4bc8b767ed87053ce974642598db1d1a6b4a /media
parent12bb3e11aac582a23034e3538a689e9a3a28da86 (diff)
downloadchromium_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.h8
-rw-r--r--media/base/media_log.cc35
-rw-r--r--media/base/media_log.h6
-rw-r--r--media/base/media_log_event.h6
-rw-r--r--media/base/pipeline.cc (renamed from media/base/pipeline_impl.cc)303
-rw-r--r--media/base/pipeline.h536
-rw-r--r--media/base/pipeline_impl.h518
-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.cc3
-rw-r--r--media/filters/ffmpeg_video_decoder.cc3
-rw-r--r--media/filters/gpu_video_decoder.cc3
-rw-r--r--media/filters/pipeline_integration_test.cc7
-rw-r--r--media/filters/video_renderer_base.cc1
-rw-r--r--media/media.gyp5
-rw-r--r--media/tools/player_wtl/movie.cc6
-rw-r--r--media/tools/player_wtl/movie.h6
-rw-r--r--media/tools/player_wtl/player_wtl.cc4
-rw-r--r--media/tools/player_x11/player_x11.cc10
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();