Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: webrtc/modules/desktop_capture/desktop_frame_rotator.cc

Issue 2500883004: Add DesktopFrame rotation functions (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_rotator.h"
12
13 #include <string.h>
14
15 #include "webrtc/base/checks.h"
16
17 namespace webrtc {
18
19 namespace {
20
21 // The count of bytes to jump per pixel if a DesktopFrame |frame| has been
22 // rotated by |rotation|.
23 int StepPerPixel(const DesktopFrame& frame, Rotation rotation) {
24 switch (rotation) {
25 case Rotation::CLOCK_WISE_0:
26 return DesktopFrame::kBytesPerPixel;
27 case Rotation::CLOCK_WISE_90:
28 return frame.stride();
29 case Rotation::CLOCK_WISE_180:
30 return -DesktopFrame::kBytesPerPixel;
31 case Rotation::CLOCK_WISE_270:
32 return -frame.stride();
33 default:
34 RTC_NOTREACHED();
35 return 0;
36 }
37 }
38
39 // The count of bytes to jump per line if a DesktopFrame |frame| has been
40 // rotated by |rotation|.
41 int StepPerLine(const DesktopFrame& frame, Rotation rotation) {
42 switch (rotation) {
43 case Rotation::CLOCK_WISE_0:
44 return frame.stride();
45 case Rotation::CLOCK_WISE_90:
46 return -DesktopFrame::kBytesPerPixel;
47 case Rotation::CLOCK_WISE_180:
48 return -frame.stride();
49 case Rotation::CLOCK_WISE_270:
50 return DesktopFrame::kBytesPerPixel;
51 default:
52 RTC_NOTREACHED();
53 return 0;
54 }
55 }
56
57 // Returns a rotated DesktopRect of |rect|. The |size| represents the size of
58 // the DesktopFrame which |rect| belongs in.
59 DesktopRect Rotate(DesktopRect rect, DesktopSize size, Rotation rotation) {
60 switch (rotation) {
61 case Rotation::CLOCK_WISE_0:
62 return rect;
63 case Rotation::CLOCK_WISE_90:
64 return DesktopRect::MakeLTRB(size.height() - rect.bottom(),
65 rect.left(),
66 size.height() - rect.top(),
67 rect.right());
68 case Rotation::CLOCK_WISE_180:
69 return DesktopRect::MakeLTRB(size.width() - rect.right(),
70 size.height() - rect.bottom(),
71 size.width() - rect.left(),
72 size.height() - rect.top());
73 case Rotation::CLOCK_WISE_270:
74 return DesktopRect::MakeLTRB(rect.top(),
75 size.width() - rect.right(),
76 rect.bottom(),
77 size.width() - rect.left());
78 default:
79 RTC_NOTREACHED();
80 return DesktopRect();
81 }
82 }
83
84 // Returns a reverse-rotated Rotation of |rotation|.
85 Rotation Reverse(Rotation rotation) {
86 switch (rotation) {
87 case Rotation::CLOCK_WISE_0:
88 return rotation;
89 case Rotation::CLOCK_WISE_90:
90 return Rotation::CLOCK_WISE_270;
91 case Rotation::CLOCK_WISE_180:
92 return Rotation::CLOCK_WISE_180;
93 case Rotation::CLOCK_WISE_270:
94 return Rotation::CLOCK_WISE_90;
95 default:
96 RTC_NOTREACHED();
97 return Rotation::CLOCK_WISE_0;
98 }
99 }
100
101 // Returns a reverse-rotated DesktopRect of |rect|. The |size| represents the
102 // size of the DesktopFrame which |rect| belongs in.
103 DesktopRect Derotate(DesktopRect rect, DesktopSize size, Rotation rotation) {
104 return Rotate(rect, size, Reverse(rotation));
105 }
106
107 // The new position of Derotate(|rect|, |rotation|).top_left() after rotated.
108 DesktopVector RotatedTopLeft(DesktopRect rect, Rotation rotation) {
109 switch (rotation) {
110 case Rotation::CLOCK_WISE_0:
111 return rect.top_left();
112 case Rotation::CLOCK_WISE_90:
113 return DesktopVector(rect.right() - 1, rect.top());
114 case Rotation::CLOCK_WISE_180:
115 return DesktopVector(rect.right() - 1, rect.bottom() - 1);
116 case Rotation::CLOCK_WISE_270:
117 return DesktopVector(rect.left(), rect.bottom() - 1);
118 default:
119 RTC_NOTREACHED();
120 return DesktopVector();
121 }
122 }
123
124 // Returns a reverse-rotated DesktopSize of |size|.
125 DesktopSize Derotate(DesktopSize size, Rotation rotation) {
126 switch (rotation) {
127 case Rotation::CLOCK_WISE_0:
128 case Rotation::CLOCK_WISE_180:
129 return size;
130 case Rotation::CLOCK_WISE_90:
131 case Rotation::CLOCK_WISE_270:
132 return DesktopSize(size.height(), size.width());
133 default:
134 RTC_NOTREACHED();
135 return DesktopSize();
136 }
137 }
138
139 } // namespace
140
141 bool CopyRotatedRectTo(const DesktopFrame& src,
142 DesktopRect rect,
143 Rotation rotation,
144 DesktopFrame* target) {
145 if (!target) {
146 return false;
147 }
148 if (!DesktopRect::MakeSize(target->size()).ContainsRect(rect)) {
149 return false;
150 }
151 if (rect.is_empty()) {
152 return true;
153 }
154
155 target->mutable_updated_region()->AddRect(rect);
156 if (rotation == Rotation::CLOCK_WISE_0) {
157 // A shortcut: if |rotation| is 0, this function uses
158 // DesktopFrame::CopyPixelsFrom() for a better performance.
159 target->CopyPixelsFrom(src, rect.top_left(), rect);
160 return true;
161 }
162
163 // The rectangle in |src|.
164 const DesktopRect src_rect =
165 Derotate(rect, Derotate(src.size(), rotation), rotation);
166 const uint8_t* src_array = src.GetFrameDataAtPos(src_rect.top_left());
167 // The stride without the area which needs to be copied. i.e. The byte
168 // count between the end of last line and the start of next line in the
169 // |src_rect|.
170 const int src_exclusive_stride =
171 src.stride() - src_rect.width() * DesktopFrame::kBytesPerPixel;
172 uint8_t* dest_array =
173 target->GetFrameDataAtPos(RotatedTopLeft(rect, rotation));
174 const int dest_step_per_pixel = StepPerPixel(*target, rotation);
175 const int dest_exclusive_stride =
176 StepPerLine(*target, rotation) -
177 dest_step_per_pixel * src_rect.width();
178
179 for (int i = 0; i < src_rect.height(); i++) {
180 for (int j = 0; j < src_rect.width(); j++) {
181 memcpy(dest_array, src_array, DesktopFrame::kBytesPerPixel);
182 src_array += DesktopFrame::kBytesPerPixel;
183 dest_array += dest_step_per_pixel;
184 }
185 src_array += src_exclusive_stride;
186 dest_array += dest_exclusive_stride;
187 }
188 return true;
189 }
190
191 bool CopyUnrotatedRectTo(const DesktopFrame& src,
192 DesktopRect rect,
193 Rotation rotation,
194 DesktopFrame* target) {
195 return CopyRotatedRectTo(
196 src, Rotate(rect, src.size(), rotation), rotation, target);
197 }
198
199 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698