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

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

Issue 348623005: DesktopVideoCaptureMachine: do not cache window layer pointer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 scoped_ptr<cc::CopyOutputResult> result); 142 scoped_ptr<cc::CopyOutputResult> result);
143 143
144 // Helper function to update cursor state. 144 // Helper function to update cursor state.
145 // |region_in_frame| defines the desktop bound in the captured frame. 145 // |region_in_frame| defines the desktop bound in the captured frame.
146 // Returns the current cursor position in captured frame. 146 // Returns the current cursor position in captured frame.
147 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame); 147 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame);
148 148
149 // Clears cursor state. 149 // Clears cursor state.
150 void ClearCursorState(); 150 void ClearCursorState();
151 151
152 // Helper function to return the layer associated with the desktop window.
153 ui::Layer* desktop_layer();
154
152 // The window associated with the desktop. 155 // The window associated with the desktop.
153 aura::Window* desktop_window_; 156 aura::Window* desktop_window_;
154 157
155 // The layer associated with the desktop.
156 ui::Layer* desktop_layer_;
157
158 // The timer that kicks off period captures. 158 // The timer that kicks off period captures.
159 base::Timer timer_; 159 base::Timer timer_;
160 160
161 // The id of the window being captured. 161 // The id of the window being captured.
162 DesktopMediaID window_id_; 162 DesktopMediaID window_id_;
163 163
164 // Makes all the decisions about which frames to copy, and how. 164 // Makes all the decisions about which frames to copy, and how.
165 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_; 165 scoped_refptr<ThreadSafeCaptureOracle> oracle_proxy_;
166 166
167 // The capture parameters for this capture. 167 // The capture parameters for this capture.
168 media::VideoCaptureParams capture_params_; 168 media::VideoCaptureParams capture_params_;
169 169
170 // YUV readback pipeline. 170 // YUV readback pipeline.
171 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_; 171 scoped_ptr<content::ReadbackYUVInterface> yuv_readback_pipeline_;
172 172
173 // Cursor state. 173 // Cursor state.
174 ui::Cursor last_cursor_; 174 ui::Cursor last_cursor_;
175 gfx::Point cursor_hot_point_; 175 gfx::Point cursor_hot_point_;
176 SkBitmap scaled_cursor_bitmap_; 176 SkBitmap scaled_cursor_bitmap_;
177 177
178 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine); 178 DISALLOW_COPY_AND_ASSIGN(DesktopVideoCaptureMachine);
179 }; 179 };
180 180
181 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine( 181 DesktopVideoCaptureMachine::DesktopVideoCaptureMachine(
182 const DesktopMediaID& source) 182 const DesktopMediaID& source)
183 : desktop_window_(NULL), 183 : desktop_window_(NULL),
184 desktop_layer_(NULL),
185 timer_(true, true), 184 timer_(true, true),
186 window_id_(source) {} 185 window_id_(source) {}
187 186
188 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {} 187 DesktopVideoCaptureMachine::~DesktopVideoCaptureMachine() {}
189 188
190 bool DesktopVideoCaptureMachine::Start( 189 bool DesktopVideoCaptureMachine::Start(
191 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy, 190 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy,
192 const media::VideoCaptureParams& params) { 191 const media::VideoCaptureParams& params) {
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
194 193
195 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_); 194 desktop_window_ = content::DesktopMediaID::GetAuraWindowById(window_id_);
196 if (!desktop_window_) 195 if (!desktop_window_)
197 return false; 196 return false;
198 197
199 // If the desktop layer is already destroyed then return failure. 198 // If the desktop layer is already destroyed then return failure.
200 desktop_layer_ = desktop_window_->layer(); 199 ui::Layer* layer = desktop_layer();
201 if (!desktop_layer_) 200 if (!layer)
202 return false; 201 return false;
203 202
204 DCHECK(oracle_proxy.get()); 203 DCHECK(oracle_proxy.get());
205 oracle_proxy_ = oracle_proxy; 204 oracle_proxy_ = oracle_proxy;
206 capture_params_ = params; 205 capture_params_ = params;
207 206
208 // Update capture size. 207 // Update capture size.
209 UpdateCaptureSize(); 208 UpdateCaptureSize();
210 209
211 // Start observing window events. 210 // Start observing window events.
212 desktop_window_->AddObserver(this); 211 desktop_window_->AddObserver(this);
213 212
214 // Start observing compositor updates. 213 // Start observing compositor updates.
215 ui::Compositor* compositor = desktop_layer_->GetCompositor(); 214 ui::Compositor* compositor = layer->GetCompositor();
216 if (!compositor) 215 if (!compositor)
217 return false; 216 return false;
218 217
219 compositor->AddObserver(this); 218 compositor->AddObserver(this);
220 219
221 // Starts timer. 220 // Starts timer.
222 timer_.Start(FROM_HERE, oracle_proxy_->capture_period(), 221 timer_.Start(FROM_HERE, oracle_proxy_->capture_period(),
223 base::Bind(&DesktopVideoCaptureMachine::Capture, AsWeakPtr(), 222 base::Bind(&DesktopVideoCaptureMachine::Capture, AsWeakPtr(),
224 false)); 223 false));
225 224
226 started_ = true; 225 started_ = true;
227 return true; 226 return true;
228 } 227 }
229 228
230 void DesktopVideoCaptureMachine::Stop(const base::Closure& callback) { 229 void DesktopVideoCaptureMachine::Stop(const base::Closure& callback) {
231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
232 231
232 // Stop observing compositor updates.
233 ui::Layer* layer = desktop_layer();
234 if (layer) {
235 ui::Compositor* compositor = layer->GetCompositor();
236 if (compositor)
237 compositor->RemoveObserver(this);
piman 2014/06/19 21:59:19 If the layer can change, how do you know the compo
hshi1 2014/06/19 22:19:33 Done.
238 }
239
233 // Stop observing window events. 240 // Stop observing window events.
234 if (desktop_window_) { 241 if (desktop_window_) {
235 desktop_window_->RemoveObserver(this); 242 desktop_window_->RemoveObserver(this);
236 desktop_window_ = NULL; 243 desktop_window_ = NULL;
237 } 244 }
238 245
239 // Stop observing compositor updates.
240 if (desktop_layer_) {
241 ui::Compositor* compositor = desktop_layer_->GetCompositor();
242 if (compositor)
243 compositor->RemoveObserver(this);
244 desktop_layer_ = NULL;
245 }
246
247 // Stop timer. 246 // Stop timer.
248 timer_.Stop(); 247 timer_.Stop();
249 248
250 started_ = false; 249 started_ = false;
251 250
252 callback.Run(); 251 callback.Run();
253 } 252 }
254 253
255 void DesktopVideoCaptureMachine::UpdateCaptureSize() { 254 void DesktopVideoCaptureMachine::UpdateCaptureSize() {
256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
257 if (oracle_proxy_ && desktop_layer_) { 256 ui::Layer* layer = desktop_layer();
257 if (oracle_proxy_ && layer) {
258 oracle_proxy_->UpdateCaptureSize(ui::ConvertSizeToPixel( 258 oracle_proxy_->UpdateCaptureSize(ui::ConvertSizeToPixel(
259 desktop_layer_, desktop_layer_->bounds().size())); 259 layer, layer->bounds().size()));
260 } 260 }
261 ClearCursorState(); 261 ClearCursorState();
262 } 262 }
263 263
264 void DesktopVideoCaptureMachine::Capture(bool dirty) { 264 void DesktopVideoCaptureMachine::Capture(bool dirty) {
265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
266 266
267 // Do not capture if the desktop layer is already destroyed. 267 // Do not capture if the desktop layer is already destroyed.
268 if (!desktop_layer_) 268 ui::Layer* layer = desktop_layer();
269 if (!layer)
danakj 2014/06/19 21:43:28 Why are there so many checks for layer when Start(
hshi1 2014/06/19 22:19:33 Done.
269 return; 270 return;
270 271
271 scoped_refptr<media::VideoFrame> frame; 272 scoped_refptr<media::VideoFrame> frame;
272 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb; 273 ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
273 274
274 const base::TimeTicks start_time = base::TimeTicks::Now(); 275 const base::TimeTicks start_time = base::TimeTicks::Now();
275 const VideoCaptureOracle::Event event = 276 const VideoCaptureOracle::Event event =
276 dirty ? VideoCaptureOracle::kCompositorUpdate 277 dirty ? VideoCaptureOracle::kCompositorUpdate
277 : VideoCaptureOracle::kTimerPoll; 278 : VideoCaptureOracle::kTimerPoll;
278 if (oracle_proxy_->ObserveEventAndDecideCapture( 279 if (oracle_proxy_->ObserveEventAndDecideCapture(
279 event, start_time, &frame, &capture_frame_cb)) { 280 event, start_time, &frame, &capture_frame_cb)) {
280 scoped_ptr<cc::CopyOutputRequest> request = 281 scoped_ptr<cc::CopyOutputRequest> request =
281 cc::CopyOutputRequest::CreateRequest( 282 cc::CopyOutputRequest::CreateRequest(
282 base::Bind(&DesktopVideoCaptureMachine::DidCopyOutput, 283 base::Bind(&DesktopVideoCaptureMachine::DidCopyOutput,
283 AsWeakPtr(), frame, start_time, capture_frame_cb)); 284 AsWeakPtr(), frame, start_time, capture_frame_cb));
284 gfx::Rect window_rect = 285 gfx::Rect window_rect =
285 ui::ConvertRectToPixel(desktop_window_->layer(), 286 ui::ConvertRectToPixel(desktop_window_->layer(),
286 gfx::Rect(desktop_window_->bounds().width(), 287 gfx::Rect(desktop_window_->bounds().width(),
287 desktop_window_->bounds().height())); 288 desktop_window_->bounds().height()));
288 request->set_area(window_rect); 289 request->set_area(window_rect);
289 desktop_layer_->RequestCopyOfOutput(request.Pass()); 290 layer->RequestCopyOfOutput(request.Pass());
290 } 291 }
291 } 292 }
292 293
293 void CopyOutputFinishedForVideo( 294 void CopyOutputFinishedForVideo(
294 base::TimeTicks start_time, 295 base::TimeTicks start_time,
295 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 296 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
296 const scoped_refptr<media::VideoFrame>& target, 297 const scoped_refptr<media::VideoFrame>& target,
297 const SkBitmap& cursor_bitmap, 298 const SkBitmap& cursor_bitmap,
298 const gfx::Point& cursor_position, 299 const gfx::Point& cursor_position,
299 scoped_ptr<cc::SingleReleaseCallback> release_callback, 300 scoped_ptr<cc::SingleReleaseCallback> release_callback,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 } 344 }
344 } 345 }
345 } 346 }
346 347
347 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse( 348 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse(
348 scoped_refptr<media::VideoFrame> video_frame, 349 scoped_refptr<media::VideoFrame> video_frame,
349 base::TimeTicks start_time, 350 base::TimeTicks start_time,
350 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 351 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
351 scoped_ptr<cc::CopyOutputResult> result) { 352 scoped_ptr<cc::CopyOutputResult> result) {
352 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
353 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) 354 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer())
354 return false; 355 return false;
355 356
356 if (capture_params_.requested_format.pixel_format == 357 if (capture_params_.requested_format.pixel_format ==
357 media::PIXEL_FORMAT_TEXTURE) { 358 media::PIXEL_FORMAT_TEXTURE) {
358 DCHECK(!video_frame); 359 DCHECK(!video_frame);
359 cc::TextureMailbox texture_mailbox; 360 cc::TextureMailbox texture_mailbox;
360 scoped_ptr<cc::SingleReleaseCallback> release_callback; 361 scoped_ptr<cc::SingleReleaseCallback> release_callback;
361 result->TakeTexture(&texture_mailbox, &release_callback); 362 result->TakeTexture(&texture_mailbox, &release_callback);
362 DCHECK(texture_mailbox.IsTexture()); 363 DCHECK(texture_mailbox.IsTexture());
363 if (!texture_mailbox.IsTexture()) 364 if (!texture_mailbox.IsTexture())
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 capture_frame_cb, 431 capture_frame_cb,
431 video_frame, 432 video_frame,
432 scaled_cursor_bitmap_, 433 scaled_cursor_bitmap_,
433 cursor_position_in_frame, 434 cursor_position_in_frame,
434 base::Passed(&release_callback))); 435 base::Passed(&release_callback)));
435 return true; 436 return true;
436 } 437 }
437 438
438 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState( 439 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState(
439 const gfx::Rect& region_in_frame) { 440 const gfx::Rect& region_in_frame) {
440 const gfx::Rect desktop_bounds = desktop_layer_->bounds(); 441 const gfx::Rect desktop_bounds = desktop_layer()->bounds();
441 gfx::NativeCursor cursor = 442 gfx::NativeCursor cursor =
442 desktop_window_->GetHost()->last_cursor(); 443 desktop_window_->GetHost()->last_cursor();
443 if (last_cursor_ != cursor) { 444 if (last_cursor_ != cursor) {
444 SkBitmap cursor_bitmap; 445 SkBitmap cursor_bitmap;
445 if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) { 446 if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) {
446 scaled_cursor_bitmap_ = skia::ImageOperations::Resize( 447 scaled_cursor_bitmap_ = skia::ImageOperations::Resize(
447 cursor_bitmap, 448 cursor_bitmap,
448 skia::ImageOperations::RESIZE_BEST, 449 skia::ImageOperations::RESIZE_BEST,
449 cursor_bitmap.width() * region_in_frame.width() / 450 cursor_bitmap.width() * region_in_frame.width() /
450 desktop_bounds.width(), 451 desktop_bounds.width(),
451 cursor_bitmap.height() * region_in_frame.height() / 452 cursor_bitmap.height() * region_in_frame.height() /
452 desktop_bounds.height()); 453 desktop_bounds.height());
453 last_cursor_ = cursor; 454 last_cursor_ = cursor;
454 } else { 455 } else {
455 // Clear cursor state if ui::GetCursorBitmap failed so that we do not 456 // Clear cursor state if ui::GetCursorBitmap failed so that we do not
456 // render cursor on the captured frame. 457 // render cursor on the captured frame.
457 ClearCursorState(); 458 ClearCursorState();
458 } 459 }
459 } 460 }
460 461
461 gfx::Point cursor_position = aura::Env::GetInstance()->last_mouse_location(); 462 gfx::Point cursor_position = aura::Env::GetInstance()->last_mouse_location();
462 aura::client::GetScreenPositionClient(desktop_window_->GetRootWindow())-> 463 aura::client::GetScreenPositionClient(desktop_window_->GetRootWindow())->
463 ConvertPointFromScreen(desktop_window_, &cursor_position); 464 ConvertPointFromScreen(desktop_window_, &cursor_position);
464 const gfx::Point hot_point_in_dip = ui::ConvertPointToDIP( 465 const gfx::Point hot_point_in_dip = ui::ConvertPointToDIP(
465 desktop_layer_, cursor_hot_point_); 466 desktop_layer(), cursor_hot_point_);
466 cursor_position.Offset(-desktop_bounds.x() - hot_point_in_dip.x(), 467 cursor_position.Offset(-desktop_bounds.x() - hot_point_in_dip.x(),
467 -desktop_bounds.y() - hot_point_in_dip.y()); 468 -desktop_bounds.y() - hot_point_in_dip.y());
468 return gfx::Point( 469 return gfx::Point(
469 region_in_frame.x() + cursor_position.x() * region_in_frame.width() / 470 region_in_frame.x() + cursor_position.x() * region_in_frame.width() /
470 desktop_bounds.width(), 471 desktop_bounds.width(),
471 region_in_frame.y() + cursor_position.y() * region_in_frame.height() / 472 region_in_frame.y() + cursor_position.y() * region_in_frame.height() /
472 desktop_bounds.height()); 473 desktop_bounds.height());
473 } 474 }
474 475
475 void DesktopVideoCaptureMachine::ClearCursorState() { 476 void DesktopVideoCaptureMachine::ClearCursorState() {
476 last_cursor_ = ui::Cursor(); 477 last_cursor_ = ui::Cursor();
477 cursor_hot_point_ = gfx::Point(); 478 cursor_hot_point_ = gfx::Point();
478 scaled_cursor_bitmap_.reset(); 479 scaled_cursor_bitmap_.reset();
479 } 480 }
480 481
482 ui::Layer* DesktopVideoCaptureMachine::desktop_layer() {
483 if (!desktop_window_)
484 return NULL;
485 return desktop_window_->layer();
486 }
487
481 void DesktopVideoCaptureMachine::OnWindowBoundsChanged( 488 void DesktopVideoCaptureMachine::OnWindowBoundsChanged(
482 aura::Window* window, 489 aura::Window* window,
483 const gfx::Rect& old_bounds, 490 const gfx::Rect& old_bounds,
484 const gfx::Rect& new_bounds) { 491 const gfx::Rect& new_bounds) {
485 DCHECK(desktop_window_ && window == desktop_window_); 492 DCHECK(desktop_window_ && window == desktop_window_);
486 493
487 // Post task to update capture size on UI thread. 494 // Post task to update capture size on UI thread.
488 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( 495 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
489 &DesktopVideoCaptureMachine::UpdateCaptureSize, AsWeakPtr())); 496 &DesktopVideoCaptureMachine::UpdateCaptureSize, AsWeakPtr()));
490 } 497 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 scoped_ptr<Client> client) { 535 scoped_ptr<Client> client) {
529 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 536 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
530 core_->AllocateAndStart(params, client.Pass()); 537 core_->AllocateAndStart(params, client.Pass());
531 } 538 }
532 539
533 void DesktopCaptureDeviceAura::StopAndDeAllocate() { 540 void DesktopCaptureDeviceAura::StopAndDeAllocate() {
534 core_->StopAndDeAllocate(); 541 core_->StopAndDeAllocate();
535 } 542 }
536 543
537 } // namespace content 544 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698