| 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 |