| 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
|
|
|