| 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { | 130 class FrameSubscriber : public RenderWidgetHostViewFrameSubscriber { |
| 131 public: | 131 public: |
| 132 FrameSubscriber(VideoCaptureOracle::Event event_type, | 132 FrameSubscriber(VideoCaptureOracle::Event event_type, |
| 133 const scoped_refptr<ThreadSafeCaptureOracle>& oracle, | 133 const scoped_refptr<ThreadSafeCaptureOracle>& oracle, |
| 134 VideoFrameDeliveryLog* delivery_log) | 134 VideoFrameDeliveryLog* delivery_log) |
| 135 : event_type_(event_type), | 135 : event_type_(event_type), |
| 136 oracle_proxy_(oracle), | 136 oracle_proxy_(oracle), |
| 137 delivery_log_(delivery_log) {} | 137 delivery_log_(delivery_log) {} |
| 138 | 138 |
| 139 virtual bool ShouldCaptureFrame( | 139 virtual bool ShouldCaptureFrame( |
| 140 const gfx::Rect& damage_rect, |
| 140 base::TimeTicks present_time, | 141 base::TimeTicks present_time, |
| 141 scoped_refptr<media::VideoFrame>* storage, | 142 scoped_refptr<media::VideoFrame>* storage, |
| 142 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* | 143 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback* |
| 143 deliver_frame_cb) OVERRIDE; | 144 deliver_frame_cb) OVERRIDE; |
| 144 | 145 |
| 145 private: | 146 private: |
| 146 const VideoCaptureOracle::Event event_type_; | 147 const VideoCaptureOracle::Event event_type_; |
| 147 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; | 148 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; |
| 148 VideoFrameDeliveryLog* const delivery_log_; | 149 VideoFrameDeliveryLog* const delivery_log_; |
| 149 }; | 150 }; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 scoped_ptr<ContentCaptureSubscription> subscription_; | 326 scoped_ptr<ContentCaptureSubscription> subscription_; |
| 326 | 327 |
| 327 // Weak pointer factory used to invalidate callbacks. | 328 // Weak pointer factory used to invalidate callbacks. |
| 328 // NOTE: Weak pointers must be invalidated before all other member variables. | 329 // NOTE: Weak pointers must be invalidated before all other member variables. |
| 329 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_; | 330 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_; |
| 330 | 331 |
| 331 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine); | 332 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine); |
| 332 }; | 333 }; |
| 333 | 334 |
| 334 bool FrameSubscriber::ShouldCaptureFrame( | 335 bool FrameSubscriber::ShouldCaptureFrame( |
| 336 const gfx::Rect& damage_rect, |
| 335 base::TimeTicks present_time, | 337 base::TimeTicks present_time, |
| 336 scoped_refptr<media::VideoFrame>* storage, | 338 scoped_refptr<media::VideoFrame>* storage, |
| 337 DeliverFrameCallback* deliver_frame_cb) { | 339 DeliverFrameCallback* deliver_frame_cb) { |
| 338 TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame", | 340 TRACE_EVENT1("mirroring", "FrameSubscriber::ShouldCaptureFrame", |
| 339 "instance", this); | 341 "instance", this); |
| 340 | 342 |
| 341 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; | 343 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; |
| 342 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( | 344 bool oracle_decision = oracle_proxy_->ObserveEventAndDecideCapture( |
| 343 event_type_, present_time, storage, &capture_frame_cb); | 345 event_type_, damage_rect, present_time, storage, &capture_frame_cb); |
| 344 | 346 |
| 345 if (!capture_frame_cb.is_null()) | 347 if (!capture_frame_cb.is_null()) |
| 346 *deliver_frame_cb = base::Bind(capture_frame_cb, *storage); | 348 *deliver_frame_cb = base::Bind(capture_frame_cb, *storage); |
| 347 if (oracle_decision) | 349 if (oracle_decision) |
| 348 delivery_log_->ChronicleFrameDelivery(present_time); | 350 delivery_log_->ChronicleFrameDelivery(present_time); |
| 349 return oracle_decision; | 351 return oracle_decision; |
| 350 } | 352 } |
| 351 | 353 |
| 352 ContentCaptureSubscription::ContentCaptureSubscription( | 354 ContentCaptureSubscription::ContentCaptureSubscription( |
| 353 const RenderWidgetHost& source, | 355 const RenderWidgetHost& source, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 377 } | 379 } |
| 378 | 380 |
| 379 // Subscribe to software paint events. This instance will service these by | 381 // Subscribe to software paint events. This instance will service these by |
| 380 // reflecting them back to the WebContentsCaptureMachine via | 382 // reflecting them back to the WebContentsCaptureMachine via |
| 381 // |capture_callback|. | 383 // |capture_callback|. |
| 382 registrar_.Add( | 384 registrar_.Add( |
| 383 this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, | 385 this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, |
| 384 Source<RenderWidgetHost>(&source)); | 386 Source<RenderWidgetHost>(&source)); |
| 385 | 387 |
| 386 // Subscribe to timer events. This instance will service these as well. | 388 // Subscribe to timer events. This instance will service these as well. |
| 387 timer_.Start(FROM_HERE, oracle_proxy->capture_period(), | 389 timer_.Start(FROM_HERE, oracle_proxy->min_capture_period(), |
| 388 base::Bind(&ContentCaptureSubscription::OnTimer, | 390 base::Bind(&ContentCaptureSubscription::OnTimer, |
| 389 base::Unretained(this))); | 391 base::Unretained(this))); |
| 390 } | 392 } |
| 391 | 393 |
| 392 ContentCaptureSubscription::~ContentCaptureSubscription() { | 394 ContentCaptureSubscription::~ContentCaptureSubscription() { |
| 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 394 if (kAcceleratedSubscriberIsSupported) { | 396 if (kAcceleratedSubscriberIsSupported) { |
| 395 RenderViewHost* source = RenderViewHost::FromID(render_process_id_, | 397 RenderViewHost* source = RenderViewHost::FromID(render_process_id_, |
| 396 render_view_id_); | 398 render_view_id_); |
| 397 if (source) { | 399 if (source) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 426 return; | 428 return; |
| 427 #endif | 429 #endif |
| 428 | 430 |
| 429 TRACE_EVENT1("mirroring", "ContentCaptureSubscription::Observe", | 431 TRACE_EVENT1("mirroring", "ContentCaptureSubscription::Observe", |
| 430 "instance", this); | 432 "instance", this); |
| 431 | 433 |
| 432 base::Closure copy_done_callback; | 434 base::Closure copy_done_callback; |
| 433 scoped_refptr<media::VideoFrame> frame; | 435 scoped_refptr<media::VideoFrame> frame; |
| 434 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; | 436 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; |
| 435 const base::TimeTicks start_time = base::TimeTicks::Now(); | 437 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 436 if (paint_subscriber_.ShouldCaptureFrame(start_time, | 438 if (paint_subscriber_.ShouldCaptureFrame(gfx::Rect(), |
| 439 start_time, |
| 437 &frame, | 440 &frame, |
| 438 &deliver_frame_cb)) { | 441 &deliver_frame_cb)) { |
| 439 // This message happens just before paint. If we post a task to do the copy, | 442 // This message happens just before paint. If we post a task to do the copy, |
| 440 // it should run soon after the paint. | 443 // it should run soon after the paint. |
| 441 BrowserThread::PostTask( | 444 BrowserThread::PostTask( |
| 442 BrowserThread::UI, FROM_HERE, | 445 BrowserThread::UI, FROM_HERE, |
| 443 base::Bind(capture_callback_, start_time, frame, deliver_frame_cb)); | 446 base::Bind(capture_callback_, start_time, frame, deliver_frame_cb)); |
| 444 } | 447 } |
| 445 } | 448 } |
| 446 | 449 |
| 447 void ContentCaptureSubscription::OnTimer() { | 450 void ContentCaptureSubscription::OnTimer() { |
| 448 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 451 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 449 TRACE_EVENT0("mirroring", "ContentCaptureSubscription::OnTimer"); | 452 TRACE_EVENT0("mirroring", "ContentCaptureSubscription::OnTimer"); |
| 450 | 453 |
| 451 scoped_refptr<media::VideoFrame> frame; | 454 scoped_refptr<media::VideoFrame> frame; |
| 452 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; | 455 RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback deliver_frame_cb; |
| 453 | 456 |
| 454 const base::TimeTicks start_time = base::TimeTicks::Now(); | 457 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 455 if (timer_subscriber_.ShouldCaptureFrame(start_time, | 458 if (timer_subscriber_.ShouldCaptureFrame(gfx::Rect(), |
| 459 start_time, |
| 456 &frame, | 460 &frame, |
| 457 &deliver_frame_cb)) { | 461 &deliver_frame_cb)) { |
| 458 capture_callback_.Run(start_time, frame, deliver_frame_cb); | 462 capture_callback_.Run(start_time, frame, deliver_frame_cb); |
| 459 } | 463 } |
| 460 } | 464 } |
| 461 | 465 |
| 462 void RenderVideoFrame(const SkBitmap& input, | 466 void RenderVideoFrame(const SkBitmap& input, |
| 463 const scoped_refptr<media::VideoFrame>& output, | 467 const scoped_refptr<media::VideoFrame>& output, |
| 464 const base::Callback<void(bool)>& done_cb) { | 468 const base::Callback<void(bool)>& done_cb) { |
| 465 base::ScopedClosureRunner failure_handler(base::Bind(done_cb, false)); | 469 base::ScopedClosureRunner failure_handler(base::Bind(done_cb, false)); |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 scoped_ptr<Client> client) { | 816 scoped_ptr<Client> client) { |
| 813 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); | 817 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); |
| 814 core_->AllocateAndStart(params, client.Pass()); | 818 core_->AllocateAndStart(params, client.Pass()); |
| 815 } | 819 } |
| 816 | 820 |
| 817 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { | 821 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { |
| 818 core_->StopAndDeAllocate(); | 822 core_->StopAndDeAllocate(); |
| 819 } | 823 } |
| 820 | 824 |
| 821 } // namespace content | 825 } // namespace content |
| OLD | NEW |