| 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..9daef0128a91dba7f902832ea6e981551bfef5ad 100644
|
| --- a/media/filters/video_renderer_impl.h
|
| +++ b/media/filters/video_renderer_impl.h
|
| @@ -6,53 +6,32 @@
|
| #define MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
|
|
|
| #include <deque>
|
| +#include <map>
|
|
|
| -#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 +51,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 +62,54 @@ 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 ShouldTransitionToEnded();
|
| + void TransitionToEnded();
|
|
|
| - // Drops the next frame from |ready_frames_| and runs |statistics_cb_|.
|
| - //
|
| - // A read is scheduled to replace the frame.
|
| - void DropNextReadyFrame_Locked();
|
| + void ResetScheduler();
|
| + void ScheduleAllFrames();
|
| + void ScheduleFirstFrameForImmediateDisplay();
|
|
|
| - void TransitionToPrerolled_Locked();
|
| + void OnVideoFrameFinished(int frame_id,
|
| + const scoped_refptr<VideoFrame>& frame,
|
| + VideoFrameScheduler::Reason reason);
|
|
|
| - // Returns true of all conditions have been met to transition from
|
| - // kPrerolling to kPrerolled.
|
| - bool ShouldTransitionToPrerolled_Locked();
|
| -
|
| - // 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.
|
| + // Unscheduled frames are stored FIFO in a queue. When a frame is scheduled
|
| + // it is assigned a unique ID and stored in a map. IDs are used to ensure we
|
| + // don't double count decoded/dropped frames for a particular frame.
|
| typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue;
|
| - VideoFrameQueue ready_frames_;
|
| + typedef std::map<int, scoped_refptr<VideoFrame> > VideoFrameIDMap;
|
| + VideoFrameQueue unscheduled_frames_;
|
| + VideoFrameIDMap scheduled_frames_;
|
| + int next_scheduled_frame_id_;
|
|
|
| // 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]
|
| // |
|
| @@ -188,15 +151,10 @@ 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.
|
| @@ -214,16 +172,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_;
|
|
|
|
|