Chromium Code Reviews| Index: media/filters/video_renderer_impl.h |
| diff --git a/media/filters/video_renderer_impl.h b/media/filters/video_renderer_impl.h |
| index 014799a7567ec674d65e31109eabe3498c764e28..c1940a4b76b7689d51ef2ef93354218738369c9c 100644 |
| --- a/media/filters/video_renderer_impl.h |
| +++ b/media/filters/video_renderer_impl.h |
| @@ -7,52 +7,30 @@ |
| #include <deque> |
| -#include "base/memory/ref_counted.h" |
| -#include "base/memory/scoped_vector.h" |
| #include "base/memory/weak_ptr.h" |
| -#include "base/synchronization/condition_variable.h" |
| -#include "base/synchronization/lock.h" |
| -#include "base/threading/platform_thread.h" |
| #include "media/base/decryptor.h" |
| -#include "media/base/demuxer_stream.h" |
| -#include "media/base/pipeline_status.h" |
| #include "media/base/video_decoder.h" |
| -#include "media/base/video_frame.h" |
| #include "media/base/video_renderer.h" |
| #include "media/filters/decoder_stream.h" |
| +#include "media/filters/video_frame_scheduler.h" |
| namespace base { |
| class SingleThreadTaskRunner; |
| +class TickClock; |
| } |
| namespace media { |
| -// VideoRendererImpl creates its own thread for the sole purpose of timing frame |
| -// presentation. It handles reading from the VideoFrameStream and stores the |
| -// results in a queue of decoded frames and executing a callback when a frame is |
| -// ready for rendering. |
| -class MEDIA_EXPORT VideoRendererImpl |
| - : public VideoRenderer, |
| - public base::PlatformThread::Delegate { |
| +// VideoRendererImpl is the state machine glue that handles reading from a |
| +// VideoFrameStream and scheduling frames to a VideoFrameScheduler. |
| +class MEDIA_EXPORT VideoRendererImpl : public VideoRenderer { |
| public: |
| - typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB; |
| - |
| // |decoders| contains the VideoDecoders to use when initializing. |
| - // |
| - // |paint_cb| is executed on the video frame timing thread whenever a new |
| - // frame is available for painting. |
| - // |
| - // Implementors should avoid doing any sort of heavy work in this method and |
| - // instead post a task to a common/worker thread to handle rendering. Slowing |
| - // down the video thread may result in losing synchronization with audio. |
| - // |
| - // Setting |drop_frames_| to true causes the renderer to drop expired frames. |
| VideoRendererImpl( |
| const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| + scoped_ptr<VideoFrameScheduler> scheduler, |
| ScopedVector<VideoDecoder> decoders, |
| - const SetDecryptorReadyCB& set_decryptor_ready_cb, |
| - const PaintCB& paint_cb, |
| - bool drop_frames); |
| + const SetDecryptorReadyCB& set_decryptor_ready_cb); |
| virtual ~VideoRendererImpl(); |
| // VideoRenderer implementation. |
| @@ -72,8 +50,7 @@ class MEDIA_EXPORT VideoRendererImpl |
| virtual void Stop(const base::Closure& callback) OVERRIDE; |
| virtual void SetPlaybackRate(float playback_rate) OVERRIDE; |
| - // PlatformThread::Delegate implementation. |
| - virtual void ThreadMain() OVERRIDE; |
| + void SetTickClockForTesting(scoped_ptr<base::TickClock> tick_clock); |
| private: |
| // Callback for |video_frame_stream_| initialization. |
| @@ -84,69 +61,50 @@ class MEDIA_EXPORT VideoRendererImpl |
| void FrameReady(VideoFrameStream::Status status, |
| const scoped_refptr<VideoFrame>& frame); |
| - // Helper method for adding a frame to |ready_frames_|. |
| - void AddReadyFrame_Locked(const scoped_refptr<VideoFrame>& frame); |
| - |
| // Helper method that schedules an asynchronous read from the |
| // |video_frame_stream_| as long as there isn't a pending read and we have |
| // capacity. |
| void AttemptRead(); |
| - void AttemptRead_Locked(); |
| // Called when VideoFrameStream::Reset() completes. |
| void OnVideoFrameStreamResetDone(); |
| - // Calculates the duration to sleep for based on |last_timestamp_|, |
| - // the next frame timestamp (may be NULL), and the provided playback rate. |
| - // |
| - // We don't use |playback_rate_| to avoid locking. |
| - base::TimeDelta CalculateSleepDuration( |
| - const scoped_refptr<VideoFrame>& next_frame, |
| - float playback_rate); |
| - |
| - // Helper function that flushes the buffers when a Stop() or error occurs. |
| - void DoStopOrError_Locked(); |
| + bool ShouldTransitionToPrerolled(); |
| + void TransitionToPrerolled(); |
| - // Runs |paint_cb_| with the next frame from |ready_frames_|. |
| - // |
| - // A read is scheduled to replace the frame. |
| - void PaintNextReadyFrame_Locked(); |
| + bool ShouldTransitionToPaused(); |
| + void TransitionToPaused(); |
| - // Drops the next frame from |ready_frames_| and runs |statistics_cb_|. |
| - // |
| - // A read is scheduled to replace the frame. |
| - void DropNextReadyFrame_Locked(); |
| + bool ShouldTransitionToEnded(); |
| + void TransitionToEnded(); |
| - void TransitionToPrerolled_Locked(); |
| + void ScheduleVideoFrames(); |
|
xhwang
2014/04/24 18:48:44
Drop the "Video" part, or s/Video/All?
scherkus (not reviewing)
2014/04/25 02:04:47
Done.
|
| + void ScheduleFirstFrameForImmediateDisplay(); |
| - // Returns true of all conditions have been met to transition from |
| - // kPrerolling to kPrerolled. |
| - bool ShouldTransitionToPrerolled_Locked(); |
| + void OnVideoFrameFinished(const scoped_refptr<VideoFrame>& frame, |
| + VideoFrameScheduler::Reason reason); |
| - // Runs |statistics_cb_| with |frames_decoded_| and |frames_dropped_|, resets |
| - // them to 0, and then waits on |frame_available_| for up to the |
| - // |wait_duration|. |
| - void UpdateStatsAndWait_Locked(base::TimeDelta wait_duration); |
| + int video_frame_count() { |
| + return static_cast<int>(unscheduled_frames_.size() + |
| + scheduled_frames_.size()); |
| + } |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| - // Used for accessing data members. |
| - base::Lock lock_; |
| + scoped_ptr<VideoFrameScheduler> scheduler_; |
| + |
| + scoped_ptr<base::TickClock> tick_clock_; |
| // Provides video frames to VideoRendererImpl. |
| VideoFrameStream video_frame_stream_; |
| - // Queue of incoming frames yet to be painted. |
| typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue; |
| - VideoFrameQueue ready_frames_; |
| + VideoFrameQueue unscheduled_frames_; |
| + VideoFrameQueue scheduled_frames_; |
| // Keeps track of whether we received the end of stream buffer. |
| bool received_end_of_stream_; |
| - // Used to signal |thread_| as frames are added to |frames_|. Rule of thumb: |
| - // always check |state_| to see if it was set to STOPPED after waking up! |
| - base::ConditionVariable frame_available_; |
| - |
| // State transition Diagram of this class: |
| // [kUninitialized] -------> [kError] |
| // | |
| @@ -159,8 +117,10 @@ class MEDIA_EXPORT VideoRendererImpl |
| // | V got first frame [kFlushing] |
| // | [kPrerolling] ^ |
| // | | | Flush() |
| - // | V Got enough frames | |
| - // | [kPrerolled]---------------------->[kPaused] |
| + // | | [kPaused] |
| + // | | ^ All frames returned |
| + // | V Got enough frames | from scheduler |
| + // | [kPrerolled]--------------------->[kPausing] |
| // | | Pause() ^ |
| // | V Play() | |
| // | [kPlaying]---------------------------| |
| @@ -177,6 +137,7 @@ class MEDIA_EXPORT VideoRendererImpl |
| kUninitialized, |
| kInitializing, |
| kPrerolled, |
| + kPausing, |
| kPaused, |
| kFlushing, |
| kFlushed, |
| @@ -188,18 +149,14 @@ class MEDIA_EXPORT VideoRendererImpl |
| }; |
| State state_; |
| - // Video thread handle. |
| - base::PlatformThreadHandle thread_; |
| - |
| // Keep track of the outstanding read on the VideoFrameStream. Flushing can |
| // only complete once the read has completed. |
| bool pending_read_; |
| - bool drop_frames_; |
| - |
| float playback_rate_; |
| // Playback operation callbacks. |
| + base::Closure pause_cb_; |
| base::Closure flush_cb_; |
| PipelineStatusCB preroll_cb_; |
| @@ -214,16 +171,6 @@ class MEDIA_EXPORT VideoRendererImpl |
| base::TimeDelta preroll_timestamp_; |
| - // Embedder callback for notifying a new frame is available for painting. |
| - PaintCB paint_cb_; |
| - |
| - // The timestamp of the last frame removed from the |ready_frames_| queue, |
| - // either for calling |paint_cb_| or for dropping. Set to kNoTimestamp() |
| - // during flushing. |
| - base::TimeDelta last_timestamp_; |
| - |
| - // Keeps track of the number of frames decoded and dropped since the |
| - // last call to |statistics_cb_|. These must be accessed under lock. |
| int frames_decoded_; |
| int frames_dropped_; |