| OLD | NEW |
| 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" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 } | 48 } |
| 49 | 49 |
| 50 static int CalculateYOffset(int x, int y, int stride) { | 50 static int CalculateYOffset(int x, int y, int stride) { |
| 51 return stride * y + x; | 51 return stride * y + x; |
| 52 } | 52 } |
| 53 | 53 |
| 54 static int CalculateUVOffset(int x, int y, int stride) { | 54 static int CalculateUVOffset(int x, int y, int stride) { |
| 55 return stride * y / 2 + x / 2; | 55 return stride * y / 2 + x / 2; |
| 56 } | 56 } |
| 57 | 57 |
| 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, | 58 void ConvertRGB32ToYUVWithRect(const uint8* rgb_plane, |
| 84 uint8* y_plane, | 59 uint8* y_plane, |
| 85 uint8* u_plane, | 60 uint8* u_plane, |
| 86 uint8* v_plane, | 61 uint8* v_plane, |
| 87 int x, | 62 int x, |
| 88 int y, | 63 int y, |
| 89 int width, | 64 int width, |
| 90 int height, | 65 int height, |
| 91 int rgb_stride, | 66 int rgb_stride, |
| 92 int y_stride, | 67 int y_stride, |
| 93 int uv_stride) { | 68 int uv_stride) { |
| 94 int rgb_offset = CalculateRGBOffset(x, y, rgb_stride); | 69 int rgb_offset = CalculateRGBOffset(x, y, rgb_stride); |
| 95 int y_offset = CalculateYOffset(x, y, y_stride); | 70 int y_offset = CalculateYOffset(x, y, y_stride); |
| 96 int uv_offset = CalculateUVOffset(x, y, uv_stride);; | 71 int uv_offset = CalculateUVOffset(x, y, uv_stride);; |
| 97 | 72 |
| 98 media::ConvertRGB32ToYUV(rgb_plane + rgb_offset, | 73 media::ConvertRGB32ToYUV(rgb_plane + rgb_offset, |
| 99 y_plane + y_offset, | 74 y_plane + y_offset, |
| 100 u_plane + uv_offset, | 75 u_plane + uv_offset, |
| 101 v_plane + uv_offset, | 76 v_plane + uv_offset, |
| 102 width, | 77 width, |
| 103 height, | 78 height, |
| 104 rgb_stride, | 79 rgb_stride, |
| 105 y_stride, | 80 y_stride, |
| 106 uv_stride); | 81 uv_stride); |
| 107 } | 82 } |
| 108 | 83 |
| 84 void ConvertAndScaleYUVToRGB32Rect(const uint8* source_yplane, |
| 85 const uint8* source_uplane, |
| 86 const uint8* source_vplane, |
| 87 int source_ystride, |
| 88 int source_uvstride, |
| 89 const SkISize& source_size, |
| 90 const SkIRect& source_clip, |
| 91 uint8* dest_buffer, |
| 92 int dest_stride, |
| 93 const SkISize& dest_size, |
| 94 const SkIRect& dest_clip, |
| 95 const SkIRect& dest_rect) { |
| 96 // N.B. It is caller's responsibility to check if strides are large enough. We |
| 97 // cannot do it here anyway. |
| 98 DCHECK(SkIRect::MakeSize(source_size).contains(source_clip)); |
| 99 DCHECK(SkIRect::MakeSize(dest_size).contains(dest_clip)); |
| 100 DCHECK(dest_clip.contains(dest_rect)); |
| 101 DCHECK(source_clip.contains(ScaleRect(dest_rect, dest_size, source_size))); |
| 102 |
| 103 // If the source and/or destination buffers don't start at (0, 0) |
| 104 // offset the pointers to pretend we have complete buffers. |
| 105 int y_offset = - CalculateYOffset(source_clip.x(), source_clip.y(), |
| 106 source_ystride); |
| 107 int uv_offset = - CalculateUVOffset(source_clip.x(), source_clip.y(), |
| 108 source_uvstride); |
| 109 int rgb_offset = - CalculateRGBOffset(dest_clip.x(), dest_clip.y(), |
| 110 dest_stride); |
| 111 |
| 112 // See if scaling is needed. |
| 113 if (source_size == dest_size) { |
| 114 DCHECK((dest_rect.x() & 1) == 0 && (dest_rect.y() & 1) == 0); |
| 115 |
| 116 y_offset += CalculateYOffset(dest_rect.left(), dest_rect.top(), |
| 117 source_ystride); |
| 118 uv_offset += CalculateUVOffset(dest_rect.left(), dest_rect.top(), |
| 119 source_uvstride); |
| 120 rgb_offset += CalculateRGBOffset(dest_rect.left(), dest_rect.top(), |
| 121 dest_stride); |
| 122 |
| 123 media::ConvertYUVToRGB32(source_yplane + y_offset, |
| 124 source_uplane + uv_offset, |
| 125 source_vplane + uv_offset, |
| 126 dest_buffer + rgb_offset, |
| 127 dest_rect.width(), |
| 128 dest_rect.height(), |
| 129 source_ystride, |
| 130 source_uvstride, |
| 131 dest_stride, |
| 132 media::YV12); |
| 133 } else { |
| 134 media::ScaleYUVToRGB32WithRect(source_yplane + y_offset, |
| 135 source_uplane + uv_offset, |
| 136 source_vplane + uv_offset, |
| 137 dest_buffer + rgb_offset, |
| 138 source_size.width(), |
| 139 source_size.height(), |
| 140 dest_size.width(), |
| 141 dest_size.height(), |
| 142 dest_rect.left(), |
| 143 dest_rect.top(), |
| 144 dest_rect.right(), |
| 145 dest_rect.bottom(), |
| 146 source_ystride, |
| 147 source_uvstride, |
| 148 dest_stride); |
| 149 } |
| 150 } |
| 151 |
| 109 int RoundToTwosMultiple(int x) { | 152 int RoundToTwosMultiple(int x) { |
| 110 return x & (~1); | 153 return x & (~1); |
| 111 } | 154 } |
| 112 | 155 |
| 113 SkIRect AlignRect(const SkIRect& rect) { | 156 SkIRect AlignRect(const SkIRect& rect) { |
| 114 int x = RoundToTwosMultiple(rect.left()); | 157 int x = RoundToTwosMultiple(rect.left()); |
| 115 int y = RoundToTwosMultiple(rect.top()); | 158 int y = RoundToTwosMultiple(rect.top()); |
| 116 int right = RoundToTwosMultiple(rect.right() + 1); | 159 int right = RoundToTwosMultiple(rect.right() + 1); |
| 117 int bottom = RoundToTwosMultiple(rect.bottom() + 1); | 160 int bottom = RoundToTwosMultiple(rect.bottom() + 1); |
| 118 return SkIRect::MakeLTRB(x, y, right, bottom); | 161 return SkIRect::MakeLTRB(x, y, right, bottom); |
| 119 } | 162 } |
| 120 | 163 |
| 121 SkIRect ScaleRect(const SkIRect& rect, | 164 SkIRect ScaleRect(const SkIRect& rect, |
| 122 const SkISize& in_size, | 165 const SkISize& in_size, |
| 123 const SkISize& out_size) { | 166 const SkISize& out_size) { |
| 124 int left = (rect.left() * out_size.width()) / in_size.width(); | 167 SkScalar scale_x = SkScalarDiv(out_size.width(), in_size.width()); |
| 125 int top = (rect.top() * out_size.height()) / in_size.height(); | 168 SkScalar scale_y = SkScalarDiv(out_size.height(), in_size.height()); |
| 126 int right = (rect.right() * out_size.width() + out_size.width() - 1) / | 169 |
| 127 in_size.width(); | 170 int left = SkScalarFloorToInt(scale_x * rect.left()); |
| 128 int bottom = (rect.bottom() * out_size.height() + out_size.height() - 1) / | 171 int top = SkScalarFloorToInt(scale_y * rect.top()); |
| 129 in_size.height(); | 172 int right = SkScalarCeilToInt(scale_x * rect.right()); |
| 173 int bottom = SkScalarCeilToInt(scale_y * rect.bottom()); |
| 130 return SkIRect::MakeLTRB(left, top, right, bottom); | 174 return SkIRect::MakeLTRB(left, top, right, bottom); |
| 131 } | 175 } |
| 132 | 176 |
| 133 void CopyRect(const uint8* src_plane, | 177 void CopyRect(const uint8* src_plane, |
| 134 int src_plane_stride, | 178 int src_plane_stride, |
| 135 uint8* dest_plane, | 179 uint8* dest_plane, |
| 136 int dest_plane_stride, | 180 int dest_plane_stride, |
| 137 int bytes_per_pixel, | 181 int bytes_per_pixel, |
| 138 const SkIRect& rect) { | 182 const SkIRect& rect) { |
| 139 // Get the address of the starting point. | 183 // Get the address of the starting point. |
| 140 const int src_y_offset = src_plane_stride * rect.top(); | 184 const int src_y_offset = src_plane_stride * rect.top(); |
| 141 const int dest_y_offset = dest_plane_stride * rect.top(); | 185 const int dest_y_offset = dest_plane_stride * rect.top(); |
| 142 const int x_offset = bytes_per_pixel * rect.left(); | 186 const int x_offset = bytes_per_pixel * rect.left(); |
| 143 src_plane += src_y_offset + x_offset; | 187 src_plane += src_y_offset + x_offset; |
| 144 dest_plane += dest_y_offset + x_offset; | 188 dest_plane += dest_y_offset + x_offset; |
| 145 | 189 |
| 146 // Copy pixels in the rectangle line by line. | 190 // Copy pixels in the rectangle line by line. |
| 147 const int bytes_per_line = bytes_per_pixel * rect.width(); | 191 const int bytes_per_line = bytes_per_pixel * rect.width(); |
| 148 const int height = rect.height(); | 192 const int height = rect.height(); |
| 149 for (int i = 0 ; i < height; ++i) { | 193 for (int i = 0 ; i < height; ++i) { |
| 150 memcpy(dest_plane, src_plane, bytes_per_line); | 194 memcpy(dest_plane, src_plane, bytes_per_line); |
| 151 src_plane += src_plane_stride; | 195 src_plane += src_plane_stride; |
| 152 dest_plane += dest_plane_stride; | 196 dest_plane += dest_plane_stride; |
| 153 } | 197 } |
| 154 } | 198 } |
| 155 | 199 |
| 200 void CopyRGB32Rect(const uint8* source_buffer, |
| 201 int source_stride, |
| 202 const SkIRect& source_clip, |
| 203 uint8* dest_buffer, |
| 204 int dest_stride, |
| 205 const SkIRect& dest_clip, |
| 206 const SkIRect& dest_rect) { |
| 207 DCHECK(dest_clip.contains(dest_rect)); |
| 208 DCHECK(source_clip.contains(dest_rect)); |
| 209 |
| 210 // Get the address of the starting point. |
| 211 int source_offset = CalculateRGBOffset(dest_rect.x() - source_clip.x(), |
| 212 dest_rect.y() - source_clip.y(), |
| 213 source_stride); |
| 214 int dest_offset = CalculateRGBOffset(dest_rect.x() - dest_clip.x(), |
| 215 dest_rect.y() - dest_clip.y(), |
| 216 source_stride); |
| 217 |
| 218 // Copy bits. |
| 219 CopyRect(source_buffer + source_offset, |
| 220 source_stride, |
| 221 dest_buffer + dest_offset, |
| 222 dest_stride, |
| 223 GetBytesPerPixel(media::VideoFrame::RGB32), |
| 224 SkIRect::MakeWH(dest_rect.width(), dest_rect.height())); |
| 225 } |
| 226 |
| 156 } // namespace remoting | 227 } // namespace remoting |
| OLD | NEW |