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/desktop_capture_device_aura.h" | 5 #include "content/browser/media/capture/desktop_capture_device_aura.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/timer/timer.h" | 8 #include "base/timer/timer.h" |
9 #include "cc/output/copy_output_request.h" | 9 #include "cc/output/copy_output_request.h" |
10 #include "cc/output/copy_output_result.h" | 10 #include "cc/output/copy_output_result.h" |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 class DesktopVideoCaptureMachine | 88 class DesktopVideoCaptureMachine |
89 : public VideoCaptureMachine, | 89 : public VideoCaptureMachine, |
90 public aura::WindowObserver, | 90 public aura::WindowObserver, |
91 public ui::CompositorObserver, | 91 public ui::CompositorObserver, |
92 public base::SupportsWeakPtr<DesktopVideoCaptureMachine> { | 92 public base::SupportsWeakPtr<DesktopVideoCaptureMachine> { |
93 public: | 93 public: |
94 DesktopVideoCaptureMachine(const DesktopMediaID& source); | 94 DesktopVideoCaptureMachine(const DesktopMediaID& source); |
95 virtual ~DesktopVideoCaptureMachine(); | 95 virtual ~DesktopVideoCaptureMachine(); |
96 | 96 |
97 // VideoCaptureFrameSource overrides. | 97 // VideoCaptureFrameSource overrides. |
98 virtual bool Start( | 98 virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, |
99 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE; | 99 const media::VideoCaptureParams& params) OVERRIDE; |
100 virtual void Stop(const base::Closure& callback) OVERRIDE; | 100 virtual void Stop(const base::Closure& callback) OVERRIDE; |
101 | 101 |
102 // Implements aura::WindowObserver. | 102 // Implements aura::WindowObserver. |
103 virtual void OnWindowBoundsChanged(aura::Window* window, | 103 virtual void OnWindowBoundsChanged(aura::Window* window, |
104 const gfx::Rect& old_bounds, | 104 const gfx::Rect& old_bounds, |
105 const gfx::Rect& new_bounds) OVERRIDE; | 105 const gfx::Rect& new_bounds) OVERRIDE; |
106 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; | 106 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; |
107 | 107 |
108 // Implements ui::CompositorObserver. | 108 // Implements ui::CompositorObserver. |
109 virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {} | 109 virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {} |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 145 |
146 // The timer that kicks off period captures. | 146 // The timer that kicks off period captures. |
147 base::Timer timer_; | 147 base::Timer timer_; |
148 | 148 |
149 // The id of the window being captured. | 149 // The id of the window being captured. |
150 DesktopMediaID window_id_; | 150 DesktopMediaID window_id_; |
151 | 151 |
152 // Makes all the decisions about which frames to copy, and how. | 152 // Makes all the decisions about which frames to copy, and how. |
153 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; | 153 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; |
154 | 154 |
| 155 // The capture parameters for this capture. |
| 156 media::VideoCaptureParams capture_params_; |
| 157 |
155 // YUV readback pipeline. | 158 // YUV readback pipeline. |
156 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_; | 159 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_; |
157 | 160 |
158 // Cursor state. | 161 // Cursor state. |
159 ui::Cursor last_cursor_; | 162 ui::Cursor last_cursor_; |
160 gfx::Point cursor_hot_point_; | 163 gfx::Point cursor_hot_point_; |
161 SkBitmap scaled_cursor_bitmap_; | 164 SkBitmap scaled_cursor_bitmap_; |
162 | 165 |
163 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine); | 166 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine); |
164 }; | 167 }; |
165 | 168 |
166 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine( | 169 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine( |
167 const DesktopMediaID& source) | 170 const DesktopMediaID& source) |
168 : desktop_window_(NULL), | 171 : desktop_window_(NULL), |
169 desktop_layer_(NULL), | 172 desktop_layer_(NULL), |
170 timer_(true, true), | 173 timer_(true, true), |
171 window_id_(source) {} | 174 window_id_(source) {} |
172 | 175 |
173 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {} | 176 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {} |
174 | 177 |
175 bool DesktopVideoCaptureMachine::Start( | 178 bool DesktopVideoCaptureMachine::Start( |
176 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) { | 179 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, |
| 180 const media::VideoCaptureParams& params) { |
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
178 | 182 |
179 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_); | 183 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_); |
180 if (!desktop_window_) | 184 if (!desktop_window_) |
181 return false; | 185 return false; |
182 | 186 |
183 // If the desktop layer is already destroyed then return failure. | 187 // If the desktop layer is already destroyed then return failure. |
184 desktop_layer_ = desktop_window_->layer(); | 188 desktop_layer_ = desktop_window_->layer(); |
185 if (!desktop_layer_) | 189 if (!desktop_layer_) |
186 return false; | 190 return false; |
187 | 191 |
188 DCHECK(oracle_proxy.get()); | 192 DCHECK(oracle_proxy.get()); |
189 oracle_proxy_ = oracle_proxy; | 193 oracle_proxy_ = oracle_proxy; |
| 194 capture_params_ = params; |
190 | 195 |
191 // Update capture size. | 196 // Update capture size. |
192 UpdateCaptureSize(); | 197 UpdateCaptureSize(); |
193 | 198 |
194 // Start observing window events. | 199 // Start observing window events. |
195 desktop_window_->AddObserver(this); | 200 desktop_window_->AddObserver(this); |
196 | 201 |
197 // Start observing compositor updates. | 202 // Start observing compositor updates. |
198 ui::Compositor* compositor = desktop_layer_->GetCompositor(); | 203 ui::Compositor* compositor = desktop_layer_->GetCompositor(); |
199 if (!compositor) | 204 if (!compositor) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 base::TimeTicks start_time, | 282 base::TimeTicks start_time, |
278 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, | 283 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, |
279 const scoped_refptr<media::VideoFrame>& target, | 284 const scoped_refptr<media::VideoFrame>& target, |
280 const SkBitmap& cursor_bitmap, | 285 const SkBitmap& cursor_bitmap, |
281 const gfx::Point& cursor_position, | 286 const gfx::Point& cursor_position, |
282 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 287 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
283 bool result) { | 288 bool result) { |
284 if (!cursor_bitmap.isNull()) | 289 if (!cursor_bitmap.isNull()) |
285 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position); | 290 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position); |
286 release_callback->Run(0, false); | 291 release_callback->Run(0, false); |
287 capture_frame_cb.Run(start_time, result); | 292 capture_frame_cb.Run(target, start_time, result); |
| 293 } |
| 294 |
| 295 void RunSingleReleaseCallback(scoped_ptr<cc::SingleReleaseCallback> cb, |
| 296 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { |
| 297 cb->Run(mailbox_holder->sync_point, false); |
288 } | 298 } |
289 | 299 |
290 void DesktopVideoCaptureMachine::DidCopyOutput( | 300 void DesktopVideoCaptureMachine::DidCopyOutput( |
291 scoped_refptr<media::VideoFrame> video_frame, | 301 scoped_refptr<media::VideoFrame> video_frame, |
292 base::TimeTicks start_time, | 302 base::TimeTicks start_time, |
293 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, | 303 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, |
294 scoped_ptr<cc::CopyOutputResult> result) { | 304 scoped_ptr<cc::CopyOutputResult> result) { |
295 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) | 305 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) |
296 return; | 306 return; |
297 | 307 |
| 308 if (capture_params_.requested_format.pixel_format == |
| 309 media::PIXEL_FORMAT_TEXTURE) { |
| 310 DCHECK(!video_frame); |
| 311 cc::TextureMailbox texture_mailbox; |
| 312 scoped_ptr<cc::SingleReleaseCallback> release_callback; |
| 313 result->TakeTexture(&texture_mailbox, &release_callback); |
| 314 DCHECK(texture_mailbox.IsTexture()); |
| 315 if (!texture_mailbox.IsTexture()) |
| 316 return; |
| 317 video_frame = media::VideoFrame::WrapNativeTexture( |
| 318 make_scoped_ptr(new gpu::MailboxHolder(texture_mailbox.mailbox(), |
| 319 texture_mailbox.target(), |
| 320 texture_mailbox.sync_point())), |
| 321 base::Bind(&RunSingleReleaseCallback, base::Passed(&release_callback)), |
| 322 result->size(), |
| 323 gfx::Rect(result->size()), |
| 324 result->size(), |
| 325 base::TimeDelta(), |
| 326 media::VideoFrame::ReadPixelsCB()); |
| 327 capture_frame_cb.Run(video_frame, start_time, true); |
| 328 return; |
| 329 } |
| 330 |
298 // Compute the dest size we want after the letterboxing resize. Make the | 331 // Compute the dest size we want after the letterboxing resize. Make the |
299 // coordinates and sizes even because we letterbox in YUV space | 332 // coordinates and sizes even because we letterbox in YUV space |
300 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to | 333 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to |
301 // line up correctly. | 334 // line up correctly. |
302 // The video frame's coded_size() and the result's size() are both physical | 335 // The video frame's coded_size() and the result's size() are both physical |
303 // pixels. | 336 // pixels. |
304 gfx::Rect region_in_frame = | 337 gfx::Rect region_in_frame = |
305 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), | 338 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), |
306 result->size()); | 339 result->size()); |
307 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, | 340 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 // static | 465 // static |
433 media::VideoCaptureDevice* DesktopCaptureDeviceAura::Create( | 466 media::VideoCaptureDevice* DesktopCaptureDeviceAura::Create( |
434 const DesktopMediaID& source) { | 467 const DesktopMediaID& source) { |
435 return new DesktopCaptureDeviceAura(source); | 468 return new DesktopCaptureDeviceAura(source); |
436 } | 469 } |
437 | 470 |
438 void DesktopCaptureDeviceAura::AllocateAndStart( | 471 void DesktopCaptureDeviceAura::AllocateAndStart( |
439 const media::VideoCaptureParams& params, | 472 const media::VideoCaptureParams& params, |
440 scoped_ptr<Client> client) { | 473 scoped_ptr<Client> client) { |
441 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); | 474 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); |
442 core_->AllocateAndStart(params, client.Pass()); | 475 media::VideoCaptureParams new_params = params; |
| 476 // Desktop capture devices ignore the requested size and return the actual |
| 477 // captured desktop size. |
| 478 new_params.requested_format.frame_size.SetSize(0, 0); |
| 479 core_->AllocateAndStart(new_params, client.Pass()); |
443 } | 480 } |
444 | 481 |
445 void DesktopCaptureDeviceAura::StopAndDeAllocate() { | 482 void DesktopCaptureDeviceAura::StopAndDeAllocate() { |
446 core_->StopAndDeAllocate(); | 483 core_->StopAndDeAllocate(); |
447 } | 484 } |
448 | 485 |
449 } // namespace content | 486 } // namespace content |
OLD | NEW |