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 |