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/metrics/histogram_macros.h" |
9 #include "base/time/default_tick_clock.h" | 10 #include "base/time/default_tick_clock.h" |
10 #include "base/trace_event/auto_open_close_event.h" | 11 #include "base/trace_event/auto_open_close_event.h" |
11 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
12 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
13 | 14 |
14 namespace media { | 15 namespace media { |
15 | 16 |
16 // Amount of time to wait between UpdateCurrentFrame() callbacks before starting | 17 // Amount of time to wait between UpdateCurrentFrame() callbacks before starting |
17 // background rendering to keep the Render() callbacks moving. | 18 // background rendering to keep the Render() callbacks moving. |
18 const int kBackgroundRenderingTimeoutMs = 250; | 19 const int kBackgroundRenderingTimeoutMs = 250; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 base::TimeDelta VideoFrameCompositor::GetCurrentFrameTimestamp() const { | 182 base::TimeDelta VideoFrameCompositor::GetCurrentFrameTimestamp() const { |
182 // When the VFC is stopped, |callback_| is cleared; this synchronously | 183 // When the VFC is stopped, |callback_| is cleared; this synchronously |
183 // prevents CallRender() from invoking ProcessNewFrame(), and so | 184 // prevents CallRender() from invoking ProcessNewFrame(), and so |
184 // |current_frame_| won't change again until after Start(). (Assuming that | 185 // |current_frame_| won't change again until after Start(). (Assuming that |
185 // PaintSingleFrame() is not also called while stopped.) | 186 // PaintSingleFrame() is not also called while stopped.) |
186 if (!current_frame_) | 187 if (!current_frame_) |
187 return base::TimeDelta(); | 188 return base::TimeDelta(); |
188 return current_frame_->timestamp(); | 189 return current_frame_->timestamp(); |
189 } | 190 } |
190 | 191 |
| 192 void VideoFrameCompositor::SetForegroundTime(base::TimeTicks when) { |
| 193 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
| 194 foreground_time_ = when; |
| 195 } |
| 196 |
191 bool VideoFrameCompositor::ProcessNewFrame( | 197 bool VideoFrameCompositor::ProcessNewFrame( |
192 const scoped_refptr<VideoFrame>& frame, | 198 const scoped_refptr<VideoFrame>& frame, |
193 bool repaint_duplicate_frame) { | 199 bool repaint_duplicate_frame) { |
194 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | 200 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
195 | 201 |
196 if (frame && current_frame_ && !repaint_duplicate_frame && | 202 if (frame && current_frame_ && !repaint_duplicate_frame && |
197 frame->unique_id() == current_frame_->unique_id()) { | 203 frame->unique_id() == current_frame_->unique_id()) { |
198 return false; | 204 return false; |
199 } | 205 } |
200 | 206 |
201 // Set the flag indicating that the current frame is unrendered, if we get a | 207 // Set the flag indicating that the current frame is unrendered, if we get a |
202 // subsequent PutCurrentFrame() call it will mark it as rendered. | 208 // subsequent PutCurrentFrame() call it will mark it as rendered. |
203 rendered_last_frame_ = false; | 209 rendered_last_frame_ = false; |
204 | 210 |
205 current_frame_ = frame; | 211 current_frame_ = frame; |
| 212 |
| 213 if (!foreground_time_.is_null()) { |
| 214 base::TimeDelta time_to_first_frame = |
| 215 base::TimeTicks::Now() - foreground_time_; |
| 216 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame", |
| 217 time_to_first_frame); |
| 218 foreground_time_ = base::TimeTicks(); |
| 219 } |
| 220 |
206 return true; | 221 return true; |
207 } | 222 } |
208 | 223 |
209 void VideoFrameCompositor::BackgroundRender() { | 224 void VideoFrameCompositor::BackgroundRender() { |
210 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); | 225 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
211 const base::TimeTicks now = tick_clock_->NowTicks(); | 226 const base::TimeTicks now = tick_clock_->NowTicks(); |
212 last_background_render_ = now; | 227 last_background_render_ = now; |
213 bool new_frame = CallRender(now, now + last_interval_, true); | 228 bool new_frame = CallRender(now, now + last_interval_, true); |
214 if (new_frame && client_) | 229 if (new_frame && client_) |
215 client_->DidReceiveFrame(); | 230 client_->DidReceiveFrame(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 last_interval_ = deadline_max - deadline_min; | 265 last_interval_ = deadline_max - deadline_min; |
251 | 266 |
252 // Restart the background rendering timer whether we're background rendering | 267 // Restart the background rendering timer whether we're background rendering |
253 // or not; in either case we should wait for |kBackgroundRenderingTimeoutMs|. | 268 // or not; in either case we should wait for |kBackgroundRenderingTimeoutMs|. |
254 if (background_rendering_enabled_) | 269 if (background_rendering_enabled_) |
255 background_rendering_timer_.Reset(); | 270 background_rendering_timer_.Reset(); |
256 return new_frame || had_new_background_frame; | 271 return new_frame || had_new_background_frame; |
257 } | 272 } |
258 | 273 |
259 } // namespace media | 274 } // namespace media |
OLD | NEW |