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

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

Issue 2364413002: Screen Video Capture: Implement suspend optimization. (Closed)
Patch Set: Unwind ScreenCaptureMachineAndroid changes. Created 4 years, 2 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
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 54
55 #include <algorithm> 55 #include <algorithm>
56 #include <memory> 56 #include <memory>
57 #include <utility> 57 #include <utility>
58 58
59 #include "base/bind.h" 59 #include "base/bind.h"
60 #include "base/callback_helpers.h" 60 #include "base/callback_helpers.h"
61 #include "base/location.h" 61 #include "base/location.h"
62 #include "base/logging.h" 62 #include "base/logging.h"
63 #include "base/macros.h" 63 #include "base/macros.h"
64 #include "base/memory/ptr_util.h"
64 #include "base/memory/weak_ptr.h" 65 #include "base/memory/weak_ptr.h"
65 #include "base/metrics/histogram_macros.h" 66 #include "base/metrics/histogram_macros.h"
66 #include "base/sequenced_task_runner.h" 67 #include "base/sequenced_task_runner.h"
67 #include "base/single_thread_task_runner.h" 68 #include "base/single_thread_task_runner.h"
68 #include "base/threading/thread.h" 69 #include "base/threading/thread.h"
69 #include "base/threading/thread_checker.h" 70 #include "base/threading/thread_checker.h"
70 #include "base/time/time.h" 71 #include "base/time/time.h"
71 #include "build/build_config.h" 72 #include "build/build_config.h"
72 #include "content/browser/media/capture/cursor_renderer.h" 73 #include "content/browser/media/capture/cursor_renderer.h"
73 #include "content/browser/media/capture/web_contents_tracker.h" 74 #include "content/browser/media/capture/web_contents_tracker.h"
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 public: 258 public:
258 WebContentsCaptureMachine(int render_process_id, 259 WebContentsCaptureMachine(int render_process_id,
259 int main_render_frame_id, 260 int main_render_frame_id,
260 bool enable_auto_throttling); 261 bool enable_auto_throttling);
261 ~WebContentsCaptureMachine() override; 262 ~WebContentsCaptureMachine() override;
262 263
263 // VideoCaptureMachine overrides. 264 // VideoCaptureMachine overrides.
264 void Start(const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, 265 void Start(const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
265 const media::VideoCaptureParams& params, 266 const media::VideoCaptureParams& params,
266 const base::Callback<void(bool)> callback) override; 267 const base::Callback<void(bool)> callback) override;
268 void Suspend() override;
269 void Resume() override;
267 void Stop(const base::Closure& callback) override; 270 void Stop(const base::Closure& callback) override;
268 bool IsAutoThrottlingEnabled() const override { 271 bool IsAutoThrottlingEnabled() const override {
269 return auto_throttling_enabled_; 272 return auto_throttling_enabled_;
270 } 273 }
271 void MaybeCaptureForRefresh() override; 274 void MaybeCaptureForRefresh() override;
272 275
273 // Starts a copy from the backing store or the composited surface. Must be run 276 // Starts a copy from the backing store or the composited surface. Must be run
274 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation 277 // on the UI BrowserThread. |deliver_frame_cb| will be run when the operation
275 // completes. The copy will occur to |target|. 278 // completes. The copy will occur to |target|.
276 // 279 //
277 // This may be used as a ContentCaptureSubscription::CaptureCallback. 280 // This may be used as a ContentCaptureSubscription::CaptureCallback.
278 void Capture(const base::TimeTicks& start_time, 281 void Capture(const base::TimeTicks& start_time,
279 const scoped_refptr<media::VideoFrame>& target, 282 const scoped_refptr<media::VideoFrame>& target,
280 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback& 283 const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
281 deliver_frame_cb); 284 deliver_frame_cb);
282 285
283 private: 286 private:
284 bool InternalStart( 287 bool InternalStart(
285 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, 288 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
286 const media::VideoCaptureParams& params); 289 const media::VideoCaptureParams& params);
290 void InternalSuspend();
291 void InternalResume();
287 void InternalStop(const base::Closure& callback); 292 void InternalStop(const base::Closure& callback);
288 void InternalMaybeCaptureForRefresh(); 293 void InternalMaybeCaptureForRefresh();
289 bool IsStarted() const; 294 bool IsStarted() const;
290 295
291 // Computes the preferred size of the target RenderWidget for optimal capture. 296 // Computes the preferred size of the target RenderWidget for optimal capture.
292 gfx::Size ComputeOptimalViewSize() const; 297 gfx::Size ComputeOptimalViewSize() const;
293 298
294 // Response callback for RenderWidgetHost::CopyFromBackingStore(). 299 // Response callback for RenderWidgetHost::CopyFromBackingStore().
295 void DidCopyFromBackingStore( 300 void DidCopyFromBackingStore(
296 const base::TimeTicks& start_time, 301 const base::TimeTicks& start_time,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 // Video capture parameters that this machine is started with. 343 // Video capture parameters that this machine is started with.
339 media::VideoCaptureParams capture_params_; 344 media::VideoCaptureParams capture_params_;
340 345
341 // Last known RenderView size. 346 // Last known RenderView size.
342 gfx::Size last_view_size_; 347 gfx::Size last_view_size_;
343 348
344 // Responsible for forwarding events from the active RenderWidgetHost to the 349 // Responsible for forwarding events from the active RenderWidgetHost to the
345 // oracle, and initiating captures accordingly. 350 // oracle, and initiating captures accordingly.
346 std::unique_ptr<ContentCaptureSubscription> subscription_; 351 std::unique_ptr<ContentCaptureSubscription> subscription_;
347 352
353 // False while frame capture has been suspended. This prevents subscriptions
354 // from being created by RenewFrameSubscription() until frame capture is
355 // resumed.
356 bool frame_capture_active_;
357
348 // Weak pointer factory used to invalidate callbacks. 358 // Weak pointer factory used to invalidate callbacks.
349 // NOTE: Weak pointers must be invalidated before all other member variables. 359 // NOTE: Weak pointers must be invalidated before all other member variables.
350 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_; 360 base::WeakPtrFactory<WebContentsCaptureMachine> weak_ptr_factory_;
351 361
352 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine); 362 DISALLOW_COPY_AND_ASSIGN(WebContentsCaptureMachine);
353 }; 363 };
354 364
355 bool FrameSubscriber::ShouldCaptureFrame( 365 bool FrameSubscriber::ShouldCaptureFrame(
356 const gfx::Rect& damage_rect, 366 const gfx::Rect& damage_rect,
357 base::TimeTicks present_time, 367 base::TimeTicks present_time,
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 } 621 }
612 622
613 WebContentsCaptureMachine::WebContentsCaptureMachine( 623 WebContentsCaptureMachine::WebContentsCaptureMachine(
614 int render_process_id, 624 int render_process_id,
615 int main_render_frame_id, 625 int main_render_frame_id,
616 bool enable_auto_throttling) 626 bool enable_auto_throttling)
617 : initial_render_process_id_(render_process_id), 627 : initial_render_process_id_(render_process_id),
618 initial_main_render_frame_id_(main_render_frame_id), 628 initial_main_render_frame_id_(main_render_frame_id),
619 tracker_(new WebContentsTracker(true)), 629 tracker_(new WebContentsTracker(true)),
620 auto_throttling_enabled_(enable_auto_throttling), 630 auto_throttling_enabled_(enable_auto_throttling),
631 frame_capture_active_(true),
621 weak_ptr_factory_(this) { 632 weak_ptr_factory_(this) {
622 DVLOG(1) << "Created WebContentsCaptureMachine for " << render_process_id 633 DVLOG(1) << "Created WebContentsCaptureMachine for " << render_process_id
623 << ':' << main_render_frame_id 634 << ':' << main_render_frame_id
624 << (auto_throttling_enabled_ ? " with auto-throttling enabled" : ""); 635 << (auto_throttling_enabled_ ? " with auto-throttling enabled" : "");
625 } 636 }
626 637
627 WebContentsCaptureMachine::~WebContentsCaptureMachine() {} 638 WebContentsCaptureMachine::~WebContentsCaptureMachine() {}
628 639
629 bool WebContentsCaptureMachine::IsStarted() const { 640 bool WebContentsCaptureMachine::IsStarted() const {
630 DCHECK_CURRENTLY_ON(BrowserThread::UI); 641 DCHECK_CURRENTLY_ON(BrowserThread::UI);
(...skipping 30 matching lines...) Expand all
661 } 672 }
662 673
663 // Note: Creation of the first WeakPtr in the following statement will cause 674 // Note: Creation of the first WeakPtr in the following statement will cause
664 // IsStarted() to return true from now on. 675 // IsStarted() to return true from now on.
665 tracker_->SetResizeChangeCallback( 676 tracker_->SetResizeChangeCallback(
666 base::Bind(&WebContentsCaptureMachine::UpdateCaptureSize, 677 base::Bind(&WebContentsCaptureMachine::UpdateCaptureSize,
667 weak_ptr_factory_.GetWeakPtr())); 678 weak_ptr_factory_.GetWeakPtr()));
668 tracker_->Start(initial_render_process_id_, initial_main_render_frame_id_, 679 tracker_->Start(initial_render_process_id_, initial_main_render_frame_id_,
669 base::Bind(&WebContentsCaptureMachine::RenewFrameSubscription, 680 base::Bind(&WebContentsCaptureMachine::RenewFrameSubscription,
670 weak_ptr_factory_.GetWeakPtr())); 681 weak_ptr_factory_.GetWeakPtr()));
682 if (WebContents* contents = tracker_->web_contents())
683 contents->IncrementCapturerCount(ComputeOptimalViewSize());
671 684
672 return true; 685 return true;
673 } 686 }
674 687
688 void WebContentsCaptureMachine::Suspend() {
689 BrowserThread::PostTask(
690 BrowserThread::UI, FROM_HERE,
691 base::Bind(&WebContentsCaptureMachine::InternalSuspend,
692 base::Unretained(this)));
693 }
694
695 void WebContentsCaptureMachine::InternalSuspend() {
696 DCHECK_CURRENTLY_ON(BrowserThread::UI);
697 if (!frame_capture_active_)
698 return;
699 frame_capture_active_ = false;
700 if (IsStarted())
701 RenewFrameSubscription(true);
702 }
703
704 void WebContentsCaptureMachine::Resume() {
705 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
706 base::Bind(&WebContentsCaptureMachine::InternalResume,
707 base::Unretained(this)));
708 }
709
710 void WebContentsCaptureMachine::InternalResume() {
711 DCHECK_CURRENTLY_ON(BrowserThread::UI);
712 if (frame_capture_active_)
713 return;
714 frame_capture_active_ = true;
715 if (IsStarted())
716 RenewFrameSubscription(true);
717 }
718
675 void WebContentsCaptureMachine::Stop(const base::Closure& callback) { 719 void WebContentsCaptureMachine::Stop(const base::Closure& callback) {
676 // Stops the capture machine asynchronously. 720 // Stops the capture machine asynchronously.
677 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 721 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
678 base::Bind(&WebContentsCaptureMachine::InternalStop, 722 base::Bind(&WebContentsCaptureMachine::InternalStop,
679 base::Unretained(this), callback)); 723 base::Unretained(this), callback));
680 } 724 }
681 725
682 void WebContentsCaptureMachine::InternalStop(const base::Closure& callback) { 726 void WebContentsCaptureMachine::InternalStop(const base::Closure& callback) {
683 DCHECK_CURRENTLY_ON(BrowserThread::UI); 727 DCHECK_CURRENTLY_ON(BrowserThread::UI);
684 728
685 if (!IsStarted()) { 729 if (!IsStarted()) {
686 callback.Run(); 730 callback.Run();
687 return; 731 return;
688 } 732 }
689 733
690 // The following cancels any outstanding callbacks and causes IsStarted() to 734 // The following cancels any outstanding callbacks and causes IsStarted() to
691 // return false from here onward. 735 // return false from here onward.
692 weak_ptr_factory_.InvalidateWeakPtrs(); 736 weak_ptr_factory_.InvalidateWeakPtrs();
693 737
694 // Note: RenewFrameSubscription() must be called before stopping |tracker_| so
695 // the web_contents() can be notified that the capturing is ending.
696 RenewFrameSubscription(false); 738 RenewFrameSubscription(false);
739 if (WebContents* contents = tracker_->web_contents())
740 contents->DecrementCapturerCount();
697 tracker_->Stop(); 741 tracker_->Stop();
698 742
699 // The render thread cannot be stopped on the UI thread, so post a message 743 // The render thread cannot be stopped on the UI thread, so post a message
700 // to the thread pool used for blocking operations. 744 // to the thread pool used for blocking operations.
701 if (render_thread_) { 745 if (render_thread_) {
702 BrowserThread::PostBlockingPoolTask( 746 BrowserThread::PostBlockingPoolTask(
703 FROM_HERE, base::Bind(&DeleteOnWorkerThread, 747 FROM_HERE, base::Bind(&DeleteOnWorkerThread,
704 base::Passed(&render_thread_), callback)); 748 base::Passed(&render_thread_), callback));
705 } 749 }
706 } 750 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 deliver_frame_cb.Run(start_time, region_in_frame, success); 921 deliver_frame_cb.Run(start_time, region_in_frame, success);
878 } 922 }
879 923
880 void WebContentsCaptureMachine::RenewFrameSubscription(bool had_target) { 924 void WebContentsCaptureMachine::RenewFrameSubscription(bool had_target) {
881 DCHECK_CURRENTLY_ON(BrowserThread::UI); 925 DCHECK_CURRENTLY_ON(BrowserThread::UI);
882 926
883 RenderWidgetHost* const rwh = 927 RenderWidgetHost* const rwh =
884 had_target ? tracker_->GetTargetRenderWidgetHost() : nullptr; 928 had_target ? tracker_->GetTargetRenderWidgetHost() : nullptr;
885 929
886 // Always destroy the old subscription before creating a new one. 930 // Always destroy the old subscription before creating a new one.
887 const bool had_subscription = !!subscription_; 931 if (subscription_) {
888 subscription_.reset(); 932 DVLOG(1) << "Cancelling existing ContentCaptureSubscription.";
889 933 subscription_.reset();
890 DVLOG(1) << "Renewing frame subscription to RWH@" << rwh 934 }
891 << ", had_subscription=" << had_subscription;
892 935
893 if (!rwh) { 936 if (!rwh) {
894 if (had_subscription && tracker_->web_contents()) 937 DVLOG(1) << "Cannot renew ContentCaptureSubscription: no RWH target.";
895 tracker_->web_contents()->DecrementCapturerCount();
896 if (IsStarted()) { 938 if (IsStarted()) {
897 // Tracking of WebContents and/or its main frame has failed before Stop() 939 // Tracking of WebContents and/or its main frame has failed before Stop()
898 // was called, so report this as an error: 940 // was called, so report this as an error:
899 oracle_proxy_->ReportError(FROM_HERE, 941 oracle_proxy_->ReportError(FROM_HERE,
900 "WebContents and/or main frame are gone."); 942 "WebContents and/or main frame are gone.");
901 } 943 }
902 return; 944 return;
903 } 945 }
904 946
905 if (!had_subscription && tracker_->web_contents()) 947 if (frame_capture_active_) {
906 tracker_->web_contents()->IncrementCapturerCount(ComputeOptimalViewSize()); 948 DVLOG(1) << "Renewing ContentCaptureSubscription to RWH@" << rwh;
907 949 subscription_.reset(new ContentCaptureSubscription(
908 subscription_.reset(new ContentCaptureSubscription( 950 *rwh, oracle_proxy_, base::Bind(&WebContentsCaptureMachine::Capture,
909 *rwh, oracle_proxy_, base::Bind(&WebContentsCaptureMachine::Capture, 951 weak_ptr_factory_.GetWeakPtr())));
910 weak_ptr_factory_.GetWeakPtr()))); 952 }
911 } 953 }
912 954
913 void WebContentsCaptureMachine::UpdateCaptureSize() { 955 void WebContentsCaptureMachine::UpdateCaptureSize() {
914 DCHECK_CURRENTLY_ON(BrowserThread::UI); 956 DCHECK_CURRENTLY_ON(BrowserThread::UI);
915 957
916 if (!oracle_proxy_) 958 if (!oracle_proxy_)
917 return; 959 return;
918 RenderWidgetHost* const rwh = tracker_->GetTargetRenderWidgetHost(); 960 RenderWidgetHost* const rwh = tracker_->GetTargetRenderWidgetHost();
919 RenderWidgetHostView* const view = rwh ? rwh->GetView() : nullptr; 961 RenderWidgetHostView* const view = rwh ? rwh->GetView() : nullptr;
920 if (!view) 962 if (!view)
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 const media::VideoCaptureParams& params, 1011 const media::VideoCaptureParams& params,
970 std::unique_ptr<Client> client) { 1012 std::unique_ptr<Client> client) {
971 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 1013 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
972 core_->AllocateAndStart(params, std::move(client)); 1014 core_->AllocateAndStart(params, std::move(client));
973 } 1015 }
974 1016
975 void WebContentsVideoCaptureDevice::RequestRefreshFrame() { 1017 void WebContentsVideoCaptureDevice::RequestRefreshFrame() {
976 core_->RequestRefreshFrame(); 1018 core_->RequestRefreshFrame();
977 } 1019 }
978 1020
1021 void WebContentsVideoCaptureDevice::MaybeSuspend() {
1022 core_->Suspend();
1023 }
1024
1025 void WebContentsVideoCaptureDevice::Resume() {
1026 core_->Resume();
1027 }
1028
979 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { 1029 void WebContentsVideoCaptureDevice::StopAndDeAllocate() {
980 core_->StopAndDeAllocate(); 1030 core_->StopAndDeAllocate();
981 } 1031 }
982 1032
983 } // namespace content 1033 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698