OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "media/blink/video_frame_compositor.h" | 5 #include "media/blink/video_frame_compositor.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/time/default_tick_clock.h" | 9 #include "base/time/default_tick_clock.h" |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 // the PostTask is processed. | 125 // the PostTask is processed. |
126 base::AutoLock lock(callback_lock_); | 126 base::AutoLock lock(callback_lock_); |
127 DCHECK(callback_); | 127 DCHECK(callback_); |
128 callback_ = nullptr; | 128 callback_ = nullptr; |
129 compositor_task_runner_->PostTask( | 129 compositor_task_runner_->PostTask( |
130 FROM_HERE, base::Bind(&VideoFrameCompositor::OnRendererStateUpdate, | 130 FROM_HERE, base::Bind(&VideoFrameCompositor::OnRendererStateUpdate, |
131 base::Unretained(this), false)); | 131 base::Unretained(this), false)); |
132 } | 132 } |
133 | 133 |
134 void VideoFrameCompositor::PaintSingleFrame( | 134 void VideoFrameCompositor::PaintSingleFrame( |
135 const scoped_refptr<VideoFrame>& frame) { | 135 const scoped_refptr<VideoFrame>& frame, |
| 136 bool repaint_duplicate_frame) { |
136 if (!compositor_task_runner_->BelongsToCurrentThread()) { | 137 if (!compositor_task_runner_->BelongsToCurrentThread()) { |
137 compositor_task_runner_->PostTask( | 138 compositor_task_runner_->PostTask( |
138 FROM_HERE, base::Bind(&VideoFrameCompositor::PaintSingleFrame, | 139 FROM_HERE, |
139 base::Unretained(this), frame)); | 140 base::Bind(&VideoFrameCompositor::PaintSingleFrame, |
| 141 base::Unretained(this), frame, repaint_duplicate_frame)); |
140 return; | 142 return; |
141 } | 143 } |
142 | 144 |
143 if (ProcessNewFrame(frame) && client_) | 145 if (ProcessNewFrame(frame, repaint_duplicate_frame) && client_) |
144 client_->DidReceiveFrame(); | 146 client_->DidReceiveFrame(); |
145 } | 147 } |
146 | 148 |
147 scoped_refptr<VideoFrame> | 149 scoped_refptr<VideoFrame> |
148 VideoFrameCompositor::GetCurrentFrameAndUpdateIfStale() { | 150 VideoFrameCompositor::GetCurrentFrameAndUpdateIfStale() { |
149 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | 151 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
150 if (client_ || !rendering_ || !is_background_rendering_) | 152 if (client_ || !rendering_ || !is_background_rendering_) |
151 return current_frame_; | 153 return current_frame_; |
152 | 154 |
153 DCHECK(!last_background_render_.is_null()); | 155 DCHECK(!last_background_render_.is_null()); |
(...skipping 17 matching lines...) Expand all Loading... |
171 // When the VFC is stopped, |callback_| is cleared; this synchronously | 173 // When the VFC is stopped, |callback_| is cleared; this synchronously |
172 // prevents CallRender() from invoking ProcessNewFrame(), and so | 174 // prevents CallRender() from invoking ProcessNewFrame(), and so |
173 // |current_frame_| won't change again until after Start(). (Assuming that | 175 // |current_frame_| won't change again until after Start(). (Assuming that |
174 // PaintSingleFrame() is not also called while stopped.) | 176 // PaintSingleFrame() is not also called while stopped.) |
175 if (!current_frame_) | 177 if (!current_frame_) |
176 return base::TimeDelta(); | 178 return base::TimeDelta(); |
177 return current_frame_->timestamp(); | 179 return current_frame_->timestamp(); |
178 } | 180 } |
179 | 181 |
180 bool VideoFrameCompositor::ProcessNewFrame( | 182 bool VideoFrameCompositor::ProcessNewFrame( |
181 const scoped_refptr<VideoFrame>& frame) { | 183 const scoped_refptr<VideoFrame>& frame, |
| 184 bool repaint_duplicate_frame) { |
182 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | 185 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
183 | 186 |
184 if (frame == current_frame_) | 187 if (!repaint_duplicate_frame && frame == current_frame_) |
185 return false; | 188 return false; |
186 | 189 |
187 // Set the flag indicating that the current frame is unrendered, if we get a | 190 // Set the flag indicating that the current frame is unrendered, if we get a |
188 // subsequent PutCurrentFrame() call it will mark it as rendered. | 191 // subsequent PutCurrentFrame() call it will mark it as rendered. |
189 rendered_last_frame_ = false; | 192 rendered_last_frame_ = false; |
190 | 193 |
191 current_frame_ = frame; | 194 current_frame_ = frame; |
192 return true; | 195 return true; |
193 } | 196 } |
194 | 197 |
(...skipping 21 matching lines...) Expand all Loading... |
216 DCHECK(rendering_); | 219 DCHECK(rendering_); |
217 | 220 |
218 // If the previous frame was never rendered and we're not in background | 221 // If the previous frame was never rendered and we're not in background |
219 // rendering mode (nor have just exited it), let the client know. | 222 // rendering mode (nor have just exited it), let the client know. |
220 if (!rendered_last_frame_ && current_frame_ && !background_rendering && | 223 if (!rendered_last_frame_ && current_frame_ && !background_rendering && |
221 !is_background_rendering_) { | 224 !is_background_rendering_) { |
222 callback_->OnFrameDropped(); | 225 callback_->OnFrameDropped(); |
223 } | 226 } |
224 | 227 |
225 const bool new_frame = ProcessNewFrame( | 228 const bool new_frame = ProcessNewFrame( |
226 callback_->Render(deadline_min, deadline_max, background_rendering)); | 229 callback_->Render(deadline_min, deadline_max, background_rendering), |
| 230 false); |
227 | 231 |
228 // We may create a new frame here with background rendering, but the provider | 232 // We may create a new frame here with background rendering, but the provider |
229 // has no way of knowing that a new frame had been processed, so keep track of | 233 // has no way of knowing that a new frame had been processed, so keep track of |
230 // the new frame, and return true on the next call to |CallRender|. | 234 // the new frame, and return true on the next call to |CallRender|. |
231 const bool had_new_background_frame = new_background_frame_; | 235 const bool had_new_background_frame = new_background_frame_; |
232 new_background_frame_ = background_rendering && new_frame; | 236 new_background_frame_ = background_rendering && new_frame; |
233 | 237 |
234 is_background_rendering_ = background_rendering; | 238 is_background_rendering_ = background_rendering; |
235 last_interval_ = deadline_max - deadline_min; | 239 last_interval_ = deadline_max - deadline_min; |
236 | 240 |
237 // Restart the background rendering timer whether we're background rendering | 241 // Restart the background rendering timer whether we're background rendering |
238 // or not; in either case we should wait for |kBackgroundRenderingTimeoutMs|. | 242 // or not; in either case we should wait for |kBackgroundRenderingTimeoutMs|. |
239 if (background_rendering_enabled_) | 243 if (background_rendering_enabled_) |
240 background_rendering_timer_.Reset(); | 244 background_rendering_timer_.Reset(); |
241 return new_frame || had_new_background_frame; | 245 return new_frame || had_new_background_frame; |
242 } | 246 } |
243 | 247 |
244 } // namespace media | 248 } // namespace media |
OLD | NEW |