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/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/timer/timer.h" | 9 #include "base/timer/timer.h" |
10 #include "cc/output/copy_output_request.h" | 10 #include "cc/output/copy_output_request.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 class DesktopVideoCaptureMachine | 90 class DesktopVideoCaptureMachine |
91 : public VideoCaptureMachine, | 91 : public VideoCaptureMachine, |
92 public aura::WindowObserver, | 92 public aura::WindowObserver, |
93 public ui::CompositorObserver, | 93 public ui::CompositorObserver, |
94 public base::SupportsWeakPtr<DesktopVideoCaptureMachine> { | 94 public base::SupportsWeakPtr<DesktopVideoCaptureMachine> { |
95 public: | 95 public: |
96 DesktopVideoCaptureMachine(const DesktopMediaID& source); | 96 DesktopVideoCaptureMachine(const DesktopMediaID& source); |
97 virtual ~DesktopVideoCaptureMachine(); | 97 virtual ~DesktopVideoCaptureMachine(); |
98 | 98 |
99 // VideoCaptureFrameSource overrides. | 99 // VideoCaptureFrameSource overrides. |
100 virtual bool Start(const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 100 virtual bool Start( |
101 const media::VideoCaptureParams& params) OVERRIDE; | 101 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) OVERRIDE; |
102 virtual void Stop(const base::Closure& callback) OVERRIDE; | 102 virtual void Stop(const base::Closure& callback) OVERRIDE; |
103 | 103 |
104 // Implements aura::WindowObserver. | 104 // Implements aura::WindowObserver. |
105 virtual void OnWindowBoundsChanged(aura::Window* window, | 105 virtual void OnWindowBoundsChanged(aura::Window* window, |
106 const gfx::Rect& old_bounds, | 106 const gfx::Rect& old_bounds, |
107 const gfx::Rect& new_bounds) OVERRIDE; | 107 const gfx::Rect& new_bounds) OVERRIDE; |
108 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; | 108 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE; |
109 | 109 |
110 // Implements ui::CompositorObserver. | 110 // Implements ui::CompositorObserver. |
111 virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {} | 111 virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {} |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 155 |
156 // The timer that kicks off period captures. | 156 // The timer that kicks off period captures. |
157 base::Timer timer_; | 157 base::Timer timer_; |
158 | 158 |
159 // The id of the window being captured. | 159 // The id of the window being captured. |
160 DesktopMediaID window_id_; | 160 DesktopMediaID window_id_; |
161 | 161 |
162 // Makes all the decisions about which frames to copy, and how. | 162 // Makes all the decisions about which frames to copy, and how. |
163 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; | 163 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; |
164 | 164 |
165 // The capture parameters for this capture. | |
166 media::VideoCaptureParams capture_params_; | |
167 | |
168 // YUV readback pipeline. | 165 // YUV readback pipeline. |
169 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_; | 166 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_; |
170 | 167 |
171 // Cursor state. | 168 // Cursor state. |
172 ui::Cursor last_cursor_; | 169 ui::Cursor last_cursor_; |
173 gfx::Point cursor_hot_point_; | 170 gfx::Point cursor_hot_point_; |
174 SkBitmap scaled_cursor_bitmap_; | 171 SkBitmap scaled_cursor_bitmap_; |
175 | 172 |
176 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine); | 173 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine); |
177 }; | 174 }; |
178 | 175 |
179 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine( | 176 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine( |
180 const DesktopMediaID& source) | 177 const DesktopMediaID& source) |
181 : desktop_window_(NULL), | 178 : desktop_window_(NULL), |
182 desktop_layer_(NULL), | 179 desktop_layer_(NULL), |
183 timer_(true, true), | 180 timer_(true, true), |
184 window_id_(source) {} | 181 window_id_(source) {} |
185 | 182 |
186 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {} | 183 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {} |
187 | 184 |
188 bool DesktopVideoCaptureMachine::Start( | 185 bool DesktopVideoCaptureMachine::Start( |
189 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, | 186 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) { |
190 const media::VideoCaptureParams& params) { | |
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
192 | 188 |
193 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_); | 189 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_); |
194 if (!desktop_window_) | 190 if (!desktop_window_) |
195 return false; | 191 return false; |
196 | 192 |
197 // If the desktop layer is already destroyed then return failure. | 193 // If the desktop layer is already destroyed then return failure. |
198 desktop_layer_ = desktop_window_->layer(); | 194 desktop_layer_ = desktop_window_->layer(); |
199 if (!desktop_layer_) | 195 if (!desktop_layer_) |
200 return false; | 196 return false; |
201 | 197 |
202 DCHECK(oracle_proxy.get()); | 198 DCHECK(oracle_proxy.get()); |
203 oracle_proxy_ = oracle_proxy; | 199 oracle_proxy_ = oracle_proxy; |
204 capture_params_ = params; | |
205 | 200 |
206 // Update capture size. | 201 // Update capture size. |
207 UpdateCaptureSize(); | 202 UpdateCaptureSize(); |
208 | 203 |
209 // Start observing window events. | 204 // Start observing window events. |
210 desktop_window_->AddObserver(this); | 205 desktop_window_->AddObserver(this); |
211 | 206 |
212 // Start observing compositor updates. | 207 // Start observing compositor updates. |
213 ui::Compositor* compositor = desktop_layer_->GetCompositor(); | 208 ui::Compositor* compositor = desktop_layer_->GetCompositor(); |
214 if (!compositor) | 209 if (!compositor) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 base::TimeTicks start_time, | 287 base::TimeTicks start_time, |
293 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, | 288 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, |
294 const scoped_refptr<media::VideoFrame>& target, | 289 const scoped_refptr<media::VideoFrame>& target, |
295 const SkBitmap& cursor_bitmap, | 290 const SkBitmap& cursor_bitmap, |
296 const gfx::Point& cursor_position, | 291 const gfx::Point& cursor_position, |
297 scoped_ptr<cc::SingleReleaseCallback> release_callback, | 292 scoped_ptr<cc::SingleReleaseCallback> release_callback, |
298 bool result) { | 293 bool result) { |
299 if (!cursor_bitmap.isNull()) | 294 if (!cursor_bitmap.isNull()) |
300 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position); | 295 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position); |
301 release_callback->Run(0, false); | 296 release_callback->Run(0, false); |
302 capture_frame_cb.Run(target, start_time, result); | 297 capture_frame_cb.Run(start_time, result); |
303 } | |
304 | |
305 void RunSingleReleaseCallback(scoped_ptr<cc::SingleReleaseCallback> cb, | |
306 const std::vector<uint32>& sync_points) { | |
307 // TODO(hshi): handle release of multiple sync points. | |
308 DCHECK_EQ(1u, sync_points.size()); | |
309 cb->Run(sync_points[0], false); | |
310 } | 298 } |
311 | 299 |
312 void DesktopVideoCaptureMachine::DidCopyOutput( | 300 void DesktopVideoCaptureMachine::DidCopyOutput( |
313 scoped_refptr<media::VideoFrame> video_frame, | 301 scoped_refptr<media::VideoFrame> video_frame, |
314 base::TimeTicks start_time, | 302 base::TimeTicks start_time, |
315 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, | 303 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, |
316 scoped_ptr<cc::CopyOutputResult> result) { | 304 scoped_ptr<cc::CopyOutputResult> result) { |
317 static bool first_call = true; | 305 static bool first_call = true; |
318 | 306 |
319 bool succeeded = ProcessCopyOutputResponse( | 307 bool succeeded = ProcessCopyOutputResponse( |
(...skipping 19 matching lines...) Expand all Loading... |
339 } | 327 } |
340 | 328 |
341 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse( | 329 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse( |
342 scoped_refptr<media::VideoFrame> video_frame, | 330 scoped_refptr<media::VideoFrame> video_frame, |
343 base::TimeTicks start_time, | 331 base::TimeTicks start_time, |
344 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, | 332 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, |
345 scoped_ptr<cc::CopyOutputResult> result) { | 333 scoped_ptr<cc::CopyOutputResult> result) { |
346 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) | 334 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) |
347 return false; | 335 return false; |
348 | 336 |
349 if (capture_params_.requested_format.pixel_format == | |
350 media::PIXEL_FORMAT_TEXTURE) { | |
351 DCHECK(!video_frame); | |
352 cc::TextureMailbox texture_mailbox; | |
353 scoped_ptr<cc::SingleReleaseCallback> release_callback; | |
354 result->TakeTexture(&texture_mailbox, &release_callback); | |
355 DCHECK(texture_mailbox.IsTexture()); | |
356 if (!texture_mailbox.IsTexture()) | |
357 return false; | |
358 video_frame = media::VideoFrame::WrapNativeTexture( | |
359 make_scoped_ptr(new gpu::MailboxHolder(texture_mailbox.mailbox(), | |
360 texture_mailbox.target(), | |
361 texture_mailbox.sync_point())), | |
362 base::Bind(&RunSingleReleaseCallback, base::Passed(&release_callback)), | |
363 result->size(), | |
364 gfx::Rect(result->size()), | |
365 result->size(), | |
366 base::TimeDelta(), | |
367 media::VideoFrame::ReadPixelsCB()); | |
368 capture_frame_cb.Run(video_frame, start_time, true); | |
369 return true; | |
370 } | |
371 | |
372 // Compute the dest size we want after the letterboxing resize. Make the | 337 // Compute the dest size we want after the letterboxing resize. Make the |
373 // coordinates and sizes even because we letterbox in YUV space | 338 // coordinates and sizes even because we letterbox in YUV space |
374 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to | 339 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to |
375 // line up correctly. | 340 // line up correctly. |
376 // The video frame's coded_size() and the result's size() are both physical | 341 // The video frame's coded_size() and the result's size() are both physical |
377 // pixels. | 342 // pixels. |
378 gfx::Rect region_in_frame = | 343 gfx::Rect region_in_frame = |
379 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), | 344 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), |
380 result->size()); | 345 result->size()); |
381 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, | 346 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 IncrementDesktopCaptureCounter(source.type == DesktopMediaID::TYPE_SCREEN | 475 IncrementDesktopCaptureCounter(source.type == DesktopMediaID::TYPE_SCREEN |
511 ? SCREEN_CAPTURER_CREATED | 476 ? SCREEN_CAPTURER_CREATED |
512 : WINDOW_CATPTURER_CREATED); | 477 : WINDOW_CATPTURER_CREATED); |
513 return new DesktopCaptureDeviceAura(source); | 478 return new DesktopCaptureDeviceAura(source); |
514 } | 479 } |
515 | 480 |
516 void DesktopCaptureDeviceAura::AllocateAndStart( | 481 void DesktopCaptureDeviceAura::AllocateAndStart( |
517 const media::VideoCaptureParams& params, | 482 const media::VideoCaptureParams& params, |
518 scoped_ptr<Client> client) { | 483 scoped_ptr<Client> client) { |
519 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); | 484 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); |
520 media::VideoCaptureParams new_params = params; | 485 core_->AllocateAndStart(params, client.Pass()); |
521 // Desktop capture devices ignore the requested size and return the actual | |
522 // captured desktop size. | |
523 new_params.requested_format.frame_size.SetSize(0, 0); | |
524 core_->AllocateAndStart(new_params, client.Pass()); | |
525 } | 486 } |
526 | 487 |
527 void DesktopCaptureDeviceAura::StopAndDeAllocate() { | 488 void DesktopCaptureDeviceAura::StopAndDeAllocate() { |
528 core_->StopAndDeAllocate(); | 489 core_->StopAndDeAllocate(); |
529 } | 490 } |
530 | 491 |
531 } // namespace content | 492 } // namespace content |
OLD | NEW |