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 client's | 10 // 1. Reserve Buffer: Before a frame can be captured, a slot in the client's |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 } | 635 } |
636 | 636 |
637 gfx::Size WebContentsCaptureMachine::ComputeOptimalViewSize() const { | 637 gfx::Size WebContentsCaptureMachine::ComputeOptimalViewSize() const { |
638 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 638 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
639 | 639 |
640 // TODO(miu): Propagate capture frame size changes as new "preferred size" | 640 // TODO(miu): Propagate capture frame size changes as new "preferred size" |
641 // updates, rather than just using the max frame size. | 641 // updates, rather than just using the max frame size. |
642 // http://crbug.com/350491 | 642 // http://crbug.com/350491 |
643 gfx::Size optimal_size = oracle_proxy_->max_frame_size(); | 643 gfx::Size optimal_size = oracle_proxy_->max_frame_size(); |
644 | 644 |
645 // If the max frame size is close to a common video aspect ratio, compute a | |
646 // standard resolution for that aspect ratio. For example, given 1365x768, | |
647 // which is very close to 16:9, the optimal size would be 1280x720. The | |
648 // purpose of this logic is to prevent scaling quality issues caused by "one | |
649 // pixel stretching" and/or odd-to-even dimension scaling, and to improve the | |
650 // performance of consumers of the captured video. | |
651 const auto HasIntendedAspectRatio = [](const gfx::Size& size, int x, int y) { | |
Kevin M
2015/07/30 00:23:06
Can you factor this out into a standalone fn that
miu
2015/07/30 20:22:53
Done. Didn't factor anything out, but did write u
| |
652 const int a = y * size.width(); | |
653 const int b = x * size.height(); | |
654 const int percentage_diff = 100 * std::abs((a - b)) / b; | |
655 return percentage_diff <= 1; // Effectively, anything strictly <2%. | |
656 }; | |
657 const auto RoundToExactAspectRatio = [](const gfx::Size& size, int x, int y) { | |
658 const int adjusted_height = | |
Kevin M
2015/07/30 00:23:06
Can you add some comments or pick a more descripti
miu
2015/07/30 20:22:53
Done.
| |
659 std::max(size.height() - (size.height() % y), y); | |
660 DCHECK_EQ((adjusted_height * x) % y, 0); | |
661 return gfx::Size(adjusted_height * x / y, adjusted_height); | |
662 }; | |
663 if (HasIntendedAspectRatio(optimal_size, 16, 9)) | |
664 optimal_size = RoundToExactAspectRatio(optimal_size, 160, 90); | |
665 else if (HasIntendedAspectRatio(optimal_size, 4, 3)) | |
666 optimal_size = RoundToExactAspectRatio(optimal_size, 64, 48); | |
667 // Else, do not make an adjustment. | |
668 | |
645 // If the ratio between physical and logical pixels is greater than 1:1, | 669 // If the ratio between physical and logical pixels is greater than 1:1, |
646 // shrink |optimal_size| by that amount. Then, when external code resizes the | 670 // shrink |optimal_size| by that amount. Then, when external code resizes the |
647 // render widget to the "preferred size," the widget will be physically | 671 // render widget to the "preferred size," the widget will be physically |
648 // rendered at the exact capture size, thereby eliminating unnecessary scaling | 672 // rendered at the exact capture size, thereby eliminating unnecessary scaling |
649 // operations in the graphics pipeline. | 673 // operations in the graphics pipeline. |
650 RenderWidgetHost* const rwh = tracker_->GetTargetRenderWidgetHost(); | 674 RenderWidgetHost* const rwh = tracker_->GetTargetRenderWidgetHost(); |
651 RenderWidgetHostView* const rwhv = rwh ? rwh->GetView() : NULL; | 675 RenderWidgetHostView* const rwhv = rwh ? rwh->GetView() : NULL; |
652 if (rwhv) { | 676 if (rwhv) { |
653 const gfx::NativeView view = rwhv->GetNativeView(); | 677 const gfx::NativeView view = rwhv->GetNativeView(); |
654 const float scale = ui::GetScaleFactorForNativeView(view); | 678 const float scale = ui::GetScaleFactorForNativeView(view); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
799 scoped_ptr<Client> client) { | 823 scoped_ptr<Client> client) { |
800 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); | 824 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); |
801 core_->AllocateAndStart(params, client.Pass()); | 825 core_->AllocateAndStart(params, client.Pass()); |
802 } | 826 } |
803 | 827 |
804 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { | 828 void WebContentsVideoCaptureDevice::StopAndDeAllocate() { |
805 core_->StopAndDeAllocate(); | 829 core_->StopAndDeAllocate(); |
806 } | 830 } |
807 | 831 |
808 } // namespace content | 832 } // namespace content |
OLD | NEW |