| Index: media/base/pipeline.h
|
| diff --git a/media/base/pipeline.h b/media/base/pipeline.h
|
| index 9325f1ab5c199a7ac6985c87d28cc205a64b5729..e023e87224a4214539497055380e1c3fc2553c35 100644
|
| --- a/media/base/pipeline.h
|
| +++ b/media/base/pipeline.h
|
| @@ -10,6 +10,7 @@
|
| #include "base/gtest_prod_util.h"
|
| #include "base/synchronization/condition_variable.h"
|
| #include "base/synchronization/lock.h"
|
| +#include "base/threading/thread_checker.h"
|
| #include "media/base/audio_renderer.h"
|
| #include "media/base/demuxer.h"
|
| #include "media/base/media_export.h"
|
| @@ -66,22 +67,20 @@ class MEDIA_EXPORT PipelineStatusNotification {
|
| //
|
| // 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) ]
|
| -// ^ SetError()
|
| -// |
|
| -// [ Any State Other Than InitXXX ]
|
| +// [ *Created ] [ Any State ]
|
| +// | Start() | Stop() / SetError()
|
| +// V V
|
| +// [ InitXXX (for each filter) ] [ Stopping ]
|
| +// | |
|
| +// V V
|
| +// [ InitPreroll ] [ Stopped ]
|
| +// |
|
| +// V
|
| +// [ Starting ] <-- [ Seeking ]
|
| +// | ^
|
| +// V |
|
| +// [ Started ] ----------'
|
| +// Seek()
|
| //
|
| // Initialization is a series of state transitions from "Created" through each
|
| // filter initialization state. When all filter initialization states have
|
| @@ -119,6 +118,10 @@ class MEDIA_EXPORT Pipeline
|
| // Build a pipeline to using the given filter collection to construct a filter
|
| // chain, executing |seek_cb| when the initial seek/preroll has completed.
|
| //
|
| + // |filter_collection| must be a complete collection containing a demuxer,
|
| + // audio/video decoders, and audio/video renderers. Failing to do so will
|
| + // result in a crash.
|
| + //
|
| // The following permanent callbacks will be executed as follows up until
|
| // Stop() has completed:
|
| // |ended_cb| will be executed whenever the media reaches the end.
|
| @@ -232,9 +235,8 @@ class MEDIA_EXPORT Pipeline
|
| kInitAudioDecoder,
|
| kInitAudioRenderer,
|
| kInitVideoRenderer,
|
| - kPausing,
|
| + kInitPrerolling,
|
| kSeeking,
|
| - kFlushing,
|
| kStarting,
|
| kStarted,
|
| kStopping,
|
| @@ -244,23 +246,13 @@ class MEDIA_EXPORT Pipeline
|
| // 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 in transition to seek state.
|
| - bool IsPipelineSeeking();
|
| + static const char* GetStateString(State state);
|
| + State GetNextState() const;
|
|
|
| // Helper method that runs & resets |seek_cb_| and resets |seek_timestamp_|
|
| // and |seek_pending_|.
|
| void FinishSeek();
|
|
|
| - // Returns true if the given state is one that transitions to a new state
|
| - // after iterating through each filter.
|
| - static bool TransientState(State state);
|
| -
|
| - // Given the current state, returns the next state.
|
| - State FindNextState(State current);
|
| -
|
| // DataSourceHost (by way of DemuxerHost) implementation.
|
| virtual void SetTotalBytes(int64 total_bytes) OVERRIDE;
|
| virtual void AddBufferedByteRange(int64 start, int64 end) OVERRIDE;
|
| @@ -283,16 +275,6 @@ class MEDIA_EXPORT Pipeline
|
| void OnAudioRendererEnded();
|
| void OnVideoRendererEnded();
|
|
|
| - // Callbacks executed by filters upon completing initialization.
|
| - void OnFilterInitialize(PipelineStatus status);
|
| -
|
| - // Callback executed by filters upon completing Play(), Pause(), Flush(),
|
| - // Seek() or Stop().
|
| - void OnFilterStateTransition(PipelineStatus status);
|
| -
|
| - // Callback executed by filters when completing teardown operations.
|
| - void OnTeardownStateTransition(PipelineStatus status);
|
| -
|
| // Callback executed by filters to update statistics.
|
| void OnUpdateStatistics(const PipelineStatistics& stats);
|
|
|
| @@ -314,13 +296,6 @@ class MEDIA_EXPORT Pipeline
|
| const PipelineStatusCB& seek_cb,
|
| const BufferingStateCB& buffering_state_cb);
|
|
|
| - // InitializeTask() performs initialization in multiple passes. It is executed
|
| - // as a result of calling Start() or InitializationComplete() that advances
|
| - // initialization to the next state. It works as a hub of state transition for
|
| - // initialization. One stage communicates its status to the next through
|
| - // |last_stage_status|.
|
| - void InitializeTask(PipelineStatus last_stage_status);
|
| -
|
| // Stops and destroys all filters, placing the pipeline in the kStopped state.
|
| void StopTask(const base::Closure& stop_cb);
|
|
|
| @@ -345,38 +320,12 @@ 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 stream does not exist.
|
| - bool InitializeAudioDecoder(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<DemuxerStream>& stream);
|
| + // Kicks off initialization for each media object, executing |done_cb| with
|
| + // the result when completed.
|
| + void InitializeDemuxer(const PipelineStatusCB& done_cb);
|
| + void InitializeAudioDecoder(const PipelineStatusCB& done_cb);
|
| + void InitializeAudioRenderer(const PipelineStatusCB& done_cb);
|
| + void InitializeVideoRenderer(const PipelineStatusCB& done_cb);
|
|
|
| // Kicks off destroying filters. Called by StopTask() and ErrorChangedTask().
|
| // When we start to tear down the pipeline, we will consider two cases:
|
| @@ -390,30 +339,34 @@ class MEDIA_EXPORT Pipeline
|
| // Compute the time corresponding to a byte offset.
|
| base::TimeDelta TimeForByteOffset_Locked(int64 byte_offset) const;
|
|
|
| - // Initiates an asynchronous Pause/Seek/Play/Stop() call sequence executing
|
| - // |done_cb| when completed.
|
| - void DoPause(const PipelineStatusCB& done_cb);
|
| - void DoFlush(const PipelineStatusCB& done_cb);
|
| - void DoPlay(const PipelineStatusCB& done_cb);
|
| - void DoStop(const PipelineStatusCB& done_cb);
|
| + void OnStateTransition(PipelineStatus status);
|
| + void StateTransitionTask(PipelineStatus status);
|
|
|
| - // Initiates an asynchronous Seek() and preroll call sequence executing
|
| - // |done_cb| with the final status when completed. If |skip_demuxer_seek| is
|
| - // true then only renderers will attempt to preroll.
|
| + // Initiates an asynchronous preroll call sequence executing |done_cb|
|
| + // with the final status when completed.
|
| + void DoInitialPreroll(const PipelineStatusCB& done_cb);
|
| +
|
| + // Initiates an asynchronous pause-flush-seek-preroll call sequence
|
| + // executing |done_cb| with the final status when completed.
|
| //
|
| // 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(base::TimeDelta seek_timestamp, const PipelineStatusCB& done_cb);
|
| +
|
| + // Updates playback rate and volume and initiates an asynchronous play call
|
| + // sequence executing |done_cb| with the final status when completed.
|
| + void DoPlay(const PipelineStatusCB& done_cb);
|
| +
|
| + // Initiates an asynchronous pause-flush-stop call sequence executing
|
| + // |done_cb| when completed.
|
| + void DoStop(const PipelineStatusCB& done_cb);
|
| + void OnStopCompleted(PipelineStatus status);
|
|
|
| void OnAudioUnderflow();
|
|
|
| void StartClockIfWaitingForTimeUpdate_Locked();
|
|
|
| - // Report pipeline |status| through |cb| avoiding duplicate error reporting.
|
| - void ReportStatus(const PipelineStatusCB& cb, PipelineStatus status);
|
| -
|
| // Message loop used to execute pipeline tasks.
|
| scoped_refptr<base::MessageLoopProxy> message_loop_;
|
|
|
| @@ -426,15 +379,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 perform a stop operation.
|
| - bool tearing_down_;
|
| -
|
| - // Whether or not a playback rate change should be done once seeking is done.
|
| - bool playback_rate_change_pending_;
|
| -
|
| // Amount of available buffered data. Set by filters.
|
| Ranges<int64> buffered_byte_ranges_;
|
| Ranges<base::TimeDelta> buffered_time_ranges_;
|
| @@ -459,9 +403,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.
|
| @@ -491,10 +432,6 @@ class MEDIA_EXPORT Pipeline
|
| // Member that tracks the current state.
|
| State state_;
|
|
|
| - // For kSeeking we need to remember where we're seeking between filter
|
| - // replies.
|
| - base::TimeDelta seek_timestamp_;
|
| -
|
| // Whether we've received the audio/video ended events.
|
| bool audio_ended_;
|
| bool video_ended_;
|
| @@ -502,12 +439,15 @@ class MEDIA_EXPORT Pipeline
|
| // Set to true in DisableAudioRendererTask().
|
| bool audio_disabled_;
|
|
|
| - // Filter collection as passed in by Start().
|
| scoped_ptr<FilterCollection> filter_collection_;
|
|
|
| - // Callbacks for various pipeline operations.
|
| + // Temporary callback used for Start() and Seek().
|
| PipelineStatusCB seek_cb_;
|
| +
|
| + // Temporary callback used for Stop().
|
| base::Closure stop_cb_;
|
| +
|
| + // Permanent callbacks passed in via Start().
|
| PipelineStatusCB ended_cb_;
|
| PipelineStatusCB error_cb_;
|
| BufferingStateCB buffering_state_cb_;
|
| @@ -527,19 +467,22 @@ class MEDIA_EXPORT Pipeline
|
| // Demuxer reference used for setting the preload value.
|
| scoped_refptr<Demuxer> demuxer_;
|
|
|
| - // Helper class that stores filter references during pipeline
|
| - // initialization.
|
| - struct PipelineInitState;
|
| - scoped_ptr<PipelineInitState> pipeline_init_state_;
|
| + // Audio decoder reference used during initialization.
|
| + //
|
| + // TODO(scherkus): Remove after renderers do initialization, see
|
| + // http://crbug.com/145635
|
| + scoped_refptr<AudioDecoder> audio_decoder_;
|
|
|
| - // Statistics.
|
| PipelineStatistics statistics_;
|
| +
|
| // Time of pipeline creation; is non-zero only until the pipeline first
|
| // reaches "kStarted", at which point it is used & zeroed out.
|
| base::Time creation_time_;
|
|
|
| scoped_ptr<SerialRunner> pending_callbacks_;
|
|
|
| + base::ThreadChecker thread_checker_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(Pipeline);
|
| };
|
|
|
|
|