summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-09 00:12:04 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-09 00:12:04 +0000
commit83548cfb4900fa35d3f34a88340f10d2bcce74fc (patch)
tree4317a48420047c6c3d170d4a430743b832cc9ef9 /media
parentcfdae27555853c2c57f7aa91179bc39407dc77bc (diff)
downloadchromium_src-83548cfb4900fa35d3f34a88340f10d2bcce74fc.zip
chromium_src-83548cfb4900fa35d3f34a88340f10d2bcce74fc.tar.gz
chromium_src-83548cfb4900fa35d3f34a88340f10d2bcce74fc.tar.bz2
Big media::Pipeline cleanup.
Before I can even start refactoring, I need to remove a lot of accumulated cruft and fix some style stuff. PipelineStatus has been merged into Pipeline and I got rid of GetInterpolatedTime() as well as the ability to schedule callbacks when time has updated. We haven't found a need for these features and they introduced a good amount of code complexity. TEST=media_unittests should still pass BUG=16008 Review URL: http://codereview.chromium.org/149215 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20218 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/filter_host.h34
-rw-r--r--media/base/filter_host_impl.cc63
-rw-r--r--media/base/filter_host_impl.h64
-rw-r--r--media/base/mock_filter_host.h29
-rw-r--r--media/base/pipeline.h163
-rw-r--r--media/base/pipeline_impl.cc293
-rw-r--r--media/base/pipeline_impl.h71
-rw-r--r--media/filters/video_renderer_base.cc2
-rw-r--r--media/player/movie.cc2
9 files changed, 245 insertions, 476 deletions
diff --git a/media/base/filter_host.h b/media/base/filter_host.h
index b911473..4907df2a 100644
--- a/media/base/filter_host.h
+++ b/media/base/filter_host.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2008-2009 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.
@@ -24,31 +24,6 @@ namespace media {
class FilterHost {
public:
- // The PipelineStatus class allows read-only access to the pipeline state.
- // This is the same object that is used by the pipeline client to examine
- // the state of the running pipeline. The lifetime of the PipelineStatus
- // interface is the same as the lifetime of the FilterHost interface, so
- // it is acceptable for filters to use the returned pointer until their
- // Stop method has been called.
- virtual const PipelineStatus* GetPipelineStatus() const = 0;
-
- // Registers a callback to receive global clock update notifications. The
- // callback will be called repeatedly and filters do not need to re-register
- // after each invocation of the callback. To remove the callback, filters
- // may call this method passing NULL for the callback argument.
- //
- // Callback arguments:
- // base::TimeDelta - the new pipeline time, in microseconds.
- virtual void SetTimeUpdateCallback(Callback1<base::TimeDelta>::Type* cb) = 0;
-
- // Request that the time callback be called at the specified stream
- // time. This will set a timer specific to the filter that will be fired
- // no sooner than the specified time based on the interpolated time. Note
- // that, becuase the callback will be made with the interpolated time, it is
- // possible for time to move "backward" slightly when the audio device updates
- // the pipeline time though the SetTime method.
- virtual void ScheduleTimeUpdateCallback(base::TimeDelta time) = 0;
-
// Filters must call this method to indicate that their initialization is
// complete. They may call this from within their Initialize() method or may
// choose call it after processing some data.
@@ -58,8 +33,11 @@ class FilterHost {
// method with PIPELINE_OK or PIPELINE_STOPPING (used internally by pipeline).
virtual void Error(PipelineError error) = 0;
- // Sets the current time. Any filters that have registered a callback through
- // the SetTimeUpdateCallback method will be notified of the change.
+ // Gets the current time in microseconds.
+ virtual base::TimeDelta GetTime() const = 0;
+
+ // Updates the current time. Other filters should poll to examine the updated
+ // time.
virtual void SetTime(base::TimeDelta time) = 0;
// Get the duration of the media in microseconds. If the duration has not
diff --git a/media/base/filter_host_impl.cc b/media/base/filter_host_impl.cc
index 0cd348a..96e4e93 100644
--- a/media/base/filter_host_impl.cc
+++ b/media/base/filter_host_impl.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2008-2009 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.
@@ -6,56 +6,6 @@
namespace media {
-void FilterHostImpl::SetTimeUpdateCallback(
- Callback1<base::TimeDelta>::Type* callback) {
- time_update_callback_.reset(callback);
-}
-
-void FilterHostImpl::RunTimeUpdateCallback(base::TimeDelta time) {
- if (time_update_callback_.get()) {
- time_update_callback_->Run(time);
- }
-}
-
-// To understand why this method takes the |caller| parameter, see the comments
-// of the TimeUpdatedTask in the file filter_host_impl.h.
-void FilterHostImpl::RunScheduledTimeUpdateCallback(TimeUpdateTask* caller) {
- time_update_lock_.Acquire();
- if (caller == scheduled_time_update_task_) {
- scheduled_time_update_task_ = NULL;
- }
- time_update_lock_.Release();
- RunTimeUpdateCallback(pipeline()->GetInterpolatedTime());
-}
-
-void FilterHostImpl::ScheduleTimeUpdateCallback(base::TimeDelta time) {
- time_update_lock_.Acquire();
- if (stopped_) {
- time_update_lock_.Release();
- } else {
- DCHECK(time_update_callback_.get());
- if (scheduled_time_update_task_) {
- scheduled_time_update_task_->Cancel();
- }
- scheduled_time_update_task_ = new TimeUpdateTask(this);
- Task* task = scheduled_time_update_task_;
- time_update_lock_.Release();
-
- // Here, we compute the delta from now & adjust it by the playback rate.
- time -= pipeline()->GetInterpolatedTime();
- int delay = static_cast<int>(time.InMilliseconds());
- float rate = pipeline()->GetPlaybackRate();
- if (rate > 0.0f) {
- delay = static_cast<int>(delay / rate);
- }
- if (delay > 0) {
- pipeline_thread_->message_loop()->PostDelayedTask(FROM_HERE, task, delay);
- } else {
- pipeline_thread_->message_loop()->PostTask(FROM_HERE, task);
- }
- }
-}
-
void FilterHostImpl::InitializationComplete() {
pipeline_thread_->InitializationComplete(this);
}
@@ -64,6 +14,10 @@ void FilterHostImpl::Error(PipelineError error) {
pipeline_thread_->Error(error);
}
+base::TimeDelta FilterHostImpl::GetTime() const {
+ return pipeline()->GetTime();
+}
+
void FilterHostImpl::SetTime(base::TimeDelta time) {
pipeline_thread_->SetTime(time);
}
@@ -88,18 +42,11 @@ void FilterHostImpl::SetVideoSize(size_t width, size_t height) {
pipeline()->SetVideoSize(width, height);
}
-const PipelineStatus* FilterHostImpl::GetPipelineStatus() const {
- return pipeline();
-}
-
void FilterHostImpl::Stop() {
if (!stopped_) {
filter_->Stop();
AutoLock auto_lock(time_update_lock_);
stopped_ = true;
- if (scheduled_time_update_task_) {
- scheduled_time_update_task_->Cancel();
- }
}
}
diff --git a/media/base/filter_host_impl.h b/media/base/filter_host_impl.h
index 4ae9260..1fcb0c4 100644
--- a/media/base/filter_host_impl.h
+++ b/media/base/filter_host_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2008-2009 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.
@@ -16,11 +16,9 @@ namespace media {
class FilterHostImpl : public FilterHost {
public:
// FilterHost interface.
- virtual const PipelineStatus* GetPipelineStatus() const;
- virtual void SetTimeUpdateCallback(Callback1<base::TimeDelta>::Type* cb);
- virtual void ScheduleTimeUpdateCallback(base::TimeDelta time);
virtual void InitializationComplete();
virtual void Error(PipelineError error);
+ virtual base::TimeDelta GetTime() const;
virtual void SetTime(base::TimeDelta time);
virtual void SetDuration(base::TimeDelta duration);
virtual void SetBufferedTime(base::TimeDelta buffered_time);
@@ -31,7 +29,7 @@ class FilterHostImpl : public FilterHost {
// These methods are public, but are intended for use by the
// PipelineThread class only.
- // Creates a FilterHostImpl object and populates the filter_type_ member
+ // Creates a FilterHostImpl object and populates the |filter_type_| member
// by calling the Filter class's static filter_type() method. This ensures
// that the GetFilter method can safely cast the filter interface from the
// MediaFilter base class interface to the specific Filter interface.
@@ -40,12 +38,11 @@ class FilterHostImpl : public FilterHost {
: pipeline_thread_(pipeline_thread),
filter_type_(Filter::filter_type()),
filter_(filter),
- scheduled_time_update_task_(NULL),
stopped_(false) {
}
~FilterHostImpl() {}
- // If this FilterHost contains a filter of the specifed Filter class, then
+ // If this FilterHost contains a filter of the specified Filter class, then
// this method returns a pointer to the interface, otherwise it returns NULL
// in |*filter_out|.
template <class Filter>
@@ -54,10 +51,6 @@ class FilterHostImpl : public FilterHost {
reinterpret_cast<Filter*>(media_filter()) : NULL;
}
- // Call the filter if it has registered a time update callback if the filter
- // has registered one though the FilterHost::SetTimeUpdateCallback method.
- void RunTimeUpdateCallback(base::TimeDelta time);
-
// Stops the filter.
void Stop();
@@ -65,49 +58,6 @@ class FilterHostImpl : public FilterHost {
MediaFilter* media_filter() const { return filter_; }
private:
- // This task class is used to schedule a time update callback for the filter.
- // Because a filter may call the ScheduleTimeUpdateCallback method from any
- // thread, and becuase we only want to honor the last call to that method,
- // we always have only one current task.
- // We are required to keep a pointer to the host and a boolean that tells
- // us if the task was canceled because the cancelation could happen on one
- // thread, just as the pipeline thread is calling the Run method on this task.
- // So, we can't just NULL out the host_ to cancel this because it could
- // fault. Once we have called the host, it needs to enter it's critical
- // section and make sure that the task that has Run is, in fact, the last one
- // that was scheduled.
- // In the case where the filter host is Stopping (or being destroyed), it will
- // be guaranteed to happen on the pipeline thread, thus making the setting
- // of the |canceled_| bool thread safe since the task would only execute on
- // the pipeline thread. This means that it could be possible for a task to
- // hold a pointer to a |host_| that has been deleted, but it will never access
- // that pointer because the task was canceled.
- class TimeUpdateTask : public CancelableTask {
- public:
- explicit TimeUpdateTask(FilterHostImpl* host)
- : host_(host),
- canceled_(false) {}
-
- virtual void Run() {
- if (!canceled_) {
- host_->RunScheduledTimeUpdateCallback(this);
- }
- }
-
- virtual void Cancel() {
- canceled_ = true;
- }
-
- private:
- FilterHostImpl* const host_;
- bool canceled_;
-
- DISALLOW_COPY_AND_ASSIGN(TimeUpdateTask);
- };
-
- // Method used by the TimeUpdateTask to call back to the filter.
- void RunScheduledTimeUpdateCallback(TimeUpdateTask* caller);
-
// Useful method for getting the pipeline.
PipelineImpl* pipeline() const { return pipeline_thread_->pipeline(); }
@@ -120,15 +70,9 @@ class FilterHostImpl : public FilterHost {
// A pointer to the filter's MediaFilter base interface.
scoped_refptr<MediaFilter> filter_;
- // An optional callback that will be called when the time is updated.
- scoped_ptr<Callback1<base::TimeDelta>::Type> time_update_callback_;
-
// Critical section used for scheduled time update callbacks.
Lock time_update_lock_;
- // Pointer to the current time update callback task.
- TimeUpdateTask* scheduled_time_update_task_;
-
// Used to avoid calling Filter's Stop() method multiple times.
bool stopped_;
diff --git a/media/base/mock_filter_host.h b/media/base/mock_filter_host.h
index 0c1ae43..d6fde0b 100644
--- a/media/base/mock_filter_host.h
+++ b/media/base/mock_filter_host.h
@@ -40,18 +40,6 @@ class MockFilterHost : public FilterHost {
virtual ~MockFilterHost() {}
- virtual const PipelineStatus* GetPipelineStatus() const {
- return mock_pipeline_;
- }
-
- virtual void SetTimeUpdateCallback(Callback1<base::TimeDelta>::Type* cb) {
- time_update_callback_.reset(cb);
- }
-
- virtual void ScheduleTimeUpdateCallback(base::TimeDelta time) {
- scheduled_callback_time_ = time;
- }
-
virtual void InitializationComplete() {
EXPECT_FALSE(initialized_);
initialized_ = true;
@@ -64,6 +52,10 @@ class MockFilterHost : public FilterHost {
wait_for_error_.Signal();
}
+ virtual base::TimeDelta GetTime() const {
+ return mock_pipeline_->GetTime();
+ }
+
virtual void SetTime(base::TimeDelta time) {
mock_pipeline_->SetTime(time);
}
@@ -88,15 +80,6 @@ class MockFilterHost : public FilterHost {
mock_pipeline_->SetVideoSize(width, height);
}
- // Used by unit tests to manipulate the filter.
- base::TimeDelta GetScheduledCallbackTime() const {
- return scheduled_callback_time_;
- }
-
- Callback1<base::TimeDelta>::Type* GetTimeUpdateCallback() const {
- return time_update_callback_.get();
- }
-
bool IsInitialized() const {
return initialized_;
}
@@ -124,10 +107,6 @@ class MockFilterHost : public FilterHost {
private:
MockPipeline* mock_pipeline_;
scoped_refptr<Filter> filter_;
- scoped_ptr<Callback1<base::TimeDelta>::Type> time_update_callback_;
-
- // Keeps track of the time passed into ScheduleTimeUpdateCallback().
- base::TimeDelta scheduled_callback_time_;
// Tracks if the filter has executed InitializationComplete().
bool initialized_;
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 66dab005..d418e4b 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 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.
@@ -15,7 +15,7 @@
#include "media/base/factory.h"
namespace base {
- class TimeDelta;
+class TimeDelta;
}
namespace media {
@@ -44,88 +44,15 @@ enum PipelineError {
DEMUXER_ERROR_COULD_NOT_CREATE_THREAD,
};
-// Base class for Pipeline class which allows for read-only access to members.
-// Filters are allowed to access the PipelineStatus interface but are not given
-// access to the client Pipeline methods.
-class PipelineStatus {
- public:
- // Returns the current initialization state of the pipeline. Clients can
- // examine this to determine if it is acceptable to call SetRate/SetVolume/
- // Seek after calling Start on the pipeline. Note that this will be
- // set to true prior to a call to the client's |init_complete_callback| if
- // initialization is successful.
- virtual bool IsInitialized() const = 0;
-
- // Get the duration of the media in microseconds. If the duration has not
- // been determined yet, then returns 0.
- virtual base::TimeDelta GetDuration() const = 0;
-
- // Get the approximate amount of playable data buffered so far in micro-
- // seconds.
- virtual base::TimeDelta GetBufferedTime() const = 0;
-
- // 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;
-
- // Get the total number of bytes that are buffered on the client and ready to
- // be played.
- virtual int64 GetBufferedBytes() const = 0;
-
- // Gets the 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 GetVideoSize(size_t* width_out, size_t* height_out) const = 0;
-
- // 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;
-
- // 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;
-
- // Gets the current pipeline time in microseconds. For a pipeline "time"
- // progresses from 0 to the end of the media. This time base is updated
- // by the audio renderer to allow for synchronization of audio and video.
- // Note that a more accurate time may be obtained by calling the
- // GetInterpolatedTime method which estimates the position of the audio
- // device based on a combination of the last time the audio device reported
- // it's position and the current system time.
- virtual base::TimeDelta GetTime() const = 0;
-
- // Gets the current pipeline time in microseconds. For a pipeline "time"
- // progresses from 0 to the end of the media. Becuase this method provides
- // an estimated time, it is possible that subsequent calls to this method will
- // actually progress backwards slightly, so callers must not assume that this
- // method will always return times larger than the last one.
- virtual base::TimeDelta GetInterpolatedTime() const = 0;
-
- // Gets the current error status for the pipeline. If the pipeline is
- // operating correctly, this will return OK.
- virtual PipelineError GetError() const = 0;
-
- // If the |major_mime_type| exists in the pipeline and is being rendered, this
- // method will return true. Types are defined in media/base/media_foramt.h.
- // For example, to determine if a pipeline contains video:
- // bool has_video = pipeline->IsRendered(mime_type::kMajorTypeVideo);
- virtual bool IsRendered(const std::string& major_mime_type) const = 0;
-
- protected:
- virtual ~PipelineStatus() {}
-};
-
// Client-provided callbacks for various pipeline operations.
//
// TODO(scherkus): consider returning a PipelineError instead of a bool, or
// perhaps a client callback interface.
typedef Callback1<bool>::Type PipelineCallback;
-class Pipeline : public PipelineStatus {
+class Pipeline {
public:
- // Build a pipeline to render the given URI using the given filter factory to
+ // Build a pipeline to render the given URL using the given filter factory to
// construct a filter chain. Returns true if successful, false otherwise
// (i.e., pipeline already started). Note that a return value of true
// only indicates that the initialization process has started successfully.
@@ -149,42 +76,90 @@ class Pipeline : public PipelineStatus {
// the pipeline class, not on the thread that originally called the Start()
// method.
virtual bool Start(FilterFactory* filter_factory,
- const std::string& uri,
+ const std::string& url,
PipelineCallback* start_callback) = 0;
// Stops the pipeline and resets to an uninitialized state. This method
// will block the calling thread until the pipeline has been completely
- // torn down and reset to an uninitialized state. After calling Stop, it
- // is acceptable to call Start again since Stop leaves the pipeline
+ // torn down and reset to an uninitialized state. After calling Stop(), it
+ // is acceptable to call Start() again since Stop() leaves the pipeline
// in a state identical to a newly created pipeline.
- // Calling this method is not strictly required because the pipeline
- // destructor will stop it pipeline if it has not been stopped already.
+ //
+ // Stop() must be called before destroying the pipeline.
+ //
+ // TODO(scherkus): it shouldn't be acceptable to call Start() again after you
+ // Stop() a pipeline -- it should be destroyed and replaced with a new
+ // instance.
virtual void Stop() = 0;
+ // 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.
+ // The callback will return true if the seek was carried out, false otherwise
+ // (i.e., streaming media).
+ virtual void Seek(base::TimeDelta time, PipelineCallback* seek_callback) = 0;
+
+ // Returns the current initialization state of the pipeline. Note that this
+ // will be set to true prior to a executing |init_complete_callback| if
+ // initialization is successful.
+ virtual bool IsInitialized() const = 0;
+
+ // If the |major_mime_type| exists in the pipeline and is being rendered, this
+ // method will return true. Types are defined in media/base/media_foramt.h.
+ // For example, to determine if a pipeline contains video:
+ // bool has_video = pipeline->IsRendered(mime_type::kMajorTypeVideo);
+ virtual bool IsRendered(const std::string& major_mime_type) const = 0;
+
+ // 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;
+
// 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(ralphl): What about maximum rate? Does HTML5 specify a max?
//
- // This method must be called only after initialization has completed.
+ // TODO(scherkus): What about maximum rate? Does HTML5 specify a max?
virtual void SetPlaybackRate(float playback_rate) = 0;
- // 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.
- // The callback will return true if the seek was carried out, false otherwise
- // (i.e., streaming media).
- //
- // This method must be called only after initialization has completed.
- virtual void Seek(base::TimeDelta time,
- PipelineCallback* seek_callback) = 0;
+ // 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;
// 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.
- //
- // This method must be called only after initialization has completed.
virtual void SetVolume(float volume) = 0;
+ // Gets the current pipeline time. For a pipeline "time" progresses from 0 to
+ // the end of the media.
+ virtual base::TimeDelta GetTime() const = 0;
+
+ // Get the approximate amount of playable data buffered so far in micro-
+ // seconds.
+ virtual base::TimeDelta GetBufferedTime() const = 0;
+
+ // Get the duration of the media in microseconds. If the duration has not
+ // been determined yet, then returns 0.
+ virtual base::TimeDelta GetDuration() const = 0;
+
+ // Get the total number of bytes that are buffered on the client and ready to
+ // be played.
+ virtual int64 GetBufferedBytes() const = 0;
+
+ // 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;
+
+ // Gets the 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 GetVideoSize(size_t* width_out, size_t* height_out) const = 0;
+
+ // Gets the current error status for the pipeline. If the pipeline is
+ // operating correctly, this will return OK.
+ virtual PipelineError GetError() const = 0;
+
protected:
virtual ~Pipeline() {}
};
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index 16148d3..e9edc4f 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -54,110 +54,6 @@ PipelineImpl::~PipelineImpl() {
Stop();
}
-bool PipelineImpl::IsInitialized() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return initialized_;
-}
-
-base::TimeDelta PipelineImpl::GetDuration() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return duration_;
-}
-
-base::TimeDelta PipelineImpl::GetBufferedTime() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return buffered_time_;
-}
-
-int64 PipelineImpl::GetTotalBytes() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return total_bytes_;
-}
-
-int64 PipelineImpl::GetBufferedBytes() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return buffered_bytes_;
-}
-
-void PipelineImpl::GetVideoSize(size_t* width_out, size_t* height_out) const {
- DCHECK(width_out);
- DCHECK(height_out);
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- *width_out = video_width_;
- *height_out = video_height_;
-}
-
-float PipelineImpl::GetVolume() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return volume_;
-}
-
-float PipelineImpl::GetPlaybackRate() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return playback_rate_;
-}
-
-base::TimeDelta PipelineImpl::GetTime() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return time_;
-}
-
-base::TimeDelta PipelineImpl::GetInterpolatedTime() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- base::TimeDelta time = time_;
- if (playback_rate_ > 0.0f) {
- base::TimeDelta delta = base::TimeTicks::Now() - ticks_at_last_set_time_;
- if (playback_rate_ == 1.0f) {
- time += delta;
- } else {
- int64 adjusted_delta = static_cast<int64>(delta.InMicroseconds() *
- playback_rate_);
- time += base::TimeDelta::FromMicroseconds(adjusted_delta);
- }
- }
- return time;
-}
-
-void PipelineImpl::SetTime(base::TimeDelta time) {
- AutoLock auto_lock(lock_);
- time_ = time;
- ticks_at_last_set_time_ = base::TimeTicks::Now();
-}
-
-void PipelineImpl::InternalSetPlaybackRate(float rate) {
- AutoLock auto_lock(lock_);
- if (playback_rate_ == 0.0f && rate > 0.0f) {
- ticks_at_last_set_time_ = base::TimeTicks::Now();
- }
- playback_rate_ = rate;
-}
-
-PipelineError PipelineImpl::GetError() const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- return error_;
-}
-
-bool PipelineImpl::IsRendered(const std::string& major_mime_type) const {
- AutoLock auto_lock(const_cast<Lock&>(lock_));
- bool is_rendered = (rendered_mime_types_.find(major_mime_type) !=
- rendered_mime_types_.end());
- return is_rendered;
-}
-
-
-bool PipelineImpl::InternalSetError(PipelineError error) {
- // Don't want callers to set an error of "OK". STOPPING is a special value
- // that should only be used internally by the StopTask() method.
- DCHECK(PIPELINE_OK != error && PIPELINE_STOPPING != error);
- AutoLock auto_lock(lock_);
- bool changed_error = false;
- if (PIPELINE_OK == error_) {
- error_ = error;
- changed_error = true;
- }
- return changed_error;
-}
-
// Creates the PipelineThread and calls it's start method.
bool PipelineImpl::Start(FilterFactory* factory,
const std::string& url,
@@ -192,6 +88,34 @@ void PipelineImpl::Stop() {
ResetState();
}
+void PipelineImpl::Seek(base::TimeDelta time,
+ PipelineCallback* seek_callback) {
+ DCHECK(!IsPipelineThread());
+
+ if (IsPipelineOk()) {
+ pipeline_thread_->Seek(time, seek_callback);
+ } else {
+ NOTREACHED();
+ }
+}
+
+bool PipelineImpl::IsInitialized() const {
+ AutoLock auto_lock(lock_);
+ return initialized_;
+}
+
+bool PipelineImpl::IsRendered(const std::string& major_mime_type) const {
+ AutoLock auto_lock(lock_);
+ bool is_rendered = (rendered_mime_types_.find(major_mime_type) !=
+ rendered_mime_types_.end());
+ return is_rendered;
+}
+
+float PipelineImpl::GetPlaybackRate() const {
+ AutoLock auto_lock(lock_);
+ return playback_rate_;
+}
+
void PipelineImpl::SetPlaybackRate(float rate) {
DCHECK(!IsPipelineThread());
@@ -203,15 +127,9 @@ void PipelineImpl::SetPlaybackRate(float rate) {
}
}
-void PipelineImpl::Seek(base::TimeDelta time,
- PipelineCallback* seek_callback) {
- DCHECK(!IsPipelineThread());
-
- if (IsPipelineOk()) {
- pipeline_thread_->Seek(time, seek_callback);
- } else {
- NOTREACHED();
- }
+float PipelineImpl::GetVolume() const {
+ AutoLock auto_lock(lock_);
+ return volume_;
}
void PipelineImpl::SetVolume(float volume) {
@@ -224,6 +142,44 @@ void PipelineImpl::SetVolume(float volume) {
}
}
+base::TimeDelta PipelineImpl::GetTime() const {
+ AutoLock auto_lock(lock_);
+ return time_;
+}
+
+base::TimeDelta PipelineImpl::GetBufferedTime() const {
+ AutoLock auto_lock(lock_);
+ return buffered_time_;
+}
+
+base::TimeDelta PipelineImpl::GetDuration() const {
+ AutoLock auto_lock(lock_);
+ return duration_;
+}
+
+int64 PipelineImpl::GetBufferedBytes() const {
+ AutoLock auto_lock(lock_);
+ return buffered_bytes_;
+}
+
+int64 PipelineImpl::GetTotalBytes() const {
+ AutoLock auto_lock(lock_);
+ return total_bytes_;
+}
+
+void PipelineImpl::GetVideoSize(size_t* width_out, size_t* height_out) const {
+ CHECK(width_out);
+ CHECK(height_out);
+ AutoLock auto_lock(lock_);
+ *width_out = video_width_;
+ *height_out = video_height_;
+}
+
+PipelineError PipelineImpl::GetError() const {
+ AutoLock auto_lock(lock_);
+ return error_;
+}
+
void PipelineImpl::ResetState() {
AutoLock auto_lock(lock_);
pipeline_thread_ = NULL;
@@ -238,7 +194,6 @@ void PipelineImpl::ResetState() {
playback_rate_ = 0.0f;
error_ = PIPELINE_OK;
time_ = base::TimeDelta();
- ticks_at_last_set_time_ = base::TimeTicks::Now();
rendered_mime_types_.clear();
}
@@ -277,6 +232,29 @@ void PipelineImpl::SetVideoSize(size_t width, size_t height) {
video_height_ = height;
}
+void PipelineImpl::SetTime(base::TimeDelta time) {
+ AutoLock auto_lock(lock_);
+ time_ = time;
+}
+
+void PipelineImpl::InternalSetPlaybackRate(float rate) {
+ AutoLock auto_lock(lock_);
+ playback_rate_ = rate;
+}
+
+bool PipelineImpl::InternalSetError(PipelineError error) {
+ // Don't want callers to set an error of "OK". STOPPING is a special value
+ // that should only be used internally by the StopTask() method.
+ DCHECK(PIPELINE_OK != error && PIPELINE_STOPPING != error);
+ AutoLock auto_lock(lock_);
+ bool changed_error = false;
+ if (PIPELINE_OK == error_) {
+ error_ = error;
+ changed_error = true;
+ }
+ return changed_error;
+}
+
void PipelineImpl::InsertRenderedMimeType(const std::string& major_mime_type) {
AutoLock auto_lock(lock_);
rendered_mime_types_.insert(major_mime_type);
@@ -288,7 +266,6 @@ void PipelineImpl::InsertRenderedMimeType(const std::string& major_mime_type) {
PipelineThread::PipelineThread(PipelineImpl* pipeline)
: pipeline_(pipeline),
thread_("PipelineThread"),
- time_update_callback_scheduled_(false),
state_(kCreated) {
}
@@ -308,7 +285,8 @@ bool PipelineThread::Start(FilterFactory* filter_factory,
filter_factory_ = filter_factory;
url_ = url;
init_callback_.reset(init_complete_callback);
- PostTask(NewRunnableMethod(this, &PipelineThread::StartTask));
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineThread::StartTask));
return true;
}
return false;
@@ -319,7 +297,8 @@ bool PipelineThread::Start(FilterFactory* filter_factory,
// stopped.
void PipelineThread::Stop() {
if (thread_.IsRunning()) {
- PostTask(NewRunnableMethod(this, &PipelineThread::StopTask));
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineThread::StopTask));
thread_.Stop();
}
DCHECK(filter_hosts_.empty());
@@ -327,37 +306,36 @@ void PipelineThread::Stop() {
}
// Called on client's thread.
-void PipelineThread::SetPlaybackRate(float rate) {
- PostTask(NewRunnableMethod(this, &PipelineThread::SetPlaybackRateTask, rate));
+void PipelineThread::Seek(base::TimeDelta time,
+ PipelineCallback* seek_callback) {
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineThread::SeekTask, time, seek_callback));
}
// Called on client's thread.
-void PipelineThread::Seek(base::TimeDelta time,
- PipelineCallback* seek_callback) {
- PostTask(NewRunnableMethod(this, &PipelineThread::SeekTask, time,
- seek_callback));
+void PipelineThread::SetPlaybackRate(float rate) {
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineThread::SetPlaybackRateTask, rate));
}
// Called on client's thread.
void PipelineThread::SetVolume(float volume) {
- PostTask(NewRunnableMethod(this, &PipelineThread::SetVolumeTask, volume));
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineThread::SetVolumeTask, volume));
}
+// Called from any thread.
void PipelineThread::InitializationComplete(FilterHostImpl* host) {
if (IsPipelineOk()) {
// Continue the start task by proceeding to the next stage.
- PostTask(NewRunnableMethod(this, &PipelineThread::StartTask));
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineThread::StartTask));
}
}
-// Called from any thread. Updates the pipeline time and schedules a task to
-// call back to filters that have registered a callback for time updates.
+// Called from any thread. Updates the pipeline time.
void PipelineThread::SetTime(base::TimeDelta time) {
pipeline()->SetTime(time);
- if (!time_update_callback_scheduled_) {
- time_update_callback_scheduled_ = true;
- PostTask(NewRunnableMethod(this, &PipelineThread::SetTimeTask));
- }
}
// Called from any thread. Sets the pipeline |error_| member and schedules a
@@ -368,17 +346,19 @@ void PipelineThread::Error(PipelineError error) {
// If this method returns false, then an error has already happened, so no
// reason to run the StopTask again. It's going to happen.
if (pipeline()->InternalSetError(error)) {
- PostTask(NewRunnableMethod(this, &PipelineThread::StopTask));
+ message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineThread::StopTask));
}
}
-// This is a helper method to post task on message_loop(). This method is only
-// called from this class or from Pipeline.
-void PipelineThread::PostTask(Task* task) {
- message_loop()->PostTask(FROM_HERE, task);
+// Called as a result of destruction of the thread.
+//
+// TODO(scherkus): this can block the client due to synchronous Stop() API call.
+void PipelineThread::WillDestroyCurrentMessageLoop() {
+ STLDeleteElements(&filter_hosts_);
+ STLDeleteElements(&filter_threads_);
}
-
// Main initialization method called on the pipeline thread. This code attempts
// to use the specified filter factory to build a pipeline.
// Initialization step performed in this method depends on current state of this
@@ -603,29 +583,6 @@ void PipelineThread::SetVolumeTask(float volume) {
}
}
-void PipelineThread::SetTimeTask() {
- DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
-
- time_update_callback_scheduled_ = false;
- for (FilterHostVector::iterator iter = filter_hosts_.begin();
- iter != filter_hosts_.end();
- ++iter) {
- (*iter)->RunTimeUpdateCallback(pipeline_->time_);
- }
-}
-
-template <class Filter>
-void PipelineThread::GetFilter(scoped_refptr<Filter>* filter_out) const {
- DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
-
- *filter_out = NULL;
- for (FilterHostVector::const_iterator iter = filter_hosts_.begin();
- iter != filter_hosts_.end() && NULL == *filter_out;
- iter++) {
- (*iter)->GetFilter(filter_out);
- }
-}
-
template <class Filter, class Source>
void PipelineThread::CreateFilter(FilterFactory* filter_factory,
Source source,
@@ -723,12 +680,16 @@ bool PipelineThread::CreateRenderer() {
return false;
}
-// Called as a result of destruction of the thread.
-//
-// TODO(scherkus): this can block the client due to synchronous Stop() API call.
-void PipelineThread::WillDestroyCurrentMessageLoop() {
- STLDeleteElements(&filter_hosts_);
- STLDeleteElements(&filter_threads_);
+template <class Filter>
+void PipelineThread::GetFilter(scoped_refptr<Filter>* filter_out) const {
+ DCHECK_EQ(PlatformThread::CurrentId(), thread_.thread_id());
+
+ *filter_out = NULL;
+ for (FilterHostVector::const_iterator iter = filter_hosts_.begin();
+ iter != filter_hosts_.end() && NULL == *filter_out;
+ iter++) {
+ (*iter)->GetFilter(filter_out);
+ }
}
} // namespace media
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index 5e348d5..a8e9e09 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2008-2009 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.
@@ -32,29 +32,25 @@ class PipelineImpl : public Pipeline {
PipelineImpl();
virtual ~PipelineImpl();
- // Implementation of PipelineStatus methods.
+ // Pipeline implementation.
+ virtual bool Start(FilterFactory* filter_factory,
+ const std::string& uri,
+ PipelineCallback* start_callback);
+ virtual void Stop();
+ virtual void Seek(base::TimeDelta time, PipelineCallback* seek_callback);
virtual bool IsInitialized() const;
- virtual base::TimeDelta GetDuration() const;
+ virtual bool IsRendered(const std::string& major_mime_type) const;
+ virtual float GetPlaybackRate() const;
+ virtual void SetPlaybackRate(float playback_rate);
+ virtual float GetVolume() const;
+ virtual void SetVolume(float volume);
+ virtual base::TimeDelta GetTime() const;
virtual base::TimeDelta GetBufferedTime() const;
+ virtual base::TimeDelta GetDuration() const;
+ virtual int64 GetBufferedBytes() const;
virtual int64 GetTotalBytes() const;
- virtual int64 GetBufferedBytes()const;
virtual void GetVideoSize(size_t* width_out, size_t* height_out) const;
- virtual float GetVolume() const;
- virtual float GetPlaybackRate() const;
- virtual base::TimeDelta GetTime() const;
- virtual base::TimeDelta GetInterpolatedTime() const;
virtual PipelineError GetError() const;
- virtual bool IsRendered(const std::string& major_mime_type) const;
-
- // Implementation of Pipeline methods.
- virtual bool Start(FilterFactory* filter_factory,
- const std::string& url,
- PipelineCallback* start_callback);
- virtual void Stop();
- virtual void SetPlaybackRate(float rate);
- virtual void Seek(base::TimeDelta time,
- PipelineCallback* seek_callback);
- virtual void SetVolume(float volume);
private:
friend class FilterHostImpl;
@@ -117,7 +113,7 @@ class PipelineImpl : public Pipeline {
int64 total_bytes_;
// Lock used to serialize access for getter/setter methods.
- Lock lock_;
+ mutable Lock lock_;
// Video width and height. Set by a FilterHostImpl object on behalf
// of a filter. The video_size_access_lock_ is used to make sure access
@@ -142,10 +138,6 @@ class PipelineImpl : public Pipeline {
// audio renderer filter.
base::TimeDelta time_;
- // Internal system timer at last time the SetTime method was called. Used to
- // compute interpolated time.
- base::TimeTicks ticks_at_last_set_time_;
-
// 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
@@ -195,8 +187,8 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
const std::string& url_media_source,
PipelineCallback* init_complete_callback);
void Stop();
- void SetPlaybackRate(float rate);
void Seek(base::TimeDelta time, PipelineCallback* seek_callback);
+ void SetPlaybackRate(float rate);
void SetVolume(float volume);
// Methods called by a FilterHostImpl object. These methods may be called
@@ -215,10 +207,6 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
// If the pipeline is running a nested message loop, it will be exited.
void Error(PipelineError error);
- // Called by a FilterHostImpl on behalf of a filter that calls the
- // FilterHost::PostTask method.
- void PostTask(Task* task);
-
// Simple accessor used by the FilterHostImpl class to get access to the
// pipeline object.
PipelineImpl* pipeline() const { return pipeline_; }
@@ -231,6 +219,10 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
PlatformThreadId thread_id() const { return thread_.thread_id(); }
private:
+ // Only allow ourselves to be destroyed via ref-counting.
+ friend class base::RefCountedThreadSafe<PipelineThread>;
+ virtual ~PipelineThread();
+
enum State {
kCreated,
kInitDataSource,
@@ -244,16 +236,6 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
kError,
};
- // Implementation of MessageLoop::DestructionObserver. StartTask registers
- // this class as a destruction observer on the thread's message loop.
- // It is used to destroy the list of FilterHosts
- // (and thus destroy the associated filters) when all tasks have been
- // processed and the message loop has been quit.
- virtual void WillDestroyCurrentMessageLoop();
-
- friend class base::RefCountedThreadSafe<PipelineThread>;
- virtual ~PipelineThread();
-
// Simple method used to make sure the pipeline is running normally.
bool IsPipelineOk() { return PIPELINE_OK == pipeline_->error_; }
@@ -267,6 +249,13 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
state_ == kInitVideoRenderer;
}
+ // Implementation of MessageLoop::DestructionObserver. StartTask registers
+ // this class as a destruction observer on the thread's message loop.
+ // It is used to destroy the list of FilterHosts
+ // (and thus destroy the associated filters) when all tasks have been
+ // processed and the message loop has been quit.
+ virtual void WillDestroyCurrentMessageLoop();
+
// The following "task" methods correspond to the public methods, but these
// methods are run as the result of posting a task to the PipelineThread's
// message loop.
@@ -280,14 +269,10 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
void SetPlaybackRateTask(float rate);
void SeekTask(base::TimeDelta time, PipelineCallback* seek_callback);
void SetVolumeTask(float volume);
- void SetTimeTask();
// Internal methods used in the implementation of the pipeline thread. All
// of these methods are only called on the pipeline thread.
- // Calls the Stop method on every filter in the pipeline
- void StopFilters();
-
// The following template functions make use of the fact that media filter
// derived interfaces are self-describing in the sense that they all contain
// the static method filter_type() which returns a FilterType enum that
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index 2a9ba66..094c92a 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -188,7 +188,7 @@ void VideoRendererBase::ThreadMain() {
OnFrameAvailable();
// Determine the current and next presentation timestamps.
- base::TimeDelta now = host_->GetPipelineStatus()->GetTime();
+ base::TimeDelta now = host_->GetTime();
base::TimeDelta this_pts = current_frame_->GetTimestamp();
base::TimeDelta next_pts;
if (next_frame) {
diff --git a/media/player/movie.cc b/media/player/movie.cc
index 1ef840f..e37a497 100644
--- a/media/player/movie.cc
+++ b/media/player/movie.cc
@@ -119,7 +119,7 @@ float Movie::GetDuration() {
float Movie::GetPosition() {
float position = 0.f;
if (pipeline_.get())
- position = (pipeline_->GetInterpolatedTime()).InMicroseconds() / 1000000.0f;
+ position = (pipeline_->GetTime()).InMicroseconds() / 1000000.0f;
return position;
}