OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Implementation notes: This needs to work on a variety of hardware | 5 // Implementation notes: This needs to work on a variety of hardware |
6 // configurations where the speed of the CPU and GPU greatly affect overall | 6 // configurations where the speed of the CPU and GPU greatly affect overall |
7 // performance. Therefore, the process of capturing has been split up into a | 7 // performance. Therefore, the process of capturing has been split up into a |
8 // pipeline of three stages. Each stage executes on its own thread: | 8 // pipeline of three stages. Each stage executes on its own thread: |
9 // | 9 // |
10 // 1. Capture: A bitmap is snapshotted/copied from the RenderView's backing | 10 // 1. Capture: A bitmap is snapshotted/copied from the RenderView's backing |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 | 426 |
427 void VideoFrameRenderer::RenderOnRenderThread( | 427 void VideoFrameRenderer::RenderOnRenderThread( |
428 int frame_number, | 428 int frame_number, |
429 const SkBitmap& captured_bitmap, | 429 const SkBitmap& captured_bitmap, |
430 int frame_width, int frame_height, | 430 int frame_width, int frame_height, |
431 const DoneCB& done_cb) { | 431 const DoneCB& done_cb) { |
432 DCHECK_EQ(render_thread_.message_loop(), MessageLoop::current()); | 432 DCHECK_EQ(render_thread_.message_loop(), MessageLoop::current()); |
433 | 433 |
434 TRACE_EVENT1("mirroring", "RenderFrame", "frame_number", frame_number); | 434 TRACE_EVENT1("mirroring", "RenderFrame", "frame_number", frame_number); |
435 | 435 |
| 436 base::ScopedClosureRunner failure_handler( |
| 437 base::Bind(done_cb, static_cast<const SkBitmap*>(NULL))); |
| 438 |
436 gfx::Size fitted_size; | 439 gfx::Size fitted_size; |
437 { | 440 { |
438 SkAutoLockPixels locker(captured_bitmap); | 441 SkAutoLockPixels locker(captured_bitmap); |
439 | 442 |
440 // Sanity-check the captured bitmap. | 443 // Sanity-check the captured bitmap. |
441 if (captured_bitmap.empty() || | 444 if (captured_bitmap.empty() || |
442 !captured_bitmap.readyToDraw() || | 445 !captured_bitmap.readyToDraw() || |
443 captured_bitmap.config() != SkBitmap::kARGB_8888_Config || | 446 captured_bitmap.config() != SkBitmap::kARGB_8888_Config || |
444 captured_bitmap.width() < 2 || captured_bitmap.height() < 2) { | 447 captured_bitmap.width() < 2 || captured_bitmap.height() < 2) { |
445 DVLOG(1) << "captured_bitmap unacceptable (size=" | 448 DVLOG(1) << "captured_bitmap unacceptable (size=" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 out->region_used = region_in_frame; | 517 out->region_used = region_in_frame; |
515 | 518 |
516 scaled_bitmap->copyPixelsTo( | 519 scaled_bitmap->copyPixelsTo( |
517 out->frame_buffer.getAddr32(region_in_frame.x(), region_in_frame.y()), | 520 out->frame_buffer.getAddr32(region_in_frame.x(), region_in_frame.y()), |
518 out->frame_buffer.getSize(), | 521 out->frame_buffer.getSize(), |
519 out->frame_buffer.rowBytes(), | 522 out->frame_buffer.rowBytes(), |
520 true); | 523 true); |
521 } | 524 } |
522 | 525 |
523 // The result is now ready. | 526 // The result is now ready. |
| 527 failure_handler.Release(); |
524 { | 528 { |
525 base::AutoLock guard(lock_); | 529 base::AutoLock guard(lock_); |
526 out->in_use = true; | 530 out->in_use = true; |
527 } | 531 } |
528 done_cb.Run(&out->frame_buffer); | 532 done_cb.Run(&out->frame_buffer); |
529 } | 533 } |
530 | 534 |
531 void VideoFrameRenderer::Release(const SkBitmap* frame_buffer) { | 535 void VideoFrameRenderer::Release(const SkBitmap* frame_buffer) { |
532 if (frame_buffer == &(output_[0].frame_buffer)) { | 536 if (frame_buffer == &(output_[0].frame_buffer)) { |
533 base::AutoLock guard(lock_); | 537 base::AutoLock guard(lock_); |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 } | 997 } |
994 | 998 |
995 void CaptureMachine::RenderComplete(int frame_number, | 999 void CaptureMachine::RenderComplete(int frame_number, |
996 const base::Time& capture_time, | 1000 const base::Time& capture_time, |
997 const SkBitmap* frame_buffer) { | 1001 const SkBitmap* frame_buffer) { |
998 DCHECK_EQ(manager_thread_.message_loop(), MessageLoop::current()); | 1002 DCHECK_EQ(manager_thread_.message_loop(), MessageLoop::current()); |
999 | 1003 |
1000 --num_renders_pending_; | 1004 --num_renders_pending_; |
1001 DCHECK_LE(0, num_renders_pending_); | 1005 DCHECK_LE(0, num_renders_pending_); |
1002 | 1006 |
1003 if (state_ != kCapturing) { | 1007 if (state_ != kCapturing || !frame_buffer) { |
1004 return; | 1008 return; |
1005 } | 1009 } |
1006 | 1010 |
1007 DCHECK(!capture_time.is_null()); | 1011 DCHECK(!capture_time.is_null()); |
1008 DCHECK(frame_buffer); | 1012 DCHECK(frame_buffer); |
1009 deliverer_.Deliver( | 1013 deliverer_.Deliver( |
1010 frame_number, *frame_buffer, capture_time, | 1014 frame_number, *frame_buffer, capture_time, |
1011 base::Bind(&CaptureMachine::DeliverComplete, this, frame_buffer)); | 1015 base::Bind(&CaptureMachine::DeliverComplete, this, frame_buffer)); |
1012 } | 1016 } |
1013 | 1017 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 capturer_->SetConsumer(NULL); | 1087 capturer_->SetConsumer(NULL); |
1084 capturer_->DeAllocate(); | 1088 capturer_->DeAllocate(); |
1085 } | 1089 } |
1086 | 1090 |
1087 const media::VideoCaptureDevice::Name& | 1091 const media::VideoCaptureDevice::Name& |
1088 WebContentsVideoCaptureDevice::device_name() { | 1092 WebContentsVideoCaptureDevice::device_name() { |
1089 return device_name_; | 1093 return device_name_; |
1090 } | 1094 } |
1091 | 1095 |
1092 } // namespace content | 1096 } // namespace content |
OLD | NEW |