Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Side by Side Diff: content/browser/media/capture/web_contents_video_capture_device.cc

Issue 418283003: "Buttery Smooth" Tab Capture. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698