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. Spanning several threads, the process of capturing has been | 7 // performance. Spanning several threads, the process of capturing has been |
8 // split up into four conceptual stages: | 8 // split up into four conceptual stages: |
9 // | 9 // |
10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the consumer's | 10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the consumer's |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 oracle_->ObserveEventAndDecideCapture(event, event_time); | 431 oracle_->ObserveEventAndDecideCapture(event, event_time); |
432 const bool content_is_dirty = | 432 const bool content_is_dirty = |
433 (event == VideoCaptureOracle::kCompositorUpdate || | 433 (event == VideoCaptureOracle::kCompositorUpdate || |
434 event == VideoCaptureOracle::kSoftwarePaint); | 434 event == VideoCaptureOracle::kSoftwarePaint); |
435 const char* event_name = | 435 const char* event_name = |
436 (event == VideoCaptureOracle::kTimerPoll ? "poll" : | 436 (event == VideoCaptureOracle::kTimerPoll ? "poll" : |
437 (event == VideoCaptureOracle::kCompositorUpdate ? "gpu" : | 437 (event == VideoCaptureOracle::kCompositorUpdate ? "gpu" : |
438 "paint")); | 438 "paint")); |
439 | 439 |
440 // Consider the various reasons not to initiate a capture. | 440 // Consider the various reasons not to initiate a capture. |
441 if (should_capture && !output_buffer) { | 441 if (should_capture && !output_buffer.get()) { |
442 TRACE_EVENT_INSTANT1("mirroring", "EncodeLimited", | 442 TRACE_EVENT_INSTANT1("mirroring", |
| 443 "EncodeLimited", |
443 TRACE_EVENT_SCOPE_THREAD, | 444 TRACE_EVENT_SCOPE_THREAD, |
444 "trigger", event_name); | 445 "trigger", |
| 446 event_name); |
445 return false; | 447 return false; |
446 } else if (!should_capture && output_buffer) { | 448 } else if (!should_capture && output_buffer.get()) { |
447 if (content_is_dirty) { | 449 if (content_is_dirty) { |
448 // This is a normal and acceptable way to drop a frame. We've hit our | 450 // This is a normal and acceptable way to drop a frame. We've hit our |
449 // capture rate limit: for example, the content is animating at 60fps but | 451 // capture rate limit: for example, the content is animating at 60fps but |
450 // we're capturing at 30fps. | 452 // we're capturing at 30fps. |
451 TRACE_EVENT_INSTANT1("mirroring", "FpsRateLimited", | 453 TRACE_EVENT_INSTANT1("mirroring", "FpsRateLimited", |
452 TRACE_EVENT_SCOPE_THREAD, | 454 TRACE_EVENT_SCOPE_THREAD, |
453 "trigger", event_name); | 455 "trigger", event_name); |
454 } | 456 } |
455 return false; | 457 return false; |
456 } else if (!should_capture && !output_buffer) { | 458 } else if (!should_capture && !output_buffer.get()) { |
457 // We decided not to capture, but we wouldn't have been able to if we wanted | 459 // We decided not to capture, but we wouldn't have been able to if we wanted |
458 // to because no output buffer was available. | 460 // to because no output buffer was available. |
459 TRACE_EVENT_INSTANT1("mirroring", "NearlyEncodeLimited", | 461 TRACE_EVENT_INSTANT1("mirroring", "NearlyEncodeLimited", |
460 TRACE_EVENT_SCOPE_THREAD, | 462 TRACE_EVENT_SCOPE_THREAD, |
461 "trigger", event_name); | 463 "trigger", event_name); |
462 return false; | 464 return false; |
463 } | 465 } |
464 int frame_number = oracle_->RecordCapture(); | 466 int frame_number = oracle_->RecordCapture(); |
465 TRACE_EVENT_ASYNC_BEGIN2("mirroring", "Capture", output_buffer.get(), | 467 TRACE_EVENT_ASYNC_BEGIN2("mirroring", "Capture", output_buffer.get(), |
466 "frame_number", frame_number, | 468 "frame_number", frame_number, |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 } | 681 } |
680 | 682 |
681 TRACE_EVENT_ASYNC_STEP0("mirroring", "Capture", output.get(), "YUV"); | 683 TRACE_EVENT_ASYNC_STEP0("mirroring", "Capture", output.get(), "YUV"); |
682 { | 684 { |
683 SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); | 685 SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap); |
684 | 686 |
685 media::CopyRGBToVideoFrame( | 687 media::CopyRGBToVideoFrame( |
686 reinterpret_cast<uint8*>(scaled_bitmap.getPixels()), | 688 reinterpret_cast<uint8*>(scaled_bitmap.getPixels()), |
687 scaled_bitmap.rowBytes(), | 689 scaled_bitmap.rowBytes(), |
688 region_in_frame, | 690 region_in_frame, |
689 output); | 691 output.get()); |
690 } | 692 } |
691 | 693 |
692 // The result is now ready. | 694 // The result is now ready. |
693 failure_handler.Release(); | 695 failure_handler.Release(); |
694 done_cb.Run(true); | 696 done_cb.Run(true); |
695 } | 697 } |
696 | 698 |
697 VideoFrameDeliveryLog::VideoFrameDeliveryLog() | 699 VideoFrameDeliveryLog::VideoFrameDeliveryLog() |
698 : last_frame_rate_log_time_(), | 700 : last_frame_rate_log_time_(), |
699 count_frames_rendered_(0), | 701 count_frames_rendered_(0), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 } | 735 } |
734 } | 736 } |
735 | 737 |
736 // static | 738 // static |
737 scoped_ptr<CaptureMachine> CaptureMachine::Create( | 739 scoped_ptr<CaptureMachine> CaptureMachine::Create( |
738 int render_process_id, | 740 int render_process_id, |
739 int render_view_id, | 741 int render_view_id, |
740 const scoped_refptr<base::SequencedTaskRunner>& render_task_runner, | 742 const scoped_refptr<base::SequencedTaskRunner>& render_task_runner, |
741 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) { | 743 const scoped_refptr<ThreadSafeCaptureOracle>& oracle_proxy) { |
742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
743 DCHECK(render_task_runner); | 745 DCHECK(render_task_runner.get()); |
744 DCHECK(oracle_proxy); | 746 DCHECK(oracle_proxy.get()); |
745 scoped_ptr<CaptureMachine> machine( | 747 scoped_ptr<CaptureMachine> machine( |
746 new CaptureMachine(render_task_runner, oracle_proxy)); | 748 new CaptureMachine(render_task_runner, oracle_proxy)); |
747 | 749 |
748 if (!machine->StartObservingWebContents(render_process_id, render_view_id)) | 750 if (!machine->StartObservingWebContents(render_process_id, render_view_id)) |
749 machine.reset(); | 751 machine.reset(); |
750 | 752 |
751 return machine.Pass(); | 753 return machine.Pass(); |
752 } | 754 } |
753 | 755 |
754 CaptureMachine::CaptureMachine( | 756 CaptureMachine::CaptureMachine( |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 void WebContentsVideoCaptureDevice::DeAllocate() { | 1264 void WebContentsVideoCaptureDevice::DeAllocate() { |
1263 impl_->DeAllocate(); | 1265 impl_->DeAllocate(); |
1264 } | 1266 } |
1265 | 1267 |
1266 const media::VideoCaptureDevice::Name& | 1268 const media::VideoCaptureDevice::Name& |
1267 WebContentsVideoCaptureDevice::device_name() { | 1269 WebContentsVideoCaptureDevice::device_name() { |
1268 return device_name_; | 1270 return device_name_; |
1269 } | 1271 } |
1270 | 1272 |
1271 } // namespace content | 1273 } // namespace content |
OLD | NEW |