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

Side by Side Diff: remoting/base/util.cc

Issue 9320025: Introducing a helper wrapper for YUV-to-RGB convertion and/or scaling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More review feedback. Created 8 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « remoting/base/util.h ('k') | remoting/base/util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "remoting/base/util.h" 5 #include "remoting/base/util.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
11 #include "base/time.h" 11 #include "base/time.h"
12 #include "media/base/video_frame.h" 12 #include "media/base/video_frame.h"
13 #include "media/base/yuv_convert.h" 13 #include "media/base/yuv_convert.h"
14 #include "third_party/skia/include/core/SkRegion.h"
14 15
15 using media::VideoFrame; 16 using media::VideoFrame;
16 17
17 namespace remoting { 18 namespace remoting {
18 19
19 // Do not write LOG messages in this routine since it is called from within 20 // Do not write LOG messages in this routine since it is called from within
20 // our LOG message handler. Bad things will happen. 21 // our LOG message handler. Bad things will happen.
21 std::string GetTimestampString() { 22 std::string GetTimestampString() {
22 base::Time t = base::Time::NowFromSystemTime(); 23 base::Time t = base::Time::NowFromSystemTime();
23 base::Time::Exploded tex; 24 base::Time::Exploded tex;
(...skipping 17 matching lines...) Expand all
41 return 0; 42 return 0;
42 } 43 }
43 } 44 }
44 45
45 // Helper methods to calculate plane offset given the coordinates. 46 // Helper methods to calculate plane offset given the coordinates.
46 static int CalculateRGBOffset(int x, int y, int stride) { 47 static int CalculateRGBOffset(int x, int y, int stride) {
47 return stride * y + GetBytesPerPixel(media::VideoFrame::RGB32) * x; 48 return stride * y + GetBytesPerPixel(media::VideoFrame::RGB32) * x;
48 } 49 }
49 50
50 static int CalculateYOffset(int x, int y, int stride) { 51 static int CalculateYOffset(int x, int y, int stride) {
52 DCHECK(((x & 1) == 0) && ((y & 1) == 0));
51 return stride * y + x; 53 return stride * y + x;
52 } 54 }
53 55
54 static int CalculateUVOffset(int x, int y, int stride) { 56 static int CalculateUVOffset(int x, int y, int stride) {
57 DCHECK(((x & 1) == 0) && ((y & 1) == 0));
55 return stride * y / 2 + x / 2; 58 return stride * y / 2 + x / 2;
56 } 59 }
57 60
58 void ConvertYUVToRGB32WithRect(const uint8* y_plane,
59 const uint8* u_plane,
60 const uint8* v_plane,
61 uint8* rgb_plane,
62 const SkIRect& rect,
63 int y_stride,
64 int uv_stride,
65 int rgb_stride) {
66 DCHECK((rect.x() & 1) == 0 && (rect.y() & 1) == 0);
67 int rgb_offset = CalculateRGBOffset(rect.left(), rect.top(), rgb_stride);
68 int y_offset = CalculateYOffset(rect.left(), rect.top(), y_stride);
69 int uv_offset = CalculateUVOffset(rect.left(), rect.top(), uv_stride);
70
71 media::ConvertYUVToRGB32(y_plane + y_offset,
72 u_plane + uv_offset,
73 v_plane + uv_offset,
74 rgb_plane + rgb_offset,
75 rect.width(),
76 rect.height(),
77 y_stride,
78 uv_stride,
79 rgb_stride,
80 media::YV12);
81 }
82
83 void ConvertRGB32ToYUVWithRect(const uint8* rgb_plane, 61 void ConvertRGB32ToYUVWithRect(const uint8* rgb_plane,
84 uint8* y_plane, 62 uint8* y_plane,
85 uint8* u_plane, 63 uint8* u_plane,
86 uint8* v_plane, 64 uint8* v_plane,
87 int x, 65 int x,
88 int y, 66 int y,
89 int width, 67 int width,
90 int height, 68 int height,
91 int rgb_stride, 69 int rgb_stride,
92 int y_stride, 70 int y_stride,
93 int uv_stride) { 71 int uv_stride) {
94 int rgb_offset = CalculateRGBOffset(x, y, rgb_stride); 72 int rgb_offset = CalculateRGBOffset(x, y, rgb_stride);
95 int y_offset = CalculateYOffset(x, y, y_stride); 73 int y_offset = CalculateYOffset(x, y, y_stride);
96 int uv_offset = CalculateUVOffset(x, y, uv_stride);; 74 int uv_offset = CalculateUVOffset(x, y, uv_stride);;
97 75
98 media::ConvertRGB32ToYUV(rgb_plane + rgb_offset, 76 media::ConvertRGB32ToYUV(rgb_plane + rgb_offset,
99 y_plane + y_offset, 77 y_plane + y_offset,
100 u_plane + uv_offset, 78 u_plane + uv_offset,
101 v_plane + uv_offset, 79 v_plane + uv_offset,
102 width, 80 width,
103 height, 81 height,
104 rgb_stride, 82 rgb_stride,
105 y_stride, 83 y_stride,
106 uv_stride); 84 uv_stride);
107 } 85 }
108 86
87 void ConvertAndScaleYUVToRGB32Rect(const uint8* source_yplane,
88 const uint8* source_uplane,
89 const uint8* source_vplane,
90 int source_ystride,
91 int source_uvstride,
92 const SkISize& source_size,
93 const SkIRect& source_buffer_rect,
94 uint8* dest_buffer,
95 int dest_stride,
96 const SkISize& dest_size,
97 const SkIRect& dest_buffer_rect,
98 const SkIRect& dest_rect) {
99 // N.B. It is caller's responsibility to check if strides are large enough. We
100 // cannot do it here anyway.
101 DCHECK(SkIRect::MakeSize(source_size).contains(source_buffer_rect));
102 DCHECK(SkIRect::MakeSize(dest_size).contains(dest_buffer_rect));
103 DCHECK(dest_buffer_rect.contains(dest_rect));
104 DCHECK(ScaleRect(source_buffer_rect, source_size, dest_size).
105 contains(dest_rect));
106
107 // If the source and/or destination buffers don't start at (0, 0)
108 // offset the pointers to pretend we have complete buffers.
109 int y_offset = - CalculateYOffset(source_buffer_rect.x(),
110 source_buffer_rect.y(),
111 source_ystride);
112 int uv_offset = - CalculateUVOffset(source_buffer_rect.x(),
113 source_buffer_rect.y(),
114 source_uvstride);
115 int rgb_offset = - CalculateRGBOffset(dest_buffer_rect.x(),
116 dest_buffer_rect.y(),
117 dest_stride);
118
119 // See if scaling is needed.
120 if (source_size == dest_size) {
121 // Calculate the inner rectangle that can be copied by the optimized
122 // ConvertYUVToRGB32().
123 SkIRect inner_rect =
124 SkIRect::MakeLTRB(RoundToTwosMultiple(dest_rect.left() + 1),
125 RoundToTwosMultiple(dest_rect.top() + 1),
126 dest_rect.right(),
127 dest_rect.bottom());
128
129 // Offset pointers to point to the top left corner of the inner rectangle.
130 y_offset += CalculateYOffset(inner_rect.x(), inner_rect.y(),
131 source_ystride);
132 uv_offset += CalculateUVOffset(inner_rect.x(), inner_rect.y(),
133 source_uvstride);
134 rgb_offset += CalculateRGBOffset(inner_rect.x(), inner_rect.y(),
135 dest_stride);
136
137 media::ConvertYUVToRGB32(source_yplane + y_offset,
138 source_uplane + uv_offset,
139 source_vplane + uv_offset,
140 dest_buffer + rgb_offset,
141 inner_rect.width(),
142 inner_rect.height(),
143 source_ystride,
144 source_uvstride,
145 dest_stride,
146 media::YV12);
147
148 // Now see if some pixels weren't copied due to alignment.
149 if (dest_rect != inner_rect) {
150 SkIRect outer_rect =
151 SkIRect::MakeLTRB(RoundToTwosMultiple(dest_rect.left()),
152 RoundToTwosMultiple(dest_rect.top()),
153 dest_rect.right(),
154 dest_rect.bottom());
155
156 SkIPoint offset = SkIPoint::Make(outer_rect.x() - inner_rect.x(),
157 outer_rect.y() - inner_rect.y());
158
159 // Offset the pointers to point to the top left corner of the outer
160 // rectangle.
161 y_offset += CalculateYOffset(offset.x(), offset.y(), source_ystride);
162 uv_offset += CalculateUVOffset(offset.x(), offset.y(), source_uvstride);
163 rgb_offset += CalculateRGBOffset(offset.x(), offset.y(), dest_stride);
164
165 // Draw unaligned edges.
166 SkRegion edges(dest_rect);
167 edges.op(inner_rect, SkRegion::kDifference_Op);
168 for (SkRegion::Iterator i(edges); !i.done(); i.next()) {
169 SkIRect rect(i.rect());
170 rect.offset(- outer_rect.left(), - outer_rect.top());
171 media::ScaleYUVToRGB32WithRect(source_yplane + y_offset,
172 source_uplane + uv_offset,
173 source_vplane + uv_offset,
174 dest_buffer + rgb_offset,
175 source_size.width(),
176 source_size.height(),
177 dest_size.width(),
178 dest_size.height(),
179 rect.left(),
180 rect.top(),
181 rect.right(),
182 rect.bottom(),
183 source_ystride,
184 source_uvstride,
185 dest_stride);
186 }
187 }
188 } else {
189 media::ScaleYUVToRGB32WithRect(source_yplane + y_offset,
190 source_uplane + uv_offset,
191 source_vplane + uv_offset,
192 dest_buffer + rgb_offset,
193 source_size.width(),
194 source_size.height(),
195 dest_size.width(),
196 dest_size.height(),
197 dest_rect.left(),
198 dest_rect.top(),
199 dest_rect.right(),
200 dest_rect.bottom(),
201 source_ystride,
202 source_uvstride,
203 dest_stride);
204 }
205 }
206
109 int RoundToTwosMultiple(int x) { 207 int RoundToTwosMultiple(int x) {
110 return x & (~1); 208 return x & (~1);
111 } 209 }
112 210
113 SkIRect AlignRect(const SkIRect& rect) { 211 SkIRect AlignRect(const SkIRect& rect) {
114 int x = RoundToTwosMultiple(rect.left()); 212 int x = RoundToTwosMultiple(rect.left());
115 int y = RoundToTwosMultiple(rect.top()); 213 int y = RoundToTwosMultiple(rect.top());
116 int right = RoundToTwosMultiple(rect.right() + 1); 214 int right = RoundToTwosMultiple(rect.right() + 1);
117 int bottom = RoundToTwosMultiple(rect.bottom() + 1); 215 int bottom = RoundToTwosMultiple(rect.bottom() + 1);
118 return SkIRect::MakeLTRB(x, y, right, bottom); 216 return SkIRect::MakeLTRB(x, y, right, bottom);
(...skipping 27 matching lines...) Expand all
146 // Copy pixels in the rectangle line by line. 244 // Copy pixels in the rectangle line by line.
147 const int bytes_per_line = bytes_per_pixel * rect.width(); 245 const int bytes_per_line = bytes_per_pixel * rect.width();
148 const int height = rect.height(); 246 const int height = rect.height();
149 for (int i = 0 ; i < height; ++i) { 247 for (int i = 0 ; i < height; ++i) {
150 memcpy(dest_plane, src_plane, bytes_per_line); 248 memcpy(dest_plane, src_plane, bytes_per_line);
151 src_plane += src_plane_stride; 249 src_plane += src_plane_stride;
152 dest_plane += dest_plane_stride; 250 dest_plane += dest_plane_stride;
153 } 251 }
154 } 252 }
155 253
254 void CopyRGB32Rect(const uint8* source_buffer,
255 int source_stride,
256 const SkIRect& source_buffer_rect,
257 uint8* dest_buffer,
258 int dest_stride,
259 const SkIRect& dest_buffer_rect,
260 const SkIRect& dest_rect) {
261 DCHECK(dest_buffer_rect.contains(dest_rect));
262 DCHECK(source_buffer_rect.contains(dest_rect));
263
264 // Get the address of the starting point.
265 int source_offset = CalculateRGBOffset(dest_rect.x() - source_buffer_rect.x(),
266 dest_rect.y() - source_buffer_rect.y(),
267 source_stride);
268 int dest_offset = CalculateRGBOffset(dest_rect.x() - dest_buffer_rect.x(),
269 dest_rect.y() - dest_buffer_rect.y(),
270 source_stride);
271
272 // Copy bits.
273 CopyRect(source_buffer + source_offset,
274 source_stride,
275 dest_buffer + dest_offset,
276 dest_stride,
277 GetBytesPerPixel(media::VideoFrame::RGB32),
278 SkIRect::MakeWH(dest_rect.width(), dest_rect.height()));
279 }
280
156 } // namespace remoting 281 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/base/util.h ('k') | remoting/base/util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698