Index: media/base/pipeline.h |
diff --git a/media/base/pipeline.h b/media/base/pipeline.h |
index 5eae2e09e1f2ce80b76d90d977a3750fc4352479..db326c2928353f2aa9d6080ad650e4ecd56f22fb 100644 |
--- a/media/base/pipeline.h |
+++ b/media/base/pipeline.h |
@@ -5,36 +5,21 @@ |
#ifndef MEDIA_BASE_PIPELINE_H_ |
#define MEDIA_BASE_PIPELINE_H_ |
-#include "base/gtest_prod_util.h" |
-#include "base/macros.h" |
#include "base/memory/ref_counted.h" |
-#include "base/memory/weak_ptr.h" |
-#include "base/synchronization/lock.h" |
-#include "base/threading/thread_checker.h" |
-#include "base/time/default_tick_clock.h" |
+#include "base/time/time.h" |
#include "media/base/buffering_state.h" |
#include "media/base/cdm_context.h" |
-#include "media/base/demuxer.h" |
#include "media/base/media_export.h" |
#include "media/base/pipeline_status.h" |
#include "media/base/ranges.h" |
-#include "media/base/serial_runner.h" |
#include "media/base/text_track.h" |
#include "media/base/video_rotation.h" |
#include "ui/gfx/geometry/size.h" |
-namespace base { |
-class SingleThreadTaskRunner; |
-class TimeDelta; |
-} |
- |
namespace media { |
-class MediaLog; |
+class Demuxer; |
class Renderer; |
-class TextRenderer; |
-class TextTrackConfig; |
-class TimeDeltaInterpolator; |
class VideoFrame; |
// Metadata describing a pipeline once it has been initialized. |
@@ -51,56 +36,11 @@ struct PipelineMetadata { |
typedef base::Callback<void(PipelineMetadata)> PipelineMetadataCB; |
-// Pipeline runs the media pipeline. Filters are created and called on the |
-// task runner 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 ] [ Any State ] |
-// | Start() | Stop() / SetError() |
-// V V |
-// [ InitXXX (for each filter) ] [ Stopping ] |
-// | | |
-// V V |
-// [ Playing ] <---------. [ Stopped ] |
-// | | Seek() | |
-// | V | |
-// | [ Seeking ] ----' |
-// | ^ |
-// | Suspend() | |
-// V | |
-// [ Suspending ] | |
-// | | |
-// V | |
-// [ Suspended ] | |
-// | Resume() | |
-// V | |
-// [ Resuming ] ---------' |
-// |
-// Initialization is a series of state transitions from "Created" through each |
-// filter initialization state. When all filter initialization states have |
-// completed, we simulate a Seek() to the beginning of the media to give filters |
-// a chance to preroll. 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. |
-// |
-// TODO(sandersd): It should be possible to pass through Suspended when going |
-// from InitDemuxer to InitRenderer, thereby eliminating the Resuming state. |
-// Some annoying differences between the two paths need to be removed first. |
-class MEDIA_EXPORT Pipeline : public DemuxerHost { |
+class MEDIA_EXPORT Pipeline { |
public: |
// Used to paint VideoFrame. |
typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB; |
- // Constructs a media pipeline that will execute on |task_runner|. |
- Pipeline(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
- MediaLog* media_log); |
- ~Pipeline() override; |
- |
// Build a pipeline to using the given |demuxer| and |renderer| to construct |
// a filter chain, executing |seek_cb| when the initial seek has completed. |
// |
@@ -120,16 +60,16 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost { |
// |waiting_for_decryption_key_cb| will be executed whenever the key needed |
// to decrypt the stream is not available. |
// It is an error to call this method after the pipeline has already started. |
- void Start(Demuxer* demuxer, |
- scoped_ptr<Renderer> renderer, |
- const base::Closure& ended_cb, |
- const PipelineStatusCB& error_cb, |
- const PipelineStatusCB& seek_cb, |
- const PipelineMetadataCB& metadata_cb, |
- const BufferingStateCB& buffering_state_cb, |
- const base::Closure& duration_change_cb, |
- const AddTextTrackCB& add_text_track_cb, |
- const base::Closure& waiting_for_decryption_key_cb); |
+ virtual void Start(Demuxer* demuxer, |
+ scoped_ptr<Renderer> renderer, |
+ const base::Closure& ended_cb, |
+ const PipelineStatusCB& error_cb, |
+ const PipelineStatusCB& seek_cb, |
+ const PipelineMetadataCB& metadata_cb, |
+ const BufferingStateCB& buffering_state_cb, |
+ const base::Closure& duration_change_cb, |
+ const AddTextTrackCB& add_text_track_cb, |
+ const base::Closure& waiting_for_decryption_key_cb) = 0; |
// Asynchronously stops the pipeline, executing |stop_cb| when the pipeline |
// teardown has completed. |
@@ -138,7 +78,7 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost { |
// call Stop() at any point during the lifetime of the pipeline. |
// |
// It is safe to delete the pipeline during the execution of |stop_cb|. |
- void Stop(const base::Closure& stop_cb); |
+ virtual void Stop(const base::Closure& stop_cb) = 0; |
// Attempt to seek to the position specified by time. |seek_cb| will be |
// executed when the all filters in the pipeline have processed the seek. |
@@ -147,291 +87,74 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost { |
// succeeded. |
// |
// It is an error to call this method if the pipeline has not started or |
- // is suspended. |
- void Seek(base::TimeDelta time, const PipelineStatusCB& seek_cb); |
+ // has been suspended. |
+ virtual void Seek(base::TimeDelta time, const PipelineStatusCB& seek_cb) = 0; |
+ |
+ // Suspends the pipeline, discarding the current renderer. |
+ // |
+ // While suspended, GetMediaTime() returns the presentation timestamp of the |
+ // last rendered frame. |
+ // |
+ // It is an error to call this method if the pipeline has not started or is |
+ // seeking. |
+ virtual void Suspend(const PipelineStatusCB& suspend_cb) = 0; |
+ |
+ // Resume the pipeline with a new renderer, and initialize it with a seek. |
+ // |
+ // It is an error to call this method if the pipeline has not finished |
+ // suspending. |
+ virtual void Resume(scoped_ptr<Renderer> renderer, |
+ base::TimeDelta timestamp, |
+ const PipelineStatusCB& seek_cb) = 0; |
// Returns true if the pipeline has been started via Start(). If IsRunning() |
// returns true, it is expected that Stop() will be called before destroying |
// the pipeline. |
- bool IsRunning() const; |
+ virtual bool IsRunning() const = 0; |
// Gets the current playback rate of the pipeline. When the pipeline is |
// started, the playback rate will be 0.0. A rate of 1.0 indicates |
// that the pipeline is rendering the media at the standard rate. Valid |
// values for playback rate are >= 0.0. |
- double GetPlaybackRate() const; |
+ virtual double GetPlaybackRate() const = 0; |
// Attempt to adjust the playback rate. Setting a playback rate of 0.0 pauses |
// all rendering of the media. A rate of 1.0 indicates a normal playback |
// rate. Values for the playback rate must be greater than or equal to 0.0. |
// |
// TODO(scherkus): What about maximum rate? Does HTML5 specify a max? |
- void SetPlaybackRate(double playback_rate); |
- |
- // Suspend the pipeline, discarding the current renderer. |
- // |
- // While suspended, GetMediaTime() returns the presentation timestamp of the |
- // last rendered frame. |
- // |
- // It is an error to call this method if the pipeline has not started or is |
- // seeking. |
- void Suspend(const PipelineStatusCB& suspend_cb); |
- |
- // Resume the pipeline with a new renderer, and initialize it with a seek. |
- void Resume(scoped_ptr<Renderer> renderer, |
- base::TimeDelta timestamp, |
- const PipelineStatusCB& seek_cb); |
+ virtual void SetPlaybackRate(double playback_rate) = 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. |
- float GetVolume() const; |
+ 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. |
- void SetVolume(float volume); |
+ virtual void SetVolume(float volume) = 0; |
// Returns the current media playback time, which progresses from 0 until |
// GetMediaDuration(). |
- base::TimeDelta GetMediaTime() const; |
+ virtual base::TimeDelta GetMediaTime() const = 0; |
// Get approximate time ranges of buffered media. |
- Ranges<base::TimeDelta> GetBufferedTimeRanges() const; |
+ virtual Ranges<base::TimeDelta> GetBufferedTimeRanges() const = 0; |
// Get the duration of the media in microseconds. If the duration has not |
// been determined yet, then returns 0. |
- base::TimeDelta GetMediaDuration() const; |
+ virtual base::TimeDelta GetMediaDuration() const = 0; |
// Return true if loading progress has been made since the last time this |
// method was called. |
- bool DidLoadingProgress(); |
+ virtual bool DidLoadingProgress() = 0; |
// Gets the current pipeline statistics. |
- PipelineStatistics GetStatistics() const; |
- |
- void SetCdm(CdmContext* cdm_context, const CdmAttachedCB& cdm_attached_cb); |
- |
- void SetErrorForTesting(PipelineStatus status); |
- bool HasWeakPtrsForTesting() const; |
- |
- private: |
- FRIEND_TEST_ALL_PREFIXES(PipelineTest, GetBufferedTimeRanges); |
- FRIEND_TEST_ALL_PREFIXES(PipelineTest, EndedCallback); |
- FRIEND_TEST_ALL_PREFIXES(PipelineTest, AudioStreamShorterThanVideo); |
- friend class MediaLog; |
- |
- // Pipeline states, as described above. |
- enum State { |
- kCreated, |
- kInitDemuxer, |
- kInitRenderer, |
- kSeeking, |
- kPlaying, |
- kStopping, |
- kStopped, |
- kSuspending, |
- kSuspended, |
- kResuming, |
- }; |
- |
- // Updates |state_|. All state transitions should use this call. |
- void SetState(State next_state); |
- |
- 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(); |
- |
- // DemuxerHost implementaion. |
- void OnBufferedTimeRangesChanged( |
- const Ranges<base::TimeDelta>& ranges) override; |
- void SetDuration(base::TimeDelta duration) override; |
- void OnDemuxerError(PipelineStatus error) override; |
- void AddTextStream(DemuxerStream* text_stream, |
- const TextTrackConfig& config) override; |
- void RemoveTextStream(DemuxerStream* text_stream) override; |
- |
- // Callback executed when a rendering error happened, initiating the teardown |
- // sequence. |
- void OnError(PipelineStatus error); |
- |
- // Callback executed by filters to update statistics. |
- void OnUpdateStatistics(const PipelineStatistics& stats_delta); |
- |
- // The following "task" methods correspond to the public methods, but these |
- // methods are run as the result of posting a task to the Pipeline's |
- // task runner. |
- void StartTask(); |
- |
- // Suspends the pipeline, discarding the current renderer. |
- void SuspendTask(const PipelineStatusCB& suspend_cb); |
- |
- // Resumes the pipeline with a new renderer, and initializes it with a seek. |
- void ResumeTask(scoped_ptr<Renderer> renderer, |
- base::TimeDelta timestamp, |
- const PipelineStatusCB& seek_sb); |
- |
- // Stops and destroys all filters, placing the pipeline in the kStopped state. |
- void StopTask(const base::Closure& stop_cb); |
- |
- // Carries out stopping and destroying all filters, placing the pipeline in |
- // the kStopped state. |
- void ErrorChangedTask(PipelineStatus error); |
- |
- // Carries out notifying filters that the playback rate has changed. |
- void PlaybackRateChangedTask(double playback_rate); |
- |
- // Carries out notifying filters that the volume has changed. |
- void VolumeChangedTask(float volume); |
- |
- // Carries out notifying filters that we are seeking to a new timestamp. |
- void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_cb); |
- |
- // Carries out setting the |cdm_context| in |renderer_|, and then fires |
- // |cdm_attached_cb| with the result. If |renderer_| is null, |
- // |cdm_attached_cb| will be fired immediately with true, and |cdm_context| |
- // will be set in |renderer_| later when |renderer_| is created. |
- void SetCdmTask(CdmContext* cdm_context, |
- const CdmAttachedCB& cdm_attached_cb); |
- |
- // Callbacks executed when a renderer has ended. |
- void OnRendererEnded(); |
- void OnTextRendererEnded(); |
- void RunEndedCallbackIfNeeded(); |
- |
- scoped_ptr<TextRenderer> CreateTextRenderer(); |
- |
- // Carries out adding a new text stream to the text renderer. |
- void AddTextStreamTask(DemuxerStream* text_stream, |
- const TextTrackConfig& config); |
- |
- // Carries out removing a text stream from the text renderer. |
- void RemoveTextStreamTask(DemuxerStream* text_stream); |
- |
- // Callbacks executed when a text track is added. |
- void OnAddTextTrack(const TextTrackConfig& config, |
- const AddTextTrackDoneCB& done_cb); |
- |
- // Kicks off initialization for each media object, executing |done_cb| with |
- // the result when completed. |
- void InitializeDemuxer(const PipelineStatusCB& done_cb); |
- void InitializeRenderer(const PipelineStatusCB& done_cb); |
- |
- void StateTransitionTask(PipelineStatus status); |
- |
- // Initiates an asynchronous pause-flush-seek-preroll call sequence |
- // executing |done_cb| with the final status when completed. |
- void DoSeek(base::TimeDelta seek_timestamp, 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 ReportMetadata(); |
- |
- void BufferingStateChanged(BufferingState new_buffering_state); |
- |
- // Task runner used to execute pipeline tasks. |
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
- |
- // MediaLog to which to log events. |
- scoped_refptr<MediaLog> media_log_; |
- |
- // Lock used to serialize access for the following data members. |
- mutable base::Lock lock_; |
- |
- // Whether or not the pipeline is running. |
- bool running_; |
- |
- // Amount of available buffered data as reported by |demuxer_|. |
- Ranges<base::TimeDelta> buffered_time_ranges_; |
- |
- // True when OnBufferedTimeRangesChanged() has been called more recently than |
- // DidLoadingProgress(). |
- bool did_loading_progress_; |
- |
- // Current volume level (from 0.0f to 1.0f). This value is set immediately |
- // via SetVolume() and a task is dispatched on the task runner to notify the |
- // filters. |
- float volume_; |
- |
- // Current playback rate (>= 0.0). This value is set immediately via |
- // SetPlaybackRate() and a task is dispatched on the task runner to notify |
- // the filters. |
- double playback_rate_; |
- |
- // Current duration as reported by |demuxer_|. |
- base::TimeDelta duration_; |
- |
- // 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 |
- // reset the pipeline state, and restore this to PIPELINE_OK. |
- PipelineStatus status_; |
- |
- // The following data members are only accessed by tasks posted to |
- // |task_runner_|. |
- |
- // Member that tracks the current state. |
- State state_; |
- |
- // The timestamp to start playback from after starting/seeking/resuming has |
- // completed. |
- base::TimeDelta start_timestamp_; |
- |
- // The media timestamp to return while the pipeline is suspended. Otherwise |
- // set to kNoTimestamp(). |
- base::TimeDelta suspend_timestamp_; |
- |
- // Whether we've received the audio/video/text ended events. |
- bool renderer_ended_; |
- bool text_renderer_ended_; |
- |
- // Temporary callback used for Start(), Seek(), and Resume(). |
- PipelineStatusCB seek_cb_; |
- |
- // Temporary callback used for Stop(). |
- base::Closure stop_cb_; |
- |
- // Temporary callback used for Suspend(). |
- PipelineStatusCB suspend_cb_; |
- |
- // Permanent callbacks passed in via Start(). |
- base::Closure ended_cb_; |
- PipelineStatusCB error_cb_; |
- PipelineMetadataCB metadata_cb_; |
- BufferingStateCB buffering_state_cb_; |
- base::Closure duration_change_cb_; |
- AddTextTrackCB add_text_track_cb_; |
- base::Closure waiting_for_decryption_key_cb_; |
- |
- // Holds the initialized demuxer. Used for seeking. Owned by client. |
- Demuxer* demuxer_; |
- |
- // Holds the initialized renderers. Used for setting the volume, |
- // playback rate, and determining when playback has finished. |
- scoped_ptr<Renderer> renderer_; |
- scoped_ptr<TextRenderer> text_renderer_; |
- |
- PipelineStatistics statistics_; |
- |
- scoped_ptr<SerialRunner> pending_callbacks_; |
- |
- // CdmContext to be used to decrypt (and decode) encrypted stream in this |
- // pipeline. Non-null only when SetCdm() is called and the pipeline has not |
- // been started. Then during Start(), this value will be set on |renderer_|. |
- CdmContext* pending_cdm_context_; |
- |
- base::ThreadChecker thread_checker_; |
- |
- // NOTE: Weak pointers must be invalidated before all other member variables. |
- base::WeakPtrFactory<Pipeline> weak_factory_; |
+ virtual PipelineStatistics GetStatistics() const = 0; |
- DISALLOW_COPY_AND_ASSIGN(Pipeline); |
+ virtual void SetCdm(CdmContext* cdm_context, |
+ const CdmAttachedCB& cdm_attached_cb) = 0; |
}; |
} // namespace media |