OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 InitializeColorBand(); | 69 InitializeColorBand(); |
70 } | 70 } |
71 | 71 |
72 virtual void SetUp() { | 72 virtual void SetUp() { |
73 dump_ = FLAG_planarfunctions_dump; | 73 dump_ = FLAG_planarfunctions_dump; |
74 repeat_ = FLAG_planarfunctions_repeat; | 74 repeat_ = FLAG_planarfunctions_repeat; |
75 } | 75 } |
76 | 76 |
77 // Initialize the color band for testing. | 77 // Initialize the color band for testing. |
78 void InitializeColorBand() { | 78 void InitializeColorBand() { |
79 testing_color_y_.reset(new uint8[kTestingColorNum]); | 79 testing_color_y_.reset(new uint8_t[kTestingColorNum]); |
80 testing_color_u_.reset(new uint8[kTestingColorNum]); | 80 testing_color_u_.reset(new uint8_t[kTestingColorNum]); |
81 testing_color_v_.reset(new uint8[kTestingColorNum]); | 81 testing_color_v_.reset(new uint8_t[kTestingColorNum]); |
82 testing_color_r_.reset(new uint8[kTestingColorNum]); | 82 testing_color_r_.reset(new uint8_t[kTestingColorNum]); |
83 testing_color_g_.reset(new uint8[kTestingColorNum]); | 83 testing_color_g_.reset(new uint8_t[kTestingColorNum]); |
84 testing_color_b_.reset(new uint8[kTestingColorNum]); | 84 testing_color_b_.reset(new uint8_t[kTestingColorNum]); |
85 int color_counter = 0; | 85 int color_counter = 0; |
86 for (int i = 0; i < kTestingColorChannelResolution; ++i) { | 86 for (int i = 0; i < kTestingColorChannelResolution; ++i) { |
87 uint8 color_r = static_cast<uint8>( | 87 uint8_t color_r = |
88 i * 255 / (kTestingColorChannelResolution - 1)); | 88 static_cast<uint8_t>(i * 255 / (kTestingColorChannelResolution - 1)); |
89 for (int j = 0; j < kTestingColorChannelResolution; ++j) { | 89 for (int j = 0; j < kTestingColorChannelResolution; ++j) { |
90 uint8 color_g = static_cast<uint8>( | 90 uint8_t color_g = static_cast<uint8_t>( |
91 j * 255 / (kTestingColorChannelResolution - 1)); | 91 j * 255 / (kTestingColorChannelResolution - 1)); |
92 for (int k = 0; k < kTestingColorChannelResolution; ++k) { | 92 for (int k = 0; k < kTestingColorChannelResolution; ++k) { |
93 uint8 color_b = static_cast<uint8>( | 93 uint8_t color_b = static_cast<uint8_t>( |
94 k * 255 / (kTestingColorChannelResolution - 1)); | 94 k * 255 / (kTestingColorChannelResolution - 1)); |
95 testing_color_r_[color_counter] = color_r; | 95 testing_color_r_[color_counter] = color_r; |
96 testing_color_g_[color_counter] = color_g; | 96 testing_color_g_[color_counter] = color_g; |
97 testing_color_b_[color_counter] = color_b; | 97 testing_color_b_[color_counter] = color_b; |
98 // Converting the testing RGB colors to YUV colors. | 98 // Converting the testing RGB colors to YUV colors. |
99 ConvertRgbPixel(color_r, color_g, color_b, | 99 ConvertRgbPixel(color_r, color_g, color_b, |
100 &(testing_color_y_[color_counter]), | 100 &(testing_color_y_[color_counter]), |
101 &(testing_color_u_[color_counter]), | 101 &(testing_color_u_[color_counter]), |
102 &(testing_color_v_[color_counter])); | 102 &(testing_color_v_[color_counter])); |
103 ++color_counter; | 103 ++color_counter; |
104 } | 104 } |
105 } | 105 } |
106 } | 106 } |
107 } | 107 } |
108 // Simple and slow RGB->YUV conversion. From NTSC standard, c/o Wikipedia. | 108 // Simple and slow RGB->YUV conversion. From NTSC standard, c/o Wikipedia. |
109 // (from lmivideoframe_unittest.cc) | 109 // (from lmivideoframe_unittest.cc) |
110 void ConvertRgbPixel(uint8 r, uint8 g, uint8 b, | 110 void ConvertRgbPixel(uint8_t r, |
111 uint8* y, uint8* u, uint8* v) { | 111 uint8_t g, |
| 112 uint8_t b, |
| 113 uint8_t* y, |
| 114 uint8_t* u, |
| 115 uint8_t* v) { |
112 *y = ClampUint8(.257 * r + .504 * g + .098 * b + 16); | 116 *y = ClampUint8(.257 * r + .504 * g + .098 * b + 16); |
113 *u = ClampUint8(-.148 * r - .291 * g + .439 * b + 128); | 117 *u = ClampUint8(-.148 * r - .291 * g + .439 * b + 128); |
114 *v = ClampUint8(.439 * r - .368 * g - .071 * b + 128); | 118 *v = ClampUint8(.439 * r - .368 * g - .071 * b + 128); |
115 } | 119 } |
116 | 120 |
117 uint8 ClampUint8(double value) { | 121 uint8_t ClampUint8(double value) { |
118 value = std::max(0., std::min(255., value)); | 122 value = std::max(0., std::min(255., value)); |
119 uint8 uint8_value = static_cast<uint8>(value); | 123 uint8_t uint8_value = static_cast<uint8_t>(value); |
120 return uint8_value; | 124 return uint8_value; |
121 } | 125 } |
122 | 126 |
123 // Generate a Red-Green-Blue inter-weaving chessboard-like | 127 // Generate a Red-Green-Blue inter-weaving chessboard-like |
124 // YUV testing image (I420/I422/I444). | 128 // YUV testing image (I420/I422/I444). |
125 // The pattern looks like c0 c1 c2 c3 ... | 129 // The pattern looks like c0 c1 c2 c3 ... |
126 // c1 c2 c3 c4 ... | 130 // c1 c2 c3 c4 ... |
127 // c2 c3 c4 c5 ... | 131 // c2 c3 c4 c5 ... |
128 // ............... | 132 // ............... |
129 // The size of each chrome block is (block_size) x (block_size). | 133 // The size of each chrome block is (block_size) x (block_size). |
130 uint8* CreateFakeYuvTestingImage(int height, int width, int block_size, | 134 uint8_t* CreateFakeYuvTestingImage(int height, |
131 libyuv::JpegSubsamplingType subsample_type, | 135 int width, |
132 uint8* &y_pointer, | 136 int block_size, |
133 uint8* &u_pointer, | 137 libyuv::JpegSubsamplingType subsample_type, |
134 uint8* &v_pointer) { | 138 uint8_t*& y_pointer, |
| 139 uint8_t*& u_pointer, |
| 140 uint8_t*& v_pointer) { |
135 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } | 141 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } |
136 int y_size = height * width; | 142 int y_size = height * width; |
137 int u_size, v_size; | 143 int u_size, v_size; |
138 int vertical_sample_ratio = 1, horizontal_sample_ratio = 1; | 144 int vertical_sample_ratio = 1, horizontal_sample_ratio = 1; |
139 switch (subsample_type) { | 145 switch (subsample_type) { |
140 case libyuv::kJpegYuv420: | 146 case libyuv::kJpegYuv420: |
141 u_size = ((height + 1) >> 1) * ((width + 1) >> 1); | 147 u_size = ((height + 1) >> 1) * ((width + 1) >> 1); |
142 v_size = u_size; | 148 v_size = u_size; |
143 vertical_sample_ratio = 2, horizontal_sample_ratio = 2; | 149 vertical_sample_ratio = 2, horizontal_sample_ratio = 2; |
144 break; | 150 break; |
145 case libyuv::kJpegYuv422: | 151 case libyuv::kJpegYuv422: |
146 u_size = height * ((width + 1) >> 1); | 152 u_size = height * ((width + 1) >> 1); |
147 v_size = u_size; | 153 v_size = u_size; |
148 vertical_sample_ratio = 1, horizontal_sample_ratio = 2; | 154 vertical_sample_ratio = 1, horizontal_sample_ratio = 2; |
149 break; | 155 break; |
150 case libyuv::kJpegYuv444: | 156 case libyuv::kJpegYuv444: |
151 v_size = u_size = y_size; | 157 v_size = u_size = y_size; |
152 vertical_sample_ratio = 1, horizontal_sample_ratio = 1; | 158 vertical_sample_ratio = 1, horizontal_sample_ratio = 1; |
153 break; | 159 break; |
154 case libyuv::kJpegUnknown: | 160 case libyuv::kJpegUnknown: |
155 default: | 161 default: |
156 return NULL; | 162 return NULL; |
157 break; | 163 break; |
158 } | 164 } |
159 uint8* image_pointer = new uint8[y_size + u_size + v_size + kAlignment]; | 165 uint8_t* image_pointer = new uint8_t[y_size + u_size + v_size + kAlignment]; |
160 y_pointer = ALIGNP(image_pointer, kAlignment); | 166 y_pointer = ALIGNP(image_pointer, kAlignment); |
161 u_pointer = ALIGNP(&image_pointer[y_size], kAlignment); | 167 u_pointer = ALIGNP(&image_pointer[y_size], kAlignment); |
162 v_pointer = ALIGNP(&image_pointer[y_size + u_size], kAlignment); | 168 v_pointer = ALIGNP(&image_pointer[y_size + u_size], kAlignment); |
163 uint8* current_y_pointer = y_pointer; | 169 uint8_t* current_y_pointer = y_pointer; |
164 uint8* current_u_pointer = u_pointer; | 170 uint8_t* current_u_pointer = u_pointer; |
165 uint8* current_v_pointer = v_pointer; | 171 uint8_t* current_v_pointer = v_pointer; |
166 for (int j = 0; j < height; ++j) { | 172 for (int j = 0; j < height; ++j) { |
167 for (int i = 0; i < width; ++i) { | 173 for (int i = 0; i < width; ++i) { |
168 int color = ((i / block_size) + (j / block_size)) % kTestingColorNum; | 174 int color = ((i / block_size) + (j / block_size)) % kTestingColorNum; |
169 *(current_y_pointer++) = testing_color_y_[color]; | 175 *(current_y_pointer++) = testing_color_y_[color]; |
170 if (i % horizontal_sample_ratio == 0 && | 176 if (i % horizontal_sample_ratio == 0 && |
171 j % vertical_sample_ratio == 0) { | 177 j % vertical_sample_ratio == 0) { |
172 *(current_u_pointer++) = testing_color_u_[color]; | 178 *(current_u_pointer++) = testing_color_u_[color]; |
173 *(current_v_pointer++) = testing_color_v_[color]; | 179 *(current_v_pointer++) = testing_color_v_[color]; |
174 } | 180 } |
175 } | 181 } |
176 } | 182 } |
177 return image_pointer; | 183 return image_pointer; |
178 } | 184 } |
179 | 185 |
180 // Generate a Red-Green-Blue inter-weaving chessboard-like | 186 // Generate a Red-Green-Blue inter-weaving chessboard-like |
181 // YUY2/UYVY testing image. | 187 // YUY2/UYVY testing image. |
182 // The pattern looks like c0 c1 c2 c3 ... | 188 // The pattern looks like c0 c1 c2 c3 ... |
183 // c1 c2 c3 c4 ... | 189 // c1 c2 c3 c4 ... |
184 // c2 c3 c4 c5 ... | 190 // c2 c3 c4 c5 ... |
185 // ............... | 191 // ............... |
186 // The size of each chrome block is (block_size) x (block_size). | 192 // The size of each chrome block is (block_size) x (block_size). |
187 uint8* CreateFakeInterleaveYuvTestingImage( | 193 uint8_t* CreateFakeInterleaveYuvTestingImage(int height, |
188 int height, int width, int block_size, | 194 int width, |
189 uint8* &yuv_pointer, FourCC fourcc_type) { | 195 int block_size, |
| 196 uint8_t*& yuv_pointer, |
| 197 FourCC fourcc_type) { |
190 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } | 198 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } |
191 if (fourcc_type != FOURCC_YUY2 && fourcc_type != FOURCC_UYVY) { | 199 if (fourcc_type != FOURCC_YUY2 && fourcc_type != FOURCC_UYVY) { |
192 LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type) | 200 LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type) |
193 << " is not supported."; | 201 << " is not supported."; |
194 return NULL; | 202 return NULL; |
195 } | 203 } |
196 // Regularize the width of the output to be even. | 204 // Regularize the width of the output to be even. |
197 int awidth = (width + 1) & ~1; | 205 int awidth = (width + 1) & ~1; |
198 | 206 |
199 uint8* image_pointer = new uint8[2 * height * awidth + kAlignment]; | 207 uint8_t* image_pointer = new uint8_t[2 * height * awidth + kAlignment]; |
200 yuv_pointer = ALIGNP(image_pointer, kAlignment); | 208 yuv_pointer = ALIGNP(image_pointer, kAlignment); |
201 uint8* current_yuv_pointer = yuv_pointer; | 209 uint8_t* current_yuv_pointer = yuv_pointer; |
202 switch (fourcc_type) { | 210 switch (fourcc_type) { |
203 case FOURCC_YUY2: { | 211 case FOURCC_YUY2: { |
204 for (int j = 0; j < height; ++j) { | 212 for (int j = 0; j < height; ++j) { |
205 for (int i = 0; i < awidth; i += 2, current_yuv_pointer += 4) { | 213 for (int i = 0; i < awidth; i += 2, current_yuv_pointer += 4) { |
206 int color1 = ((i / block_size) + (j / block_size)) % | 214 int color1 = ((i / block_size) + (j / block_size)) % |
207 kTestingColorNum; | 215 kTestingColorNum; |
208 int color2 = (((i + 1) / block_size) + (j / block_size)) % | 216 int color2 = (((i + 1) / block_size) + (j / block_size)) % |
209 kTestingColorNum; | 217 kTestingColorNum; |
210 current_yuv_pointer[0] = testing_color_y_[color1]; | 218 current_yuv_pointer[0] = testing_color_y_[color1]; |
211 if (i < width) { | 219 if (i < width) { |
212 current_yuv_pointer[1] = static_cast<uint8>( | 220 current_yuv_pointer[1] = static_cast<uint8_t>( |
213 (static_cast<uint32>(testing_color_u_[color1]) + | 221 (static_cast<uint32_t>(testing_color_u_[color1]) + |
214 static_cast<uint32>(testing_color_u_[color2])) / 2); | 222 static_cast<uint32_t>(testing_color_u_[color2])) / |
| 223 2); |
215 current_yuv_pointer[2] = testing_color_y_[color2]; | 224 current_yuv_pointer[2] = testing_color_y_[color2]; |
216 current_yuv_pointer[3] = static_cast<uint8>( | 225 current_yuv_pointer[3] = static_cast<uint8_t>( |
217 (static_cast<uint32>(testing_color_v_[color1]) + | 226 (static_cast<uint32_t>(testing_color_v_[color1]) + |
218 static_cast<uint32>(testing_color_v_[color2])) / 2); | 227 static_cast<uint32_t>(testing_color_v_[color2])) / |
| 228 2); |
219 } else { | 229 } else { |
220 current_yuv_pointer[1] = testing_color_u_[color1]; | 230 current_yuv_pointer[1] = testing_color_u_[color1]; |
221 current_yuv_pointer[2] = 0; | 231 current_yuv_pointer[2] = 0; |
222 current_yuv_pointer[3] = testing_color_v_[color1]; | 232 current_yuv_pointer[3] = testing_color_v_[color1]; |
223 } | 233 } |
224 } | 234 } |
225 } | 235 } |
226 break; | 236 break; |
227 } | 237 } |
228 case FOURCC_UYVY: { | 238 case FOURCC_UYVY: { |
229 for (int j = 0; j < height; ++j) { | 239 for (int j = 0; j < height; ++j) { |
230 for (int i = 0; i < awidth; i += 2, current_yuv_pointer += 4) { | 240 for (int i = 0; i < awidth; i += 2, current_yuv_pointer += 4) { |
231 int color1 = ((i / block_size) + (j / block_size)) % | 241 int color1 = ((i / block_size) + (j / block_size)) % |
232 kTestingColorNum; | 242 kTestingColorNum; |
233 int color2 = (((i + 1) / block_size) + (j / block_size)) % | 243 int color2 = (((i + 1) / block_size) + (j / block_size)) % |
234 kTestingColorNum; | 244 kTestingColorNum; |
235 if (i < width) { | 245 if (i < width) { |
236 current_yuv_pointer[0] = static_cast<uint8>( | 246 current_yuv_pointer[0] = static_cast<uint8_t>( |
237 (static_cast<uint32>(testing_color_u_[color1]) + | 247 (static_cast<uint32_t>(testing_color_u_[color1]) + |
238 static_cast<uint32>(testing_color_u_[color2])) / 2); | 248 static_cast<uint32_t>(testing_color_u_[color2])) / |
| 249 2); |
239 current_yuv_pointer[1] = testing_color_y_[color1]; | 250 current_yuv_pointer[1] = testing_color_y_[color1]; |
240 current_yuv_pointer[2] = static_cast<uint8>( | 251 current_yuv_pointer[2] = static_cast<uint8_t>( |
241 (static_cast<uint32>(testing_color_v_[color1]) + | 252 (static_cast<uint32_t>(testing_color_v_[color1]) + |
242 static_cast<uint32>(testing_color_v_[color2])) / 2); | 253 static_cast<uint32_t>(testing_color_v_[color2])) / |
| 254 2); |
243 current_yuv_pointer[3] = testing_color_y_[color2]; | 255 current_yuv_pointer[3] = testing_color_y_[color2]; |
244 } else { | 256 } else { |
245 current_yuv_pointer[0] = testing_color_u_[color1]; | 257 current_yuv_pointer[0] = testing_color_u_[color1]; |
246 current_yuv_pointer[1] = testing_color_y_[color1]; | 258 current_yuv_pointer[1] = testing_color_y_[color1]; |
247 current_yuv_pointer[2] = testing_color_v_[color1]; | 259 current_yuv_pointer[2] = testing_color_v_[color1]; |
248 current_yuv_pointer[3] = 0; | 260 current_yuv_pointer[3] = 0; |
249 } | 261 } |
250 } | 262 } |
251 } | 263 } |
252 break; | 264 break; |
253 } | 265 } |
254 } | 266 } |
255 return image_pointer; | 267 return image_pointer; |
256 } | 268 } |
257 | 269 |
258 // Generate a Red-Green-Blue inter-weaving chessboard-like | 270 // Generate a Red-Green-Blue inter-weaving chessboard-like |
259 // NV12 testing image. | 271 // NV12 testing image. |
260 // (Note: No interpolation is used.) | 272 // (Note: No interpolation is used.) |
261 // The pattern looks like c0 c1 c2 c3 ... | 273 // The pattern looks like c0 c1 c2 c3 ... |
262 // c1 c2 c3 c4 ... | 274 // c1 c2 c3 c4 ... |
263 // c2 c3 c4 c5 ... | 275 // c2 c3 c4 c5 ... |
264 // ............... | 276 // ............... |
265 // The size of each chrome block is (block_size) x (block_size). | 277 // The size of each chrome block is (block_size) x (block_size). |
266 uint8* CreateFakeNV12TestingImage(int height, int width, int block_size, | 278 uint8_t* CreateFakeNV12TestingImage(int height, |
267 uint8* &y_pointer, uint8* &uv_pointer) { | 279 int width, |
| 280 int block_size, |
| 281 uint8_t*& y_pointer, |
| 282 uint8_t*& uv_pointer) { |
268 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } | 283 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } |
269 | 284 |
270 uint8* image_pointer = new uint8[height * width + | 285 uint8_t* image_pointer = |
271 ((height + 1) / 2) * ((width + 1) / 2) * 2 + kAlignment]; | 286 new uint8_t[height * width + |
| 287 ((height + 1) / 2) * ((width + 1) / 2) * 2 + kAlignment]; |
272 y_pointer = ALIGNP(image_pointer, kAlignment); | 288 y_pointer = ALIGNP(image_pointer, kAlignment); |
273 uv_pointer = y_pointer + height * width; | 289 uv_pointer = y_pointer + height * width; |
274 uint8* current_uv_pointer = uv_pointer; | 290 uint8_t* current_uv_pointer = uv_pointer; |
275 uint8* current_y_pointer = y_pointer; | 291 uint8_t* current_y_pointer = y_pointer; |
276 for (int j = 0; j < height; ++j) { | 292 for (int j = 0; j < height; ++j) { |
277 for (int i = 0; i < width; ++i) { | 293 for (int i = 0; i < width; ++i) { |
278 int color = ((i / block_size) + (j / block_size)) % | 294 int color = ((i / block_size) + (j / block_size)) % |
279 kTestingColorNum; | 295 kTestingColorNum; |
280 *(current_y_pointer++) = testing_color_y_[color]; | 296 *(current_y_pointer++) = testing_color_y_[color]; |
281 } | 297 } |
282 if (j % 2 == 0) { | 298 if (j % 2 == 0) { |
283 for (int i = 0; i < width; i += 2, current_uv_pointer += 2) { | 299 for (int i = 0; i < width; i += 2, current_uv_pointer += 2) { |
284 int color = ((i / block_size) + (j / block_size)) % | 300 int color = ((i / block_size) + (j / block_size)) % |
285 kTestingColorNum; | 301 kTestingColorNum; |
286 current_uv_pointer[0] = testing_color_u_[color]; | 302 current_uv_pointer[0] = testing_color_u_[color]; |
287 current_uv_pointer[1] = testing_color_v_[color]; | 303 current_uv_pointer[1] = testing_color_v_[color]; |
288 } | 304 } |
289 } | 305 } |
290 } | 306 } |
291 return image_pointer; | 307 return image_pointer; |
292 } | 308 } |
293 | 309 |
294 // Generate a Red-Green-Blue inter-weaving chessboard-like | 310 // Generate a Red-Green-Blue inter-weaving chessboard-like |
295 // M420 testing image. | 311 // M420 testing image. |
296 // (Note: No interpolation is used.) | 312 // (Note: No interpolation is used.) |
297 // The pattern looks like c0 c1 c2 c3 ... | 313 // The pattern looks like c0 c1 c2 c3 ... |
298 // c1 c2 c3 c4 ... | 314 // c1 c2 c3 c4 ... |
299 // c2 c3 c4 c5 ... | 315 // c2 c3 c4 c5 ... |
300 // ............... | 316 // ............... |
301 // The size of each chrome block is (block_size) x (block_size). | 317 // The size of each chrome block is (block_size) x (block_size). |
302 uint8* CreateFakeM420TestingImage( | 318 uint8_t* CreateFakeM420TestingImage(int height, |
303 int height, int width, int block_size, uint8* &m420_pointer) { | 319 int width, |
| 320 int block_size, |
| 321 uint8_t*& m420_pointer) { |
304 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } | 322 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } |
305 | 323 |
306 uint8* image_pointer = new uint8[height * width + | 324 uint8_t* image_pointer = |
307 ((height + 1) / 2) * ((width + 1) / 2) * 2 + kAlignment]; | 325 new uint8_t[height * width + |
| 326 ((height + 1) / 2) * ((width + 1) / 2) * 2 + kAlignment]; |
308 m420_pointer = ALIGNP(image_pointer, kAlignment); | 327 m420_pointer = ALIGNP(image_pointer, kAlignment); |
309 uint8* current_m420_pointer = m420_pointer; | 328 uint8_t* current_m420_pointer = m420_pointer; |
310 for (int j = 0; j < height; ++j) { | 329 for (int j = 0; j < height; ++j) { |
311 for (int i = 0; i < width; ++i) { | 330 for (int i = 0; i < width; ++i) { |
312 int color = ((i / block_size) + (j / block_size)) % | 331 int color = ((i / block_size) + (j / block_size)) % |
313 kTestingColorNum; | 332 kTestingColorNum; |
314 *(current_m420_pointer++) = testing_color_y_[color]; | 333 *(current_m420_pointer++) = testing_color_y_[color]; |
315 } | 334 } |
316 if (j % 2 == 1) { | 335 if (j % 2 == 1) { |
317 for (int i = 0; i < width; i += 2, current_m420_pointer += 2) { | 336 for (int i = 0; i < width; i += 2, current_m420_pointer += 2) { |
318 int color = ((i / block_size) + ((j - 1) / block_size)) % | 337 int color = ((i / block_size) + ((j - 1) / block_size)) % |
319 kTestingColorNum; | 338 kTestingColorNum; |
320 current_m420_pointer[0] = testing_color_u_[color]; | 339 current_m420_pointer[0] = testing_color_u_[color]; |
321 current_m420_pointer[1] = testing_color_v_[color]; | 340 current_m420_pointer[1] = testing_color_v_[color]; |
322 } | 341 } |
323 } | 342 } |
324 } | 343 } |
325 return image_pointer; | 344 return image_pointer; |
326 } | 345 } |
327 | 346 |
328 // Generate a Red-Green-Blue inter-weaving chessboard-like | 347 // Generate a Red-Green-Blue inter-weaving chessboard-like |
329 // ARGB/ABGR/RAW/BG24 testing image. | 348 // ARGB/ABGR/RAW/BG24 testing image. |
330 // The pattern looks like c0 c1 c2 c3 ... | 349 // The pattern looks like c0 c1 c2 c3 ... |
331 // c1 c2 c3 c4 ... | 350 // c1 c2 c3 c4 ... |
332 // c2 c3 c4 c5 ... | 351 // c2 c3 c4 c5 ... |
333 // ............... | 352 // ............... |
334 // The size of each chrome block is (block_size) x (block_size). | 353 // The size of each chrome block is (block_size) x (block_size). |
335 uint8* CreateFakeArgbTestingImage(int height, int width, int block_size, | 354 uint8_t* CreateFakeArgbTestingImage(int height, |
336 uint8* &argb_pointer, FourCC fourcc_type) { | 355 int width, |
| 356 int block_size, |
| 357 uint8_t*& argb_pointer, |
| 358 FourCC fourcc_type) { |
337 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } | 359 if (height <= 0 || width <= 0 || block_size <= 0) { return NULL; } |
338 uint8* image_pointer = NULL; | 360 uint8_t* image_pointer = NULL; |
339 if (fourcc_type == FOURCC_ABGR || fourcc_type == FOURCC_BGRA || | 361 if (fourcc_type == FOURCC_ABGR || fourcc_type == FOURCC_BGRA || |
340 fourcc_type == FOURCC_ARGB) { | 362 fourcc_type == FOURCC_ARGB) { |
341 image_pointer = new uint8[height * width * 4 + kAlignment]; | 363 image_pointer = new uint8_t[height * width * 4 + kAlignment]; |
342 } else if (fourcc_type == FOURCC_RAW || fourcc_type == FOURCC_24BG) { | 364 } else if (fourcc_type == FOURCC_RAW || fourcc_type == FOURCC_24BG) { |
343 image_pointer = new uint8[height * width * 3 + kAlignment]; | 365 image_pointer = new uint8_t[height * width * 3 + kAlignment]; |
344 } else { | 366 } else { |
345 LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type) | 367 LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type) |
346 << " is not supported."; | 368 << " is not supported."; |
347 return NULL; | 369 return NULL; |
348 } | 370 } |
349 argb_pointer = ALIGNP(image_pointer, kAlignment); | 371 argb_pointer = ALIGNP(image_pointer, kAlignment); |
350 uint8* current_pointer = argb_pointer; | 372 uint8_t* current_pointer = argb_pointer; |
351 switch (fourcc_type) { | 373 switch (fourcc_type) { |
352 case FOURCC_ARGB: { | 374 case FOURCC_ARGB: { |
353 for (int j = 0; j < height; ++j) { | 375 for (int j = 0; j < height; ++j) { |
354 for (int i = 0; i < width; ++i) { | 376 for (int i = 0; i < width; ++i) { |
355 int color = ((i / block_size) + (j / block_size)) % | 377 int color = ((i / block_size) + (j / block_size)) % |
356 kTestingColorNum; | 378 kTestingColorNum; |
357 *(current_pointer++) = testing_color_b_[color]; | 379 *(current_pointer++) = testing_color_b_[color]; |
358 *(current_pointer++) = testing_color_g_[color]; | 380 *(current_pointer++) = testing_color_g_[color]; |
359 *(current_pointer++) = testing_color_r_[color]; | 381 *(current_pointer++) = testing_color_r_[color]; |
360 *(current_pointer++) = 255; | 382 *(current_pointer++) = 255; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 default: { | 437 default: { |
416 LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type) | 438 LOG(LS_ERROR) << "Format " << static_cast<int>(fourcc_type) |
417 << " is not supported."; | 439 << " is not supported."; |
418 } | 440 } |
419 } | 441 } |
420 return image_pointer; | 442 return image_pointer; |
421 } | 443 } |
422 | 444 |
423 // Check if two memory chunks are equal. | 445 // Check if two memory chunks are equal. |
424 // (tolerate MSE errors within a threshold). | 446 // (tolerate MSE errors within a threshold). |
425 static bool IsMemoryEqual(const uint8* ibuf, const uint8* obuf, | 447 static bool IsMemoryEqual(const uint8_t* ibuf, |
426 int osize, double average_error) { | 448 const uint8_t* obuf, |
| 449 int osize, |
| 450 double average_error) { |
427 double sse = cricket::ComputeSumSquareError(ibuf, obuf, osize); | 451 double sse = cricket::ComputeSumSquareError(ibuf, obuf, osize); |
428 double error = sse / osize; // Mean Squared Error. | 452 double error = sse / osize; // Mean Squared Error. |
429 double PSNR = cricket::ComputePSNR(sse, osize); | 453 double PSNR = cricket::ComputePSNR(sse, osize); |
430 LOG(LS_INFO) << "Image MSE: " << error << " Image PSNR: " << PSNR | 454 LOG(LS_INFO) << "Image MSE: " << error << " Image PSNR: " << PSNR |
431 << " First Diff Byte: " << FindDiff(ibuf, obuf, osize); | 455 << " First Diff Byte: " << FindDiff(ibuf, obuf, osize); |
432 return (error < average_error); | 456 return (error < average_error); |
433 } | 457 } |
434 | 458 |
435 // Returns the index of the first differing byte. Easier to debug than memcmp. | 459 // Returns the index of the first differing byte. Easier to debug than memcmp. |
436 static int FindDiff(const uint8* buf1, const uint8* buf2, int len) { | 460 static int FindDiff(const uint8_t* buf1, const uint8_t* buf2, int len) { |
437 int i = 0; | 461 int i = 0; |
438 while (i < len && buf1[i] == buf2[i]) { | 462 while (i < len && buf1[i] == buf2[i]) { |
439 i++; | 463 i++; |
440 } | 464 } |
441 return (i < len) ? i : -1; | 465 return (i < len) ? i : -1; |
442 } | 466 } |
443 | 467 |
444 // Dump the result image (ARGB format). | 468 // Dump the result image (ARGB format). |
445 void DumpArgbImage(const uint8* obuf, int width, int height) { | 469 void DumpArgbImage(const uint8_t* obuf, int width, int height) { |
446 DumpPlanarArgbTestImage(GetTestName(), obuf, width, height); | 470 DumpPlanarArgbTestImage(GetTestName(), obuf, width, height); |
447 } | 471 } |
448 | 472 |
449 // Dump the result image (YUV420 format). | 473 // Dump the result image (YUV420 format). |
450 void DumpYuvImage(const uint8* obuf, int width, int height) { | 474 void DumpYuvImage(const uint8_t* obuf, int width, int height) { |
451 DumpPlanarYuvTestImage(GetTestName(), obuf, width, height); | 475 DumpPlanarYuvTestImage(GetTestName(), obuf, width, height); |
452 } | 476 } |
453 | 477 |
454 std::string GetTestName() { | 478 std::string GetTestName() { |
455 const testing::TestInfo* const test_info = | 479 const testing::TestInfo* const test_info = |
456 testing::UnitTest::GetInstance()->current_test_info(); | 480 testing::UnitTest::GetInstance()->current_test_info(); |
457 std::string test_name(test_info->name()); | 481 std::string test_name(test_info->name()); |
458 return test_name; | 482 return test_name; |
459 } | 483 } |
460 | 484 |
461 bool dump_; | 485 bool dump_; |
462 int repeat_; | 486 int repeat_; |
463 | 487 |
464 // Y, U, V and R, G, B channels of testing colors. | 488 // Y, U, V and R, G, B channels of testing colors. |
465 rtc::scoped_ptr<uint8[]> testing_color_y_; | 489 rtc::scoped_ptr<uint8_t[]> testing_color_y_; |
466 rtc::scoped_ptr<uint8[]> testing_color_u_; | 490 rtc::scoped_ptr<uint8_t[]> testing_color_u_; |
467 rtc::scoped_ptr<uint8[]> testing_color_v_; | 491 rtc::scoped_ptr<uint8_t[]> testing_color_v_; |
468 rtc::scoped_ptr<uint8[]> testing_color_r_; | 492 rtc::scoped_ptr<uint8_t[]> testing_color_r_; |
469 rtc::scoped_ptr<uint8[]> testing_color_g_; | 493 rtc::scoped_ptr<uint8_t[]> testing_color_g_; |
470 rtc::scoped_ptr<uint8[]> testing_color_b_; | 494 rtc::scoped_ptr<uint8_t[]> testing_color_b_; |
471 }; | 495 }; |
472 | 496 |
473 TEST_F(PlanarFunctionsTest, I420Copy) { | 497 TEST_F(PlanarFunctionsTest, I420Copy) { |
474 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 498 uint8_t* y_pointer = nullptr; |
| 499 uint8_t* u_pointer = nullptr; |
| 500 uint8_t* v_pointer = nullptr; |
475 int y_pitch = kWidth; | 501 int y_pitch = kWidth; |
476 int u_pitch = (kWidth + 1) >> 1; | 502 int u_pitch = (kWidth + 1) >> 1; |
477 int v_pitch = (kWidth + 1) >> 1; | 503 int v_pitch = (kWidth + 1) >> 1; |
478 int y_size = kHeight * kWidth; | 504 int y_size = kHeight * kWidth; |
479 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 505 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
480 int block_size = 3; | 506 int block_size = 3; |
481 // Generate a fake input image. | 507 // Generate a fake input image. |
482 rtc::scoped_ptr<uint8[]> yuv_input( | 508 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
483 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 509 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
484 libyuv::kJpegYuv420, | 510 v_pointer)); |
485 y_pointer, u_pointer, v_pointer)); | |
486 // Allocate space for the output image. | 511 // Allocate space for the output image. |
487 rtc::scoped_ptr<uint8[]> yuv_output( | 512 rtc::scoped_ptr<uint8_t[]> yuv_output( |
488 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment]); | 513 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment]); |
489 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); | 514 uint8_t* y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); |
490 uint8 *u_output_pointer = y_output_pointer + y_size; | 515 uint8_t* u_output_pointer = y_output_pointer + y_size; |
491 uint8 *v_output_pointer = u_output_pointer + uv_size; | 516 uint8_t* v_output_pointer = u_output_pointer + uv_size; |
492 | 517 |
493 for (int i = 0; i < repeat_; ++i) { | 518 for (int i = 0; i < repeat_; ++i) { |
494 libyuv::I420Copy(y_pointer, y_pitch, | 519 libyuv::I420Copy(y_pointer, y_pitch, |
495 u_pointer, u_pitch, | 520 u_pointer, u_pitch, |
496 v_pointer, v_pitch, | 521 v_pointer, v_pitch, |
497 y_output_pointer, y_pitch, | 522 y_output_pointer, y_pitch, |
498 u_output_pointer, u_pitch, | 523 u_output_pointer, u_pitch, |
499 v_output_pointer, v_pitch, | 524 v_output_pointer, v_pitch, |
500 kWidth, kHeight); | 525 kWidth, kHeight); |
501 } | 526 } |
502 | 527 |
503 // Expect the copied frame to be exactly the same. | 528 // Expect the copied frame to be exactly the same. |
504 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, | 529 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, |
505 I420_SIZE(kHeight, kWidth), 1.e-6)); | 530 I420_SIZE(kHeight, kWidth), 1.e-6)); |
506 | 531 |
507 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 532 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
508 } | 533 } |
509 | 534 |
510 TEST_F(PlanarFunctionsTest, I422ToI420) { | 535 TEST_F(PlanarFunctionsTest, I422ToI420) { |
511 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 536 uint8_t* y_pointer = nullptr; |
| 537 uint8_t* u_pointer = nullptr; |
| 538 uint8_t* v_pointer = nullptr; |
512 int y_pitch = kWidth; | 539 int y_pitch = kWidth; |
513 int u_pitch = (kWidth + 1) >> 1; | 540 int u_pitch = (kWidth + 1) >> 1; |
514 int v_pitch = (kWidth + 1) >> 1; | 541 int v_pitch = (kWidth + 1) >> 1; |
515 int y_size = kHeight * kWidth; | 542 int y_size = kHeight * kWidth; |
516 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 543 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
517 int block_size = 2; | 544 int block_size = 2; |
518 // Generate a fake input image. | 545 // Generate a fake input image. |
519 rtc::scoped_ptr<uint8[]> yuv_input( | 546 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
520 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 547 kHeight, kWidth, block_size, libyuv::kJpegYuv422, y_pointer, u_pointer, |
521 libyuv::kJpegYuv422, | 548 v_pointer)); |
522 y_pointer, u_pointer, v_pointer)); | |
523 // Allocate space for the output image. | 549 // Allocate space for the output image. |
524 rtc::scoped_ptr<uint8[]> yuv_output( | 550 rtc::scoped_ptr<uint8_t[]> yuv_output( |
525 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment]); | 551 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment]); |
526 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); | 552 uint8_t* y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); |
527 uint8 *u_output_pointer = y_output_pointer + y_size; | 553 uint8_t* u_output_pointer = y_output_pointer + y_size; |
528 uint8 *v_output_pointer = u_output_pointer + uv_size; | 554 uint8_t* v_output_pointer = u_output_pointer + uv_size; |
529 // Generate the expected output. | 555 // Generate the expected output. |
530 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, | 556 uint8_t* y_expected_pointer = nullptr; |
531 *v_expected_pointer = NULL; | 557 uint8_t* u_expected_pointer = nullptr; |
532 rtc::scoped_ptr<uint8[]> yuv_output_expected( | 558 uint8_t* v_expected_pointer = nullptr; |
533 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 559 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( |
534 libyuv::kJpegYuv420, | 560 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, |
535 y_expected_pointer, u_expected_pointer, v_expected_pointer)); | 561 u_expected_pointer, v_expected_pointer)); |
536 | 562 |
537 for (int i = 0; i < repeat_; ++i) { | 563 for (int i = 0; i < repeat_; ++i) { |
538 libyuv::I422ToI420(y_pointer, y_pitch, | 564 libyuv::I422ToI420(y_pointer, y_pitch, |
539 u_pointer, u_pitch, | 565 u_pointer, u_pitch, |
540 v_pointer, v_pitch, | 566 v_pointer, v_pitch, |
541 y_output_pointer, y_pitch, | 567 y_output_pointer, y_pitch, |
542 u_output_pointer, u_pitch, | 568 u_output_pointer, u_pitch, |
543 v_output_pointer, v_pitch, | 569 v_output_pointer, v_pitch, |
544 kWidth, kHeight); | 570 kWidth, kHeight); |
545 } | 571 } |
546 | 572 |
547 // Compare the output frame with what is expected; expect exactly the same. | 573 // Compare the output frame with what is expected; expect exactly the same. |
548 // Note: MSE should be set to a larger threshold if an odd block width | 574 // Note: MSE should be set to a larger threshold if an odd block width |
549 // is used, since the conversion will be lossy. | 575 // is used, since the conversion will be lossy. |
550 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, | 576 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, |
551 I420_SIZE(kHeight, kWidth), 1.e-6)); | 577 I420_SIZE(kHeight, kWidth), 1.e-6)); |
552 | 578 |
553 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 579 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
554 } | 580 } |
555 | 581 |
556 TEST_P(PlanarFunctionsTest, M420ToI420) { | 582 TEST_P(PlanarFunctionsTest, M420ToI420) { |
557 // Get the unalignment offset | 583 // Get the unalignment offset |
558 int unalignment = GetParam(); | 584 int unalignment = GetParam(); |
559 uint8 *m420_pointer = NULL; | 585 uint8_t* m420_pointer = NULL; |
560 int y_pitch = kWidth; | 586 int y_pitch = kWidth; |
561 int m420_pitch = kWidth; | 587 int m420_pitch = kWidth; |
562 int u_pitch = (kWidth + 1) >> 1; | 588 int u_pitch = (kWidth + 1) >> 1; |
563 int v_pitch = (kWidth + 1) >> 1; | 589 int v_pitch = (kWidth + 1) >> 1; |
564 int y_size = kHeight * kWidth; | 590 int y_size = kHeight * kWidth; |
565 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 591 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
566 int block_size = 2; | 592 int block_size = 2; |
567 // Generate a fake input image. | 593 // Generate a fake input image. |
568 rtc::scoped_ptr<uint8[]> yuv_input( | 594 rtc::scoped_ptr<uint8_t[]> yuv_input( |
569 CreateFakeM420TestingImage(kHeight, kWidth, block_size, m420_pointer)); | 595 CreateFakeM420TestingImage(kHeight, kWidth, block_size, m420_pointer)); |
570 // Allocate space for the output image. | 596 // Allocate space for the output image. |
571 rtc::scoped_ptr<uint8[]> yuv_output( | 597 rtc::scoped_ptr<uint8_t[]> yuv_output( |
572 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); | 598 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); |
573 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment) + unalignment; | 599 uint8_t* y_output_pointer = |
574 uint8 *u_output_pointer = y_output_pointer + y_size; | 600 ALIGNP(yuv_output.get(), kAlignment) + unalignment; |
575 uint8 *v_output_pointer = u_output_pointer + uv_size; | 601 uint8_t* u_output_pointer = y_output_pointer + y_size; |
| 602 uint8_t* v_output_pointer = u_output_pointer + uv_size; |
576 // Generate the expected output. | 603 // Generate the expected output. |
577 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, | 604 uint8_t* y_expected_pointer = nullptr; |
578 *v_expected_pointer = NULL; | 605 uint8_t* u_expected_pointer = nullptr; |
579 rtc::scoped_ptr<uint8[]> yuv_output_expected( | 606 uint8_t* v_expected_pointer = nullptr; |
580 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 607 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( |
581 libyuv::kJpegYuv420, | 608 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, |
582 y_expected_pointer, u_expected_pointer, v_expected_pointer)); | 609 u_expected_pointer, v_expected_pointer)); |
583 | 610 |
584 for (int i = 0; i < repeat_; ++i) { | 611 for (int i = 0; i < repeat_; ++i) { |
585 libyuv::M420ToI420(m420_pointer, m420_pitch, | 612 libyuv::M420ToI420(m420_pointer, m420_pitch, |
586 y_output_pointer, y_pitch, | 613 y_output_pointer, y_pitch, |
587 u_output_pointer, u_pitch, | 614 u_output_pointer, u_pitch, |
588 v_output_pointer, v_pitch, | 615 v_output_pointer, v_pitch, |
589 kWidth, kHeight); | 616 kWidth, kHeight); |
590 } | 617 } |
591 // Compare the output frame with what is expected; expect exactly the same. | 618 // Compare the output frame with what is expected; expect exactly the same. |
592 // Note: MSE should be set to a larger threshold if an odd block width | 619 // Note: MSE should be set to a larger threshold if an odd block width |
593 // is used, since the conversion will be lossy. | 620 // is used, since the conversion will be lossy. |
594 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, | 621 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, |
595 I420_SIZE(kHeight, kWidth), 1.e-6)); | 622 I420_SIZE(kHeight, kWidth), 1.e-6)); |
596 | 623 |
597 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 624 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
598 } | 625 } |
599 | 626 |
600 TEST_P(PlanarFunctionsTest, NV12ToI420) { | 627 TEST_P(PlanarFunctionsTest, NV12ToI420) { |
601 // Get the unalignment offset | 628 // Get the unalignment offset |
602 int unalignment = GetParam(); | 629 int unalignment = GetParam(); |
603 uint8 *y_pointer = NULL, *uv_pointer = NULL; | 630 uint8_t* y_pointer = nullptr; |
| 631 uint8_t* uv_pointer = nullptr; |
604 int y_pitch = kWidth; | 632 int y_pitch = kWidth; |
605 int uv_pitch = 2 * ((kWidth + 1) >> 1); | 633 int uv_pitch = 2 * ((kWidth + 1) >> 1); |
606 int u_pitch = (kWidth + 1) >> 1; | 634 int u_pitch = (kWidth + 1) >> 1; |
607 int v_pitch = (kWidth + 1) >> 1; | 635 int v_pitch = (kWidth + 1) >> 1; |
608 int y_size = kHeight * kWidth; | 636 int y_size = kHeight * kWidth; |
609 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 637 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
610 int block_size = 2; | 638 int block_size = 2; |
611 // Generate a fake input image. | 639 // Generate a fake input image. |
612 rtc::scoped_ptr<uint8[]> yuv_input( | 640 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeNV12TestingImage( |
613 CreateFakeNV12TestingImage(kHeight, kWidth, block_size, | 641 kHeight, kWidth, block_size, y_pointer, uv_pointer)); |
614 y_pointer, uv_pointer)); | |
615 // Allocate space for the output image. | 642 // Allocate space for the output image. |
616 rtc::scoped_ptr<uint8[]> yuv_output( | 643 rtc::scoped_ptr<uint8_t[]> yuv_output( |
617 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); | 644 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); |
618 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment) + unalignment; | 645 uint8_t* y_output_pointer = |
619 uint8 *u_output_pointer = y_output_pointer + y_size; | 646 ALIGNP(yuv_output.get(), kAlignment) + unalignment; |
620 uint8 *v_output_pointer = u_output_pointer + uv_size; | 647 uint8_t* u_output_pointer = y_output_pointer + y_size; |
| 648 uint8_t* v_output_pointer = u_output_pointer + uv_size; |
621 // Generate the expected output. | 649 // Generate the expected output. |
622 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, | 650 uint8_t* y_expected_pointer = nullptr; |
623 *v_expected_pointer = NULL; | 651 uint8_t* u_expected_pointer = nullptr; |
624 rtc::scoped_ptr<uint8[]> yuv_output_expected( | 652 uint8_t* v_expected_pointer = nullptr; |
625 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 653 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( |
626 libyuv::kJpegYuv420, | 654 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, |
627 y_expected_pointer, u_expected_pointer, v_expected_pointer)); | 655 u_expected_pointer, v_expected_pointer)); |
628 | 656 |
629 for (int i = 0; i < repeat_; ++i) { | 657 for (int i = 0; i < repeat_; ++i) { |
630 libyuv::NV12ToI420(y_pointer, y_pitch, | 658 libyuv::NV12ToI420(y_pointer, y_pitch, |
631 uv_pointer, uv_pitch, | 659 uv_pointer, uv_pitch, |
632 y_output_pointer, y_pitch, | 660 y_output_pointer, y_pitch, |
633 u_output_pointer, u_pitch, | 661 u_output_pointer, u_pitch, |
634 v_output_pointer, v_pitch, | 662 v_output_pointer, v_pitch, |
635 kWidth, kHeight); | 663 kWidth, kHeight); |
636 } | 664 } |
637 // Compare the output frame with what is expected; expect exactly the same. | 665 // Compare the output frame with what is expected; expect exactly the same. |
638 // Note: MSE should be set to a larger threshold if an odd block width | 666 // Note: MSE should be set to a larger threshold if an odd block width |
639 // is used, since the conversion will be lossy. | 667 // is used, since the conversion will be lossy. |
640 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, | 668 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, |
641 I420_SIZE(kHeight, kWidth), 1.e-6)); | 669 I420_SIZE(kHeight, kWidth), 1.e-6)); |
642 | 670 |
643 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 671 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
644 } | 672 } |
645 | 673 |
646 // A common macro for testing converting YUY2/UYVY to I420. | 674 // A common macro for testing converting YUY2/UYVY to I420. |
647 #define TEST_YUVTOI420(SRC_NAME, MSE, BLOCK_SIZE) \ | 675 #define TEST_YUVTOI420(SRC_NAME, MSE, BLOCK_SIZE) \ |
648 TEST_P(PlanarFunctionsTest, SRC_NAME##ToI420) { \ | 676 TEST_P(PlanarFunctionsTest, SRC_NAME##ToI420) { \ |
649 /* Get the unalignment offset.*/ \ | 677 /* Get the unalignment offset.*/ \ |
650 int unalignment = GetParam(); \ | 678 int unalignment = GetParam(); \ |
651 uint8 *yuv_pointer = NULL; \ | 679 uint8_t* yuv_pointer = nullptr; \ |
652 int yuv_pitch = 2 * ((kWidth + 1) & ~1); \ | 680 int yuv_pitch = 2 * ((kWidth + 1) & ~1); \ |
653 int y_pitch = kWidth; \ | 681 int y_pitch = kWidth; \ |
654 int u_pitch = (kWidth + 1) >> 1; \ | 682 int u_pitch = (kWidth + 1) >> 1; \ |
655 int v_pitch = (kWidth + 1) >> 1; \ | 683 int v_pitch = (kWidth + 1) >> 1; \ |
656 int y_size = kHeight * kWidth; \ | 684 int y_size = kHeight * kWidth; \ |
657 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); \ | 685 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); \ |
658 int block_size = 2; \ | 686 int block_size = 2; \ |
659 /* Generate a fake input image.*/ \ | 687 /* Generate a fake input image.*/ \ |
660 rtc::scoped_ptr<uint8[]> yuv_input( \ | 688 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeInterleaveYuvTestingImage( \ |
661 CreateFakeInterleaveYuvTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 689 kHeight, kWidth, BLOCK_SIZE, yuv_pointer, FOURCC_##SRC_NAME)); \ |
662 yuv_pointer, FOURCC_##SRC_NAME)); \ | 690 /* Allocate space for the output image.*/ \ |
663 /* Allocate space for the output image.*/ \ | 691 rtc::scoped_ptr<uint8_t[]> yuv_output( \ |
664 rtc::scoped_ptr<uint8[]> yuv_output( \ | 692 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); \ |
665 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); \ | 693 uint8_t* y_output_pointer = \ |
666 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment) + \ | 694 ALIGNP(yuv_output.get(), kAlignment) + unalignment; \ |
667 unalignment; \ | 695 uint8_t* u_output_pointer = y_output_pointer + y_size; \ |
668 uint8 *u_output_pointer = y_output_pointer + y_size; \ | 696 uint8_t* v_output_pointer = u_output_pointer + uv_size; \ |
669 uint8 *v_output_pointer = u_output_pointer + uv_size; \ | 697 /* Generate the expected output.*/ \ |
670 /* Generate the expected output.*/ \ | 698 uint8_t* y_expected_pointer = nullptr; \ |
671 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, \ | 699 uint8_t* u_expected_pointer = nullptr; \ |
672 *v_expected_pointer = NULL; \ | 700 uint8_t* v_expected_pointer = nullptr; \ |
673 rtc::scoped_ptr<uint8[]> yuv_output_expected( \ | 701 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( \ |
674 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, \ | 702 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, \ |
675 libyuv::kJpegYuv420, \ | 703 u_expected_pointer, v_expected_pointer)); \ |
676 y_expected_pointer, u_expected_pointer, v_expected_pointer)); \ | 704 for (int i = 0; i < repeat_; ++i) { \ |
677 for (int i = 0; i < repeat_; ++i) { \ | 705 libyuv::SRC_NAME##ToI420(yuv_pointer, yuv_pitch, y_output_pointer, \ |
678 libyuv::SRC_NAME##ToI420(yuv_pointer, yuv_pitch, \ | 706 y_pitch, u_output_pointer, u_pitch, \ |
679 y_output_pointer, y_pitch, \ | 707 v_output_pointer, v_pitch, kWidth, kHeight); \ |
680 u_output_pointer, u_pitch, \ | 708 } \ |
681 v_output_pointer, v_pitch, \ | 709 /* Compare the output frame with what is expected.*/ \ |
682 kWidth, kHeight); \ | 710 /* Note: MSE should be set to a larger threshold if an odd block width*/ \ |
683 } \ | 711 /* is used, since the conversion will be lossy.*/ \ |
684 /* Compare the output frame with what is expected.*/ \ | 712 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, \ |
685 /* Note: MSE should be set to a larger threshold if an odd block width*/ \ | 713 I420_SIZE(kHeight, kWidth), MSE)); \ |
686 /* is used, since the conversion will be lossy.*/ \ | 714 if (dump_) { \ |
687 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, \ | 715 DumpYuvImage(y_output_pointer, kWidth, kHeight); \ |
688 I420_SIZE(kHeight, kWidth), MSE)); \ | 716 } \ |
689 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } \ | 717 } |
690 } \ | |
691 | 718 |
692 // TEST_P(PlanarFunctionsTest, YUV2ToI420) | 719 // TEST_P(PlanarFunctionsTest, YUV2ToI420) |
693 TEST_YUVTOI420(YUY2, 1.e-6, 2); | 720 TEST_YUVTOI420(YUY2, 1.e-6, 2); |
694 // TEST_P(PlanarFunctionsTest, UYVYToI420) | 721 // TEST_P(PlanarFunctionsTest, UYVYToI420) |
695 TEST_YUVTOI420(UYVY, 1.e-6, 2); | 722 TEST_YUVTOI420(UYVY, 1.e-6, 2); |
696 | 723 |
697 // A common macro for testing converting I420 to ARGB, BGRA and ABGR. | 724 // A common macro for testing converting I420 to ARGB, BGRA and ABGR. |
698 #define TEST_YUVTORGB(SRC_NAME, DST_NAME, JPG_TYPE, MSE, BLOCK_SIZE) \ | 725 #define TEST_YUVTORGB(SRC_NAME, DST_NAME, JPG_TYPE, MSE, BLOCK_SIZE) \ |
699 TEST_F(PlanarFunctionsTest, SRC_NAME##To##DST_NAME) { \ | 726 TEST_F(PlanarFunctionsTest, SRC_NAME##To##DST_NAME) { \ |
700 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; \ | 727 uint8_t* y_pointer = nullptr; \ |
701 uint8 *argb_expected_pointer = NULL; \ | 728 uint8_t* u_pointer = nullptr; \ |
702 int y_pitch = kWidth; \ | 729 uint8_t* v_pointer = nullptr; \ |
703 int u_pitch = (kWidth + 1) >> 1; \ | 730 uint8_t* argb_expected_pointer = NULL; \ |
704 int v_pitch = (kWidth + 1) >> 1; \ | 731 int y_pitch = kWidth; \ |
705 /* Generate a fake input image.*/ \ | 732 int u_pitch = (kWidth + 1) >> 1; \ |
706 rtc::scoped_ptr<uint8[]> yuv_input( \ | 733 int v_pitch = (kWidth + 1) >> 1; \ |
707 CreateFakeYuvTestingImage(kHeight, kWidth, BLOCK_SIZE, JPG_TYPE, \ | 734 /* Generate a fake input image.*/ \ |
708 y_pointer, u_pointer, v_pointer)); \ | 735 rtc::scoped_ptr<uint8_t[]> yuv_input( \ |
709 /* Generate the expected output.*/ \ | 736 CreateFakeYuvTestingImage(kHeight, kWidth, BLOCK_SIZE, JPG_TYPE, \ |
710 rtc::scoped_ptr<uint8[]> argb_expected( \ | 737 y_pointer, u_pointer, v_pointer)); \ |
711 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 738 /* Generate the expected output.*/ \ |
712 argb_expected_pointer, FOURCC_##DST_NAME)); \ | 739 rtc::scoped_ptr<uint8_t[]> argb_expected( \ |
713 /* Allocate space for the output.*/ \ | 740 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ |
714 rtc::scoped_ptr<uint8[]> argb_output( \ | 741 argb_expected_pointer, FOURCC_##DST_NAME)); \ |
715 new uint8[kHeight * kWidth * 4 + kAlignment]); \ | 742 /* Allocate space for the output.*/ \ |
716 uint8 *argb_pointer = ALIGNP(argb_expected.get(), kAlignment); \ | 743 rtc::scoped_ptr<uint8_t[]> argb_output( \ |
717 for (int i = 0; i < repeat_; ++i) { \ | 744 new uint8_t[kHeight * kWidth * 4 + kAlignment]); \ |
718 libyuv::SRC_NAME##To##DST_NAME(y_pointer, y_pitch, \ | 745 uint8_t* argb_pointer = ALIGNP(argb_expected.get(), kAlignment); \ |
719 u_pointer, u_pitch, \ | 746 for (int i = 0; i < repeat_; ++i) { \ |
720 v_pointer, v_pitch, \ | 747 libyuv::SRC_NAME##To##DST_NAME(y_pointer, y_pitch, u_pointer, u_pitch, \ |
721 argb_pointer, \ | 748 v_pointer, v_pitch, argb_pointer, \ |
722 kWidth * 4, \ | 749 kWidth * 4, kWidth, kHeight); \ |
723 kWidth, kHeight); \ | 750 } \ |
724 } \ | 751 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ |
725 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ | 752 kHeight* kWidth * 4, MSE)); \ |
726 kHeight * kWidth * 4, MSE)); \ | 753 if (dump_) { \ |
727 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } \ | 754 DumpArgbImage(argb_pointer, kWidth, kHeight); \ |
728 } | 755 } \ |
| 756 } |
729 | 757 |
730 // TEST_F(PlanarFunctionsTest, I420ToARGB) | 758 // TEST_F(PlanarFunctionsTest, I420ToARGB) |
731 TEST_YUVTORGB(I420, ARGB, libyuv::kJpegYuv420, 3., 2); | 759 TEST_YUVTORGB(I420, ARGB, libyuv::kJpegYuv420, 3., 2); |
732 // TEST_F(PlanarFunctionsTest, I420ToABGR) | 760 // TEST_F(PlanarFunctionsTest, I420ToABGR) |
733 TEST_YUVTORGB(I420, ABGR, libyuv::kJpegYuv420, 3., 2); | 761 TEST_YUVTORGB(I420, ABGR, libyuv::kJpegYuv420, 3., 2); |
734 // TEST_F(PlanarFunctionsTest, I420ToBGRA) | 762 // TEST_F(PlanarFunctionsTest, I420ToBGRA) |
735 TEST_YUVTORGB(I420, BGRA, libyuv::kJpegYuv420, 3., 2); | 763 TEST_YUVTORGB(I420, BGRA, libyuv::kJpegYuv420, 3., 2); |
736 // TEST_F(PlanarFunctionsTest, I422ToARGB) | 764 // TEST_F(PlanarFunctionsTest, I422ToARGB) |
737 TEST_YUVTORGB(I422, ARGB, libyuv::kJpegYuv422, 3., 2); | 765 TEST_YUVTORGB(I422, ARGB, libyuv::kJpegYuv422, 3., 2); |
738 // TEST_F(PlanarFunctionsTest, I444ToARGB) | 766 // TEST_F(PlanarFunctionsTest, I444ToARGB) |
739 TEST_YUVTORGB(I444, ARGB, libyuv::kJpegYuv444, 3., 3); | 767 TEST_YUVTORGB(I444, ARGB, libyuv::kJpegYuv444, 3., 3); |
740 // Note: an empirical MSE tolerance 3.0 is used here for the probable | 768 // Note: an empirical MSE tolerance 3.0 is used here for the probable |
741 // error from float-to-uint8 type conversion. | 769 // error from float-to-uint8_t type conversion. |
742 | 770 |
743 TEST_F(PlanarFunctionsTest, I400ToARGB_Reference) { | 771 TEST_F(PlanarFunctionsTest, I400ToARGB_Reference) { |
744 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 772 uint8_t* y_pointer = nullptr; |
| 773 uint8_t* u_pointer = nullptr; |
| 774 uint8_t* v_pointer = nullptr; |
745 int y_pitch = kWidth; | 775 int y_pitch = kWidth; |
746 int u_pitch = (kWidth + 1) >> 1; | 776 int u_pitch = (kWidth + 1) >> 1; |
747 int v_pitch = (kWidth + 1) >> 1; | 777 int v_pitch = (kWidth + 1) >> 1; |
748 int block_size = 3; | 778 int block_size = 3; |
749 // Generate a fake input image. | 779 // Generate a fake input image. |
750 rtc::scoped_ptr<uint8[]> yuv_input( | 780 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
751 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 781 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
752 libyuv::kJpegYuv420, | 782 v_pointer)); |
753 y_pointer, u_pointer, v_pointer)); | |
754 // As the comparison standard, we convert a grayscale image (by setting both | 783 // As the comparison standard, we convert a grayscale image (by setting both |
755 // U and V channels to be 128) using an I420 converter. | 784 // U and V channels to be 128) using an I420 converter. |
756 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 785 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
757 | 786 |
758 rtc::scoped_ptr<uint8[]> uv(new uint8[uv_size + kAlignment]); | 787 rtc::scoped_ptr<uint8_t[]> uv(new uint8_t[uv_size + kAlignment]); |
759 u_pointer = v_pointer = ALIGNP(uv.get(), kAlignment); | 788 u_pointer = v_pointer = ALIGNP(uv.get(), kAlignment); |
760 memset(u_pointer, 128, uv_size); | 789 memset(u_pointer, 128, uv_size); |
761 | 790 |
762 // Allocate space for the output image and generate the expected output. | 791 // Allocate space for the output image and generate the expected output. |
763 rtc::scoped_ptr<uint8[]> argb_expected( | 792 rtc::scoped_ptr<uint8_t[]> argb_expected( |
764 new uint8[kHeight * kWidth * 4 + kAlignment]); | 793 new uint8_t[kHeight * kWidth * 4 + kAlignment]); |
765 rtc::scoped_ptr<uint8[]> argb_output( | 794 rtc::scoped_ptr<uint8_t[]> argb_output( |
766 new uint8[kHeight * kWidth * 4 + kAlignment]); | 795 new uint8_t[kHeight * kWidth * 4 + kAlignment]); |
767 uint8 *argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); | 796 uint8_t* argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); |
768 uint8 *argb_pointer = ALIGNP(argb_output.get(), kAlignment); | 797 uint8_t* argb_pointer = ALIGNP(argb_output.get(), kAlignment); |
769 | 798 |
770 libyuv::I420ToARGB(y_pointer, y_pitch, | 799 libyuv::I420ToARGB(y_pointer, y_pitch, |
771 u_pointer, u_pitch, | 800 u_pointer, u_pitch, |
772 v_pointer, v_pitch, | 801 v_pointer, v_pitch, |
773 argb_expected_pointer, kWidth * 4, | 802 argb_expected_pointer, kWidth * 4, |
774 kWidth, kHeight); | 803 kWidth, kHeight); |
775 for (int i = 0; i < repeat_; ++i) { | 804 for (int i = 0; i < repeat_; ++i) { |
776 libyuv::I400ToARGB_Reference(y_pointer, y_pitch, | 805 libyuv::I400ToARGB_Reference(y_pointer, y_pitch, |
777 argb_pointer, kWidth * 4, | 806 argb_pointer, kWidth * 4, |
778 kWidth, kHeight); | 807 kWidth, kHeight); |
779 } | 808 } |
780 | 809 |
781 // Note: I420ToARGB and I400ToARGB_Reference should produce identical results. | 810 // Note: I420ToARGB and I400ToARGB_Reference should produce identical results. |
782 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, | 811 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, |
783 kHeight * kWidth * 4, 2.)); | 812 kHeight * kWidth * 4, 2.)); |
784 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } | 813 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } |
785 } | 814 } |
786 | 815 |
787 TEST_P(PlanarFunctionsTest, I400ToARGB) { | 816 TEST_P(PlanarFunctionsTest, I400ToARGB) { |
788 // Get the unalignment offset | 817 // Get the unalignment offset |
789 int unalignment = GetParam(); | 818 int unalignment = GetParam(); |
790 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 819 uint8_t* y_pointer = nullptr; |
| 820 uint8_t* u_pointer = nullptr; |
| 821 uint8_t* v_pointer = nullptr; |
791 int y_pitch = kWidth; | 822 int y_pitch = kWidth; |
792 int u_pitch = (kWidth + 1) >> 1; | 823 int u_pitch = (kWidth + 1) >> 1; |
793 int v_pitch = (kWidth + 1) >> 1; | 824 int v_pitch = (kWidth + 1) >> 1; |
794 int block_size = 3; | 825 int block_size = 3; |
795 // Generate a fake input image. | 826 // Generate a fake input image. |
796 rtc::scoped_ptr<uint8[]> yuv_input( | 827 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
797 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 828 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
798 libyuv::kJpegYuv420, | 829 v_pointer)); |
799 y_pointer, u_pointer, v_pointer)); | |
800 // As the comparison standard, we convert a grayscale image (by setting both | 830 // As the comparison standard, we convert a grayscale image (by setting both |
801 // U and V channels to be 128) using an I420 converter. | 831 // U and V channels to be 128) using an I420 converter. |
802 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 832 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
803 | 833 |
804 // 1 byte extra if in the unaligned mode. | 834 // 1 byte extra if in the unaligned mode. |
805 rtc::scoped_ptr<uint8[]> uv(new uint8[uv_size * 2 + kAlignment]); | 835 rtc::scoped_ptr<uint8_t[]> uv(new uint8_t[uv_size * 2 + kAlignment]); |
806 u_pointer = ALIGNP(uv.get(), kAlignment); | 836 u_pointer = ALIGNP(uv.get(), kAlignment); |
807 v_pointer = u_pointer + uv_size; | 837 v_pointer = u_pointer + uv_size; |
808 memset(u_pointer, 128, uv_size); | 838 memset(u_pointer, 128, uv_size); |
809 memset(v_pointer, 128, uv_size); | 839 memset(v_pointer, 128, uv_size); |
810 | 840 |
811 // Allocate space for the output image and generate the expected output. | 841 // Allocate space for the output image and generate the expected output. |
812 rtc::scoped_ptr<uint8[]> argb_expected( | 842 rtc::scoped_ptr<uint8_t[]> argb_expected( |
813 new uint8[kHeight * kWidth * 4 + kAlignment]); | 843 new uint8_t[kHeight * kWidth * 4 + kAlignment]); |
814 // 1 byte extra if in the misalinged mode. | 844 // 1 byte extra if in the misalinged mode. |
815 rtc::scoped_ptr<uint8[]> argb_output( | 845 rtc::scoped_ptr<uint8_t[]> argb_output( |
816 new uint8[kHeight * kWidth * 4 + kAlignment + unalignment]); | 846 new uint8_t[kHeight * kWidth * 4 + kAlignment + unalignment]); |
817 uint8 *argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); | 847 uint8_t* argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); |
818 uint8 *argb_pointer = ALIGNP(argb_output.get(), kAlignment) + unalignment; | 848 uint8_t* argb_pointer = ALIGNP(argb_output.get(), kAlignment) + unalignment; |
819 | 849 |
820 libyuv::I420ToARGB(y_pointer, y_pitch, | 850 libyuv::I420ToARGB(y_pointer, y_pitch, |
821 u_pointer, u_pitch, | 851 u_pointer, u_pitch, |
822 v_pointer, v_pitch, | 852 v_pointer, v_pitch, |
823 argb_expected_pointer, kWidth * 4, | 853 argb_expected_pointer, kWidth * 4, |
824 kWidth, kHeight); | 854 kWidth, kHeight); |
825 for (int i = 0; i < repeat_; ++i) { | 855 for (int i = 0; i < repeat_; ++i) { |
826 libyuv::I400ToARGB(y_pointer, y_pitch, | 856 libyuv::I400ToARGB(y_pointer, y_pitch, |
827 argb_pointer, kWidth * 4, | 857 argb_pointer, kWidth * 4, |
828 kWidth, kHeight); | 858 kWidth, kHeight); |
829 } | 859 } |
830 | 860 |
831 // Note: current I400ToARGB uses an approximate method, | 861 // Note: current I400ToARGB uses an approximate method, |
832 // so the error tolerance is larger here. | 862 // so the error tolerance is larger here. |
833 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, | 863 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, |
834 kHeight * kWidth * 4, 64.0)); | 864 kHeight * kWidth * 4, 64.0)); |
835 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } | 865 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } |
836 } | 866 } |
837 | 867 |
838 TEST_P(PlanarFunctionsTest, ARGBToI400) { | 868 TEST_P(PlanarFunctionsTest, ARGBToI400) { |
839 // Get the unalignment offset | 869 // Get the unalignment offset |
840 int unalignment = GetParam(); | 870 int unalignment = GetParam(); |
841 // Create a fake ARGB input image. | 871 // Create a fake ARGB input image. |
842 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 872 uint8_t* y_pointer = NULL, * u_pointer = NULL, * v_pointer = NULL; |
843 uint8 *argb_pointer = NULL; | 873 uint8_t* argb_pointer = NULL; |
844 int block_size = 3; | 874 int block_size = 3; |
845 // Generate a fake input image. | 875 // Generate a fake input image. |
846 rtc::scoped_ptr<uint8[]> argb_input( | 876 rtc::scoped_ptr<uint8_t[]> argb_input(CreateFakeArgbTestingImage( |
847 CreateFakeArgbTestingImage(kHeight, kWidth, block_size, | 877 kHeight, kWidth, block_size, argb_pointer, FOURCC_ARGB)); |
848 argb_pointer, FOURCC_ARGB)); | |
849 // Generate the expected output. Only Y channel is used | 878 // Generate the expected output. Only Y channel is used |
850 rtc::scoped_ptr<uint8[]> yuv_expected( | 879 rtc::scoped_ptr<uint8_t[]> yuv_expected(CreateFakeYuvTestingImage( |
851 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 880 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
852 libyuv::kJpegYuv420, | 881 v_pointer)); |
853 y_pointer, u_pointer, v_pointer)); | |
854 // Allocate space for the Y output. | 882 // Allocate space for the Y output. |
855 rtc::scoped_ptr<uint8[]> y_output( | 883 rtc::scoped_ptr<uint8_t[]> y_output( |
856 new uint8[kHeight * kWidth + kAlignment + unalignment]); | 884 new uint8_t[kHeight * kWidth + kAlignment + unalignment]); |
857 uint8 *y_output_pointer = ALIGNP(y_output.get(), kAlignment) + unalignment; | 885 uint8_t* y_output_pointer = ALIGNP(y_output.get(), kAlignment) + unalignment; |
858 | 886 |
859 for (int i = 0; i < repeat_; ++i) { | 887 for (int i = 0; i < repeat_; ++i) { |
860 libyuv::ARGBToI400(argb_pointer, kWidth * 4, y_output_pointer, kWidth, | 888 libyuv::ARGBToI400(argb_pointer, kWidth * 4, y_output_pointer, kWidth, |
861 kWidth, kHeight); | 889 kWidth, kHeight); |
862 } | 890 } |
863 // Check if the output matches the input Y channel. | 891 // Check if the output matches the input Y channel. |
864 // Note: an empirical MSE tolerance 2.0 is used here for the probable | 892 // Note: an empirical MSE tolerance 2.0 is used here for the probable |
865 // error from float-to-uint8 type conversion. | 893 // error from float-to-uint8_t type conversion. |
866 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, | 894 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, |
867 kHeight * kWidth, 2.)); | 895 kHeight * kWidth, 2.)); |
868 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } | 896 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } |
869 } | 897 } |
870 | 898 |
871 // A common macro for testing converting RAW, BG24, BGRA, and ABGR | 899 // A common macro for testing converting RAW, BG24, BGRA, and ABGR |
872 // to ARGB. | 900 // to ARGB. |
873 #define TEST_ARGB(SRC_NAME, FC_ID, BPP, BLOCK_SIZE) \ | 901 #define TEST_ARGB(SRC_NAME, FC_ID, BPP, BLOCK_SIZE) \ |
874 TEST_P(PlanarFunctionsTest, SRC_NAME##ToARGB) { \ | 902 TEST_P(PlanarFunctionsTest, SRC_NAME##ToARGB) { \ |
875 int unalignment = GetParam(); /* Get the unalignment offset.*/ \ | 903 int unalignment = GetParam(); /* Get the unalignment offset.*/ \ |
876 uint8 *argb_expected_pointer = NULL, *src_pointer = NULL; \ | 904 uint8_t* argb_expected_pointer = NULL, * src_pointer = NULL; \ |
877 /* Generate a fake input image.*/ \ | 905 /* Generate a fake input image.*/ \ |
878 rtc::scoped_ptr<uint8[]> src_input( \ | 906 rtc::scoped_ptr<uint8_t[]> src_input(CreateFakeArgbTestingImage( \ |
879 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 907 kHeight, kWidth, BLOCK_SIZE, src_pointer, FOURCC_##FC_ID)); \ |
880 src_pointer, FOURCC_##FC_ID)); \ | 908 /* Generate the expected output.*/ \ |
881 /* Generate the expected output.*/ \ | 909 rtc::scoped_ptr<uint8_t[]> argb_expected(CreateFakeArgbTestingImage( \ |
882 rtc::scoped_ptr<uint8[]> argb_expected( \ | 910 kHeight, kWidth, BLOCK_SIZE, argb_expected_pointer, FOURCC_ARGB)); \ |
883 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 911 /* Allocate space for the output; 1 byte extra if in the unaligned mode.*/ \ |
884 argb_expected_pointer, FOURCC_ARGB)); \ | 912 rtc::scoped_ptr<uint8_t[]> argb_output( \ |
885 /* Allocate space for the output; 1 byte extra if in the unaligned mode.*/ \ | 913 new uint8_t[kHeight * kWidth * 4 + kAlignment + unalignment]); \ |
886 rtc::scoped_ptr<uint8[]> argb_output( \ | 914 uint8_t* argb_pointer = \ |
887 new uint8[kHeight * kWidth * 4 + kAlignment + unalignment]); \ | 915 ALIGNP(argb_output.get(), kAlignment) + unalignment; \ |
888 uint8 *argb_pointer = ALIGNP(argb_output.get(), kAlignment) + unalignment; \ | 916 for (int i = 0; i < repeat_; ++i) { \ |
889 for (int i = 0; i < repeat_; ++i) { \ | 917 libyuv::SRC_NAME##ToARGB(src_pointer, kWidth*(BPP), argb_pointer, \ |
890 libyuv:: SRC_NAME##ToARGB(src_pointer, kWidth * (BPP), argb_pointer, \ | 918 kWidth * 4, kWidth, kHeight); \ |
891 kWidth * 4, kWidth, kHeight); \ | 919 } \ |
892 } \ | 920 /* Compare the result; expect identical.*/ \ |
893 /* Compare the result; expect identical.*/ \ | 921 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ |
894 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ | 922 kHeight* kWidth * 4, 1.e-6)); \ |
895 kHeight * kWidth * 4, 1.e-6)); \ | 923 if (dump_) { \ |
896 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } \ | 924 DumpArgbImage(argb_pointer, kWidth, kHeight); \ |
897 } | 925 } \ |
| 926 } |
898 | 927 |
899 TEST_ARGB(RAW, RAW, 3, 3); // TEST_P(PlanarFunctionsTest, RAWToARGB) | 928 TEST_ARGB(RAW, RAW, 3, 3); // TEST_P(PlanarFunctionsTest, RAWToARGB) |
900 TEST_ARGB(BG24, 24BG, 3, 3); // TEST_P(PlanarFunctionsTest, BG24ToARGB) | 929 TEST_ARGB(BG24, 24BG, 3, 3); // TEST_P(PlanarFunctionsTest, BG24ToARGB) |
901 TEST_ARGB(ABGR, ABGR, 4, 3); // TEST_P(PlanarFunctionsTest, ABGRToARGB) | 930 TEST_ARGB(ABGR, ABGR, 4, 3); // TEST_P(PlanarFunctionsTest, ABGRToARGB) |
902 TEST_ARGB(BGRA, BGRA, 4, 3); // TEST_P(PlanarFunctionsTest, BGRAToARGB) | 931 TEST_ARGB(BGRA, BGRA, 4, 3); // TEST_P(PlanarFunctionsTest, BGRAToARGB) |
903 | 932 |
904 // Parameter Test: The parameter is the unalignment offset. | 933 // Parameter Test: The parameter is the unalignment offset. |
905 // Aligned data for testing assembly versions. | 934 // Aligned data for testing assembly versions. |
906 INSTANTIATE_TEST_CASE_P(PlanarFunctionsAligned, PlanarFunctionsTest, | 935 INSTANTIATE_TEST_CASE_P(PlanarFunctionsAligned, PlanarFunctionsTest, |
907 ::testing::Values(0)); | 936 ::testing::Values(0)); |
908 | 937 |
909 // Purposely unalign the output argb pointer to test slow path (C version). | 938 // Purposely unalign the output argb pointer to test slow path (C version). |
910 INSTANTIATE_TEST_CASE_P(PlanarFunctionsMisaligned, PlanarFunctionsTest, | 939 INSTANTIATE_TEST_CASE_P(PlanarFunctionsMisaligned, PlanarFunctionsTest, |
911 ::testing::Values(1)); | 940 ::testing::Values(1)); |
912 | 941 |
913 } // namespace cricket | 942 } // namespace cricket |
OLD | NEW |