Chromium Code Reviews| Index: webrtc/modules/desktop_capture/desktop_frame_rotation.cc |
| diff --git a/webrtc/modules/desktop_capture/desktop_frame_rotation.cc b/webrtc/modules/desktop_capture/desktop_frame_rotation.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c9b992868460fc5cd13322598cf6e2d9bf509e53 |
| --- /dev/null |
| +++ b/webrtc/modules/desktop_capture/desktop_frame_rotation.cc |
| @@ -0,0 +1,114 @@ |
| +/* |
| + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| + * |
| + * Use of this source code is governed by a BSD-style license |
| + * that can be found in the LICENSE file in the root of the source |
| + * tree. An additional intellectual property rights grant can be found |
| + * in the file PATENTS. All contributing project authors may |
| + * be found in the AUTHORS file in the root of the source tree. |
| + */ |
| + |
| +#include "webrtc/modules/desktop_capture/desktop_frame_rotation.h" |
| + |
| +#include <string.h> |
| + |
| +#include "webrtc/base/checks.h" |
| + |
| +#include "third_party/libyuv/include/libyuv/rotate_argb.h" |
| + |
| +namespace webrtc { |
| + |
| +namespace { |
| + |
| +// Returns a reverse-rotated Rotation of |rotation|. |
| +Rotation Reverse(Rotation rotation) { |
| + switch (rotation) { |
| + case Rotation::CLOCK_WISE_0: |
| + return rotation; |
| + case Rotation::CLOCK_WISE_90: |
| + return Rotation::CLOCK_WISE_270; |
| + case Rotation::CLOCK_WISE_180: |
| + return Rotation::CLOCK_WISE_180; |
| + case Rotation::CLOCK_WISE_270: |
| + return Rotation::CLOCK_WISE_90; |
| + } |
| + RTC_NOTREACHED(); |
| + return Rotation::CLOCK_WISE_0; |
| +} |
| + |
| +// Returns a rotated DesktopSize of |size|. |
| +DesktopSize GetRotatedSize(DesktopSize size, Rotation rotation) { |
| + switch (rotation) { |
| + case Rotation::CLOCK_WISE_0: |
| + case Rotation::CLOCK_WISE_180: |
| + return size; |
| + case Rotation::CLOCK_WISE_90: |
| + case Rotation::CLOCK_WISE_270: |
| + return DesktopSize(size.height(), size.width()); |
| + } |
| + RTC_NOTREACHED(); |
| + return DesktopSize(); |
| +} |
| + |
| +libyuv::RotationMode ToLibyuvRotationMode(Rotation rotation) { |
| + switch (rotation) { |
| + case Rotation::CLOCK_WISE_0: |
| + return libyuv::kRotate0; |
| + case Rotation::CLOCK_WISE_90: |
| + return libyuv::kRotate90; |
| + case Rotation::CLOCK_WISE_180: |
| + return libyuv::kRotate180; |
| + case Rotation::CLOCK_WISE_270: |
| + return libyuv::kRotate270; |
| + } |
| + RTC_NOTREACHED(); |
| + return libyuv::kRotate0; |
| +} |
| + |
| +} // namespace |
| + |
| +DesktopRect RotateRect(DesktopRect rect, DesktopSize size, Rotation rotation) { |
| + switch (rotation) { |
| + case Rotation::CLOCK_WISE_0: |
| + return rect; |
| + case Rotation::CLOCK_WISE_90: |
| + return DesktopRect::MakeXYWH(size.height() - rect.bottom(), rect.left(), |
| + rect.height(), rect.width()); |
| + case Rotation::CLOCK_WISE_180: |
| + return DesktopRect::MakeXYWH(size.width() - rect.right(), |
| + size.height() - rect.bottom(), rect.width(), |
| + rect.height()); |
| + case Rotation::CLOCK_WISE_270: |
| + return DesktopRect::MakeXYWH(rect.top(), size.width() - rect.right(), |
| + rect.height(), rect.width()); |
| + } |
| + RTC_NOTREACHED(); |
| + return DesktopRect(); |
| +} |
| + |
| + |
| +void RotateDesktopFrame(const DesktopFrame& source, |
| + const Rotation& rotation, |
| + const DesktopRect& rect, |
|
Sergey Ulanov
2016/11/19 02:11:40
I think it's more intuitive if |rect| was specifie
Hzj_jie
2016/11/19 05:10:59
Done.
|
| + DesktopFrame* target) { |
| + RTC_DCHECK(target); |
| + RTC_DCHECK(DesktopRect::MakeSize(target->size()).ContainsRect(rect)); |
|
Sergey Ulanov
2016/11/19 02:11:40
Also need to DCHECK that source and target are the
Hzj_jie
2016/11/19 05:10:59
In a typical multi-monitor scenario of DirectX cap
Sergey Ulanov
2016/11/21 21:01:12
I see. But in this case shouldn't we also shift th
Hzj_jie
2016/11/21 23:33:30
Yes, I missed this point. But I do not think a Des
|
| + |
| + if (rect.is_empty()) { |
| + return; |
| + } |
| + |
| + target->mutable_updated_region()->AddRect(rect); |
| + const Rotation reverse_rotation = Reverse(rotation); |
| + // The rectangle in |source|. |
| + const DesktopRect source_rect = RotateRect( |
| + rect, GetRotatedSize(source.size(), reverse_rotation), reverse_rotation); |
| + int result = libyuv::ARGBRotate( |
| + source.GetFrameDataAtPos(source_rect.top_left()), source.stride(), |
| + target->GetFrameDataAtPos(rect.top_left()), target->stride(), |
| + source_rect.width(), source_rect.height(), |
| + ToLibyuvRotationMode(rotation)); |
| + RTC_DCHECK_EQ(result, 0); |
| +} |
| + |
| +} // namespace webrtc |