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 |