Chromium Code Reviews| 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(), | |
|
Ami GONE FROM CHROMIUM
2014/04/01 18:03:38
Why the empty TimeDelta?
sheu
2014/04/21 20:39:39
Just stubbed for now. It would be better to have
| |
| 326 media::VideoFrame::ReadPixelsCB()); | |
|
Ami GONE FROM CHROMIUM
2014/04/01 18:03:38
Why the empty ReadPixelsCB?
sheu
2014/04/21 20:39:39
Not expecting this frame to be read back to softwa
| |
| 327 capture_frame_cb.Run(video_frame, start_time, true); | |
| 328 return; | |
|
sheu
2014/04/01 00:11:26
Cursor compositing doesn't happen, of course.
| |
| 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 |