Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Unified Diff: media/base/pipeline.h

Issue 10828045: Rewrite media::Pipeline state transition machinery. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: stuff Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/base/pipeline.h
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index ce028be1be6b3f1102d4e126f68eaefa8a559d85..53a6a45e29166c37b2dfa976ad65126d08fdee93 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -64,28 +64,19 @@ class MEDIA_EXPORT PipelineStatusNotification {
// message loop injected into this object. Pipeline works like a state
// machine to perform asynchronous initialization, pausing, seeking and playing.
//
-// Here's a state diagram that describes the lifetime of this object.
-//
-// [ *Created ] [ Stopped ]
-// | Start() ^
-// V SetError() |
-// [ InitXXX (for each filter) ] -------->[ Stopping (for each filter) ]
-// | ^
-// V | if Stop
-// [ Seeking (for each filter) ] <--------[ Flushing (for each filter) ]
-// | if Seek ^
-// V |
-// [ Starting (for each filter) ] |
-// | |
-// V Seek()/Stop() |
-// [ Started ] -------------------------> [ Pausing (for each filter) ]
-// | ^
-// | OnRendererEnded() Seek()/Stop() |
-// `-------------> [ Ended ] ---------------------'
-// ^ SetError()
-// |
-// [ Any State Other Than InitXXX ]
-
+// kCreated (from any state)
+// | Start() | Stop()/SetError()
+// V V
+// kInitXXX (for each component) kStopping
+// | |
+// V V
+// kSeeking <-------------. kStopped
+// | |
+// V |
+// kStarting kFlushing
+// | ^
+// V Seek() |
+// kStarted ---------> kPausing
Ami GONE FROM CHROMIUM 2012/07/30 04:06:21 The fact that most states have a single ingress ed
//
// Initialization is a series of state transitions from "Created" through each
// filter initialization state. When all filter initialization states have
@@ -94,9 +85,8 @@ class MEDIA_EXPORT PipelineStatusNotification {
// From then on the normal Seek() transitions are carried out and we start
// playing the media.
//
-// If any error ever happens, this object will transition to the "Error" state
-// from any state. If Stop() is ever called, this object will transition to
-// "Stopped" state.
+// If Stop() is invoked or an error occurs during any point in time, the
+// pipeline will transition to a stopped state.
Ami GONE FROM CHROMIUM 2012/07/30 04:06:21 s/stopped/(terminal) stopped/
class MEDIA_EXPORT Pipeline
: public base::RefCountedThreadSafe<Pipeline>,
public DemuxerHost {
@@ -107,10 +97,6 @@ class MEDIA_EXPORT Pipeline
// Build a pipeline to using the given filter collection to construct a filter
// chain.
//
- // Pipeline initialization is an inherently asynchronous process. Clients can
- // either poll the IsInitialized() method (discouraged) or optionally pass in
- // |start_cb|, which will be executed when initialization completes.
- //
// The following permanent callbacks will be executed as follows:
// |start_cb_| will be executed when Start is done (successfully or not).
// |ended_cb| will be executed whenever the media reaches the end.
@@ -121,8 +107,6 @@ class MEDIA_EXPORT Pipeline
// Stop() has completed.
//
// It is an error to call this method after the pipeline has already started.
- //
- // TODO(scherkus): remove IsInitialized() and force clients to use callbacks.
void Start(scoped_ptr<FilterCollection> filter_collection,
const PipelineStatusCB& ended_cb,
const PipelineStatusCB& error_cb,
@@ -157,11 +141,6 @@ class MEDIA_EXPORT Pipeline
// the pipeline.
bool IsRunning() const;
- // Returns true if the pipeline has been started and fully initialized to a
Ami GONE FROM CHROMIUM 2012/07/30 04:06:21 hawt!
- // point where playback controls will be respected. Note that it is possible
- // for a pipeline to be started but not initialized (i.e., an error occurred).
- bool IsInitialized() const;
-
// Returns true if the media has audio.
bool HasAudio() const;
@@ -219,6 +198,7 @@ class MEDIA_EXPORT Pipeline
PipelineStatistics GetStatistics() const;
void SetClockForTesting(Clock* clock);
+ void SetErrorForTesting(PipelineStatus status);
private:
FRIEND_TEST_ALL_PREFIXES(PipelineTest, GetBufferedTimeRanges);
@@ -241,50 +221,28 @@ class MEDIA_EXPORT Pipeline
kInitVideoDecoder,
kInitVideoRenderer,
kPausing,
- kSeeking,
kFlushing,
+ kSeeking,
kStarting,
kStarted,
- kEnded,
scherkus (not reviewing) 2012/07/28 02:26:07 kEnded wasn't actually used so it's been folded in
kStopping,
kStopped,
- kError,
scherkus (not reviewing) 2012/07/28 02:26:07 kError has been replaced by kStopped && status_ !=
};
- // Reset the state of the pipeline object to the initial state. This method
- // is used by the constructor, and the Stop() method.
- void ResetState();
scherkus (not reviewing) 2012/07/28 02:26:07 This was only called via Stop() path but not SetEr
-
// Updates |state_|. All state transitions should use this call.
void SetState(State next_state);
// Simple method used to make sure the pipeline is running normally.
bool IsPipelineOk();
- // Helper method to tell whether we are stopped or in error.
- bool IsPipelineStopped();
-
- // Helper method to tell whether we are in transition to stop state.
- bool IsPipelineTearingDown();
-
- // We could also be delayed by a transition during seek is performed.
- bool IsPipelineStopPending();
-
- // Helper method to tell whether we are in transition to seek state.
- bool IsPipelineSeeking();
-
- // Helper method to execute callback from Start() and reset
- // |filter_collection_|. Called when initialization completes
- // normally or when pipeline is stopped or error occurs during
- // initialization.
- void FinishInitialization();
-
- // Returns true if the given state is one that transitions to a new state
- // after iterating through each filter.
- static bool TransientState(State state);
+ // Returns true if an asynchronous operation is under way that will result in
+ // calling DoStateTransition().
+ bool IsTransitioning();
- // Given the current state, returns the next state.
- State FindNextState(State current);
+ // Completes the state transition for the current state, taking into account
+ // any errors that may have occured.
+ void OnStateTransition(PipelineStatus status);
+ void DoStateTransition(PipelineStatus status);
Ami GONE FROM CHROMIUM 2012/07/30 04:06:21 These names are not sufficiently self-explanatory
// DataSourceHost (by way of DemuxerHost) implementation.
virtual void SetTotalBytes(int64 total_bytes) OVERRIDE;
@@ -307,18 +265,6 @@ class MEDIA_EXPORT Pipeline
// Callback executed when either of the renderers have ended.
void OnRendererEnded();
- // Callbacks executed by filters upon completing initialization.
- void OnFilterInitialize(PipelineStatus status);
-
- // Callback executed by filters upon completing Play(), Pause(), or Stop().
- void OnFilterStateTransition();
-
- // Callback executed by filters upon completing Seek().
- void OnFilterStateTransitionWithStatus(PipelineStatus status);
-
- // Callback executed by filters when completing teardown operations.
- void OnTeardownStateTransition();
-
// Callback executed by filters to update statistics.
void OnUpdateStatistics(const PipelineStatistics& stats);
@@ -368,47 +314,13 @@ class MEDIA_EXPORT Pipeline
// Carries out disabling the audio renderer.
void AudioDisabledTask();
- // Carries out advancing to the next filter during Play()/Pause()/Seek().
- void FilterStateTransitionTask();
-
- // Carries out advancing to the next teardown operation.
- void TeardownStateTransitionTask();
-
- // Carries out stopping filter threads, deleting filters, running
- // appropriate callbacks, and setting the appropriate pipeline state
- // depending on whether we performing Stop() or SetError().
- // Called after all filters have been stopped.
- void FinishDestroyingFiltersTask();
-
- // Internal methods used in the implementation of the pipeline thread. All
- // of these methods are only called on the pipeline thread.
-
- // The following initialize methods are used to select a specific type of
- // object from FilterCollection and initialize it asynchronously.
- void InitializeDemuxer();
- void OnDemuxerInitialized(PipelineStatus status);
-
- // Returns true if the asynchronous action of creating decoder has started.
- // Returns false if this method did nothing because the corresponding
- // audio/video stream does not exist.
- bool InitializeAudioDecoder(const scoped_refptr<Demuxer>& demuxer);
- bool InitializeVideoDecoder(const scoped_refptr<Demuxer>& demuxer);
-
- // Initializes a renderer and connects it with decoder. Returns true if the
- // asynchronous action of creating renderer has started. Returns
- // false if this method did nothing because the corresponding audio/video
- // stream does not exist.
- bool InitializeAudioRenderer(const scoped_refptr<AudioDecoder>& decoder);
- bool InitializeVideoRenderer(const scoped_refptr<VideoDecoder>& decoder);
-
- // Kicks off destroying filters. Called by StopTask() and ErrorChangedTask().
- // When we start to tear down the pipeline, we will consider two cases:
- // 1. when pipeline has not been initialized, we will transit to stopping
- // state first.
- // 2. when pipeline has been initialized, we will first transit to pausing
- // => flushing => stopping => stopped state.
- // This will remove the race condition during stop between filters.
- void TearDownPipeline();
+ // Initiates asynchronous initialization for each media object, executing
+ // |done_cb| when completed.
+ void DoInitDemuxer(const PipelineStatusCB& done_cb);
+ void DoInitAudioDecoder(const PipelineStatusCB& done_cb);
+ void DoInitAudioRenderer(const PipelineStatusCB& done_cb);
+ void DoInitVideoDecoder(const PipelineStatusCB& done_cb);
+ void DoInitVideoRenderer(const PipelineStatusCB& done_cb);
// Compute the time corresponding to a byte offset.
base::TimeDelta TimeForByteOffset_Locked(int64 byte_offset) const;
@@ -424,11 +336,12 @@ class MEDIA_EXPORT Pipeline
// |done_cb| with the final status when completed. If |skip_demuxer_seek| is
// true then only renderers will attempt to preroll.
//
+ // |seek_timestamp_| must be set prior to calling DoSeek().
+ //
// TODO(scherkus): Prerolling should be separate from seeking so we can report
// finer grained ready states (HAVE_CURRENT_DATA vs. HAVE_FUTURE_DATA)
// indepentent from seeking.
- void DoSeek(base::TimeDelta seek_timestamp, bool skip_demuxer_seek,
- const PipelineStatusCB& done_cb);
+ void DoSeek(bool skip_demuxer_seek, const PipelineStatusCB& done_cb);
void OnAudioUnderflow();
@@ -449,21 +362,6 @@ class MEDIA_EXPORT Pipeline
// Whether or not the pipeline is running.
bool running_;
- // Whether or not the pipeline is in transition for a seek operation.
- bool seek_pending_;
-
- // Whether or not the pipeline is pending a stop operation.
- bool stop_pending_;
-
- // Whether or not the pipeline is perform a stop operation.
- bool tearing_down_;
-
- // Whether or not an error triggered the teardown.
- bool error_caused_teardown_;
-
- // Whether or not a playback rate change should be done once seeking is done.
- bool playback_rate_change_pending_;
scherkus (not reviewing) 2012/07/28 02:26:07 I replaced this + set volume pending-ness with a s
-
// Amount of available buffered data. Set by filters.
Ranges<int64> buffered_byte_ranges_;
Ranges<base::TimeDelta> buffered_time_ranges_;
@@ -488,9 +386,6 @@ class MEDIA_EXPORT Pipeline
// the filters.
float playback_rate_;
- // Playback rate to set when the current seek has finished.
- float pending_playback_rate_;
-
// Reference clock. Keeps track of current playback time. Uses system
// clock and linear interpolation, but can have its time manually set
// by filters.
@@ -531,6 +426,7 @@ class MEDIA_EXPORT Pipeline
scoped_ptr<FilterCollection> filter_collection_;
// Callbacks for various pipeline operations.
+ PipelineStatusCB start_cb_;
PipelineStatusCB seek_cb_;
base::Closure stop_cb_;
PipelineStatusCB ended_cb_;
« no previous file with comments | « media/base/mock_filters.h ('k') | media/base/pipeline.cc » ('j') | media/base/pipeline.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698