OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Implementation notes: This needs to work on a variety of hardware | 5 // Implementation notes: This needs to work on a variety of hardware |
6 // configurations where the speed of the CPU and GPU greatly affect overall | 6 // configurations where the speed of the CPU and GPU greatly affect overall |
7 // performance. Spanning several threads, the process of capturing has been | 7 // performance. Spanning several threads, the process of capturing has been |
8 // split up into four conceptual stages: | 8 // split up into four conceptual stages: |
9 // | 9 // |
10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's | 10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 result.set_width(std::max(kMinFrameWidth, MakeEven(result.width()))); | 96 result.set_width(std::max(kMinFrameWidth, MakeEven(result.width()))); |
97 result.set_height(std::max(kMinFrameHeight, MakeEven(result.height()))); | 97 result.set_height(std::max(kMinFrameHeight, MakeEven(result.height()))); |
98 | 98 |
99 return result; | 99 return result; |
100 } | 100 } |
101 | 101 |
102 // Wrapper function to invoke ThreadSafeCaptureOracle::CaptureFrameCallback, is | 102 // Wrapper function to invoke ThreadSafeCaptureOracle::CaptureFrameCallback, is |
103 // compatible with RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback. | 103 // compatible with RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback. |
104 void InvokeCaptureFrameCallback( | 104 void InvokeCaptureFrameCallback( |
105 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, | 105 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, |
106 base::Time timestamp, | 106 base::TimeTicks timestamp, |
107 bool frame_captured) { | 107 bool frame_captured) { |
108 capture_frame_cb.Run(timestamp, frame_captured); | 108 capture_frame_cb.Run(timestamp, frame_captured); |
109 } | 109 } |
110 | 110 |
111 // FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible | 111 // FrameSubscriber is a proxy to the ThreadSafeCaptureOracle that's compatible |
112 // with RenderWidgetHostViewFrameSubscriber. We create one per event type. | 112 // with RenderWidgetHostViewFrameSubscriber. We create one per event type. |
113 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { | 113 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { |
114 public: | 114 public: |
115 FrameSubscriber(VideoCaptureOracle::Event event_type, | 115 FrameSubscriber(VideoCaptureOracle::Event event_type, |
116 const scoped_refptr<ThreadSafeCaptureOracle>& oracle) | 116 const scoped_refptr<ThreadSafeCaptureOracle>& oracle) |
117 : event_type_(event_type), | 117 : event_type_(event_type), |
118 oracle_proxy_(oracle) {} | 118 oracle_proxy_(oracle) {} |
119 | 119 |
120 virtual bool ShouldCaptureFrame( | 120 virtual bool ShouldCaptureFrame( |
121 base::Time present_time, | 121 base::TimeTicks present_time, |
122 scoped_refptr<media::VideoFrame>* storage, | 122 scoped_refptr<media::VideoFrame>* storage, |
123 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* | 123 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* |
124 deliver_frame_cb) OVERRIDE; | 124 deliver_frame_cb) OVERRIDE; |
125 | 125 |
126 private: | 126 private: |
127 const VideoCaptureOracle::Event event_type_; | 127 const VideoCaptureOracle::Event event_type_; |
128 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; | 128 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; |
129 }; | 129 }; |
130 | 130 |
131 // ContentCaptureSubscription is the relationship between a RenderWidgetHost | 131 // ContentCaptureSubscription is the relationship between a RenderWidgetHost |
132 // whose content is updating, a subscriber that is deciding which of these | 132 // whose content is updating, a subscriber that is deciding which of these |
133 // updates to capture (and where to deliver them to), and a callback that | 133 // updates to capture (and where to deliver them to), and a callback that |
134 // knows how to do the capture and prepare the result for delivery. | 134 // knows how to do the capture and prepare the result for delivery. |
135 // | 135 // |
136 // In practice, this means (a) installing a RenderWidgetHostFrameSubscriber in | 136 // In practice, this means (a) installing a RenderWidgetHostFrameSubscriber in |
137 // the RenderWidgetHostView, to process updates that occur via accelerated | 137 // the RenderWidgetHostView, to process updates that occur via accelerated |
138 // compositing, (b) installing itself as an observer of updates to the | 138 // compositing, (b) installing itself as an observer of updates to the |
139 // RenderWidgetHost's backing store, to hook updates that occur via software | 139 // RenderWidgetHost's backing store, to hook updates that occur via software |
140 // rendering, and (c) running a timer to possibly initiate non-event-driven | 140 // rendering, and (c) running a timer to possibly initiate non-event-driven |
141 // captures that the subscriber might request. | 141 // captures that the subscriber might request. |
142 // | 142 // |
143 // All of this happens on the UI thread, although the | 143 // All of this happens on the UI thread, although the |
144 // RenderWidgetHostViewFrameSubscriber we install may be dispatching updates | 144 // RenderWidgetHostViewFrameSubscriber we install may be dispatching updates |
145 // autonomously on some other thread. | 145 // autonomously on some other thread. |
146 class ContentCaptureSubscription : public content::NotificationObserver { | 146 class ContentCaptureSubscription : public content::NotificationObserver { |
147 public: | 147 public: |
148 typedef base::Callback<void( | 148 typedef base::Callback< |
149 const base::Time&, | 149 void(const base::TimeTicks&, |
150 const scoped_refptr<media::VideoFrame>&, | 150 const scoped_refptr<media::VideoFrame>&, |
151 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&)> | 151 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&)> |
152 CaptureCallback; | 152 CaptureCallback; |
153 | 153 |
154 // Create a subscription. Whenever a manual capture is required, the | 154 // Create a subscription. Whenever a manual capture is required, the |
155 // subscription will invoke |capture_callback| on the UI thread to do the | 155 // subscription will invoke |capture_callback| on the UI thread to do the |
156 // work. | 156 // work. |
157 ContentCaptureSubscription( | 157 ContentCaptureSubscription( |
158 const RenderWidgetHost& source, | 158 const RenderWidgetHost& source, |
159 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 159 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, |
160 const CaptureCallback& capture_callback); | 160 const CaptureCallback& capture_callback); |
161 virtual ~ContentCaptureSubscription(); | 161 virtual ~ContentCaptureSubscription(); |
162 | 162 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 // VideoCaptureMachine overrides. | 211 // VideoCaptureMachine overrides. |
212 virtual bool Start( | 212 virtual bool Start( |
213 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE; | 213 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE; |
214 virtual void Stop() OVERRIDE; | 214 virtual void Stop() OVERRIDE; |
215 | 215 |
216 // Starts a copy from the backing store or the composited surface. Must be run | 216 // Starts a copy from the backing store or the composited surface. Must be run |
217 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation | 217 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation |
218 // completes. The copy will occur to |target|. | 218 // completes. The copy will occur to |target|. |
219 // | 219 // |
220 // This may be used as a ContentCaptureSubscription::CaptureCallback. | 220 // This may be used as a ContentCaptureSubscription::CaptureCallback. |
221 void Capture( | 221 void Capture(const base::TimeTicks& start_time, |
222 const base::Time& start_time, | 222 const scoped_refptr<media::VideoFrame>& target, |
223 const scoped_refptr<media::VideoFrame>& target, | 223 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
224 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 224 deliver_frame_cb); |
225 deliver_frame_cb); | |
226 | 225 |
227 // content::WebContentsObserver implementation. | 226 // content::WebContentsObserver implementation. |
228 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE { | 227 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE { |
229 fullscreen_widget_id_ = routing_id; | 228 fullscreen_widget_id_ = routing_id; |
230 RenewFrameSubscription(); | 229 RenewFrameSubscription(); |
231 } | 230 } |
232 | 231 |
233 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE { | 232 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE { |
234 DCHECK_EQ(fullscreen_widget_id_, routing_id); | 233 DCHECK_EQ(fullscreen_widget_id_, routing_id); |
235 fullscreen_widget_id_ = MSG_ROUTING_NONE; | 234 fullscreen_widget_id_ = MSG_ROUTING_NONE; |
(...skipping 18 matching lines...) Expand all Loading... |
254 | 253 |
255 private: | 254 private: |
256 // Starts observing the web contents, returning false if lookup fails. | 255 // Starts observing the web contents, returning false if lookup fails. |
257 bool StartObservingWebContents(); | 256 bool StartObservingWebContents(); |
258 | 257 |
259 // Helper function to determine the view that we are currently tracking. | 258 // Helper function to determine the view that we are currently tracking. |
260 RenderWidgetHost* GetTarget(); | 259 RenderWidgetHost* GetTarget(); |
261 | 260 |
262 // Response callback for RenderWidgetHost::CopyFromBackingStore(). | 261 // Response callback for RenderWidgetHost::CopyFromBackingStore(). |
263 void DidCopyFromBackingStore( | 262 void DidCopyFromBackingStore( |
264 const base::Time& start_time, | 263 const base::TimeTicks& start_time, |
265 const scoped_refptr<media::VideoFrame>& target, | 264 const scoped_refptr<media::VideoFrame>& target, |
266 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 265 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
267 deliver_frame_cb, | 266 deliver_frame_cb, |
268 bool success, | 267 bool success, |
269 const SkBitmap& bitmap); | 268 const SkBitmap& bitmap); |
270 | 269 |
271 // Response callback for RWHVP::CopyFromCompositingSurfaceToVideoFrame(). | 270 // Response callback for RWHVP::CopyFromCompositingSurfaceToVideoFrame(). |
272 void DidCopyFromCompositingSurfaceToVideoFrame( | 271 void DidCopyFromCompositingSurfaceToVideoFrame( |
273 const base::Time& start_time, | 272 const base::TimeTicks& start_time, |
274 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 273 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
275 deliver_frame_cb, | 274 deliver_frame_cb, |
276 bool success); | 275 bool success); |
277 | 276 |
278 // Remove the old subscription, and start a new one. This should be called | 277 // Remove the old subscription, and start a new one. This should be called |
279 // after any change to the WebContents that affects the RenderWidgetHost or | 278 // after any change to the WebContents that affects the RenderWidgetHost or |
280 // attached views. | 279 // attached views. |
281 void RenewFrameSubscription(); | 280 void RenewFrameSubscription(); |
282 | 281 |
283 // Parameters saved in constructor. | 282 // Parameters saved in constructor. |
(...skipping 27 matching lines...) Expand all Loading... |
311 public: | 310 public: |
312 VideoFrameDeliveryLog(); | 311 VideoFrameDeliveryLog(); |
313 | 312 |
314 // Treat |frame_number| as having been delivered, and update the | 313 // Treat |frame_number| as having been delivered, and update the |
315 // frame rate statistics accordingly. | 314 // frame rate statistics accordingly. |
316 void ChronicleFrameDelivery(int frame_number); | 315 void ChronicleFrameDelivery(int frame_number); |
317 | 316 |
318 private: | 317 private: |
319 // The following keep track of and log the effective frame rate whenever | 318 // The following keep track of and log the effective frame rate whenever |
320 // verbose logging is turned on. | 319 // verbose logging is turned on. |
321 base::Time last_frame_rate_log_time_; | 320 base::TimeTicks last_frame_rate_log_time_; |
322 int count_frames_rendered_; | 321 int count_frames_rendered_; |
323 int last_frame_number_; | 322 int last_frame_number_; |
324 | 323 |
325 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliveryLog); | 324 DISALLOW_COPY_AND_ASSIGN(VideoFrameDeliveryLog); |
326 }; | 325 }; |
327 | 326 |
328 bool FrameSubscriber::ShouldCaptureFrame( | 327 bool FrameSubscriber::ShouldCaptureFrame( |
329 base::Time present_time, | 328 base::TimeTicks present_time, |
330 scoped_refptr<media::VideoFrame>* storage, | 329 scoped_refptr<media::VideoFrame>* storage, |
331 DeliverFrameCallback* deliver_frame_cb) { | 330 DeliverFrameCallback* deliver_frame_cb) { |
332 TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame", | 331 TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame", |
333 "instance", this); | 332 "instance", this); |
334 | 333 |
335 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; | 334 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; |
336 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( | 335 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( |
337 event_type_, present_time, storage, &capture_frame_cb); | 336 event_type_, present_time, storage, &capture_frame_cb); |
338 | 337 |
339 *deliver_frame_cb = base::Bind(&InvokeCaptureFrameCallback, capture_frame_cb); | 338 *deliver_frame_cb = base::Bind(&InvokeCaptureFrameCallback, capture_frame_cb); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 if (!rwh || !rwh->GetView() || (rwh->is_accelerated_compositing_active() && | 405 if (!rwh || !rwh->GetView() || (rwh->is_accelerated_compositing_active() && |
407 rwh->GetView()->IsSurfaceAvailableForCopy())) | 406 rwh->GetView()->IsSurfaceAvailableForCopy())) |
408 return; | 407 return; |
409 | 408 |
410 TRACE_EVENT1("mirroring", "ContentCaptureSubscription::Observe", | 409 TRACE_EVENT1("mirroring", "ContentCaptureSubscription::Observe", |
411 "instance", this); | 410 "instance", this); |
412 | 411 |
413 base::Closure copy_done_callback; | 412 base::Closure copy_done_callback; |
414 scoped_refptr<media::VideoFrame> frame; | 413 scoped_refptr<media::VideoFrame> frame; |
415 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; | 414 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; |
416 const base::Time start_time = base::Time::Now(); | 415 const base::TimeTicks start_time = base::TimeTicks::Now(); |
417 if (paint_subscriber_.ShouldCaptureFrame(start_time, | 416 if (paint_subscriber_.ShouldCaptureFrame(start_time, |
418 &frame, | 417 &frame, |
419 &deliver_frame_cb)) { | 418 &deliver_frame_cb)) { |
420 // This message happens just before paint. If we post a task to do the copy, | 419 // This message happens just before paint. If we post a task to do the copy, |
421 // it should run soon after the paint. | 420 // it should run soon after the paint. |
422 BrowserThread::PostTask( | 421 BrowserThread::PostTask( |
423 BrowserThread::UI, FROM_HERE, | 422 BrowserThread::UI, FROM_HERE, |
424 base::Bind(capture_callback_, start_time, frame, deliver_frame_cb)); | 423 base::Bind(capture_callback_, start_time, frame, deliver_frame_cb)); |
425 } | 424 } |
426 } | 425 } |
427 | 426 |
428 void ContentCaptureSubscription::OnTimer() { | 427 void ContentCaptureSubscription::OnTimer() { |
429 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
430 TRACE_EVENT0("mirroring", "ContentCaptureSubscription::OnTimer"); | 429 TRACE_EVENT0("mirroring", "ContentCaptureSubscription::OnTimer"); |
431 | 430 |
432 scoped_refptr<media::VideoFrame> frame; | 431 scoped_refptr<media::VideoFrame> frame; |
433 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; | 432 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; |
434 | 433 |
435 const base::Time start_time = base::Time::Now(); | 434 const base::TimeTicks start_time = base::TimeTicks::Now(); |
436 if (timer_subscriber_.ShouldCaptureFrame(start_time, | 435 if (timer_subscriber_.ShouldCaptureFrame(start_time, |
437 &frame, | 436 &frame, |
438 &deliver_frame_cb)) { | 437 &deliver_frame_cb)) { |
439 capture_callback_.Run(start_time, frame, deliver_frame_cb); | 438 capture_callback_.Run(start_time, frame, deliver_frame_cb); |
440 } | 439 } |
441 } | 440 } |
442 | 441 |
443 void RenderVideoFrame(const SkBitmap& input, | 442 void RenderVideoFrame(const SkBitmap& input, |
444 const scoped_refptr<media::VideoFrame>& output, | 443 const scoped_refptr<media::VideoFrame>& output, |
445 const base::Callback<void(bool)>& done_cb) { | 444 const base::Callback<void(bool)>& done_cb) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 VideoFrameDeliveryLog::VideoFrameDeliveryLog() | 511 VideoFrameDeliveryLog::VideoFrameDeliveryLog() |
513 : last_frame_rate_log_time_(), | 512 : last_frame_rate_log_time_(), |
514 count_frames_rendered_(0), | 513 count_frames_rendered_(0), |
515 last_frame_number_(0) { | 514 last_frame_number_(0) { |
516 } | 515 } |
517 | 516 |
518 void VideoFrameDeliveryLog::ChronicleFrameDelivery(int frame_number) { | 517 void VideoFrameDeliveryLog::ChronicleFrameDelivery(int frame_number) { |
519 // Log frame rate, if verbose logging is turned on. | 518 // Log frame rate, if verbose logging is turned on. |
520 static const base::TimeDelta kFrameRateLogInterval = | 519 static const base::TimeDelta kFrameRateLogInterval = |
521 base::TimeDelta::FromSeconds(10); | 520 base::TimeDelta::FromSeconds(10); |
522 const base::Time now = base::Time::Now(); | 521 const base::TimeTicks now = base::TimeTicks::Now(); |
523 if (last_frame_rate_log_time_.is_null()) { | 522 if (last_frame_rate_log_time_.is_null()) { |
524 last_frame_rate_log_time_ = now; | 523 last_frame_rate_log_time_ = now; |
525 count_frames_rendered_ = 0; | 524 count_frames_rendered_ = 0; |
526 last_frame_number_ = frame_number; | 525 last_frame_number_ = frame_number; |
527 } else { | 526 } else { |
528 ++count_frames_rendered_; | 527 ++count_frames_rendered_; |
529 const base::TimeDelta elapsed = now - last_frame_rate_log_time_; | 528 const base::TimeDelta elapsed = now - last_frame_rate_log_time_; |
530 if (elapsed >= kFrameRateLogInterval) { | 529 if (elapsed >= kFrameRateLogInterval) { |
531 const double measured_fps = | 530 const double measured_fps = |
532 count_frames_rendered_ / elapsed.InSecondsF(); | 531 count_frames_rendered_ / elapsed.InSecondsF(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 subscription_.reset(); | 581 subscription_.reset(); |
583 if (web_contents()) { | 582 if (web_contents()) { |
584 web_contents()->DecrementCapturerCount(); | 583 web_contents()->DecrementCapturerCount(); |
585 Observe(NULL); | 584 Observe(NULL); |
586 } | 585 } |
587 render_thread_.Stop(); | 586 render_thread_.Stop(); |
588 started_ = false; | 587 started_ = false; |
589 } | 588 } |
590 | 589 |
591 void WebContentsCaptureMachine::Capture( | 590 void WebContentsCaptureMachine::Capture( |
592 const base::Time& start_time, | 591 const base::TimeTicks& start_time, |
593 const scoped_refptr<media::VideoFrame>& target, | 592 const scoped_refptr<media::VideoFrame>& target, |
594 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 593 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
595 deliver_frame_cb) { | 594 deliver_frame_cb) { |
596 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
597 | 596 |
598 RenderWidgetHost* rwh = GetTarget(); | 597 RenderWidgetHost* rwh = GetTarget(); |
599 RenderWidgetHostViewPort* view = | 598 RenderWidgetHostViewPort* view = |
600 rwh ? RenderWidgetHostViewPort::FromRWHV(rwh->GetView()) : NULL; | 599 rwh ? RenderWidgetHostViewPort::FromRWHV(rwh->GetView()) : NULL; |
601 if (!view || !rwh) { | 600 if (!view || !rwh) { |
602 deliver_frame_cb.Run(base::Time(), false); | 601 deliver_frame_cb.Run(base::TimeTicks(), false); |
603 return; | 602 return; |
604 } | 603 } |
605 | 604 |
606 gfx::Size video_size = target->coded_size(); | 605 gfx::Size video_size = target->coded_size(); |
607 gfx::Size view_size = view->GetViewBounds().size(); | 606 gfx::Size view_size = view->GetViewBounds().size(); |
608 gfx::Size fitted_size; | 607 gfx::Size fitted_size; |
609 if (!view_size.IsEmpty()) { | 608 if (!view_size.IsEmpty()) { |
610 fitted_size = ComputeYV12LetterboxRegion(video_size, view_size).size(); | 609 fitted_size = ComputeYV12LetterboxRegion(video_size, view_size).size(); |
611 } | 610 } |
612 if (view_size != last_view_size_) { | 611 if (view_size != last_view_size_) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 if (process) | 690 if (process) |
692 rwh = RenderWidgetHost::FromID(process->GetID(), fullscreen_widget_id_); | 691 rwh = RenderWidgetHost::FromID(process->GetID(), fullscreen_widget_id_); |
693 } else { | 692 } else { |
694 rwh = web_contents()->GetRenderViewHost(); | 693 rwh = web_contents()->GetRenderViewHost(); |
695 } | 694 } |
696 | 695 |
697 return rwh; | 696 return rwh; |
698 } | 697 } |
699 | 698 |
700 void WebContentsCaptureMachine::DidCopyFromBackingStore( | 699 void WebContentsCaptureMachine::DidCopyFromBackingStore( |
701 const base::Time& start_time, | 700 const base::TimeTicks& start_time, |
702 const scoped_refptr<media::VideoFrame>& target, | 701 const scoped_refptr<media::VideoFrame>& target, |
703 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 702 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
704 deliver_frame_cb, | 703 deliver_frame_cb, |
705 bool success, | 704 bool success, |
706 const SkBitmap& bitmap) { | 705 const SkBitmap& bitmap) { |
707 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
708 | 707 |
709 base::Time now = base::Time::Now(); | 708 base::TimeTicks now = base::TimeTicks::Now(); |
710 if (success) { | 709 if (success) { |
711 UMA_HISTOGRAM_TIMES("TabCapture.CopyTimeBitmap", now - start_time); | 710 UMA_HISTOGRAM_TIMES("TabCapture.CopyTimeBitmap", now - start_time); |
712 TRACE_EVENT_ASYNC_STEP_INTO0("mirroring", "Capture", target.get(), | 711 TRACE_EVENT_ASYNC_STEP_INTO0("mirroring", "Capture", target.get(), |
713 "Render"); | 712 "Render"); |
714 render_thread_.message_loop_proxy()->PostTask(FROM_HERE, base::Bind( | 713 render_thread_.message_loop_proxy()->PostTask(FROM_HERE, base::Bind( |
715 &RenderVideoFrame, bitmap, target, | 714 &RenderVideoFrame, bitmap, target, |
716 base::Bind(deliver_frame_cb, start_time))); | 715 base::Bind(deliver_frame_cb, start_time))); |
717 } else { | 716 } else { |
718 // Capture can fail due to transient issues, so just skip this frame. | 717 // Capture can fail due to transient issues, so just skip this frame. |
719 DVLOG(1) << "CopyFromBackingStore failed; skipping frame."; | 718 DVLOG(1) << "CopyFromBackingStore failed; skipping frame."; |
720 deliver_frame_cb.Run(start_time, false); | 719 deliver_frame_cb.Run(start_time, false); |
721 } | 720 } |
722 } | 721 } |
723 | 722 |
724 void WebContentsCaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame( | 723 void WebContentsCaptureMachine::DidCopyFromCompositingSurfaceToVideoFrame( |
725 const base::Time& start_time, | 724 const base::TimeTicks& start_time, |
726 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 725 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
727 deliver_frame_cb, | 726 deliver_frame_cb, |
728 bool success) { | 727 bool success) { |
729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 728 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
730 base::Time now = base::Time::Now(); | 729 base::TimeTicks now = base::TimeTicks::Now(); |
731 | 730 |
732 if (success) { | 731 if (success) { |
733 UMA_HISTOGRAM_TIMES("TabCapture.CopyTimeVideoFrame", now - start_time); | 732 UMA_HISTOGRAM_TIMES("TabCapture.CopyTimeVideoFrame", now - start_time); |
734 } else { | 733 } else { |
735 // Capture can fail due to transient issues, so just skip this frame. | 734 // Capture can fail due to transient issues, so just skip this frame. |
736 DVLOG(1) << "CopyFromCompositingSurface failed; skipping frame."; | 735 DVLOG(1) << "CopyFromCompositingSurface failed; skipping frame."; |
737 } | 736 } |
738 deliver_frame_cb.Run(start_time, success); | 737 deliver_frame_cb.Run(start_time, success); |
739 } | 738 } |
740 | 739 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 scoped_ptr<Client> client) { | 781 scoped_ptr<Client> client) { |
783 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); | 782 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); |
784 impl_->AllocateAndStart(params, client.Pass()); | 783 impl_->AllocateAndStart(params, client.Pass()); |
785 } | 784 } |
786 | 785 |
787 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { | 786 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { |
788 impl_->StopAndDeAllocate(); | 787 impl_->StopAndDeAllocate(); |
789 } | 788 } |
790 | 789 |
791 } // namespace content | 790 } // namespace content |
OLD | NEW |