summaryrefslogtreecommitdiffstats
path: root/media/base/pipeline_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'media/base/pipeline_impl.h')
-rw-r--r--media/base/pipeline_impl.h139
1 files changed, 72 insertions, 67 deletions
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index a8e9e09..2d6b988 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -20,24 +20,25 @@
namespace media {
class FilterHostImpl;
-class PipelineThread;
+class PipelineInternal;
// Class which implements the Media::Pipeline contract. The majority of the
-// actual code for this object lives in the PipelineThread class, which is
+// actual code for this object lives in the PipelineInternal class, which is
// responsible for actually building and running the pipeline. This object
// is basically a simple container for state information, and is responsible
-// for creating and communicating with the PipelineThread object.
+// for creating and communicating with the PipelineInternal object.
class PipelineImpl : public Pipeline {
public:
- PipelineImpl();
+ PipelineImpl(MessageLoop* message_loop);
virtual ~PipelineImpl();
// Pipeline implementation.
virtual bool Start(FilterFactory* filter_factory,
const std::string& uri,
PipelineCallback* start_callback);
- virtual void Stop();
+ virtual void Stop(PipelineCallback* stop_callback);
virtual void Seek(base::TimeDelta time, PipelineCallback* seek_callback);
+ virtual bool IsRunning() const;
virtual bool IsInitialized() const;
virtual bool IsRendered(const std::string& major_mime_type) const;
virtual float GetPlaybackRate() const;
@@ -54,7 +55,7 @@ class PipelineImpl : public Pipeline {
private:
friend class FilterHostImpl;
- friend class PipelineThread;
+ friend class PipelineInternal;
// Reset the state of the pipeline object to the initial state. This method
// is used by the constructor, and the Stop method.
@@ -65,10 +66,6 @@ class PipelineImpl : public Pipeline {
// must not be an error.
bool IsPipelineOk() const;
- // Returns true if we're currently executing on the pipeline thread. Mostly
- // used in DCHECKs.
- bool IsPipelineThread() const;
-
// Methods called by FilterHostImpl to update pipeline state.
void SetDuration(base::TimeDelta duration);
void SetBufferedTime(base::TimeDelta buffered_time);
@@ -83,14 +80,17 @@ class PipelineImpl : public Pipeline {
// alone, and returns false.
bool InternalSetError(PipelineError error);
- // Method called by the |pipeline_thread_| to insert a mime type into
+ // Method called by the |pipeline_internal_| to insert a mime type into
// the |rendered_mime_types_| set.
void InsertRenderedMimeType(const std::string& major_mime_type);
- // Holds a ref counted reference to the PipelineThread object associated
- // with this pipeline. Prior to the call to the Start method, this member
- // will be NULL, since no thread is running.
- scoped_refptr<PipelineThread> pipeline_thread_;
+ // Message loop used to execute pipeline tasks.
+ MessageLoop* message_loop_;
+
+ // Holds a ref counted reference to the PipelineInternal object associated
+ // with this pipeline. Prior to the call to the Start() method, this member
+ // will be NULL, since we are not running.
+ scoped_refptr<PipelineInternal> pipeline_internal_;
// After calling Start, if all of the required filters are created and
// initialized, this member will be set to true by the pipeline thread.
@@ -124,14 +124,14 @@ class PipelineImpl : public Pipeline {
// Current volume level (from 0.0f to 1.0f). The volume reflects the last
// value the audio filter was called with SetVolume, so there will be a short
// period of time between the client calling SetVolume on the pipeline and
- // this value being updated. Set by the PipelineThread just prior to calling
- // the audio renderer.
+ // this value being updated. Set by the PipelineInternal just prior to
+ // calling the audio renderer.
float volume_;
// Current playback rate (>= 0.0f). This member reflects the last value
// that the filters in the pipeline were called with, so there will be a short
// period of time between the client calling SetPlaybackRate and this value
- // being updated. Set by the PipelineThread just prior to calling filters.
+ // being updated. Set by the PipelineInternal just prior to calling filters.
float playback_rate_;
// Current playback time. Set by a FilterHostImpl object on behalf of the
@@ -152,12 +152,12 @@ class PipelineImpl : public Pipeline {
};
-// The PipelineThread contains most of the logic involved with running the
-// media pipeline. Filters are created and called on a dedicated thread owned
-// by this object. This object works like a state machine to perform
-// asynchronous initialization. Initialization is done in multiple passes in
-// StartTask(). In each pass a different filter is created and chained with a
-// previously created filter.
+// PipelineInternal contains most of the logic involved with running the
+// media pipeline. Filters are created and called on the message loop injected
+// into this object. PipelineInternal works like a state machine to perform
+// asynchronous initialization. Initialization is done in multiple passes by
+// InitializeTask(). In each pass a different filter is created and chained with
+// a previously created filter.
//
// Here's a state diagram that describes the lifetime of this object.
//
@@ -172,21 +172,20 @@ class PipelineImpl : public Pipeline {
// transition to the "Error" state from any state. If Stop() is called during
// initialization, this object will transition to "Stopped" state.
-class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
- public MessageLoop::DestructionObserver {
+class PipelineInternal : public base::RefCountedThreadSafe<PipelineInternal> {
public:
// Methods called by PipelineImpl object on the client's thread. These
// methods post a task to call a corresponding xxxTask() method on the
- // pipeline thread. For example, Seek posts a task to call SeekTask.
- explicit PipelineThread(PipelineImpl* pipeline);
+ // message loop. For example, Seek posts a task to call SeekTask.
+ explicit PipelineInternal(PipelineImpl* pipeline, MessageLoop* message_loop);
// After Start() is called, a task of StartTask() is posted on the pipeline
// thread to perform initialization. See StartTask() to learn more about
// initialization.
- bool Start(FilterFactory* filter_factory,
+ void Start(FilterFactory* filter_factory,
const std::string& url_media_source,
- PipelineCallback* init_complete_callback);
- void Stop();
+ PipelineCallback* start_callback);
+ void Stop(PipelineCallback* stop_callback);
void Seek(base::TimeDelta time, PipelineCallback* seek_callback);
void SetPlaybackRate(float rate);
void SetVolume(float volume);
@@ -209,19 +208,18 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
// Simple accessor used by the FilterHostImpl class to get access to the
// pipeline object.
+ //
+ // TODO(scherkus): I think FilterHostImpl should not be talking to
+ // PipelineImpl but rather PipelineInternal.
PipelineImpl* pipeline() const { return pipeline_; }
- // Accessor used to post messages to thread's message loop.
- MessageLoop* message_loop() const { return thread_.message_loop(); }
-
- // Accessor used by PipelineImpl to check if we're executing on the pipeline
- // thread.
- PlatformThreadId thread_id() const { return thread_.thread_id(); }
+ // Returns true if the pipeline has fully initialized.
+ bool IsInitialized() { return state_ == kStarted; }
private:
// Only allow ourselves to be destroyed via ref-counting.
- friend class base::RefCountedThreadSafe<PipelineThread>;
- virtual ~PipelineThread();
+ friend class base::RefCountedThreadSafe<PipelineInternal>;
+ virtual ~PipelineInternal();
enum State {
kCreated,
@@ -249,23 +247,29 @@ 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
+ // methods are run as the result of posting a task to the PipelineInternal's
// message loop.
+ void StartTask(FilterFactory* filter_factory,
+ const std::string& url,
+ PipelineCallback* 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.
+ void InitializeTask();
+
+ // StopTask() and ErrorTask() are similar but serve different purposes:
+ // - Both destroy the filter chain.
+ // - Both will execute |start_callback| if the pipeline was initializing.
+ // - StopTask() resets the pipeline to a fresh state, where as ErrorTask()
+ // leaves the pipeline as is for client inspection.
+ // - StopTask() can be scheduled by the client calling Stop(), where as
+ // ErrorTask() is scheduled as a result of a filter calling Error().
+ void StopTask(PipelineCallback* stop_callback);
+ void ErrorTask(PipelineError error);
- // StartTask() is a special task that 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.
- void StartTask();
- void StopTask();
void SetPlaybackRateTask(float rate);
void SeekTask(base::TimeDelta time, PipelineCallback* seek_callback);
void SetVolumeTask(float volume);
@@ -302,8 +306,8 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
Source source,
const MediaFormat& source_media_format);
- // Creates a Filter and initilizes it with the given |source|. If a Filter
- // could not be created or an error occurred, this metod returns NULL and the
+ // Creates a Filter and initializes it with the given |source|. If a Filter
+ // could not be created or an error occurred, this method returns NULL and the
// pipeline's |error_| member will contain a specific error code. Note that
// the Source could be a filter or a DemuxerStream, but it must support the
// GetMediaFormat() method.
@@ -339,16 +343,15 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
template <class Filter>
void GetFilter(scoped_refptr<Filter>* filter_out) const;
- // Pointer to the pipeline that owns this PipelineThread.
- PipelineImpl* const pipeline_;
+ // Stops every filters, filter host and filter thread and releases all
+ // references to them.
+ void DestroyFilters();
- // The actual thread.
- base::Thread thread_;
+ // Pointer to the pipeline that owns this PipelineInternal.
+ PipelineImpl* pipeline_;
- // Used to avoid scheduling multiple time update tasks. If this member is
- // true then a task that will call the SetTimeTask() method is in the message
- // loop's queue.
- bool time_update_callback_scheduled_;
+ // Message loop used to execute pipeline tasks.
+ MessageLoop* message_loop_;
// Member that tracks the current state.
State state_;
@@ -359,17 +362,19 @@ class PipelineThread : public base::RefCountedThreadSafe<PipelineThread>,
// URL for the data source as passed in by Start().
std::string url_;
- // Initialization callback as passed in by Start().
- scoped_ptr<PipelineCallback> init_callback_;
+ // Callbacks for various pipeline operations.
+ scoped_ptr<PipelineCallback> start_callback_;
+ scoped_ptr<PipelineCallback> seek_callback_;
+ scoped_ptr<PipelineCallback> stop_callback_;
- // Vector of FilterHostImpl objects that contian the filters for the pipeline.
+ // Vector of FilterHostImpl objects that contain the filters for the pipeline.
typedef std::vector<FilterHostImpl*> FilterHostVector;
FilterHostVector filter_hosts_;
typedef std::vector<base::Thread*> FilterThreadVector;
FilterThreadVector filter_threads_;
- DISALLOW_COPY_AND_ASSIGN(PipelineThread);
+ DISALLOW_COPY_AND_ASSIGN(PipelineInternal);
};
} // namespace media