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

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

Issue 12096081: Replace VideoRendererBase Get/PutCurrentFrame() with a VideoFrame-containing callback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_BASE_H_ 5 #ifndef MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_
6 #define MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ 6 #define MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_
7 7
8 #include <deque> 8 #include <deque>
9 9
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
(...skipping 18 matching lines...) Expand all
29 29
30 // VideoRendererBase creates its own thread for the sole purpose of timing frame 30 // VideoRendererBase creates its own thread for the sole purpose of timing frame
31 // presentation. It handles reading from the decoder and stores the results in 31 // presentation. It handles reading from the decoder and stores the results in
32 // a queue of decoded frames and executing a callback when a frame is ready for 32 // a queue of decoded frames and executing a callback when a frame is ready for
33 // rendering. 33 // rendering.
34 class MEDIA_EXPORT VideoRendererBase 34 class MEDIA_EXPORT VideoRendererBase
35 : public VideoRenderer, 35 : public VideoRenderer,
36 public base::PlatformThread::Delegate { 36 public base::PlatformThread::Delegate {
37 public: 37 public:
38 typedef base::Callback<void(bool)> SetOpaqueCB; 38 typedef base::Callback<void(bool)> SetOpaqueCB;
39 typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
39 40
40 // Maximum duration of the last frame. 41 // Maximum duration of the last frame.
41 static base::TimeDelta kMaxLastFrameDuration(); 42 static base::TimeDelta kMaxLastFrameDuration();
42 43
43 // |paint_cb| is executed on the video frame timing thread whenever a new 44 // |paint_cb| is executed on the video frame timing thread whenever a new
44 // frame is available for painting via GetCurrentFrame(). 45 // frame is available for painting.
45 // 46 //
46 // |set_opaque_cb| is executed when the renderer is initialized to inform 47 // |set_opaque_cb| is executed when the renderer is initialized to inform
47 // the player whether the decoder's output will be opaque or not. 48 // the player whether the decoder's output will be opaque or not.
48 // 49 //
49 // Implementors should avoid doing any sort of heavy work in this method and 50 // Implementors should avoid doing any sort of heavy work in this method and
50 // instead post a task to a common/worker thread to handle rendering. Slowing 51 // instead post a task to a common/worker thread to handle rendering. Slowing
51 // down the video thread may result in losing synchronization with audio. 52 // down the video thread may result in losing synchronization with audio.
52 // 53 //
53 // Setting |drop_frames_| to true causes the renderer to drop expired frames. 54 // Setting |drop_frames_| to true causes the renderer to drop expired frames.
54 // 55 //
55 // TODO(scherkus): pass the VideoFrame* to this callback and remove 56 // TODO(scherkus): pass the VideoFrame* to this callback and remove
56 // Get/PutCurrentFrame() http://crbug.com/108435 57 // Get/PutCurrentFrame() http://crbug.com/108435
57 VideoRendererBase(const scoped_refptr<base::MessageLoopProxy>& message_loop, 58 VideoRendererBase(const scoped_refptr<base::MessageLoopProxy>& message_loop,
58 const SetDecryptorReadyCB& set_decryptor_ready_cb, 59 const SetDecryptorReadyCB& set_decryptor_ready_cb,
59 const base::Closure& paint_cb, 60 const PaintCB& paint_cb,
60 const SetOpaqueCB& set_opaque_cb, 61 const SetOpaqueCB& set_opaque_cb,
61 bool drop_frames); 62 bool drop_frames);
62 63
63 // VideoRenderer implementation. 64 // VideoRenderer implementation.
64 virtual void Initialize(const scoped_refptr<DemuxerStream>& stream, 65 virtual void Initialize(const scoped_refptr<DemuxerStream>& stream,
65 const VideoDecoderList& decoders, 66 const VideoDecoderList& decoders,
66 const PipelineStatusCB& init_cb, 67 const PipelineStatusCB& init_cb,
67 const StatisticsCB& statistics_cb, 68 const StatisticsCB& statistics_cb,
68 const TimeCB& max_time_cb, 69 const TimeCB& max_time_cb,
69 const NaturalSizeChangedCB& size_changed_cb, 70 const NaturalSizeChangedCB& size_changed_cb,
70 const base::Closure& ended_cb, 71 const base::Closure& ended_cb,
71 const PipelineStatusCB& error_cb, 72 const PipelineStatusCB& error_cb,
72 const TimeDeltaCB& get_time_cb, 73 const TimeDeltaCB& get_time_cb,
73 const TimeDeltaCB& get_duration_cb) OVERRIDE; 74 const TimeDeltaCB& get_duration_cb) OVERRIDE;
74 virtual void Play(const base::Closure& callback) OVERRIDE; 75 virtual void Play(const base::Closure& callback) OVERRIDE;
75 virtual void Pause(const base::Closure& callback) OVERRIDE; 76 virtual void Pause(const base::Closure& callback) OVERRIDE;
76 virtual void Flush(const base::Closure& callback) OVERRIDE; 77 virtual void Flush(const base::Closure& callback) OVERRIDE;
77 virtual void Preroll(base::TimeDelta time, 78 virtual void Preroll(base::TimeDelta time,
78 const PipelineStatusCB& cb) OVERRIDE; 79 const PipelineStatusCB& cb) OVERRIDE;
79 virtual void Stop(const base::Closure& callback) OVERRIDE; 80 virtual void Stop(const base::Closure& callback) OVERRIDE;
80 virtual void SetPlaybackRate(float playback_rate) OVERRIDE; 81 virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
81 82
82 // PlatformThread::Delegate implementation. 83 // PlatformThread::Delegate implementation.
83 virtual void ThreadMain() OVERRIDE; 84 virtual void ThreadMain() OVERRIDE;
84 85
85 // Clients of this class (painter/compositor) should use GetCurrentFrame()
86 // obtain ownership of VideoFrame, it should always relinquish the ownership
87 // by use PutCurrentFrame(). Current frame is not guaranteed to be non-NULL.
88 // It expects clients to use color-fill the background if current frame
89 // is NULL. This could happen before pipeline is pre-rolled or during
90 // pause/flush/preroll.
91 void GetCurrentFrame(scoped_refptr<VideoFrame>* frame_out);
92 void PutCurrentFrame(scoped_refptr<VideoFrame> frame);
93
94 protected: 86 protected:
95 virtual ~VideoRendererBase(); 87 virtual ~VideoRendererBase();
96 88
97 private: 89 private:
98 // Called when |decoder_selector_| selected the |selected_decoder|. 90 // Called when |decoder_selector_| selected the |selected_decoder|.
99 // |decrypting_demuxer_stream| was also populated if a DecryptingDemuxerStream 91 // |decrypting_demuxer_stream| was also populated if a DecryptingDemuxerStream
100 // created to help decrypt the encrypted stream. 92 // created to help decrypt the encrypted stream.
101 // Note: |decoder_selector| is passed here to keep the VideoDecoderSelector 93 // Note: |decoder_selector| is passed here to keep the VideoDecoderSelector
102 // alive until OnDecoderSelected() finishes. 94 // alive until OnDecoderSelected() finishes.
103 void OnDecoderSelected( 95 void OnDecoderSelected(
(...skipping 13 matching lines...) Expand all
117 // as there isn't a pending read and we have capacity. 109 // as there isn't a pending read and we have capacity.
118 void AttemptRead(); 110 void AttemptRead();
119 void AttemptRead_Locked(); 111 void AttemptRead_Locked();
120 112
121 // Called when VideoDecoder::Reset() completes. 113 // Called when VideoDecoder::Reset() completes.
122 void OnDecoderResetDone(); 114 void OnDecoderResetDone();
123 115
124 // Attempts to complete flushing and transition into the flushed state. 116 // Attempts to complete flushing and transition into the flushed state.
125 void AttemptFlush_Locked(); 117 void AttemptFlush_Locked();
126 118
127 // Calculates the duration to sleep for based on |current_frame_|'s timestamp, 119 // Calculates the duration to sleep for based on |last_timestamp_|,
128 // the next frame timestamp (may be NULL), and the provided playback rate. 120 // the next frame timestamp (may be NULL), and the provided playback rate.
129 // 121 //
130 // We don't use |playback_rate_| to avoid locking. 122 // We don't use |playback_rate_| to avoid locking.
131 base::TimeDelta CalculateSleepDuration( 123 base::TimeDelta CalculateSleepDuration(
132 const scoped_refptr<VideoFrame>& next_frame, 124 const scoped_refptr<VideoFrame>& next_frame,
133 float playback_rate); 125 float playback_rate);
134 126
135 // Helper function that flushes the buffers when a Stop() or error occurs. 127 // Helper function that flushes the buffers when a Stop() or error occurs.
136 void DoStopOrError_Locked(); 128 void DoStopOrError_Locked();
137 129
138 // Return the number of frames currently held by this class. 130 // Return the number of frames currently held by this class.
139 int NumFrames_Locked() const; 131 int NumFrames_Locked() const;
140 132
141 // Updates |current_frame_| to the next frame on |ready_frames_| and calls 133 // Runs |paint_cb_| with the next frame from |ready_frames_|, updating
142 // |size_changed_cb_| if the natural size changes. 134 // |last_natural_size_| and running |size_changed_cb_| if the natural size
143 void SetCurrentFrameToNextReadyFrame(); 135 // changes.
136 void PaintWithNextReadyFrame();
144 137
145 void ResetDecoder(); 138 void ResetDecoder();
146 void StopDecoder(const base::Closure& callback); 139 void StopDecoder(const base::Closure& callback);
147 140
148 // Pops the front of |decoders|, assigns it to |decoder_| and then 141 // Pops the front of |decoders|, assigns it to |decoder_| and then
149 // calls initialize on the new decoder. 142 // calls initialize on the new decoder.
150 void InitializeNextDecoder(const scoped_refptr<DemuxerStream>& demuxer_stream, 143 void InitializeNextDecoder(const scoped_refptr<DemuxerStream>& demuxer_stream,
151 scoped_ptr<VideoDecoderList> decoders); 144 scoped_ptr<VideoDecoderList> decoders);
152 145
153 // Called when |decoder_| initialization completes. 146 // Called when |decoder_| initialization completes.
154 // |demuxer_stream| & |decoders| are used if initialization failed and 147 // |demuxer_stream| & |decoders| are used if initialization failed and
155 // InitializeNextDecoder() needs to be called again. 148 // InitializeNextDecoder() needs to be called again.
156 void OnDecoderInitDone(const scoped_refptr<DemuxerStream>& demuxer_stream, 149 void OnDecoderInitDone(const scoped_refptr<DemuxerStream>& demuxer_stream,
157 scoped_ptr<VideoDecoderList> decoders, 150 scoped_ptr<VideoDecoderList> decoders,
158 PipelineStatus status); 151 PipelineStatus status);
159 152
160 scoped_refptr<base::MessageLoopProxy> message_loop_; 153 scoped_refptr<base::MessageLoopProxy> message_loop_;
161 154
162 // Used for accessing data members. 155 // Used for accessing data members.
163 base::Lock lock_; 156 base::Lock lock_;
164 157
165 SetDecryptorReadyCB set_decryptor_ready_cb_; 158 SetDecryptorReadyCB set_decryptor_ready_cb_;
166 159
167 // These two will be set by VideoDecoderSelector::SelectVideoDecoder(). 160 // These two will be set by VideoDecoderSelector::SelectVideoDecoder().
168 scoped_refptr<VideoDecoder> decoder_; 161 scoped_refptr<VideoDecoder> decoder_;
169 scoped_refptr<DecryptingDemuxerStream> decrypting_demuxer_stream_; 162 scoped_refptr<DecryptingDemuxerStream> decrypting_demuxer_stream_;
170 163
171 // Queue of incoming frames as well as the current frame since the last time 164 // Queue of incoming frames yet to be painted.
172 // OnFrameAvailable() was called.
173 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue; 165 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue;
174 VideoFrameQueue ready_frames_; 166 VideoFrameQueue ready_frames_;
175 167
176 // The current frame available to subclasses for rendering via
177 // GetCurrentFrame(). |current_frame_| can only be altered when
178 // |pending_paint_| is false.
179 scoped_refptr<VideoFrame> current_frame_;
180
181 // The previous |current_frame_| and is returned via GetCurrentFrame() in the
182 // situation where all frames were deallocated (i.e., during a flush).
183 //
184 // TODO(scherkus): remove this after getting rid of Get/PutCurrentFrame() in
185 // favour of passing ownership of the current frame to the renderer via
186 // callback.
187 scoped_refptr<VideoFrame> last_available_frame_;
188
189 // Used to signal |thread_| as frames are added to |frames_|. Rule of thumb: 168 // Used to signal |thread_| as frames are added to |frames_|. Rule of thumb:
190 // always check |state_| to see if it was set to STOPPED after waking up! 169 // always check |state_| to see if it was set to STOPPED after waking up!
191 base::ConditionVariable frame_available_; 170 base::ConditionVariable frame_available_;
192 171
193 // State transition Diagram of this class: 172 // State transition Diagram of this class:
194 // [kUninitialized] -------> [kError] 173 // [kUninitialized] -------> [kError]
195 // | 174 // |
196 // | Initialize() 175 // | Initialize()
197 // V All frames returned 176 // V All frames returned
198 // +------[kFlushed]<-----[kFlushing]<--- OnDecoderResetDone() 177 // +------[kFlushed]<-----[kFlushing]<--- OnDecoderResetDone()
(...skipping 26 matching lines...) Expand all
225 kPlaying, 204 kPlaying,
226 kEnded, 205 kEnded,
227 kStopped, 206 kStopped,
228 kError, 207 kError,
229 }; 208 };
230 State state_; 209 State state_;
231 210
232 // Video thread handle. 211 // Video thread handle.
233 base::PlatformThreadHandle thread_; 212 base::PlatformThreadHandle thread_;
234 213
235 // Keep track of various pending operations: 214 // Keep track of outstanding reads on the video decoder. Flushing can only
236 // - |pending_read_| is true when there's an active video decoding request. 215 // complete once reads have completed.
237 // - |pending_paint_| is true when |current_frame_| is currently being
238 // accessed by the subclass.
239 // - |pending_paint_with_last_available_| is true when
240 // |last_available_frame_| is currently being accessed by the subclass.
241 //
242 // Flushing cannot complete until both |pending_read_| and |pending_paint_|
243 // are false.
244 bool pending_read_; 216 bool pending_read_;
245 bool pending_paint_;
246 bool pending_paint_with_last_available_;
247 217
248 bool drop_frames_; 218 bool drop_frames_;
249 219
250 float playback_rate_; 220 float playback_rate_;
251 221
252 // Playback operation callbacks. 222 // Playback operation callbacks.
253 base::Closure flush_cb_; 223 base::Closure flush_cb_;
254 PipelineStatusCB preroll_cb_; 224 PipelineStatusCB preroll_cb_;
255 225
256 // Event callbacks. 226 // Event callbacks.
257 PipelineStatusCB init_cb_; 227 PipelineStatusCB init_cb_;
258 StatisticsCB statistics_cb_; 228 StatisticsCB statistics_cb_;
259 TimeCB max_time_cb_; 229 TimeCB max_time_cb_;
260 NaturalSizeChangedCB size_changed_cb_; 230 NaturalSizeChangedCB size_changed_cb_;
261 base::Closure ended_cb_; 231 base::Closure ended_cb_;
262 PipelineStatusCB error_cb_; 232 PipelineStatusCB error_cb_;
263 TimeDeltaCB get_time_cb_; 233 TimeDeltaCB get_time_cb_;
264 TimeDeltaCB get_duration_cb_; 234 TimeDeltaCB get_duration_cb_;
265 235
266 base::TimeDelta preroll_timestamp_; 236 base::TimeDelta preroll_timestamp_;
267 237
268 // Delayed frame used during kPrerolling to determine whether 238 // Delayed frame used during kPrerolling to determine whether
269 // |preroll_timestamp_| is between this frame and the next one. 239 // |preroll_timestamp_| is between this frame and the next one.
270 scoped_refptr<VideoFrame> prerolling_delayed_frame_; 240 scoped_refptr<VideoFrame> prerolling_delayed_frame_;
271 241
272 // Embedder callback for notifying a new frame is available for painting. 242 // Embedder callback for notifying a new frame is available for painting.
273 base::Closure paint_cb_; 243 PaintCB paint_cb_;
274 244
275 // Callback to execute to inform the player if the video decoder's output is 245 // Callback to execute to inform the player if the video decoder's output is
276 // opaque. 246 // opaque.
277 SetOpaqueCB set_opaque_cb_; 247 SetOpaqueCB set_opaque_cb_;
278 248
279 // The last natural size |size_changed_cb_| was called with. 249 // The last natural size |size_changed_cb_| was called with.
250 //
251 // TODO(scherkus): WebMediaPlayerImpl should track this instead of plumbing
252 // this through Pipeline.
scherkus (not reviewing) 2013/01/31 17:54:05 actually ... this might not be true I wonder if t
acolwell GONE FROM CHROMIUM 2013/02/01 00:24:34 I think it depends on whether we want to bubble fr
scherkus (not reviewing) 2013/02/01 22:45:25 Yeah I had the same thought -- updated TODO w/ pot
280 gfx::Size last_natural_size_; 253 gfx::Size last_natural_size_;
281 254
255 // The last timestamp of the frame |paint_cb_| was called with. Set to
acolwell GONE FROM CHROMIUM 2013/02/01 00:24:34 nit:s/The last timestamp of the frame/The timestam
scherkus (not reviewing) 2013/02/01 22:45:25 Done.
256 // kNoTimestamp() during flushing.
257 base::TimeDelta last_timestamp_;
258
282 DISALLOW_COPY_AND_ASSIGN(VideoRendererBase); 259 DISALLOW_COPY_AND_ASSIGN(VideoRendererBase);
283 }; 260 };
284 261
285 } // namespace media 262 } // namespace media
286 263
287 #endif // MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ 264 #endif // MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698