OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // VideoRendererBase creates its own thread for the sole purpose of timing frame | 5 // VideoRendererBase creates its own thread for the sole purpose of timing frame |
6 // presentation. It handles reading from the decoder and stores the results in | 6 // presentation. It handles reading from the decoder and stores the results in |
7 // a queue of decoded frames, calling OnFrameAvailable() on subclasses to notify | 7 // a queue of decoded frames, calling OnFrameAvailable() on subclasses to notify |
8 // when a frame is ready to display. | 8 // when a frame is ready to display. |
9 // | 9 // |
10 // The media filter methods Initialize(), Stop(), SetPlaybackRate() and Seek() | 10 // The media filter methods Initialize(), Stop(), SetPlaybackRate() and Seek() |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 int width() { return width_; } | 100 int width() { return width_; } |
101 int height() { return height_; } | 101 int height() { return height_; } |
102 VideoFrame::Format surface_format() { return surface_format_; } | 102 VideoFrame::Format surface_format() { return surface_format_; } |
103 VideoFrame::SurfaceType surface_type() { return surface_type_; } | 103 VideoFrame::SurfaceType surface_type() { return surface_type_; } |
104 | 104 |
105 // TODO(jiesun): move this to gles_video_render.cc. | 105 // TODO(jiesun): move this to gles_video_render.cc. |
106 inline bool uses_egl_image() { | 106 inline bool uses_egl_image() { |
107 return surface_type_ == media::VideoFrame::TYPE_EGL_IMAGE; | 107 return surface_type_ == media::VideoFrame::TYPE_EGL_IMAGE; |
108 } | 108 } |
109 | 109 |
| 110 void ReadInput(scoped_refptr<VideoFrame> frame); |
| 111 |
110 private: | 112 private: |
111 // Callback from video decoder to deliver decoded video frames and decrements | 113 // Callback from video decoder to deliver decoded video frames and decrements |
112 // |pending_reads_|. | 114 // |pending_reads_|. |
113 void OnFillBufferDone(scoped_refptr<VideoFrame> frame); | 115 void OnFillBufferDone(scoped_refptr<VideoFrame> frame); |
114 | 116 |
115 // Helper method that schedules an asynchronous read from the decoder and | 117 // Helper method that schedules an asynchronous read from the decoder and |
116 // increments |pending_reads_|. | 118 // increments |pending_reads_|. |
117 // | 119 // |
118 // Safe to call from any thread. | 120 // Safe to call from any thread. |
119 void ScheduleRead_Locked(); | 121 void ScheduleRead_Locked(); |
120 | 122 |
| 123 // Helper function to finished "flush" operation |
| 124 void OnFlushDone(); |
| 125 |
121 // Helper method that flushes all video frame in "ready queue" including | 126 // Helper method that flushes all video frame in "ready queue" including |
122 // current frame into "done queue". | 127 // current frame into "done queue". |
123 void FlushBuffers(); | 128 void FlushBuffers(); |
124 | 129 |
125 // Calculates the duration to sleep for based on |current_frame_|'s timestamp, | 130 // Calculates the duration to sleep for based on |current_frame_|'s timestamp, |
126 // the next frame timestamp (may be NULL), and the provided playback rate. | 131 // the next frame timestamp (may be NULL), and the provided playback rate. |
127 // | 132 // |
128 // We don't use |playback_rate_| to avoid locking. | 133 // We don't use |playback_rate_| to avoid locking. |
129 base::TimeDelta CalculateSleepDuration(VideoFrame* next_frame, | 134 base::TimeDelta CalculateSleepDuration(VideoFrame* next_frame, |
130 float playback_rate); | 135 float playback_rate); |
(...skipping 12 matching lines...) Expand all Loading... |
143 // OnFrameAvailable() was called. | 148 // OnFrameAvailable() was called. |
144 typedef std::deque< scoped_refptr<VideoFrame> > VideoFrameQueue; | 149 typedef std::deque< scoped_refptr<VideoFrame> > VideoFrameQueue; |
145 VideoFrameQueue frames_queue_ready_; | 150 VideoFrameQueue frames_queue_ready_; |
146 VideoFrameQueue frames_queue_done_; | 151 VideoFrameQueue frames_queue_done_; |
147 scoped_refptr<VideoFrame> current_frame_; | 152 scoped_refptr<VideoFrame> current_frame_; |
148 | 153 |
149 // Used to signal |thread_| as frames are added to |frames_|. Rule of thumb: | 154 // 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! | 155 // always check |state_| to see if it was set to STOPPED after waking up! |
151 ConditionVariable frame_available_; | 156 ConditionVariable frame_available_; |
152 | 157 |
| 158 // State transition Diagram of this class: |
| 159 // [kUninitialized] -------> [kError] |
| 160 // | |
| 161 // | Initialize() |
| 162 // V All frames returned |
| 163 // +------[kFlushed]<----------------------[kFlushing] |
| 164 // | | Seek() or upon ^ |
| 165 // | V got first frame | |
| 166 // | [kSeeking] | Flush() |
| 167 // | | | |
| 168 // | V Got enough frames | |
| 169 // | [kPrerolled]---------------------->[kPaused] |
| 170 // | | Pause() ^ |
| 171 // | V Play() | |
| 172 // | [kPlaying]---------------------------| |
| 173 // | | Pause() ^ |
| 174 // | V Receive EOF frame. | Pause() |
| 175 // | [kEnded]-----------------------------+ |
| 176 // | ^ |
| 177 // | | |
| 178 // +-----> [kStopped] [Any state other than] |
| 179 // [kUninitialized/kError] |
| 180 |
153 // Simple state tracking variable. | 181 // Simple state tracking variable. |
154 enum State { | 182 enum State { |
155 kUninitialized, | 183 kUninitialized, |
| 184 kPrerolled, |
156 kPaused, | 185 kPaused, |
157 kFlushing, | 186 kFlushing, |
| 187 kFlushed, |
158 kSeeking, | 188 kSeeking, |
159 kPlaying, | 189 kPlaying, |
160 kEnded, | 190 kEnded, |
161 kStopped, | 191 kStopped, |
162 kError, | 192 kError, |
163 }; | 193 }; |
164 State state_; | 194 State state_; |
165 | 195 |
166 // Video thread handle. | 196 // Video thread handle. |
167 PlatformThreadHandle thread_; | 197 PlatformThreadHandle thread_; |
168 | 198 |
169 // Previous time returned from the pipeline. | 199 // Previous time returned from the pipeline. |
170 base::TimeDelta previous_time_; | 200 base::TimeDelta previous_time_; |
171 | 201 |
172 // Keeps track of our pending reads. We *must* have no pending reads before | 202 // Keeps track of our pending buffers. We *must* have no pending reads |
173 // executing the pause callback, otherwise we breach the contract that all | 203 // before executing the flush callback; We decrement it each time we receive |
174 // filters are idling. | 204 // a buffer and increment it each time we send a buffer out. therefore if |
175 // | 205 // decoder provides buffer, |pending_reads_| is always non-positive and if |
176 // We use size_t since we compare against std::deque::size(). | 206 // renderer provides buffer, |pending_reads_| is always non-negative. |
177 size_t pending_reads_; | 207 int pending_reads_; |
178 bool pending_paint_; | 208 bool pending_paint_; |
179 | 209 |
180 float playback_rate_; | 210 float playback_rate_; |
181 | 211 |
182 // Filter callbacks. | 212 // Filter callbacks. |
183 scoped_ptr<FilterCallback> flush_callback_; | 213 scoped_ptr<FilterCallback> flush_callback_; |
184 scoped_ptr<FilterCallback> seek_callback_; | 214 scoped_ptr<FilterCallback> seek_callback_; |
185 | 215 |
186 base::TimeDelta seek_timestamp_; | 216 base::TimeDelta seek_timestamp_; |
187 | 217 |
188 DISALLOW_COPY_AND_ASSIGN(VideoRendererBase); | 218 DISALLOW_COPY_AND_ASSIGN(VideoRendererBase); |
189 }; | 219 }; |
190 | 220 |
191 } // namespace media | 221 } // namespace media |
192 | 222 |
193 #endif // MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ | 223 #endif // MEDIA_FILTERS_VIDEO_RENDERER_BASE_H_ |
OLD | NEW |