| 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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 const base::Callback<void(bool)>& done_cb); | 211 const base::Callback<void(bool)>& done_cb); |
| 212 | 212 |
| 213 // Renews capture subscriptions based on feedback from WebContentsTracker, and | 213 // Renews capture subscriptions based on feedback from WebContentsTracker, and |
| 214 // also executes copying of the backing store on the UI BrowserThread. | 214 // also executes copying of the backing store on the UI BrowserThread. |
| 215 class WebContentsCaptureMachine : public VideoCaptureMachine { | 215 class WebContentsCaptureMachine : public VideoCaptureMachine { |
| 216 public: | 216 public: |
| 217 WebContentsCaptureMachine(int render_process_id, int main_render_frame_id); | 217 WebContentsCaptureMachine(int render_process_id, int main_render_frame_id); |
| 218 ~WebContentsCaptureMachine() override; | 218 ~WebContentsCaptureMachine() override; |
| 219 | 219 |
| 220 // VideoCaptureMachine overrides. | 220 // VideoCaptureMachine overrides. |
| 221 bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 221 void Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, |
| 222 const media::VideoCaptureParams& params) override; | 222 const media::VideoCaptureParams& params, |
| 223 const base::Callback<void(bool)> callback) override; |
| 223 void Stop(const base::Closure& callback) override; | 224 void Stop(const base::Closure& callback) override; |
| 224 | 225 |
| 225 // Starts a copy from the backing store or the composited surface. Must be run | 226 // Starts a copy from the backing store or the composited surface. Must be run |
| 226 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation | 227 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation |
| 227 // completes. The copy will occur to |target|. | 228 // completes. The copy will occur to |target|. |
| 228 // | 229 // |
| 229 // This may be used as a ContentCaptureSubscription::CaptureCallback. | 230 // This may be used as a ContentCaptureSubscription::CaptureCallback. |
| 230 void Capture(const base::TimeTicks& start_time, | 231 void Capture(const base::TimeTicks& start_time, |
| 231 const scoped_refptr<media::VideoFrame>& target, | 232 const scoped_refptr<media::VideoFrame>& target, |
| 232 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 233 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
| 233 deliver_frame_cb); | 234 deliver_frame_cb); |
| 234 | 235 |
| 235 private: | 236 private: |
| 237 bool InternalStart(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, |
| 238 const media::VideoCaptureParams& params); |
| 239 void InternalStop(const base::Closure& callback); |
| 236 bool IsStarted() const; | 240 bool IsStarted() const; |
| 237 | 241 |
| 238 // Computes the preferred size of the target RenderWidget for optimal capture. | 242 // Computes the preferred size of the target RenderWidget for optimal capture. |
| 239 gfx::Size ComputeOptimalTargetSize() const; | 243 gfx::Size ComputeOptimalTargetSize() const; |
| 240 | 244 |
| 241 // Response callback for RenderWidgetHost::CopyFromBackingStore(). | 245 // Response callback for RenderWidgetHost::CopyFromBackingStore(). |
| 242 void DidCopyFromBackingStore( | 246 void DidCopyFromBackingStore( |
| 243 const base::TimeTicks& start_time, | 247 const base::TimeTicks& start_time, |
| 244 const scoped_refptr<media::VideoFrame>& target, | 248 const scoped_refptr<media::VideoFrame>& target, |
| 245 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& | 249 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 tracker_(new WebContentsTracker(true)), | 479 tracker_(new WebContentsTracker(true)), |
| 476 weak_ptr_factory_(this) {} | 480 weak_ptr_factory_(this) {} |
| 477 | 481 |
| 478 WebContentsCaptureMachine::~WebContentsCaptureMachine() {} | 482 WebContentsCaptureMachine::~WebContentsCaptureMachine() {} |
| 479 | 483 |
| 480 bool WebContentsCaptureMachine::IsStarted() const { | 484 bool WebContentsCaptureMachine::IsStarted() const { |
| 481 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 485 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 482 return weak_ptr_factory_.HasWeakPtrs(); | 486 return weak_ptr_factory_.HasWeakPtrs(); |
| 483 } | 487 } |
| 484 | 488 |
| 485 bool WebContentsCaptureMachine::Start( | 489 void WebContentsCaptureMachine::Start( |
| 490 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, |
| 491 const media::VideoCaptureParams& params, |
| 492 const base::Callback<void(bool)> callback) { |
| 493 // Starts the capture machine asynchronously. |
| 494 BrowserThread::PostTaskAndReplyWithResult( |
| 495 BrowserThread::UI, |
| 496 FROM_HERE, |
| 497 base::Bind(&WebContentsCaptureMachine::InternalStart, |
| 498 base::Unretained(this), |
| 499 oracle_proxy, |
| 500 params), |
| 501 callback); |
| 502 } |
| 503 |
| 504 bool WebContentsCaptureMachine::InternalStart( |
| 486 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 505 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, |
| 487 const media::VideoCaptureParams& params) { | 506 const media::VideoCaptureParams& params) { |
| 488 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 507 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 489 DCHECK(!IsStarted()); | 508 DCHECK(!IsStarted()); |
| 490 | 509 |
| 491 DCHECK(oracle_proxy.get()); | 510 DCHECK(oracle_proxy.get()); |
| 492 oracle_proxy_ = oracle_proxy; | 511 oracle_proxy_ = oracle_proxy; |
| 493 capture_params_ = params; | 512 capture_params_ = params; |
| 494 | 513 |
| 495 render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread")); | 514 render_thread_.reset(new base::Thread("WebContentsVideo_RenderThread")); |
| 496 if (!render_thread_->Start()) { | 515 if (!render_thread_->Start()) { |
| 497 DVLOG(1) << "Failed to spawn render thread."; | 516 DVLOG(1) << "Failed to spawn render thread."; |
| 498 render_thread_.reset(); | 517 render_thread_.reset(); |
| 499 return false; | 518 return false; |
| 500 } | 519 } |
| 501 | 520 |
| 502 // Note: Creation of the first WeakPtr in the following statement will cause | 521 // Note: Creation of the first WeakPtr in the following statement will cause |
| 503 // IsStarted() to return true from now on. | 522 // IsStarted() to return true from now on. |
| 504 tracker_->Start(initial_render_process_id_, initial_main_render_frame_id_, | 523 tracker_->Start(initial_render_process_id_, initial_main_render_frame_id_, |
| 505 base::Bind(&WebContentsCaptureMachine::RenewFrameSubscription, | 524 base::Bind(&WebContentsCaptureMachine::RenewFrameSubscription, |
| 506 weak_ptr_factory_.GetWeakPtr())); | 525 weak_ptr_factory_.GetWeakPtr())); |
| 507 | 526 |
| 508 return true; | 527 return true; |
| 509 } | 528 } |
| 510 | 529 |
| 511 void WebContentsCaptureMachine::Stop(const base::Closure& callback) { | 530 void WebContentsCaptureMachine::Stop(const base::Closure& callback) { |
| 531 // Stops the capture machine asynchronously. |
| 532 BrowserThread::PostTask( |
| 533 BrowserThread::UI, FROM_HERE, base::Bind( |
| 534 &WebContentsCaptureMachine::InternalStop, |
| 535 base::Unretained(this), |
| 536 callback)); |
| 537 } |
| 538 |
| 539 void WebContentsCaptureMachine::InternalStop(const base::Closure& callback) { |
| 512 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 540 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 513 | 541 |
| 514 if (!IsStarted()) { | 542 if (!IsStarted()) { |
| 515 callback.Run(); | 543 callback.Run(); |
| 516 return; | 544 return; |
| 517 } | 545 } |
| 518 | 546 |
| 519 // The following cancels any outstanding callbacks and causes IsStarted() to | 547 // The following cancels any outstanding callbacks and causes IsStarted() to |
| 520 // return false from here onward. | 548 // return false from here onward. |
| 521 weak_ptr_factory_.InvalidateWeakPtrs(); | 549 weak_ptr_factory_.InvalidateWeakPtrs(); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 scoped_ptr<Client> client) { | 748 scoped_ptr<Client> client) { |
| 721 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); | 749 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); |
| 722 core_->AllocateAndStart(params, client.Pass()); | 750 core_->AllocateAndStart(params, client.Pass()); |
| 723 } | 751 } |
| 724 | 752 |
| 725 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { | 753 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { |
| 726 core_->StopAndDeAllocate(); | 754 core_->StopAndDeAllocate(); |
| 727 } | 755 } |
| 728 | 756 |
| 729 } // namespace content | 757 } // namespace content |
| OLD | NEW |