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

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

Powered by Google App Engine
This is Rietveld 408576698