Commit 83548cfb authored by scherkus@chromium.org's avatar scherkus@chromium.org

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
parent cfdae275
// 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -24,31 +24,6 @@ namespace media { ...@@ -24,31 +24,6 @@ namespace media {
class FilterHost { class FilterHost {
public: 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 // Filters must call this method to indicate that their initialization is
// complete. They may call this from within their Initialize() method or may // complete. They may call this from within their Initialize() method or may
// choose call it after processing some data. // choose call it after processing some data.
...@@ -58,8 +33,11 @@ class FilterHost { ...@@ -58,8 +33,11 @@ class FilterHost {
// method with PIPELINE_OK or PIPELINE_STOPPING (used internally by pipeline). // method with PIPELINE_OK or PIPELINE_STOPPING (used internally by pipeline).
virtual void Error(PipelineError error) = 0; virtual void Error(PipelineError error) = 0;
// Sets the current time. Any filters that have registered a callback through // Gets the current time in microseconds.
// the SetTimeUpdateCallback method will be notified of the change. 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; virtual void SetTime(base::TimeDelta time) = 0;
// Get the duration of the media in microseconds. If the duration has not // Get the duration of the media in microseconds. If the duration has not
......
// 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -6,56 +6,6 @@ ...@@ -6,56 +6,6 @@
namespace media { 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() { void FilterHostImpl::InitializationComplete() {
pipeline_thread_->InitializationComplete(this); pipeline_thread_->InitializationComplete(this);
} }
...@@ -64,6 +14,10 @@ void FilterHostImpl::Error(PipelineError error) { ...@@ -64,6 +14,10 @@ void FilterHostImpl::Error(PipelineError error) {
pipeline_thread_->Error(error); pipeline_thread_->Error(error);
} }
base::TimeDelta FilterHostImpl::GetTime() const {
return pipeline()->GetTime();
}
void FilterHostImpl::SetTime(base::TimeDelta time) { void FilterHostImpl::SetTime(base::TimeDelta time) {
pipeline_thread_->SetTime(time); pipeline_thread_->SetTime(time);
} }
...@@ -88,18 +42,11 @@ void FilterHostImpl::SetVideoSize(size_t width, size_t height) { ...@@ -88,18 +42,11 @@ void FilterHostImpl::SetVideoSize(size_t width, size_t height) {
pipeline()->SetVideoSize(width, height); pipeline()->SetVideoSize(width, height);
} }
const PipelineStatus* FilterHostImpl::GetPipelineStatus() const {
return pipeline();
}
void FilterHostImpl::Stop() { void FilterHostImpl::Stop() {
if (!stopped_) { if (!stopped_) {
filter_->Stop(); filter_->Stop();
AutoLock auto_lock(time_update_lock_); AutoLock auto_lock(time_update_lock_);
stopped_ = true; stopped_ = true;
if (scheduled_time_update_task_) {
scheduled_time_update_task_->Cancel();
}
} }
} }
......
// 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -16,11 +16,9 @@ namespace media { ...@@ -16,11 +16,9 @@ namespace media {
class FilterHostImpl : public FilterHost { class FilterHostImpl : public FilterHost {
public: public:
// FilterHost interface. // 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 InitializationComplete();
virtual void Error(PipelineError error); virtual void Error(PipelineError error);
virtual base::TimeDelta GetTime() const;
virtual void SetTime(base::TimeDelta time); virtual void SetTime(base::TimeDelta time);
virtual void SetDuration(base::TimeDelta duration); virtual void SetDuration(base::TimeDelta duration);
virtual void SetBufferedTime(base::TimeDelta buffered_time); virtual void SetBufferedTime(base::TimeDelta buffered_time);
...@@ -31,7 +29,7 @@ class FilterHostImpl : public FilterHost { ...@@ -31,7 +29,7 @@ class FilterHostImpl : public FilterHost {
// These methods are public, but are intended for use by the // These methods are public, but are intended for use by the
// PipelineThread class only. // 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 // by calling the Filter class's static filter_type() method. This ensures
// that the GetFilter method can safely cast the filter interface from the // that the GetFilter method can safely cast the filter interface from the
// MediaFilter base class interface to the specific Filter interface. // MediaFilter base class interface to the specific Filter interface.
...@@ -40,12 +38,11 @@ class FilterHostImpl : public FilterHost { ...@@ -40,12 +38,11 @@ class FilterHostImpl : public FilterHost {
: pipeline_thread_(pipeline_thread), : pipeline_thread_(pipeline_thread),
filter_type_(Filter::filter_type()), filter_type_(Filter::filter_type()),
filter_(filter), filter_(filter),
scheduled_time_update_task_(NULL),
stopped_(false) { stopped_(false) {
} }
~FilterHostImpl() {} ~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 // this method returns a pointer to the interface, otherwise it returns NULL
// in |*filter_out|. // in |*filter_out|.
template <class Filter> template <class Filter>
...@@ -54,10 +51,6 @@ class FilterHostImpl : public FilterHost { ...@@ -54,10 +51,6 @@ class FilterHostImpl : public FilterHost {
reinterpret_cast<Filter*>(media_filter()) : NULL; 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. // Stops the filter.
void Stop(); void Stop();
...@@ -65,49 +58,6 @@ class FilterHostImpl : public FilterHost { ...@@ -65,49 +58,6 @@ class FilterHostImpl : public FilterHost {
MediaFilter* media_filter() const { return filter_; } MediaFilter* media_filter() const { return filter_; }
private: 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. // Useful method for getting the pipeline.
PipelineImpl* pipeline() const { return pipeline_thread_->pipeline(); } PipelineImpl* pipeline() const { return pipeline_thread_->pipeline(); }
...@@ -120,15 +70,9 @@ class FilterHostImpl : public FilterHost { ...@@ -120,15 +70,9 @@ class FilterHostImpl : public FilterHost {
// A pointer to the filter's MediaFilter base interface. // A pointer to the filter's MediaFilter base interface.
scoped_refptr<MediaFilter> filter_; 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. // Critical section used for scheduled time update callbacks.
Lock time_update_lock_; 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. // Used to avoid calling Filter's Stop() method multiple times.
bool stopped_; bool stopped_;
......
...@@ -40,18 +40,6 @@ class MockFilterHost : public FilterHost { ...@@ -40,18 +40,6 @@ class MockFilterHost : public FilterHost {
virtual ~MockFilterHost() {} 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() { virtual void InitializationComplete() {
EXPECT_FALSE(initialized_); EXPECT_FALSE(initialized_);
initialized_ = true; initialized_ = true;
...@@ -64,6 +52,10 @@ class MockFilterHost : public FilterHost { ...@@ -64,6 +52,10 @@ class MockFilterHost : public FilterHost {
wait_for_error_.Signal(); wait_for_error_.Signal();
} }
virtual base::TimeDelta GetTime() const {
return mock_pipeline_->GetTime();
}
virtual void SetTime(base::TimeDelta time) { virtual void SetTime(base::TimeDelta time) {
mock_pipeline_->SetTime(time); mock_pipeline_->SetTime(time);
} }
...@@ -88,15 +80,6 @@ class MockFilterHost : public FilterHost { ...@@ -88,15 +80,6 @@ class MockFilterHost : public FilterHost {
mock_pipeline_->SetVideoSize(width, height); 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 { bool IsInitialized() const {
return initialized_; return initialized_;
} }
...@@ -124,10 +107,6 @@ class MockFilterHost : public FilterHost { ...@@ -124,10 +107,6 @@ class MockFilterHost : public FilterHost {
private: private:
MockPipeline* mock_pipeline_; MockPipeline* mock_pipeline_;
scoped_refptr<Filter> filter_; 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(). // Tracks if the filter has executed InitializationComplete().
bool initialized_; bool initialized_;
......
// 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include "media/base/factory.h" #include "media/base/factory.h"
namespace base { namespace base {
class TimeDelta; class TimeDelta;
} }
namespace media { namespace media {
...@@ -44,88 +44,15 @@ enum PipelineError { ...@@ -44,88 +44,15 @@ enum PipelineError {
DEMUXER_ERROR_COULD_NOT_CREATE_THREAD, 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. // Client-provided callbacks for various pipeline operations.
// //
// TODO(scherkus): consider returning a PipelineError instead of a bool, or // TODO(scherkus): consider returning a PipelineError instead of a bool, or
// perhaps a client callback interface. // perhaps a client callback interface.
typedef Callback1<bool>::Type PipelineCallback; typedef Callback1<bool>::Type PipelineCallback;
class Pipeline : public PipelineStatus { class Pipeline {
public: 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 // construct a filter chain. Returns true if successful, false otherwise
// (i.e., pipeline already started). Note that a return value of true // (i.e., pipeline already started). Note that a return value of true
// only indicates that the initialization process has started successfully. // only indicates that the initialization process has started successfully.
...@@ -149,42 +76,90 @@ class Pipeline : public PipelineStatus { ...@@ -149,42 +76,90 @@ class Pipeline : public PipelineStatus {
// the pipeline class, not on the thread that originally called the Start() // the pipeline class, not on the thread that originally called the Start()
// method. // method.
virtual bool Start(FilterFactory* filter_factory, virtual bool Start(FilterFactory* filter_factory,
const std::string& uri, const std::string& url,
PipelineCallback* start_callback) = 0; PipelineCallback* start_callback) = 0;
// Stops the pipeline and resets to an uninitialized state. This method // Stops the pipeline and resets to an uninitialized state. This method
// will block the calling thread until the pipeline has been completely // will block the calling thread until the pipeline has been completely
// torn down and reset to an uninitialized state. After calling Stop, it // torn down and reset to an uninitialized state. After calling Stop(), it
// is acceptable to call Start again since Stop leaves the pipeline // is acceptable to call Start() again since Stop() leaves the pipeline
// in a state identical to a newly created 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; 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 // 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 // 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. // 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; virtual void SetPlaybackRate(float playback_rate) = 0;
// Attempt to seek to the position specified by time. |seek_callback| will be // Gets the current volume setting being used by the audio renderer. When
// executed when the all filters in the pipeline have processed the seek. // the pipeline is started, this value will be 1.0f. Valid values range
// The callback will return true if the seek was carried out, false otherwise // from 0.0f to 1.0f.
// (i.e., streaming media). virtual float GetVolume() const = 0;
//
// This method must be called only after initialization has completed.
virtual void Seek(base::TimeDelta time,
PipelineCallback* seek_callback) = 0;
// Attempt to set the volume of the audio renderer. Valid values for volume // 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 // range from 0.0f (muted) to 1.0f (full volume). This value affects all
// channels proportionately for multi-channel audio streams. // channels proportionately for multi-channel audio streams.
//
// This method must be called only after initialization has completed.
virtual void SetVolume(float volume) = 0; 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: protected:
virtual ~Pipeline() {} virtual ~Pipeline() {}
}; };
......
This diff is collapsed.
// 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 // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -32,29 +32,25 @@ class PipelineImpl : public Pipeline { ...@@ -32,29 +32,25 @@ class PipelineImpl : public Pipeline {
PipelineImpl(); PipelineImpl();
virtual ~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 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 GetBufferedTime() const;
virtual base::TimeDelta GetDuration() const;
virtual int64 GetBufferedBytes() const;
virtual int64 GetTotalBytes() const; virtual int64 GetTotalBytes() const;
virtual int64 GetBufferedBytes()const;
virtual void GetVideoSize(size_t* width_out, size_t* height_out) 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 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: private:
friend class FilterHostImpl; friend class FilterHostImpl;
...@@ -117,7 +113,7 @@ class PipelineImpl : public Pipeline { ...@@ -117,7 +113,7 @@ class PipelineImpl : public Pipeline {
int64 total_bytes_; int64 total_bytes_;
// Lock used to serialize access for getter/setter methods. // 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 // 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 // of a filter. The video_size_access_lock_ is used to make sure access
...@@ -142,10 +138,6 @@ class PipelineImpl : public Pipeline { ...@@ -142,10 +138,6 @@ class PipelineImpl : public Pipeline {
// audio renderer filter. // audio renderer filter.
base::TimeDelta time_; 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 // Status of the pipeline. Initialized to PIPELINE_OK which indicates that
// the pipeline is operating correctly. Any other value indicates that the // the pipeline is operating correctly. Any other value indicates that the
// pipeline is stopped or is stopping. Clients can call the Stop method to // pipeline is stopped or is stopping. Clients can call the Stop method to
...@@ -195,8 +187,8 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>, ...@@ -195,8 +187,8 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
const std::string& url_media_source, const std::string& url_media_source,
PipelineCallback* init_complete_callback); PipelineCallback* init_complete_callback);
void Stop(); void Stop();
void SetPlaybackRate(float rate);
void Seek(base::TimeDelta time, PipelineCallback* seek_callback); void Seek(base::TimeDelta time, PipelineCallback* seek_callback);
void SetPlaybackRate(float rate);
void SetVolume(float volume); void SetVolume(float volume);
// Methods called by a FilterHostImpl object. These methods may be called // Methods called by a FilterHostImpl object. These methods may be called
...@@ -215,10 +207,6 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>, ...@@ -215,10 +207,6 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
// If the pipeline is running a nested message loop, it will be exited. // If the pipeline is running a nested message loop, it will be exited.
void Error(PipelineError error); 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 // Simple accessor used by the FilterHostImpl class to get access to the
// pipeline object. // pipeline object.
PipelineImpl* pipeline() const { return pipeline_; } PipelineImpl* pipeline() const { return pipeline_; }
...@@ -231,6 +219,10 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>, ...@@ -231,6 +219,10 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
PlatformThreadId thread_id() const { return thread_.thread_id(); } PlatformThreadId thread_id() const { return thread_.thread_id(); }
private: private:
// Only allow ourselves to be destroyed via ref-counting.
friend class base::RefCountedThreadSafe<PipelineThread>;
virtual ~PipelineThread();
enum State { enum State {
kCreated, kCreated,
kInitDataSource, kInitDataSource,
...@@ -244,16 +236,6 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>, ...@@ -244,16 +236,6 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
kError, 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. // Simple method used to make sure the pipeline is running normally.
bool IsPipelineOk() { return PIPELINE_OK == pipeline_->error_; } bool IsPipelineOk() { return PIPELINE_OK == pipeline_->error_; }
...@@ -267,6 +249,13 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>, ...@@ -267,6 +249,13 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
state_ == kInitVideoRenderer; 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 // 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 // methods are run as the result of posting a task to the PipelineThread's
// message loop. // message loop.
...@@ -280,14 +269,10 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>, ...@@ -280,14 +269,10 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
void SetPlaybackRateTask(float rate); void SetPlaybackRateTask(float rate);
void SeekTask(base::TimeDelta time, PipelineCallback* seek_callback); void SeekTask(base::TimeDelta time, PipelineCallback* seek_callback);
void SetVolumeTask(float volume); void SetVolumeTask(float volume);
void SetTimeTask();
// Internal methods used in the implementation of the pipeline thread. All // Internal methods used in the implementation of the pipeline thread. All
// of these methods are only called on the pipeline thread. // 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 // The following template functions make use of the fact that media filter
// derived interfaces are self-describing in the sense that they all contain // derived interfaces are self-describing in the sense that they all contain
// the static method filter_type() which returns a FilterType enum that // the static method filter_type() which returns a FilterType enum that
......
...@@ -188,7 +188,7 @@ void VideoRendererBase::ThreadMain() { ...@@ -188,7 +188,7 @@ void VideoRendererBase::ThreadMain() {
OnFrameAvailable(); OnFrameAvailable();
// Determine the current and next presentation timestamps. // 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 this_pts = current_frame_->GetTimestamp();
base::TimeDelta next_pts; base::TimeDelta next_pts;
if (next_frame) { if (next_frame) {
......
...@@ -119,7 +119,7 @@ float Movie::GetDuration() { ...@@ -119,7 +119,7 @@ float Movie::GetDuration() {
float Movie::GetPosition() { float Movie::GetPosition() {
float position = 0.f; float position = 0.f;
if (pipeline_.get()) if (pipeline_.get())
position = (pipeline_->GetInterpolatedTime()).InMicroseconds() / 1000000.0f; position = (pipeline_->GetTime()).InMicroseconds() / 1000000.0f;
return position; return position;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment