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

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: rebase over split out CLs Created 6 years, 7 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
« no previous file with comments | « media/filters/pipeline_integration_test_base.cc ('k') | media/filters/video_renderer_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <map>
9 10
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/memory/weak_ptr.h" 11 #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" 12 #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" 13 #include "media/base/video_decoder.h"
20 #include "media/base/video_frame.h"
21 #include "media/base/video_renderer.h" 14 #include "media/base/video_renderer.h"
22 #include "media/filters/decoder_stream.h" 15 #include "media/filters/decoder_stream.h"
16 #include "media/filters/video_frame_scheduler.h"
23 17
24 namespace base { 18 namespace base {
25 class SingleThreadTaskRunner; 19 class SingleThreadTaskRunner;
20 class TickClock;
26 } 21 }
27 22
28 namespace media { 23 namespace media {
29 24
30 // VideoRendererImpl creates its own thread for the sole purpose of timing frame 25 // VideoRendererImpl is the state machine glue that handles reading from a
31 // presentation. It handles reading from the VideoFrameStream and stores the 26 // VideoFrameStream and scheduling frames to a VideoFrameScheduler.
32 // results in a queue of decoded frames and executing a callback when a frame is 27 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: 28 public:
38 typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
39
40 // |decoders| contains the VideoDecoders to use when initializing. 29 // |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( 30 VideoRendererImpl(
51 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 31 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
32 scoped_ptr<VideoFrameScheduler> scheduler,
52 ScopedVector<VideoDecoder> decoders, 33 ScopedVector<VideoDecoder> decoders,
53 const SetDecryptorReadyCB& set_decryptor_ready_cb, 34 const SetDecryptorReadyCB& set_decryptor_ready_cb);
54 const PaintCB& paint_cb,
55 bool drop_frames);
56 virtual ~VideoRendererImpl(); 35 virtual ~VideoRendererImpl();
57 36
58 // VideoRenderer implementation. 37 // VideoRenderer implementation.
59 virtual void Initialize(DemuxerStream* stream, 38 virtual void Initialize(DemuxerStream* stream,
60 const PipelineStatusCB& init_cb, 39 const PipelineStatusCB& init_cb,
61 const StatisticsCB& statistics_cb, 40 const StatisticsCB& statistics_cb,
62 const TimeCB& max_time_cb, 41 const TimeCB& max_time_cb,
63 const base::Closure& ended_cb, 42 const base::Closure& ended_cb,
64 const PipelineStatusCB& error_cb, 43 const PipelineStatusCB& error_cb,
65 const TimeDeltaCB& get_time_cb, 44 const TimeDeltaCB& get_time_cb,
66 const TimeDeltaCB& get_duration_cb) OVERRIDE; 45 const TimeDeltaCB& get_duration_cb) OVERRIDE;
67 virtual void Play(const base::Closure& callback) OVERRIDE; 46 virtual void Play(const base::Closure& callback) OVERRIDE;
68 virtual void Pause(const base::Closure& callback) OVERRIDE; 47 virtual void Pause(const base::Closure& callback) OVERRIDE;
69 virtual void Flush(const base::Closure& callback) OVERRIDE; 48 virtual void Flush(const base::Closure& callback) OVERRIDE;
70 virtual void Preroll(base::TimeDelta time, 49 virtual void Preroll(base::TimeDelta time,
71 const PipelineStatusCB& cb) OVERRIDE; 50 const PipelineStatusCB& cb) OVERRIDE;
72 virtual void Stop(const base::Closure& callback) OVERRIDE; 51 virtual void Stop(const base::Closure& callback) OVERRIDE;
73 virtual void SetPlaybackRate(float playback_rate) OVERRIDE; 52 virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
74 53
75 // PlatformThread::Delegate implementation. 54 void SetTickClockForTesting(scoped_ptr<base::TickClock> tick_clock);
76 virtual void ThreadMain() OVERRIDE;
77 55
78 private: 56 private:
79 // Callback for |video_frame_stream_| initialization. 57 // Callback for |video_frame_stream_| initialization.
80 void OnVideoFrameStreamInitialized(bool success); 58 void OnVideoFrameStreamInitialized(bool success);
81 59
82 // Callback for |video_frame_stream_| to deliver decoded video frames and 60 // Callback for |video_frame_stream_| to deliver decoded video frames and
83 // report video decoding status. 61 // report video decoding status.
84 void FrameReady(VideoFrameStream::Status status, 62 void FrameReady(VideoFrameStream::Status status,
85 const scoped_refptr<VideoFrame>& frame); 63 const scoped_refptr<VideoFrame>& frame);
86 64
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 65 // 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 66 // |video_frame_stream_| as long as there isn't a pending read and we have
92 // capacity. 67 // capacity.
93 void AttemptRead(); 68 void AttemptRead();
94 void AttemptRead_Locked();
95 69
96 // Called when VideoFrameStream::Reset() completes. 70 // Called when VideoFrameStream::Reset() completes.
97 void OnVideoFrameStreamResetDone(); 71 void OnVideoFrameStreamResetDone();
98 72
99 // Calculates the duration to sleep for based on |last_timestamp_|, 73 bool ShouldTransitionToPrerolled();
100 // the next frame timestamp (may be NULL), and the provided playback rate. 74 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 75
107 // Helper function that flushes the buffers when a Stop() or error occurs. 76 bool ShouldTransitionToEnded();
108 void DoStopOrError_Locked(); 77 void TransitionToEnded();
109 78
110 // Runs |paint_cb_| with the next frame from |ready_frames_|. 79 void ResetScheduler();
111 // 80 void ScheduleAllFrames();
112 // A read is scheduled to replace the frame. 81 void ScheduleFirstFrameForImmediateDisplay();
113 void PaintNextReadyFrame_Locked();
114 82
115 // Drops the next frame from |ready_frames_| and runs |statistics_cb_|. 83 void OnVideoFrameFinished(int frame_id,
116 // 84 const scoped_refptr<VideoFrame>& frame,
117 // A read is scheduled to replace the frame. 85 VideoFrameScheduler::Reason reason);
118 void DropNextReadyFrame_Locked();
119 86
120 void TransitionToPrerolled_Locked(); 87 int video_frame_count() {
121 88 return static_cast<int>(unscheduled_frames_.size() +
122 // Returns true of all conditions have been met to transition from 89 scheduled_frames_.size());
123 // kPrerolling to kPrerolled. 90 }
124 bool ShouldTransitionToPrerolled_Locked();
125
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. 101 // Unscheduled frames are stored FIFO in a queue. When a frame is scheduled
102 // it is assigned a unique ID and stored in a map. IDs are used to ensure we
103 // don't double count decoded/dropped frames for a particular frame.
140 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue; 104 typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue;
141 VideoFrameQueue ready_frames_; 105 typedef std::map<int, scoped_refptr<VideoFrame> > VideoFrameIDMap;
106 VideoFrameQueue unscheduled_frames_;
107 VideoFrameIDMap scheduled_frames_;
108 int next_scheduled_frame_id_;
142 109
143 // Keeps track of whether we received the end of stream buffer. 110 // Keeps track of whether we received the end of stream buffer.
144 bool received_end_of_stream_; 111 bool received_end_of_stream_;
145 112
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: 113 // State transition Diagram of this class:
151 // [kUninitialized] -------> [kError] 114 // [kUninitialized] -------> [kError]
152 // | 115 // |
153 // | Initialize() 116 // | Initialize()
154 // [kInitializing] 117 // [kInitializing]
155 // | 118 // |
156 // V 119 // V
157 // +------[kFlushed]<---------------OnVideoFrameStreamResetDone() 120 // +------[kFlushed]<---------------OnVideoFrameStreamResetDone()
158 // | | Preroll() or upon ^ 121 // | | Preroll() or upon ^
159 // | V got first frame [kFlushing] 122 // | V got first frame [kFlushing]
(...skipping 21 matching lines...) Expand all
181 kFlushing, 144 kFlushing,
182 kFlushed, 145 kFlushed,
183 kPrerolling, 146 kPrerolling,
184 kPlaying, 147 kPlaying,
185 kEnded, 148 kEnded,
186 kStopped, 149 kStopped,
187 kError, 150 kError,
188 }; 151 };
189 State state_; 152 State state_;
190 153
191 // Video thread handle.
192 base::PlatformThreadHandle thread_;
193
194 // Keep track of the outstanding read on the VideoFrameStream. Flushing can 154 // Keep track of the outstanding read on the VideoFrameStream. Flushing can
195 // only complete once the read has completed. 155 // only complete once the read has completed.
196 bool pending_read_; 156 bool pending_read_;
197 157
198 bool drop_frames_;
199
200 float playback_rate_; 158 float playback_rate_;
201 159
202 // Playback operation callbacks. 160 // Playback operation callbacks.
203 base::Closure flush_cb_; 161 base::Closure flush_cb_;
204 PipelineStatusCB preroll_cb_; 162 PipelineStatusCB preroll_cb_;
205 163
206 // Event callbacks. 164 // Event callbacks.
207 PipelineStatusCB init_cb_; 165 PipelineStatusCB init_cb_;
208 StatisticsCB statistics_cb_; 166 StatisticsCB statistics_cb_;
209 TimeCB max_time_cb_; 167 TimeCB max_time_cb_;
210 base::Closure ended_cb_; 168 base::Closure ended_cb_;
211 PipelineStatusCB error_cb_; 169 PipelineStatusCB error_cb_;
212 TimeDeltaCB get_time_cb_; 170 TimeDeltaCB get_time_cb_;
213 TimeDeltaCB get_duration_cb_; 171 TimeDeltaCB get_duration_cb_;
214 172
215 base::TimeDelta preroll_timestamp_; 173 base::TimeDelta preroll_timestamp_;
216 174
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_; 175 int frames_decoded_;
228 int frames_dropped_; 176 int frames_dropped_;
229 177
230 // NOTE: Weak pointers must be invalidated before all other member variables. 178 // NOTE: Weak pointers must be invalidated before all other member variables.
231 base::WeakPtrFactory<VideoRendererImpl> weak_factory_; 179 base::WeakPtrFactory<VideoRendererImpl> weak_factory_;
232 180
233 DISALLOW_COPY_AND_ASSIGN(VideoRendererImpl); 181 DISALLOW_COPY_AND_ASSIGN(VideoRendererImpl);
234 }; 182 };
235 183
236 } // namespace media 184 } // namespace media
237 185
238 #endif // MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_ 186 #endif // MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
OLDNEW
« no previous file with comments | « media/filters/pipeline_integration_test_base.cc ('k') | media/filters/video_renderer_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698