Line data Source code
1 : /*
2 : * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/modules/desktop_capture/desktop_frame_rotation.h"
12 :
13 : #include <string.h>
14 :
15 : #include "webrtc/base/checks.h"
16 : #include "libyuv/rotate_argb.h"
17 :
18 : namespace webrtc {
19 :
20 : namespace {
21 :
22 0 : libyuv::RotationMode ToLibyuvRotationMode(Rotation rotation) {
23 0 : switch (rotation) {
24 : case Rotation::CLOCK_WISE_0:
25 0 : return libyuv::kRotate0;
26 : case Rotation::CLOCK_WISE_90:
27 0 : return libyuv::kRotate90;
28 : case Rotation::CLOCK_WISE_180:
29 0 : return libyuv::kRotate180;
30 : case Rotation::CLOCK_WISE_270:
31 0 : return libyuv::kRotate270;
32 : }
33 0 : RTC_NOTREACHED();
34 0 : return libyuv::kRotate0;
35 : }
36 :
37 0 : DesktopRect RotateAndOffsetRect(DesktopRect rect,
38 : DesktopSize size,
39 : Rotation rotation,
40 : DesktopVector offset) {
41 0 : DesktopRect result = RotateRect(rect, size, rotation);
42 0 : result.Translate(offset);
43 0 : return result;
44 : }
45 :
46 : } // namespace
47 :
48 0 : Rotation ReverseRotation(Rotation rotation) {
49 0 : switch (rotation) {
50 : case Rotation::CLOCK_WISE_0:
51 0 : return rotation;
52 : case Rotation::CLOCK_WISE_90:
53 0 : return Rotation::CLOCK_WISE_270;
54 : case Rotation::CLOCK_WISE_180:
55 0 : return Rotation::CLOCK_WISE_180;
56 : case Rotation::CLOCK_WISE_270:
57 0 : return Rotation::CLOCK_WISE_90;
58 : }
59 0 : RTC_NOTREACHED();
60 0 : return Rotation::CLOCK_WISE_0;
61 : }
62 :
63 0 : DesktopSize RotateSize(DesktopSize size, Rotation rotation) {
64 0 : switch (rotation) {
65 : case Rotation::CLOCK_WISE_0:
66 : case Rotation::CLOCK_WISE_180:
67 0 : return size;
68 : case Rotation::CLOCK_WISE_90:
69 : case Rotation::CLOCK_WISE_270:
70 0 : return DesktopSize(size.height(), size.width());
71 : }
72 0 : RTC_NOTREACHED();
73 0 : return DesktopSize();
74 : }
75 :
76 0 : DesktopRect RotateRect(DesktopRect rect, DesktopSize size, Rotation rotation) {
77 0 : switch (rotation) {
78 : case Rotation::CLOCK_WISE_0:
79 0 : return rect;
80 : case Rotation::CLOCK_WISE_90:
81 0 : return DesktopRect::MakeXYWH(size.height() - rect.bottom(), rect.left(),
82 0 : rect.height(), rect.width());
83 : case Rotation::CLOCK_WISE_180:
84 0 : return DesktopRect::MakeXYWH(size.width() - rect.right(),
85 0 : size.height() - rect.bottom(), rect.width(),
86 0 : rect.height());
87 : case Rotation::CLOCK_WISE_270:
88 0 : return DesktopRect::MakeXYWH(rect.top(), size.width() - rect.right(),
89 0 : rect.height(), rect.width());
90 : }
91 0 : RTC_NOTREACHED();
92 0 : return DesktopRect();
93 : }
94 :
95 0 : void RotateDesktopFrame(const DesktopFrame& source,
96 : const DesktopRect& source_rect,
97 : const Rotation& rotation,
98 : const DesktopVector& target_offset,
99 : DesktopFrame* target) {
100 0 : RTC_DCHECK(target);
101 0 : RTC_DCHECK(DesktopRect::MakeSize(source.size()).ContainsRect(source_rect));
102 : // The rectangle in |target|.
103 : const DesktopRect target_rect =
104 0 : RotateAndOffsetRect(source_rect, source.size(), rotation, target_offset);
105 0 : RTC_DCHECK(DesktopRect::MakeSize(target->size()).ContainsRect(target_rect));
106 :
107 0 : if (target_rect.is_empty()) {
108 0 : return;
109 : }
110 :
111 0 : int result = libyuv::ARGBRotate(
112 0 : source.GetFrameDataAtPos(source_rect.top_left()), source.stride(),
113 0 : target->GetFrameDataAtPos(target_rect.top_left()), target->stride(),
114 : source_rect.width(), source_rect.height(),
115 0 : ToLibyuvRotationMode(rotation));
116 0 : RTC_DCHECK_EQ(result, 0);
117 : }
118 :
119 : } // namespace webrtc
|