Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: media/filters/video_renderer_impl.h

Issue 237353007: Refactor VideoRendererImpl to use VideoFrameScheduler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: pretty much done Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_ 5 #ifndef MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
6 #define MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_ 6 #define MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
7 7
8 #include <deque> 8 #include <deque>
9 9
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
13 #include "base/synchronization/condition_variable.h"
14 #include "base/synchronization/lock.h"
15 #include "base/threading/platform_thread.h"
16 #include "media/base/decryptor.h" 11 #include "media/base/decryptor.h"
17 #include "media/base/demuxer_stream.h"
18 #include "media/base/pipeline_status.h"
19 #include "media/base/video_decoder.h" 12 #include "media/base/video_decoder.h"
20 #include "media/base/video_frame.h"
21 #include "media/base/video_renderer.h" 13 #include "media/base/video_renderer.h"
22 #include "media/filters/decoder_stream.h" 14 #include "media/filters/decoder_stream.h"
15 #include "media/filters/video_frame_scheduler.h"
23 16
24 namespace base { 17 namespace base {
25 class SingleThreadTaskRunner; 18 class SingleThreadTaskRunner;
19 class TickClock;
26 } 20 }
27 21
28 namespace media { 22 namespace media {
29 23
30 // VideoRendererImpl creates its own thread for the sole purpose of timing frame 24 // VideoRendererImpl is the state machine glue that handles reading from a
31 // presentation. It handles reading from the VideoFrameStream and stores the 25 // VideoFrameStream and scheduling frames to a VideoFrameScheduler.
32 // results in a queue of decoded frames and executing a callback when a frame is 26 class MEDIA_EXPORT VideoRendererImpl : public VideoRenderer {
33 // ready for rendering.
34 class MEDIA_EXPORT VideoRendererImpl
35 : public VideoRenderer,
36 public base::PlatformThread::Delegate {
37 public: 27 public:
38 typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
39
40 // |decoders| contains the VideoDecoders to use when initializing. 28 // |decoders| contains the VideoDecoders to use when initializing.
41 //
42 // |paint_cb| is executed on the video frame timing thread whenever a new
43 // frame is available for painting.
44 //
45 // Implementors should avoid doing any sort of heavy work in this method and
46 // instead post a task to a common/worker thread to handle rendering. Slowing
47 // down the video thread may result in losing synchronization with audio.
48 //
49 // Setting |drop_frames_| to true causes the renderer to drop expired frames.
50 VideoRendererImpl( 29 VideoRendererImpl(
51 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 30 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
31 scoped_ptr<VideoFrameScheduler> scheduler,
52 ScopedVector<VideoDecoder> decoders, 32 ScopedVector<VideoDecoder> decoders,
53 const SetDecryptorReadyCB& set_decryptor_ready_cb, 33 const SetDecryptorReadyCB& set_decryptor_ready_cb);
54 const PaintCB& paint_cb,
55 bool drop_frames);
56 virtual ~VideoRendererImpl(); 34 virtual ~VideoRendererImpl();
57 35
58 // VideoRenderer implementation. 36 // VideoRenderer implementation.
59 virtual void Initialize(DemuxerStream* stream, 37 virtual void Initialize(DemuxerStream* stream,
60 const PipelineStatusCB& init_cb, 38 const PipelineStatusCB& init_cb,
61 const StatisticsCB& statistics_cb, 39 const StatisticsCB& statistics_cb,
62 const TimeCB& max_time_cb, 40 const TimeCB& max_time_cb,
63 const base::Closure& ended_cb, 41 const base::Closure& ended_cb,
64 const PipelineStatusCB& error_cb, 42 const PipelineStatusCB& error_cb,
65 const TimeDeltaCB& get_time_cb, 43 const TimeDeltaCB& get_time_cb,
66 const TimeDeltaCB& get_duration_cb) OVERRIDE; 44 const TimeDeltaCB& get_duration_cb) OVERRIDE;
67 virtual void Play(const base::Closure& callback) OVERRIDE; 45 virtual void Play(const base::Closure& callback) OVERRIDE;
68 virtual void Pause(const base::Closure& callback) OVERRIDE; 46 virtual void Pause(const base::Closure& callback) OVERRIDE;
69 virtual void Flush(const base::Closure& callback) OVERRIDE; 47 virtual void Flush(const base::Closure& callback) OVERRIDE;
70 virtual void Preroll(base::TimeDelta time, 48 virtual void Preroll(base::TimeDelta time,
71 const PipelineStatusCB& cb) OVERRIDE; 49 const PipelineStatusCB& cb) OVERRIDE;
72 virtual void Stop(const base::Closure& callback) OVERRIDE; 50 virtual void Stop(const base::Closure& callback) OVERRIDE;
73 virtual void SetPlaybackRate(float playback_rate) OVERRIDE; 51 virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
74 52
75 // PlatformThread::Delegate implementation. 53 void SetTickClockForTesting(scoped_ptr<base::TickClock> tick_clock);
76 virtual void ThreadMain() OVERRIDE;
77 54
78 private: 55 private:
79 // Callback for |video_frame_stream_| initialization. 56 // Callback for |video_frame_stream_| initialization.
80 void OnVideoFrameStreamInitialized(bool success); 57 void OnVideoFrameStreamInitialized(bool success);
81 58
82 // Callback for |video_frame_stream_| to deliver decoded video frames and 59 // Callback for |video_frame_stream_| to deliver decoded video frames and
83 // report video decoding status. 60 // report video decoding status.
84 void FrameReady(VideoFrameStream::Status status, 61 void FrameReady(VideoFrameStream::Status status,
85 const scoped_refptr<VideoFrame>& frame); 62 const scoped_refptr<VideoFrame>& frame);
86 63
87 // Helper method for adding a frame to |ready_frames_|.
88 void AddReadyFrame_Locked(const scoped_refptr<VideoFrame>& frame);
89
90 // Helper method that schedules an asynchronous read from the 64 // Helper method that schedules an asynchronous read from the
91 // |video_frame_stream_| as long as there isn't a pending read and we have 65 // |video_frame_stream_| as long as there isn't a pending read and we have
92 // capacity. 66 // capacity.
93 void AttemptRead(); 67 void AttemptRead();
94 void AttemptRead_Locked();
95 68
96 // Called when VideoFrameStream::Reset() completes. 69 // Called when VideoFrameStream::Reset() completes.
97 void OnVideoFrameStreamResetDone(); 70 void OnVideoFrameStreamResetDone();
98 71
99 // Calculates the duration to sleep for based on |last_timestamp_|, 72 bool ShouldTransitionToPrerolled();
100 // the next frame timestamp (may be NULL), and the provided playback rate. 73 void TransitionToPrerolled();
101 //
102 // We don't use |playback_rate_| to avoid locking.
103 base::TimeDelta CalculateSleepDuration(
104 const scoped_refptr<VideoFrame>& next_frame,
105 float playback_rate);
106 74
107 // Helper function that flushes the buffers when a Stop() or error occurs. 75 bool ShouldTransitionToPaused();
108 void DoStopOrError_Locked(); 76 void TransitionToPaused();
109 77
110 // Runs |paint_cb_| with the next frame from |ready_frames_|. 78 bool ShouldTransitionToEnded();
111 // 79 void TransitionToEnded();
112 // A read is scheduled to replace the frame.
113 void PaintNextReadyFrame_Locked();
114 80
115 // Drops the next frame from |ready_frames_| and runs |statistics_cb_|. 81 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.
116 // 82 void ScheduleFirstFrameForImmediateDisplay();
117 // A read is scheduled to replace the frame.
118 void DropNextReadyFrame_Locked();
119 83
120 void TransitionToPrerolled_Locked(); 84 void OnVideoFrameFinished(const scoped_refptr<VideoFrame>& frame,
85 VideoFrameScheduler::Reason reason);
121 86
122 // Returns true of all conditions have been met to transition from 87 int video_frame_count() {
123 // kPrerolling to kPrerolled. 88 return static_cast<int>(unscheduled_frames_.size() +
124 bool ShouldTransitionToPrerolled_Locked(); 89 scheduled_frames_.size());
125 90 }
126 // Runs |statistics_cb_| with |frames_decoded_| and |frames_dropped_|, resets
127 // them to 0, and then waits on |frame_available_| for up to the
128 // |wait_duration|.
129 void UpdateStatsAndWait_Locked(base::TimeDelta wait_duration);
130 91
131 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 92 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
132 93
133 // Used for accessing data members. 94 scoped_ptr<VideoFrameScheduler> scheduler_;
134 base::Lock lock_; 95
96 scoped_ptr<base::TickClock> tick_clock_;
135 97
136 // Provides video frames to VideoRendererImpl. 98 // Provides video frames to VideoRendererImpl.
137 VideoFrameStream video_frame_stream_; 99 VideoFrameStream video_frame_stream_;
138 100
139 // Queue of incoming frames yet to be painted.
140 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue; 101 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue;
141 VideoFrameQueue ready_frames_; 102 VideoFrameQueue unscheduled_frames_;
103 VideoFrameQueue scheduled_frames_;
142 104
143 // Keeps track of whether we received the end of stream buffer. 105 // Keeps track of whether we received the end of stream buffer.
144 bool received_end_of_stream_; 106 bool received_end_of_stream_;
145 107
146 // Used to signal |thread_| as frames are added to |frames_|. Rule of thumb:
147 // always check |state_| to see if it was set to STOPPED after waking up!
148 base::ConditionVariable frame_available_;
149
150 // State transition Diagram of this class: 108 // State transition Diagram of this class:
151 // [kUninitialized] -------> [kError] 109 // [kUninitialized] -------> [kError]
152 // | 110 // |
153 // | Initialize() 111 // | Initialize()
154 // [kInitializing] 112 // [kInitializing]
155 // | 113 // |
156 // V 114 // V
157 // +------[kFlushed]<---------------OnVideoFrameStreamResetDone() 115 // +------[kFlushed]<---------------OnVideoFrameStreamResetDone()
158 // | | Preroll() or upon ^ 116 // | | Preroll() or upon ^
159 // | V got first frame [kFlushing] 117 // | V got first frame [kFlushing]
160 // | [kPrerolling] ^ 118 // | [kPrerolling] ^
161 // | | | Flush() 119 // | | | Flush()
162 // | V Got enough frames | 120 // | | [kPaused]
163 // | [kPrerolled]---------------------->[kPaused] 121 // | | ^ All frames returned
122 // | V Got enough frames | from scheduler
123 // | [kPrerolled]--------------------->[kPausing]
164 // | | Pause() ^ 124 // | | Pause() ^
165 // | V Play() | 125 // | V Play() |
166 // | [kPlaying]---------------------------| 126 // | [kPlaying]---------------------------|
167 // | | Pause() ^ 127 // | | Pause() ^
168 // | V Receive EOF frame. | Pause() 128 // | V Receive EOF frame. | Pause()
169 // | [kEnded]-----------------------------+ 129 // | [kEnded]-----------------------------+
170 // | ^ 130 // | ^
171 // | | 131 // | |
172 // +-----> [kStopped] [Any state other than] 132 // +-----> [kStopped] [Any state other than]
173 // [kUninitialized/kError] 133 // [kUninitialized/kError]
174 134
175 // Simple state tracking variable. 135 // Simple state tracking variable.
176 enum State { 136 enum State {
177 kUninitialized, 137 kUninitialized,
178 kInitializing, 138 kInitializing,
179 kPrerolled, 139 kPrerolled,
140 kPausing,
180 kPaused, 141 kPaused,
181 kFlushing, 142 kFlushing,
182 kFlushed, 143 kFlushed,
183 kPrerolling, 144 kPrerolling,
184 kPlaying, 145 kPlaying,
185 kEnded, 146 kEnded,
186 kStopped, 147 kStopped,
187 kError, 148 kError,
188 }; 149 };
189 State state_; 150 State state_;
190 151
191 // Video thread handle.
192 base::PlatformThreadHandle thread_;
193
194 // Keep track of the outstanding read on the VideoFrameStream. Flushing can 152 // Keep track of the outstanding read on the VideoFrameStream. Flushing can
195 // only complete once the read has completed. 153 // only complete once the read has completed.
196 bool pending_read_; 154 bool pending_read_;
197 155
198 bool drop_frames_;
199
200 float playback_rate_; 156 float playback_rate_;
201 157
202 // Playback operation callbacks. 158 // Playback operation callbacks.
159 base::Closure pause_cb_;
203 base::Closure flush_cb_; 160 base::Closure flush_cb_;
204 PipelineStatusCB preroll_cb_; 161 PipelineStatusCB preroll_cb_;
205 162
206 // Event callbacks. 163 // Event callbacks.
207 PipelineStatusCB init_cb_; 164 PipelineStatusCB init_cb_;
208 StatisticsCB statistics_cb_; 165 StatisticsCB statistics_cb_;
209 TimeCB max_time_cb_; 166 TimeCB max_time_cb_;
210 base::Closure ended_cb_; 167 base::Closure ended_cb_;
211 PipelineStatusCB error_cb_; 168 PipelineStatusCB error_cb_;
212 TimeDeltaCB get_time_cb_; 169 TimeDeltaCB get_time_cb_;
213 TimeDeltaCB get_duration_cb_; 170 TimeDeltaCB get_duration_cb_;
214 171
215 base::TimeDelta preroll_timestamp_; 172 base::TimeDelta preroll_timestamp_;
216 173
217 // Embedder callback for notifying a new frame is available for painting.
218 PaintCB paint_cb_;
219
220 // The timestamp of the last frame removed from the |ready_frames_| queue,
221 // either for calling |paint_cb_| or for dropping. Set to kNoTimestamp()
222 // during flushing.
223 base::TimeDelta last_timestamp_;
224
225 // Keeps track of the number of frames decoded and dropped since the
226 // last call to |statistics_cb_|. These must be accessed under lock.
227 int frames_decoded_; 174 int frames_decoded_;
228 int frames_dropped_; 175 int frames_dropped_;
229 176
230 // NOTE: Weak pointers must be invalidated before all other member variables. 177 // NOTE: Weak pointers must be invalidated before all other member variables.
231 base::WeakPtrFactory<VideoRendererImpl> weak_factory_; 178 base::WeakPtrFactory<VideoRendererImpl> weak_factory_;
232 179
233 DISALLOW_COPY_AND_ASSIGN(VideoRendererImpl); 180 DISALLOW_COPY_AND_ASSIGN(VideoRendererImpl);
234 }; 181 };
235 182
236 } // namespace media 183 } // namespace media
237 184
238 #endif // MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_ 185 #endif // MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698