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

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

Issue 965123002: Crash fix for desktop capture size calculations, and some minor things. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 9 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
« no previous file with comments | « content/browser/media/capture/content_video_capture_device_core.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 138
139 // A helper which does the real work for DidCopyOutput. Returns true if 139 // A helper which does the real work for DidCopyOutput. Returns true if
140 // succeeded. 140 // succeeded.
141 bool ProcessCopyOutputResponse( 141 bool ProcessCopyOutputResponse(
142 scoped_refptr<media::VideoFrame> video_frame, 142 scoped_refptr<media::VideoFrame> video_frame,
143 base::TimeTicks start_time, 143 base::TimeTicks start_time,
144 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 144 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
145 scoped_ptr<cc::CopyOutputResult> result); 145 scoped_ptr<cc::CopyOutputResult> result);
146 146
147 // Helper function to update cursor state. 147 // Helper function to update cursor state.
148 // |region_in_frame| defines the desktop bound in the captured frame. 148 // |region_in_frame| defines where the desktop is rendered in the captured
149 // frame.
149 // Returns the current cursor position in captured frame. 150 // Returns the current cursor position in captured frame.
150 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame); 151 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame);
151 152
152 // Clears cursor state. 153 // Clears cursor state.
153 void ClearCursorState(); 154 void ClearCursorState();
154 155
155 // The window associated with the desktop. 156 // The window associated with the desktop.
156 aura::Window* desktop_window_; 157 aura::Window* desktop_window_;
157 158
158 // The timer that kicks off period captures. 159 // The timer that kicks off period captures.
159 base::Timer timer_; 160 base::Timer timer_;
160 161
161 // The id of the window being captured. 162 // The id of the window being captured.
162 DesktopMediaID window_id_; 163 DesktopMediaID window_id_;
163 164
164 // Makes all the decisions about which frames to copy, and how. 165 // Makes all the decisions about which frames to copy, and how.
165 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; 166 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
166 167
167 // The capture parameters for this capture. 168 // The capture parameters for this capture.
168 media::VideoCaptureParams capture_params_; 169 media::VideoCaptureParams capture_params_;
169 170
170 // YUV readback pipeline. 171 // YUV readback pipeline.
171 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_; 172 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_;
172 173
173 // Cursor state. 174 // Cursor state.
174 ui::Cursor last_cursor_; 175 ui::Cursor last_cursor_;
176 gfx::Size desktop_size_when_cursor_last_updated_;
175 gfx::Point cursor_hot_point_; 177 gfx::Point cursor_hot_point_;
176 SkBitmap scaled_cursor_bitmap_; 178 SkBitmap scaled_cursor_bitmap_;
177 179
178 // TODO(jiayl): Remove power_save_blocker_ when there is an API to keep the 180 // TODO(jiayl): Remove power_save_blocker_ when there is an API to keep the
179 // screen from sleeping for the drive-by web. 181 // screen from sleeping for the drive-by web.
180 scoped_ptr<PowerSaveBlocker> power_save_blocker_; 182 scoped_ptr<PowerSaveBlocker> power_save_blocker_;
181 183
182 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine); 184 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine);
183 }; 185 };
184 186
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 } 342 }
341 } 343 }
342 } 344 }
343 345
344 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse( 346 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse(
345 scoped_refptr<media::VideoFrame> video_frame, 347 scoped_refptr<media::VideoFrame> video_frame,
346 base::TimeTicks start_time, 348 base::TimeTicks start_time,
347 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 349 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
348 scoped_ptr<cc::CopyOutputResult> result) { 350 scoped_ptr<cc::CopyOutputResult> result) {
349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
352
350 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_window_) 353 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_window_)
351 return false; 354 return false;
352 355
353 if (capture_params_.requested_format.pixel_format == 356 if (capture_params_.requested_format.pixel_format ==
354 media::PIXEL_FORMAT_TEXTURE) { 357 media::PIXEL_FORMAT_TEXTURE) {
355 DCHECK(!video_frame.get()); 358 DCHECK(!video_frame.get());
356 cc::TextureMailbox texture_mailbox; 359 cc::TextureMailbox texture_mailbox;
357 scoped_ptr<cc::SingleReleaseCallback> release_callback; 360 scoped_ptr<cc::SingleReleaseCallback> release_callback;
358 result->TakeTexture(&texture_mailbox, &release_callback); 361 result->TakeTexture(&texture_mailbox, &release_callback);
359 DCHECK(texture_mailbox.IsTexture()); 362 DCHECK(texture_mailbox.IsTexture());
360 if (!texture_mailbox.IsTexture()) 363 if (!texture_mailbox.IsTexture())
361 return false; 364 return false;
362 video_frame = media::VideoFrame::WrapNativeTexture( 365 video_frame = media::VideoFrame::WrapNativeTexture(
363 make_scoped_ptr(new gpu::MailboxHolder(texture_mailbox.mailbox(), 366 make_scoped_ptr(new gpu::MailboxHolder(texture_mailbox.mailbox(),
364 texture_mailbox.target(), 367 texture_mailbox.target(),
365 texture_mailbox.sync_point())), 368 texture_mailbox.sync_point())),
366 base::Bind(&RunSingleReleaseCallback, base::Passed(&release_callback)), 369 base::Bind(&RunSingleReleaseCallback, base::Passed(&release_callback)),
367 result->size(), gfx::Rect(result->size()), result->size(), 370 result->size(), gfx::Rect(result->size()), result->size(),
368 base::TimeDelta(), false); 371 base::TimeDelta(), false);
369 capture_frame_cb.Run(video_frame, start_time, true); 372 capture_frame_cb.Run(video_frame, start_time, true);
370 return true; 373 return true;
374 } else {
375 DCHECK(video_frame.get());
371 } 376 }
372 377
373 // Compute the dest size we want after the letterboxing resize. Make the 378 // Compute the dest size we want after the letterboxing resize. Make the
374 // coordinates and sizes even because we letterbox in YUV space 379 // coordinates and sizes even because we letterbox in YUV space
375 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to 380 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
376 // line up correctly. 381 // line up correctly.
377 // The video frame's visible_rect() and the result's size() are both physical 382 // The video frame's visible_rect() and the result's size() are both physical
378 // pixels. 383 // pixels.
379 gfx::Rect region_in_frame = media::ComputeLetterboxRegion( 384 gfx::Rect region_in_frame = media::ComputeLetterboxRegion(
380 video_frame->visible_rect(), result->size()); 385 video_frame->visible_rect(), result->size());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 video_frame, 428 video_frame,
424 scaled_cursor_bitmap_, 429 scaled_cursor_bitmap_,
425 cursor_position_in_frame, 430 cursor_position_in_frame,
426 base::Passed(&release_callback))); 431 base::Passed(&release_callback)));
427 return true; 432 return true;
428 } 433 }
429 434
430 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState( 435 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState(
431 const gfx::Rect& region_in_frame) { 436 const gfx::Rect& region_in_frame) {
432 const gfx::Rect desktop_bounds = desktop_window_->layer()->bounds(); 437 const gfx::Rect desktop_bounds = desktop_window_->layer()->bounds();
438 if (desktop_bounds.IsEmpty()) {
439 // Return early to prevent divide-by-zero in calculations below.
440 ClearCursorState();
441 return gfx::Point();
442 }
443
433 gfx::NativeCursor cursor = 444 gfx::NativeCursor cursor =
434 desktop_window_->GetHost()->last_cursor(); 445 desktop_window_->GetHost()->last_cursor();
435 if (last_cursor_ != cursor) { 446 if (last_cursor_ != cursor ||
447 desktop_size_when_cursor_last_updated_ != desktop_bounds.size()) {
436 SkBitmap cursor_bitmap; 448 SkBitmap cursor_bitmap;
437 if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) { 449 if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) {
450 const int scaled_width = cursor_bitmap.width() *
451 region_in_frame.width() / desktop_bounds.width();
452 const int scaled_height = cursor_bitmap.height() *
453 region_in_frame.height() / desktop_bounds.height();
454 if (scaled_width <= 0 || scaled_height <= 0) {
455 ClearCursorState();
456 return gfx::Point();
457 }
438 scaled_cursor_bitmap_ = skia::ImageOperations::Resize( 458 scaled_cursor_bitmap_ = skia::ImageOperations::Resize(
439 cursor_bitmap, 459 cursor_bitmap,
440 skia::ImageOperations::RESIZE_BEST, 460 skia::ImageOperations::RESIZE_BEST,
441 cursor_bitmap.width() * region_in_frame.width() / 461 scaled_width,
442 desktop_bounds.width(), 462 scaled_height);
443 cursor_bitmap.height() * region_in_frame.height() /
444 desktop_bounds.height());
445 last_cursor_ = cursor; 463 last_cursor_ = cursor;
464 desktop_size_when_cursor_last_updated_ = desktop_bounds.size();
446 } else { 465 } else {
447 // Clear cursor state if ui::GetCursorBitmap failed so that we do not 466 // Clear cursor state if ui::GetCursorBitmap failed so that we do not
448 // render cursor on the captured frame. 467 // render cursor on the captured frame.
449 ClearCursorState(); 468 ClearCursorState();
450 } 469 }
451 } 470 }
452 471
453 gfx::Point cursor_position = aura::Env::GetInstance()->last_mouse_location(); 472 gfx::Point cursor_position = aura::Env::GetInstance()->last_mouse_location();
454 aura::client::GetScreenPositionClient(desktop_window_->GetRootWindow())-> 473 aura::client::GetScreenPositionClient(desktop_window_->GetRootWindow())->
455 ConvertPointFromScreen(desktop_window_, &cursor_position); 474 ConvertPointFromScreen(desktop_window_, &cursor_position);
456 const gfx::Point hot_point_in_dip = ui::ConvertPointToDIP( 475 const gfx::Point hot_point_in_dip = ui::ConvertPointToDIP(
457 desktop_window_->layer(), cursor_hot_point_); 476 desktop_window_->layer(), cursor_hot_point_);
458 cursor_position.Offset(-desktop_bounds.x() - hot_point_in_dip.x(), 477 cursor_position.Offset(-desktop_bounds.x() - hot_point_in_dip.x(),
459 -desktop_bounds.y() - hot_point_in_dip.y()); 478 -desktop_bounds.y() - hot_point_in_dip.y());
460 return gfx::Point( 479 return gfx::Point(
461 region_in_frame.x() + cursor_position.x() * region_in_frame.width() / 480 region_in_frame.x() + cursor_position.x() * region_in_frame.width() /
462 desktop_bounds.width(), 481 desktop_bounds.width(),
463 region_in_frame.y() + cursor_position.y() * region_in_frame.height() / 482 region_in_frame.y() + cursor_position.y() * region_in_frame.height() /
464 desktop_bounds.height()); 483 desktop_bounds.height());
465 } 484 }
466 485
467 void DesktopVideoCaptureMachine::ClearCursorState() { 486 void DesktopVideoCaptureMachine::ClearCursorState() {
468 last_cursor_ = ui::Cursor(); 487 last_cursor_ = ui::Cursor();
488 desktop_size_when_cursor_last_updated_ = gfx::Size();
469 cursor_hot_point_ = gfx::Point(); 489 cursor_hot_point_ = gfx::Point();
470 scaled_cursor_bitmap_.reset(); 490 scaled_cursor_bitmap_.reset();
471 } 491 }
472 492
473 void DesktopVideoCaptureMachine::OnWindowBoundsChanged( 493 void DesktopVideoCaptureMachine::OnWindowBoundsChanged(
474 aura::Window* window, 494 aura::Window* window,
475 const gfx::Rect& old_bounds, 495 const gfx::Rect& old_bounds,
476 const gfx::Rect& new_bounds) { 496 const gfx::Rect& new_bounds) {
477 DCHECK(desktop_window_ && window == desktop_window_); 497 DCHECK(desktop_window_ && window == desktop_window_);
478 498
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 scoped_ptr<Client> client) { 553 scoped_ptr<Client> client) {
534 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 554 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
535 core_->AllocateAndStart(params, client.Pass()); 555 core_->AllocateAndStart(params, client.Pass());
536 } 556 }
537 557
538 void DesktopCaptureDeviceAura::StopAndDeAllocate() { 558 void DesktopCaptureDeviceAura::StopAndDeAllocate() {
539 core_->StopAndDeAllocate(); 559 core_->StopAndDeAllocate();
540 } 560 }
541 561
542 } // namespace content 562 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/capture/content_video_capture_device_core.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698