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.h518
1 files changed, 0 insertions, 518 deletions
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
deleted file mode 100644
index 5b9ee4e..0000000
--- a/media/base/pipeline_impl.h
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Implementation of Pipeline & PipelineStatusNotification (an async-to-sync
-// callback adapter).
-
-#ifndef MEDIA_BASE_PIPELINE_IMPL_H_
-#define MEDIA_BASE_PIPELINE_IMPL_H_
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop.h"
-#include "base/synchronization/condition_variable.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/thread.h"
-#include "base/time.h"
-#include "media/base/clock.h"
-#include "media/base/composite_filter.h"
-#include "media/base/demuxer.h"
-#include "media/base/download_rate_monitor.h"
-#include "media/base/filter_host.h"
-#include "media/base/pipeline.h"
-#include "ui/gfx/size.h"
-
-namespace media {
-
-class MediaLog;
-
-// Adapter for using asynchronous Pipeline methods in code that wants to run
-// synchronously. To use, construct an instance of this class and pass the
-// |Callback()| to the Pipeline method requiring a callback. Then Wait() for
-// the callback to get fired and call status() to see what the callback's
-// argument was. This object is for one-time use; call |Callback()| exactly
-// once.
-class MEDIA_EXPORT PipelineStatusNotification {
- public:
- PipelineStatusNotification();
- ~PipelineStatusNotification();
-
- // See class-level comment for usage.
- PipelineStatusCB Callback();
- void Wait();
- PipelineStatus status();
-
- private:
- void Notify(media::PipelineStatus status);
-
- base::Lock lock_;
- base::ConditionVariable cv_;
- media::PipelineStatus status_;
- bool notified_;
-
- DISALLOW_COPY_AND_ASSIGN(PipelineStatusNotification);
-};
-
-// PipelineImpl runs the media pipeline. Filters are created and called on the
-// message loop injected into this object. PipelineImpl 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) ]
-// | ^
-// | NotifyEnded() Seek()/Stop() |
-// `-------------> [ Ended ] ---------------------'
-// ^ SetError()
-// |
-// [ Any State Other Than InitXXX ]
-
-//
-// Initialization is a series of state transitions from "Created" through each
-// filter initialization state. When all filter initialization states have
-// completed, we are implicitly in a "Paused" state. At that point 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.
-class MEDIA_EXPORT PipelineImpl
- : public Pipeline,
- public FilterHost,
- public DemuxerHost {
- public:
- explicit PipelineImpl(MessageLoop* message_loop, MediaLog* media_log);
-
- // Pipeline implementation.
- virtual void Init(const PipelineStatusCB& ended_callback,
- const PipelineStatusCB& error_callback,
- const NetworkEventCB& network_callback) OVERRIDE;
- virtual bool Start(scoped_ptr<FilterCollection> filter_collection,
- const std::string& uri,
- const PipelineStatusCB& start_callback) OVERRIDE;
- virtual void Stop(const PipelineStatusCB& stop_callback) OVERRIDE;
- virtual void Seek(base::TimeDelta time,
- const PipelineStatusCB& seek_callback) OVERRIDE;
- virtual bool IsRunning() const OVERRIDE;
- virtual bool IsInitialized() const OVERRIDE;
- virtual bool HasAudio() const OVERRIDE;
- virtual bool HasVideo() const OVERRIDE;
- virtual float GetPlaybackRate() const OVERRIDE;
- virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
- virtual float GetVolume() const OVERRIDE;
- virtual void SetVolume(float volume) OVERRIDE;
- virtual void SetPreload(Preload preload) OVERRIDE;
- virtual base::TimeDelta GetCurrentTime() const OVERRIDE;
- virtual base::TimeDelta GetBufferedTime() OVERRIDE;
- virtual base::TimeDelta GetMediaDuration() const OVERRIDE;
- virtual int64 GetBufferedBytes() const OVERRIDE;
- virtual int64 GetTotalBytes() const OVERRIDE;
- virtual void GetNaturalVideoSize(gfx::Size* out_size) const OVERRIDE;
- virtual bool IsStreaming() const OVERRIDE;
- virtual bool IsLocalSource() const OVERRIDE;
- virtual PipelineStatistics GetStatistics() const OVERRIDE;
-
- void SetClockForTesting(Clock* clock);
-
- private:
- friend class MediaLog;
-
- // Pipeline states, as described above.
- enum State {
- kCreated,
- kInitDemuxer,
- kInitAudioDecoder,
- kInitAudioRenderer,
- kInitVideoDecoder,
- kInitVideoRenderer,
- kPausing,
- kSeeking,
- kFlushing,
- kStarting,
- kStarted,
- kEnded,
- kStopping,
- kStopped,
- kError,
- };
-
- virtual ~PipelineImpl();
-
- // Reset the state of the pipeline object to the initial state. This method
- // is used by the constructor, and the Stop() method.
- void ResetState();
-
- // 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);
-
- // 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 SetBufferedBytes(int64 buffered_bytes) OVERRIDE;
- virtual void SetNetworkActivity(bool is_downloading_data) OVERRIDE;
-
- // DemuxerHost implementaion.
- virtual void SetDuration(base::TimeDelta duration) OVERRIDE;
- virtual void SetBufferedTime(base::TimeDelta buffered_time) OVERRIDE;
- virtual void SetCurrentReadPosition(int64 offset) OVERRIDE;
- virtual void OnDemuxerError(PipelineStatus error) OVERRIDE;
-
- // FilterHost implementation.
- virtual void SetError(PipelineStatus error) OVERRIDE;
- virtual base::TimeDelta GetTime() const OVERRIDE;
- virtual base::TimeDelta GetDuration() const OVERRIDE;
- virtual void SetTime(base::TimeDelta time) OVERRIDE;
- virtual void SetNaturalVideoSize(const gfx::Size& size) OVERRIDE;
- virtual void NotifyEnded() OVERRIDE;
- virtual void DisableAudioRenderer() OVERRIDE;
-
- // 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);
-
- // The following "task" methods correspond to the public methods, but these
- // methods are run as the result of posting a task to the PipelineInternal's
- // message loop.
- void StartTask(scoped_ptr<FilterCollection> filter_collection,
- const std::string& url,
- const PipelineStatusCB& 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. 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 PipelineStatusCB& stop_callback);
-
- // Carries out stopping and destroying all filters, placing the pipeline in
- // the kError state.
- void ErrorChangedTask(PipelineStatus error);
-
- // Carries out notifying filters that the playback rate has changed.
- void PlaybackRateChangedTask(float playback_rate);
-
- // Carries out notifying filters that the volume has changed.
- void VolumeChangedTask(float volume);
-
- // Returns media preload value.
- virtual Preload GetPreload() const;
-
- // Carries out notifying filters that the preload value has changed.
- void PreloadChangedTask(Preload preload);
-
- // Carries out notifying filters that we are seeking to a new timestamp.
- void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_callback);
-
- // Carries out handling a notification from a filter that it has ended.
- void NotifyEndedTask();
-
- // Carries out handling a notification of network event.
- void NotifyNetworkEventTask(NetworkEvent type);
-
- // Carries out disabling the audio renderer.
- void DisableAudioRendererTask();
-
- // 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.
-
- // PrepareFilter() creates the filter's thread and injects a FilterHost and
- // MessageLoop.
- bool PrepareFilter(scoped_refptr<Filter> filter);
-
- // The following initialize methods are used to select a specific type of
- // Filter object from FilterCollection and initialize it asynchronously.
- void InitializeDemuxer();
- void OnDemuxerBuilt(PipelineStatus status, Demuxer* demuxer);
-
- // 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();
-
- // Compute the current time. Assumes that the lock has been acquired by the
- // caller.
- base::TimeDelta GetCurrentTime_Locked() const;
-
- // Initiates a Stop() on |demuxer_| & |pipeline_filter_|. |callback|
- // is called once both objects have been stopped.
- void DoStop(const base::Closure& callback);
-
- // Called when |demuxer_| has stopped. This method calls Stop()
- // on |pipeline_filter_|.
- void OnDemuxerStopDone(const base::Closure& callback);
-
- // Initiates a Seek() on the |demuxer_| & |pipeline_filter_|.
- void DoSeek(base::TimeDelta seek_timestamp);
-
- // Called when |demuxer_| finishes seeking. If seeking was successful,
- // then Seek() is called on |pipeline_filter_|.
- void OnDemuxerSeekDone(base::TimeDelta seek_timestamp,
- PipelineStatus status);
-
- void OnAudioUnderflow();
-
- // Called when |download_rate_monitor_| believes that the media can
- // be played through without needing to pause to buffer.
- void OnCanPlayThrough();
-
- // Carries out the notification that the media can be played through without
- // needing to pause to buffer.
- void NotifyCanPlayThrough();
-
- void StartClockIfWaitingForTimeUpdate_Locked();
-
- // Message loop used to execute pipeline tasks.
- MessageLoop* message_loop_;
-
- // 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_;
-
- // 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_;
-
- // Duration of the media in microseconds. Set by filters.
- base::TimeDelta duration_;
-
- // Amount of available buffered data in microseconds. Set by filters.
- base::TimeDelta buffered_time_;
-
- // Amount of available buffered data. Set by filters.
- int64 buffered_bytes_;
-
- // Total size of the media. Set by filters.
- int64 total_bytes_;
-
- // Video's natural width and height. Set by filters.
- gfx::Size natural_size_;
-
- // Set by the demuxer to indicate whether the data source is a streaming
- // source.
- bool streaming_;
-
- // Indicates whether the data source is local, such as a local media file
- // from disk or a local webcam stream.
- bool local_source_;
-
- // Current volume level (from 0.0f to 1.0f). This value is set immediately
- // via SetVolume() and a task is dispatched on the message loop to notify the
- // filters.
- float volume_;
-
- // Current value of preload attribute. This value is set immediately via
- // SetPreload() and a task is dispatched on the message loop to notify the
- // filters.
- Preload preload_;
-
- // Current playback rate (>= 0.0f). This value is set immediately via
- // SetPlaybackRate() and a task is dispatched on the message loop to notify
- // 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.
- scoped_ptr<Clock> clock_;
-
- // If this value is set to true, then |clock_| is paused and we are waiting
- // for an update of the clock greater than or equal to the elapsed time to
- // start the clock.
- bool waiting_for_clock_update_;
-
- // 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_;
-
- // Whether the media contains rendered audio and video streams.
- bool has_audio_;
- bool has_video_;
-
- // The following data members are only accessed by tasks posted to
- // |message_loop_|.
-
- // 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_;
-
- // For GetCurrentBytes()/SetCurrentBytes() we need to know what byte we are
- // currently reading.
- int64 current_bytes_;
-
- // Set to true in DisableAudioRendererTask().
- bool audio_disabled_;
-
- // Keep track of the maximum buffered position so the buffering appears
- // smooth.
- // TODO(vrk): This is a hack.
- base::TimeDelta max_buffered_time_;
-
- // Filter collection as passed in by Start().
- scoped_ptr<FilterCollection> filter_collection_;
-
- // URL for the data source as passed in by Start().
- std::string url_;
-
- // Callbacks for various pipeline operations.
- PipelineStatusCB seek_callback_;
- PipelineStatusCB stop_callback_;
- PipelineStatusCB ended_callback_;
- PipelineStatusCB error_callback_;
- NetworkEventCB network_callback_;
-
- // Reference to the filter(s) that constitute the pipeline.
- scoped_refptr<Filter> pipeline_filter_;
-
- // Decoder reference used for signalling imminent shutdown.
- // This is a HACK necessary because WebMediaPlayerImpl::Destroy() holds the
- // renderer thread loop hostage for until PipelineImpl::Stop() calls its
- // callback. http://crbug.com/110228 tracks removing this hack.
- scoped_refptr<VideoDecoder> video_decoder_;
-
- // Renderer references used for setting the volume and determining
- // when playback has finished.
- scoped_refptr<AudioRenderer> audio_renderer_;
- scoped_refptr<VideoRenderer> video_renderer_;
-
- // Demuxer reference used for setting the preload value.
- scoped_refptr<Demuxer> demuxer_;
-
- // Helper class that stores filter references during pipeline
- // initialization.
- class PipelineInitState;
- scoped_ptr<PipelineInitState> pipeline_init_state_;
-
- // 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_;
-
- // Approximates the rate at which the media is being downloaded.
- DownloadRateMonitor download_rate_monitor_;
-
- // True if the pipeline is actively downloading bytes, false otherwise.
- bool is_downloading_data_;
-
- FRIEND_TEST_ALL_PREFIXES(PipelineImplTest, GetBufferedTime);
-
- DISALLOW_COPY_AND_ASSIGN(PipelineImpl);
-};
-
-} // namespace media
-
-#endif // MEDIA_BASE_PIPELINE_IMPL_H_