| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 #include "content/browser/media/capture/aura_window_capture_machine.h" | 5 #include "content/browser/media/capture/aura_window_capture_machine.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "cc/output/copy_output_request.h" | 12 #include "cc/output/copy_output_request.h" |
| 13 #include "cc/output/copy_output_result.h" | 13 #include "cc/output/copy_output_result.h" |
| 14 #include "components/display_compositor/gl_helper.h" | 14 #include "components/display_compositor/gl_helper.h" |
| 15 #include "content/browser/compositor/image_transport_factory.h" | 15 #include "content/browser/compositor/image_transport_factory.h" |
| 16 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" | 16 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" |
| 17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 18 #include "device/capture/content/thread_safe_capture_oracle.h" |
| 19 #include "device/capture/content/video_capture_oracle.h" |
| 18 #include "device/power_save_blocker/power_save_blocker.h" | 20 #include "device/power_save_blocker/power_save_blocker.h" |
| 19 #include "media/base/video_capture_types.h" | 21 #include "media/base/video_capture_types.h" |
| 20 #include "media/base/video_util.h" | 22 #include "media/base/video_util.h" |
| 21 #include "media/capture/content/thread_safe_capture_oracle.h" | |
| 22 #include "media/capture/content/video_capture_oracle.h" | |
| 23 #include "skia/ext/image_operations.h" | 23 #include "skia/ext/image_operations.h" |
| 24 #include "third_party/skia/include/core/SkBitmap.h" | 24 #include "third_party/skia/include/core/SkBitmap.h" |
| 25 #include "ui/aura/client/screen_position_client.h" | 25 #include "ui/aura/client/screen_position_client.h" |
| 26 #include "ui/aura/env.h" | 26 #include "ui/aura/env.h" |
| 27 #include "ui/aura/window.h" | 27 #include "ui/aura/window.h" |
| 28 #include "ui/aura/window_observer.h" | 28 #include "ui/aura/window_observer.h" |
| 29 #include "ui/aura/window_tree_host.h" | 29 #include "ui/aura/window_tree_host.h" |
| 30 #include "ui/base/cursor/cursors_aura.h" | 30 #include "ui/base/cursor/cursors_aura.h" |
| 31 #include "ui/compositor/compositor.h" | 31 #include "ui/compositor/compositor.h" |
| 32 #include "ui/compositor/dip_util.h" | 32 #include "ui/compositor/dip_util.h" |
| 33 #include "ui/compositor/layer.h" | 33 #include "ui/compositor/layer.h" |
| 34 #include "ui/wm/public/activation_client.h" | 34 #include "ui/wm/public/activation_client.h" |
| 35 | 35 |
| 36 namespace content { | 36 namespace content { |
| 37 | 37 |
| 38 AuraWindowCaptureMachine::AuraWindowCaptureMachine() | 38 AuraWindowCaptureMachine::AuraWindowCaptureMachine() |
| 39 : desktop_window_(NULL), | 39 : desktop_window_(NULL), |
| 40 screen_capture_(false), | 40 screen_capture_(false), |
| 41 weak_factory_(this) {} | 41 weak_factory_(this) {} |
| 42 | 42 |
| 43 AuraWindowCaptureMachine::~AuraWindowCaptureMachine() {} | 43 AuraWindowCaptureMachine::~AuraWindowCaptureMachine() {} |
| 44 | 44 |
| 45 void AuraWindowCaptureMachine::Start( | 45 void AuraWindowCaptureMachine::Start( |
| 46 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, | 46 const scoped_refptr<device::ThreadSafeCaptureOracle>& oracle_proxy, |
| 47 const media::VideoCaptureParams& params, | 47 const media::VideoCaptureParams& params, |
| 48 const base::Callback<void(bool)> callback) { | 48 const base::Callback<void(bool)> callback) { |
| 49 // Starts the capture machine asynchronously. | 49 // Starts the capture machine asynchronously. |
| 50 BrowserThread::PostTaskAndReplyWithResult( | 50 BrowserThread::PostTaskAndReplyWithResult( |
| 51 BrowserThread::UI, | 51 BrowserThread::UI, |
| 52 FROM_HERE, | 52 FROM_HERE, |
| 53 base::Bind(&AuraWindowCaptureMachine::InternalStart, | 53 base::Bind(&AuraWindowCaptureMachine::InternalStart, |
| 54 base::Unretained(this), | 54 base::Unretained(this), |
| 55 oracle_proxy, | 55 oracle_proxy, |
| 56 params), | 56 params), |
| 57 callback); | 57 callback); |
| 58 } | 58 } |
| 59 | 59 |
| 60 bool AuraWindowCaptureMachine::InternalStart( | 60 bool AuraWindowCaptureMachine::InternalStart( |
| 61 const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy, | 61 const scoped_refptr<device::ThreadSafeCaptureOracle>& oracle_proxy, |
| 62 const media::VideoCaptureParams& params) { | 62 const media::VideoCaptureParams& params) { |
| 63 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 63 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 64 | 64 |
| 65 // The window might be destroyed between SetWindow() and Start(). | 65 // The window might be destroyed between SetWindow() and Start(). |
| 66 if (!desktop_window_) | 66 if (!desktop_window_) |
| 67 return false; | 67 return false; |
| 68 | 68 |
| 69 // If the associated layer is already destroyed then return failure. | 69 // If the associated layer is already destroyed then return failure. |
| 70 ui::Layer* layer = desktop_window_->layer(); | 70 ui::Layer* layer = desktop_window_->layer(); |
| 71 if (!layer) | 71 if (!layer) |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 } | 163 } |
| 164 | 164 |
| 165 void AuraWindowCaptureMachine::Capture(base::TimeTicks event_time) { | 165 void AuraWindowCaptureMachine::Capture(base::TimeTicks event_time) { |
| 166 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 166 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 167 | 167 |
| 168 // Do not capture if the desktop window is already destroyed. | 168 // Do not capture if the desktop window is already destroyed. |
| 169 if (!desktop_window_) | 169 if (!desktop_window_) |
| 170 return; | 170 return; |
| 171 | 171 |
| 172 scoped_refptr<media::VideoFrame> frame; | 172 scoped_refptr<media::VideoFrame> frame; |
| 173 media::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; | 173 device::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; |
| 174 | 174 |
| 175 // TODO(miu): Need to fix this so the compositor is providing the presentation | 175 // TODO(miu): Need to fix this so the compositor is providing the presentation |
| 176 // timestamps and damage regions, to leverage the frame timestamp rewriting | 176 // timestamps and damage regions, to leverage the frame timestamp rewriting |
| 177 // logic. http://crbug.com/492839 | 177 // logic. http://crbug.com/492839 |
| 178 const base::TimeTicks start_time = base::TimeTicks::Now(); | 178 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 179 media::VideoCaptureOracle::Event event; | 179 device::VideoCaptureOracle::Event event; |
| 180 if (event_time.is_null()) { | 180 if (event_time.is_null()) { |
| 181 event = media::VideoCaptureOracle::kActiveRefreshRequest; | 181 event = device::VideoCaptureOracle::kActiveRefreshRequest; |
| 182 event_time = start_time; | 182 event_time = start_time; |
| 183 } else { | 183 } else { |
| 184 event = media::VideoCaptureOracle::kCompositorUpdate; | 184 event = device::VideoCaptureOracle::kCompositorUpdate; |
| 185 } | 185 } |
| 186 if (oracle_proxy_->ObserveEventAndDecideCapture( | 186 if (oracle_proxy_->ObserveEventAndDecideCapture( |
| 187 event, gfx::Rect(), event_time, &frame, &capture_frame_cb)) { | 187 event, gfx::Rect(), event_time, &frame, &capture_frame_cb)) { |
| 188 std::unique_ptr<cc::CopyOutputRequest> request = | 188 std::unique_ptr<cc::CopyOutputRequest> request = |
| 189 cc::CopyOutputRequest::CreateRequest(base::Bind( | 189 cc::CopyOutputRequest::CreateRequest(base::Bind( |
| 190 &AuraWindowCaptureMachine::DidCopyOutput, | 190 &AuraWindowCaptureMachine::DidCopyOutput, |
| 191 weak_factory_.GetWeakPtr(), frame, event_time, start_time, | 191 weak_factory_.GetWeakPtr(), frame, event_time, start_time, |
| 192 capture_frame_cb)); | 192 capture_frame_cb)); |
| 193 gfx::Rect window_rect = gfx::Rect(desktop_window_->bounds().width(), | 193 gfx::Rect window_rect = gfx::Rect(desktop_window_->bounds().width(), |
| 194 desktop_window_->bounds().height()); | 194 desktop_window_->bounds().height()); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 video_frame->stride(media::VideoFrame::kVPlane), | 313 video_frame->stride(media::VideoFrame::kVPlane), |
| 314 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(), | 314 video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(), |
| 315 base::Bind(&CopyOutputFinishedForVideo, weak_factory_.GetWeakPtr(), | 315 base::Bind(&CopyOutputFinishedForVideo, weak_factory_.GetWeakPtr(), |
| 316 event_time, capture_frame_cb, video_frame, | 316 event_time, capture_frame_cb, video_frame, |
| 317 base::Passed(&release_callback))); | 317 base::Passed(&release_callback))); |
| 318 media::LetterboxYUV(video_frame.get(), region_in_frame); | 318 media::LetterboxYUV(video_frame.get(), region_in_frame); |
| 319 return true; | 319 return true; |
| 320 } | 320 } |
| 321 | 321 |
| 322 using CaptureFrameCallback = | 322 using CaptureFrameCallback = |
| 323 media::ThreadSafeCaptureOracle::CaptureFrameCallback; | 323 device::ThreadSafeCaptureOracle::CaptureFrameCallback; |
| 324 | 324 |
| 325 void AuraWindowCaptureMachine::CopyOutputFinishedForVideo( | 325 void AuraWindowCaptureMachine::CopyOutputFinishedForVideo( |
| 326 base::WeakPtr<AuraWindowCaptureMachine> machine, | 326 base::WeakPtr<AuraWindowCaptureMachine> machine, |
| 327 base::TimeTicks event_time, | 327 base::TimeTicks event_time, |
| 328 const CaptureFrameCallback& capture_frame_cb, | 328 const CaptureFrameCallback& capture_frame_cb, |
| 329 const scoped_refptr<media::VideoFrame>& target, | 329 const scoped_refptr<media::VideoFrame>& target, |
| 330 std::unique_ptr<cc::SingleReleaseCallback> release_callback, | 330 std::unique_ptr<cc::SingleReleaseCallback> release_callback, |
| 331 bool result) { | 331 bool result) { |
| 332 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 332 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 333 | 333 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 Capture(timestamp); | 411 Capture(timestamp); |
| 412 } | 412 } |
| 413 | 413 |
| 414 void AuraWindowCaptureMachine::OnCompositingShuttingDown( | 414 void AuraWindowCaptureMachine::OnCompositingShuttingDown( |
| 415 ui::Compositor* compositor) { | 415 ui::Compositor* compositor) { |
| 416 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 416 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 417 compositor->RemoveAnimationObserver(this); | 417 compositor->RemoveAnimationObserver(this); |
| 418 } | 418 } |
| 419 | 419 |
| 420 } // namespace content | 420 } // namespace content |
| OLD | NEW |