| 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..7a3a8acc4ff919075fa73e0f584683f6b85a632e
|
| --- /dev/null
|
| +++ b/webrtc/modules/desktop_capture/desktop_frame_rotation.cc
|
| @@ -0,0 +1,120 @@
|
| +/*
|
| + * 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 {
|
| +
|
| +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;
|
| +}
|
| +
|
| +DesktopRect RotateAndOffsetRect(DesktopRect rect,
|
| + DesktopSize size,
|
| + Rotation rotation,
|
| + DesktopVector offset) {
|
| + DesktopRect result = RotateRect(rect, size, rotation);
|
| + result.Translate(offset);
|
| + return result;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +Rotation ReverseRotation(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;
|
| +}
|
| +
|
| +DesktopSize RotateSize(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();
|
| +}
|
| +
|
| +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 DesktopRect& source_rect,
|
| + const Rotation& rotation,
|
| + const DesktopVector& target_offset,
|
| + DesktopFrame* target) {
|
| + RTC_DCHECK(target);
|
| + RTC_DCHECK(DesktopRect::MakeSize(source.size()).ContainsRect(source_rect));
|
| + // The rectangle in |target|.
|
| + const DesktopRect target_rect =
|
| + RotateAndOffsetRect(source_rect, source.size(), rotation, target_offset);
|
| + RTC_DCHECK(DesktopRect::MakeSize(target->size()).ContainsRect(target_rect));
|
| +
|
| + if (target_rect.is_empty()) {
|
| + return;
|
| + }
|
| +
|
| + target->mutable_updated_region()->AddRect(target_rect);
|
| + int result = libyuv::ARGBRotate(
|
| + source.GetFrameDataAtPos(source_rect.top_left()), source.stride(),
|
| + target->GetFrameDataAtPos(target_rect.top_left()), target->stride(),
|
| + source_rect.width(), source_rect.height(),
|
| + ToLibyuvRotationMode(rotation));
|
| + RTC_DCHECK_EQ(result, 0);
|
| +}
|
| +
|
| +} // namespace webrtc
|
|
|