Chromium Code Reviews| 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 = NULL, * u_pointer = NULL, * v_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
Can you rewrite this, so that each variable is dec
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 475 int y_pitch = kWidth; | 499 int y_pitch = kWidth; |
| 476 int u_pitch = (kWidth + 1) >> 1; | 500 int u_pitch = (kWidth + 1) >> 1; |
| 477 int v_pitch = (kWidth + 1) >> 1; | 501 int v_pitch = (kWidth + 1) >> 1; |
| 478 int y_size = kHeight * kWidth; | 502 int y_size = kHeight * kWidth; |
| 479 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 503 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
| 480 int block_size = 3; | 504 int block_size = 3; |
| 481 // Generate a fake input image. | 505 // Generate a fake input image. |
| 482 rtc::scoped_ptr<uint8[]> yuv_input( | 506 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
| 483 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 507 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
| 484 libyuv::kJpegYuv420, | 508 v_pointer)); |
| 485 y_pointer, u_pointer, v_pointer)); | |
| 486 // Allocate space for the output image. | 509 // Allocate space for the output image. |
| 487 rtc::scoped_ptr<uint8[]> yuv_output( | 510 rtc::scoped_ptr<uint8_t[]> yuv_output( |
| 488 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment]); | 511 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment]); |
| 489 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); | 512 uint8_t* y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); |
| 490 uint8 *u_output_pointer = y_output_pointer + y_size; | 513 uint8_t* u_output_pointer = y_output_pointer + y_size; |
| 491 uint8 *v_output_pointer = u_output_pointer + uv_size; | 514 uint8_t* v_output_pointer = u_output_pointer + uv_size; |
| 492 | 515 |
| 493 for (int i = 0; i < repeat_; ++i) { | 516 for (int i = 0; i < repeat_; ++i) { |
| 494 libyuv::I420Copy(y_pointer, y_pitch, | 517 libyuv::I420Copy(y_pointer, y_pitch, |
| 495 u_pointer, u_pitch, | 518 u_pointer, u_pitch, |
| 496 v_pointer, v_pitch, | 519 v_pointer, v_pitch, |
| 497 y_output_pointer, y_pitch, | 520 y_output_pointer, y_pitch, |
| 498 u_output_pointer, u_pitch, | 521 u_output_pointer, u_pitch, |
| 499 v_output_pointer, v_pitch, | 522 v_output_pointer, v_pitch, |
| 500 kWidth, kHeight); | 523 kWidth, kHeight); |
| 501 } | 524 } |
| 502 | 525 |
| 503 // Expect the copied frame to be exactly the same. | 526 // Expect the copied frame to be exactly the same. |
| 504 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, | 527 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, |
| 505 I420_SIZE(kHeight, kWidth), 1.e-6)); | 528 I420_SIZE(kHeight, kWidth), 1.e-6)); |
| 506 | 529 |
| 507 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 530 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
| 508 } | 531 } |
| 509 | 532 |
| 510 TEST_F(PlanarFunctionsTest, I422ToI420) { | 533 TEST_F(PlanarFunctionsTest, I422ToI420) { |
| 511 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 534 uint8_t* y_pointer = NULL, * u_pointer = NULL, * v_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
Same as above.
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 512 int y_pitch = kWidth; | 535 int y_pitch = kWidth; |
| 513 int u_pitch = (kWidth + 1) >> 1; | 536 int u_pitch = (kWidth + 1) >> 1; |
| 514 int v_pitch = (kWidth + 1) >> 1; | 537 int v_pitch = (kWidth + 1) >> 1; |
| 515 int y_size = kHeight * kWidth; | 538 int y_size = kHeight * kWidth; |
| 516 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 539 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
| 517 int block_size = 2; | 540 int block_size = 2; |
| 518 // Generate a fake input image. | 541 // Generate a fake input image. |
| 519 rtc::scoped_ptr<uint8[]> yuv_input( | 542 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
| 520 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 543 kHeight, kWidth, block_size, libyuv::kJpegYuv422, y_pointer, u_pointer, |
| 521 libyuv::kJpegYuv422, | 544 v_pointer)); |
| 522 y_pointer, u_pointer, v_pointer)); | |
| 523 // Allocate space for the output image. | 545 // Allocate space for the output image. |
| 524 rtc::scoped_ptr<uint8[]> yuv_output( | 546 rtc::scoped_ptr<uint8_t[]> yuv_output( |
| 525 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment]); | 547 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment]); |
| 526 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); | 548 uint8_t* y_output_pointer = ALIGNP(yuv_output.get(), kAlignment); |
| 527 uint8 *u_output_pointer = y_output_pointer + y_size; | 549 uint8_t* u_output_pointer = y_output_pointer + y_size; |
| 528 uint8 *v_output_pointer = u_output_pointer + uv_size; | 550 uint8_t* v_output_pointer = u_output_pointer + uv_size; |
| 529 // Generate the expected output. | 551 // Generate the expected output. |
| 530 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, | 552 uint8_t* y_expected_pointer = NULL, * u_expected_pointer = NULL, |
| 531 *v_expected_pointer = NULL; | 553 * v_expected_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
Again
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 532 rtc::scoped_ptr<uint8[]> yuv_output_expected( | 554 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( |
| 533 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 555 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, |
| 534 libyuv::kJpegYuv420, | 556 u_expected_pointer, v_expected_pointer)); |
| 535 y_expected_pointer, u_expected_pointer, v_expected_pointer)); | |
| 536 | 557 |
| 537 for (int i = 0; i < repeat_; ++i) { | 558 for (int i = 0; i < repeat_; ++i) { |
| 538 libyuv::I422ToI420(y_pointer, y_pitch, | 559 libyuv::I422ToI420(y_pointer, y_pitch, |
| 539 u_pointer, u_pitch, | 560 u_pointer, u_pitch, |
| 540 v_pointer, v_pitch, | 561 v_pointer, v_pitch, |
| 541 y_output_pointer, y_pitch, | 562 y_output_pointer, y_pitch, |
| 542 u_output_pointer, u_pitch, | 563 u_output_pointer, u_pitch, |
| 543 v_output_pointer, v_pitch, | 564 v_output_pointer, v_pitch, |
| 544 kWidth, kHeight); | 565 kWidth, kHeight); |
| 545 } | 566 } |
| 546 | 567 |
| 547 // Compare the output frame with what is expected; expect exactly the same. | 568 // 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 | 569 // Note: MSE should be set to a larger threshold if an odd block width |
| 549 // is used, since the conversion will be lossy. | 570 // is used, since the conversion will be lossy. |
| 550 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, | 571 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, |
| 551 I420_SIZE(kHeight, kWidth), 1.e-6)); | 572 I420_SIZE(kHeight, kWidth), 1.e-6)); |
| 552 | 573 |
| 553 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 574 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
| 554 } | 575 } |
| 555 | 576 |
| 556 TEST_P(PlanarFunctionsTest, M420ToI420) { | 577 TEST_P(PlanarFunctionsTest, M420ToI420) { |
| 557 // Get the unalignment offset | 578 // Get the unalignment offset |
| 558 int unalignment = GetParam(); | 579 int unalignment = GetParam(); |
| 559 uint8 *m420_pointer = NULL; | 580 uint8_t* m420_pointer = NULL; |
| 560 int y_pitch = kWidth; | 581 int y_pitch = kWidth; |
| 561 int m420_pitch = kWidth; | 582 int m420_pitch = kWidth; |
| 562 int u_pitch = (kWidth + 1) >> 1; | 583 int u_pitch = (kWidth + 1) >> 1; |
| 563 int v_pitch = (kWidth + 1) >> 1; | 584 int v_pitch = (kWidth + 1) >> 1; |
| 564 int y_size = kHeight * kWidth; | 585 int y_size = kHeight * kWidth; |
| 565 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 586 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
| 566 int block_size = 2; | 587 int block_size = 2; |
| 567 // Generate a fake input image. | 588 // Generate a fake input image. |
| 568 rtc::scoped_ptr<uint8[]> yuv_input( | 589 rtc::scoped_ptr<uint8_t[]> yuv_input( |
| 569 CreateFakeM420TestingImage(kHeight, kWidth, block_size, m420_pointer)); | 590 CreateFakeM420TestingImage(kHeight, kWidth, block_size, m420_pointer)); |
| 570 // Allocate space for the output image. | 591 // Allocate space for the output image. |
| 571 rtc::scoped_ptr<uint8[]> yuv_output( | 592 rtc::scoped_ptr<uint8_t[]> yuv_output( |
| 572 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); | 593 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); |
| 573 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment) + unalignment; | 594 uint8_t* y_output_pointer = |
| 574 uint8 *u_output_pointer = y_output_pointer + y_size; | 595 ALIGNP(yuv_output.get(), kAlignment) + unalignment; |
| 575 uint8 *v_output_pointer = u_output_pointer + uv_size; | 596 uint8_t* u_output_pointer = y_output_pointer + y_size; |
| 597 uint8_t* v_output_pointer = u_output_pointer + uv_size; | |
| 576 // Generate the expected output. | 598 // Generate the expected output. |
| 577 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, | 599 uint8_t* y_expected_pointer = NULL, * u_expected_pointer = NULL, |
| 578 *v_expected_pointer = NULL; | 600 * v_expected_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
...and here.
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 579 rtc::scoped_ptr<uint8[]> yuv_output_expected( | 601 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( |
| 580 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 602 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, |
| 581 libyuv::kJpegYuv420, | 603 u_expected_pointer, v_expected_pointer)); |
| 582 y_expected_pointer, u_expected_pointer, v_expected_pointer)); | |
| 583 | 604 |
| 584 for (int i = 0; i < repeat_; ++i) { | 605 for (int i = 0; i < repeat_; ++i) { |
| 585 libyuv::M420ToI420(m420_pointer, m420_pitch, | 606 libyuv::M420ToI420(m420_pointer, m420_pitch, |
| 586 y_output_pointer, y_pitch, | 607 y_output_pointer, y_pitch, |
| 587 u_output_pointer, u_pitch, | 608 u_output_pointer, u_pitch, |
| 588 v_output_pointer, v_pitch, | 609 v_output_pointer, v_pitch, |
| 589 kWidth, kHeight); | 610 kWidth, kHeight); |
| 590 } | 611 } |
| 591 // Compare the output frame with what is expected; expect exactly the same. | 612 // 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 | 613 // Note: MSE should be set to a larger threshold if an odd block width |
| 593 // is used, since the conversion will be lossy. | 614 // is used, since the conversion will be lossy. |
| 594 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, | 615 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, |
| 595 I420_SIZE(kHeight, kWidth), 1.e-6)); | 616 I420_SIZE(kHeight, kWidth), 1.e-6)); |
| 596 | 617 |
| 597 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 618 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
| 598 } | 619 } |
| 599 | 620 |
| 600 TEST_P(PlanarFunctionsTest, NV12ToI420) { | 621 TEST_P(PlanarFunctionsTest, NV12ToI420) { |
| 601 // Get the unalignment offset | 622 // Get the unalignment offset |
| 602 int unalignment = GetParam(); | 623 int unalignment = GetParam(); |
| 603 uint8 *y_pointer = NULL, *uv_pointer = NULL; | 624 uint8_t* y_pointer = NULL, * uv_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
Here
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 604 int y_pitch = kWidth; | 625 int y_pitch = kWidth; |
| 605 int uv_pitch = 2 * ((kWidth + 1) >> 1); | 626 int uv_pitch = 2 * ((kWidth + 1) >> 1); |
| 606 int u_pitch = (kWidth + 1) >> 1; | 627 int u_pitch = (kWidth + 1) >> 1; |
| 607 int v_pitch = (kWidth + 1) >> 1; | 628 int v_pitch = (kWidth + 1) >> 1; |
| 608 int y_size = kHeight * kWidth; | 629 int y_size = kHeight * kWidth; |
| 609 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 630 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
| 610 int block_size = 2; | 631 int block_size = 2; |
| 611 // Generate a fake input image. | 632 // Generate a fake input image. |
| 612 rtc::scoped_ptr<uint8[]> yuv_input( | 633 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeNV12TestingImage( |
| 613 CreateFakeNV12TestingImage(kHeight, kWidth, block_size, | 634 kHeight, kWidth, block_size, y_pointer, uv_pointer)); |
| 614 y_pointer, uv_pointer)); | |
| 615 // Allocate space for the output image. | 635 // Allocate space for the output image. |
| 616 rtc::scoped_ptr<uint8[]> yuv_output( | 636 rtc::scoped_ptr<uint8_t[]> yuv_output( |
| 617 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); | 637 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); |
| 618 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment) + unalignment; | 638 uint8_t* y_output_pointer = |
| 619 uint8 *u_output_pointer = y_output_pointer + y_size; | 639 ALIGNP(yuv_output.get(), kAlignment) + unalignment; |
| 620 uint8 *v_output_pointer = u_output_pointer + uv_size; | 640 uint8_t* u_output_pointer = y_output_pointer + y_size; |
| 641 uint8_t* v_output_pointer = u_output_pointer + uv_size; | |
| 621 // Generate the expected output. | 642 // Generate the expected output. |
| 622 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, | 643 uint8_t* y_expected_pointer = NULL, * u_expected_pointer = NULL, |
| 623 *v_expected_pointer = NULL; | 644 * v_expected_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
Here
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 624 rtc::scoped_ptr<uint8[]> yuv_output_expected( | 645 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( |
| 625 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 646 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, |
| 626 libyuv::kJpegYuv420, | 647 u_expected_pointer, v_expected_pointer)); |
| 627 y_expected_pointer, u_expected_pointer, v_expected_pointer)); | |
| 628 | 648 |
| 629 for (int i = 0; i < repeat_; ++i) { | 649 for (int i = 0; i < repeat_; ++i) { |
| 630 libyuv::NV12ToI420(y_pointer, y_pitch, | 650 libyuv::NV12ToI420(y_pointer, y_pitch, |
| 631 uv_pointer, uv_pitch, | 651 uv_pointer, uv_pitch, |
| 632 y_output_pointer, y_pitch, | 652 y_output_pointer, y_pitch, |
| 633 u_output_pointer, u_pitch, | 653 u_output_pointer, u_pitch, |
| 634 v_output_pointer, v_pitch, | 654 v_output_pointer, v_pitch, |
| 635 kWidth, kHeight); | 655 kWidth, kHeight); |
| 636 } | 656 } |
| 637 // Compare the output frame with what is expected; expect exactly the same. | 657 // 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 | 658 // Note: MSE should be set to a larger threshold if an odd block width |
| 639 // is used, since the conversion will be lossy. | 659 // is used, since the conversion will be lossy. |
| 640 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, | 660 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, |
| 641 I420_SIZE(kHeight, kWidth), 1.e-6)); | 661 I420_SIZE(kHeight, kWidth), 1.e-6)); |
| 642 | 662 |
| 643 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } | 663 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } |
| 644 } | 664 } |
| 645 | 665 |
| 646 // A common macro for testing converting YUY2/UYVY to I420. | 666 // A common macro for testing converting YUY2/UYVY to I420. |
| 647 #define TEST_YUVTOI420(SRC_NAME, MSE, BLOCK_SIZE) \ | 667 #define TEST_YUVTOI420(SRC_NAME, MSE, BLOCK_SIZE) \ |
| 648 TEST_P(PlanarFunctionsTest, SRC_NAME##ToI420) { \ | 668 TEST_P(PlanarFunctionsTest, SRC_NAME##ToI420) { \ |
| 649 /* Get the unalignment offset.*/ \ | 669 /* Get the unalignment offset.*/ \ |
| 650 int unalignment = GetParam(); \ | 670 int unalignment = GetParam(); \ |
| 651 uint8 *yuv_pointer = NULL; \ | 671 uint8_t* yuv_pointer = NULL; \ |
| 652 int yuv_pitch = 2 * ((kWidth + 1) & ~1); \ | 672 int yuv_pitch = 2 * ((kWidth + 1) & ~1); \ |
| 653 int y_pitch = kWidth; \ | 673 int y_pitch = kWidth; \ |
| 654 int u_pitch = (kWidth + 1) >> 1; \ | 674 int u_pitch = (kWidth + 1) >> 1; \ |
| 655 int v_pitch = (kWidth + 1) >> 1; \ | 675 int v_pitch = (kWidth + 1) >> 1; \ |
| 656 int y_size = kHeight * kWidth; \ | 676 int y_size = kHeight * kWidth; \ |
| 657 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); \ | 677 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); \ |
| 658 int block_size = 2; \ | 678 int block_size = 2; \ |
| 659 /* Generate a fake input image.*/ \ | 679 /* Generate a fake input image.*/ \ |
| 660 rtc::scoped_ptr<uint8[]> yuv_input( \ | 680 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeInterleaveYuvTestingImage( \ |
| 661 CreateFakeInterleaveYuvTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 681 kHeight, kWidth, BLOCK_SIZE, yuv_pointer, FOURCC_##SRC_NAME)); \ |
| 662 yuv_pointer, FOURCC_##SRC_NAME)); \ | 682 /* Allocate space for the output image.*/ \ |
| 663 /* Allocate space for the output image.*/ \ | 683 rtc::scoped_ptr<uint8_t[]> yuv_output( \ |
| 664 rtc::scoped_ptr<uint8[]> yuv_output( \ | 684 new uint8_t[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); \ |
| 665 new uint8[I420_SIZE(kHeight, kWidth) + kAlignment + unalignment]); \ | 685 uint8_t* y_output_pointer = \ |
| 666 uint8 *y_output_pointer = ALIGNP(yuv_output.get(), kAlignment) + \ | 686 ALIGNP(yuv_output.get(), kAlignment) + unalignment; \ |
| 667 unalignment; \ | 687 uint8_t* u_output_pointer = y_output_pointer + y_size; \ |
| 668 uint8 *u_output_pointer = y_output_pointer + y_size; \ | 688 uint8_t* v_output_pointer = u_output_pointer + uv_size; \ |
| 669 uint8 *v_output_pointer = u_output_pointer + uv_size; \ | 689 /* Generate the expected output.*/ \ |
| 670 /* Generate the expected output.*/ \ | 690 uint8_t* y_expected_pointer = NULL, * u_expected_pointer = NULL, \ |
| 671 uint8 *y_expected_pointer = NULL, *u_expected_pointer = NULL, \ | 691 * v_expected_pointer = NULL; \ |
|
tlegrand-webrtc
2015/10/05 13:49:01
Declare separately.
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 672 *v_expected_pointer = NULL; \ | 692 rtc::scoped_ptr<uint8_t[]> yuv_output_expected(CreateFakeYuvTestingImage( \ |
| 673 rtc::scoped_ptr<uint8[]> yuv_output_expected( \ | 693 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_expected_pointer, \ |
| 674 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, \ | 694 u_expected_pointer, v_expected_pointer)); \ |
| 675 libyuv::kJpegYuv420, \ | 695 for (int i = 0; i < repeat_; ++i) { \ |
| 676 y_expected_pointer, u_expected_pointer, v_expected_pointer)); \ | 696 libyuv::SRC_NAME##ToI420(yuv_pointer, yuv_pitch, y_output_pointer, \ |
| 677 for (int i = 0; i < repeat_; ++i) { \ | 697 y_pitch, u_output_pointer, u_pitch, \ |
| 678 libyuv::SRC_NAME##ToI420(yuv_pointer, yuv_pitch, \ | 698 v_output_pointer, v_pitch, kWidth, kHeight); \ |
| 679 y_output_pointer, y_pitch, \ | 699 } \ |
| 680 u_output_pointer, u_pitch, \ | 700 /* Compare the output frame with what is expected.*/ \ |
| 681 v_output_pointer, v_pitch, \ | 701 /* Note: MSE should be set to a larger threshold if an odd block width*/ \ |
| 682 kWidth, kHeight); \ | 702 /* is used, since the conversion will be lossy.*/ \ |
| 683 } \ | 703 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, \ |
| 684 /* Compare the output frame with what is expected.*/ \ | 704 I420_SIZE(kHeight, kWidth), MSE)); \ |
| 685 /* Note: MSE should be set to a larger threshold if an odd block width*/ \ | 705 if (dump_) { \ |
| 686 /* is used, since the conversion will be lossy.*/ \ | 706 DumpYuvImage(y_output_pointer, kWidth, kHeight); \ |
| 687 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_expected_pointer, \ | 707 } \ |
| 688 I420_SIZE(kHeight, kWidth), MSE)); \ | 708 } |
|
tlegrand-webrtc
2015/10/05 13:49:01
Clang format here was unfortunate, since it's diff
pbos-webrtc
2015/10/06 09:14:59
Acknowledged.
| |
| 689 if (dump_) { DumpYuvImage(y_output_pointer, kWidth, kHeight); } \ | |
| 690 } \ | |
| 691 | 709 |
| 692 // TEST_P(PlanarFunctionsTest, YUV2ToI420) | 710 // TEST_P(PlanarFunctionsTest, YUV2ToI420) |
| 693 TEST_YUVTOI420(YUY2, 1.e-6, 2); | 711 TEST_YUVTOI420(YUY2, 1.e-6, 2); |
| 694 // TEST_P(PlanarFunctionsTest, UYVYToI420) | 712 // TEST_P(PlanarFunctionsTest, UYVYToI420) |
| 695 TEST_YUVTOI420(UYVY, 1.e-6, 2); | 713 TEST_YUVTOI420(UYVY, 1.e-6, 2); |
| 696 | 714 |
| 697 // A common macro for testing converting I420 to ARGB, BGRA and ABGR. | 715 // 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) \ | 716 #define TEST_YUVTORGB(SRC_NAME, DST_NAME, JPG_TYPE, MSE, BLOCK_SIZE) \ |
| 699 TEST_F(PlanarFunctionsTest, SRC_NAME##To##DST_NAME) { \ | 717 TEST_F(PlanarFunctionsTest, SRC_NAME##To##DST_NAME) { \ |
| 700 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; \ | 718 uint8_t* y_pointer = NULL, * u_pointer = NULL, * v_pointer = NULL; \ |
|
tlegrand-webrtc
2015/10/05 13:49:01
And here
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 701 uint8 *argb_expected_pointer = NULL; \ | 719 uint8_t* argb_expected_pointer = NULL; \ |
| 702 int y_pitch = kWidth; \ | 720 int y_pitch = kWidth; \ |
| 703 int u_pitch = (kWidth + 1) >> 1; \ | 721 int u_pitch = (kWidth + 1) >> 1; \ |
| 704 int v_pitch = (kWidth + 1) >> 1; \ | 722 int v_pitch = (kWidth + 1) >> 1; \ |
| 705 /* Generate a fake input image.*/ \ | 723 /* Generate a fake input image.*/ \ |
| 706 rtc::scoped_ptr<uint8[]> yuv_input( \ | 724 rtc::scoped_ptr<uint8_t[]> yuv_input( \ |
| 707 CreateFakeYuvTestingImage(kHeight, kWidth, BLOCK_SIZE, JPG_TYPE, \ | 725 CreateFakeYuvTestingImage(kHeight, kWidth, BLOCK_SIZE, JPG_TYPE, \ |
| 708 y_pointer, u_pointer, v_pointer)); \ | 726 y_pointer, u_pointer, v_pointer)); \ |
| 709 /* Generate the expected output.*/ \ | 727 /* Generate the expected output.*/ \ |
| 710 rtc::scoped_ptr<uint8[]> argb_expected( \ | 728 rtc::scoped_ptr<uint8_t[]> argb_expected( \ |
| 711 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 729 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ |
| 712 argb_expected_pointer, FOURCC_##DST_NAME)); \ | 730 argb_expected_pointer, FOURCC_##DST_NAME)); \ |
| 713 /* Allocate space for the output.*/ \ | 731 /* Allocate space for the output.*/ \ |
| 714 rtc::scoped_ptr<uint8[]> argb_output( \ | 732 rtc::scoped_ptr<uint8_t[]> argb_output( \ |
| 715 new uint8[kHeight * kWidth * 4 + kAlignment]); \ | 733 new uint8_t[kHeight * kWidth * 4 + kAlignment]); \ |
| 716 uint8 *argb_pointer = ALIGNP(argb_expected.get(), kAlignment); \ | 734 uint8_t* argb_pointer = ALIGNP(argb_expected.get(), kAlignment); \ |
| 717 for (int i = 0; i < repeat_; ++i) { \ | 735 for (int i = 0; i < repeat_; ++i) { \ |
| 718 libyuv::SRC_NAME##To##DST_NAME(y_pointer, y_pitch, \ | 736 libyuv::SRC_NAME##To##DST_NAME(y_pointer, y_pitch, u_pointer, u_pitch, \ |
| 719 u_pointer, u_pitch, \ | 737 v_pointer, v_pitch, argb_pointer, \ |
| 720 v_pointer, v_pitch, \ | 738 kWidth * 4, kWidth, kHeight); \ |
| 721 argb_pointer, \ | 739 } \ |
| 722 kWidth * 4, \ | 740 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ |
| 723 kWidth, kHeight); \ | 741 kHeight* kWidth * 4, MSE)); \ |
| 724 } \ | 742 if (dump_) { \ |
| 725 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ | 743 DumpArgbImage(argb_pointer, kWidth, kHeight); \ |
| 726 kHeight * kWidth * 4, MSE)); \ | 744 } \ |
| 727 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } \ | 745 } |
| 728 } | |
| 729 | 746 |
| 730 // TEST_F(PlanarFunctionsTest, I420ToARGB) | 747 // TEST_F(PlanarFunctionsTest, I420ToARGB) |
| 731 TEST_YUVTORGB(I420, ARGB, libyuv::kJpegYuv420, 3., 2); | 748 TEST_YUVTORGB(I420, ARGB, libyuv::kJpegYuv420, 3., 2); |
| 732 // TEST_F(PlanarFunctionsTest, I420ToABGR) | 749 // TEST_F(PlanarFunctionsTest, I420ToABGR) |
| 733 TEST_YUVTORGB(I420, ABGR, libyuv::kJpegYuv420, 3., 2); | 750 TEST_YUVTORGB(I420, ABGR, libyuv::kJpegYuv420, 3., 2); |
| 734 // TEST_F(PlanarFunctionsTest, I420ToBGRA) | 751 // TEST_F(PlanarFunctionsTest, I420ToBGRA) |
| 735 TEST_YUVTORGB(I420, BGRA, libyuv::kJpegYuv420, 3., 2); | 752 TEST_YUVTORGB(I420, BGRA, libyuv::kJpegYuv420, 3., 2); |
| 736 // TEST_F(PlanarFunctionsTest, I422ToARGB) | 753 // TEST_F(PlanarFunctionsTest, I422ToARGB) |
| 737 TEST_YUVTORGB(I422, ARGB, libyuv::kJpegYuv422, 3., 2); | 754 TEST_YUVTORGB(I422, ARGB, libyuv::kJpegYuv422, 3., 2); |
| 738 // TEST_F(PlanarFunctionsTest, I444ToARGB) | 755 // TEST_F(PlanarFunctionsTest, I444ToARGB) |
| 739 TEST_YUVTORGB(I444, ARGB, libyuv::kJpegYuv444, 3., 3); | 756 TEST_YUVTORGB(I444, ARGB, libyuv::kJpegYuv444, 3., 3); |
| 740 // Note: an empirical MSE tolerance 3.0 is used here for the probable | 757 // Note: an empirical MSE tolerance 3.0 is used here for the probable |
| 741 // error from float-to-uint8 type conversion. | 758 // error from float-to-uint8_t type conversion. |
| 742 | 759 |
| 743 TEST_F(PlanarFunctionsTest, I400ToARGB_Reference) { | 760 TEST_F(PlanarFunctionsTest, I400ToARGB_Reference) { |
| 744 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 761 uint8_t* y_pointer = NULL, * u_pointer = NULL, * v_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
Here
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 745 int y_pitch = kWidth; | 762 int y_pitch = kWidth; |
| 746 int u_pitch = (kWidth + 1) >> 1; | 763 int u_pitch = (kWidth + 1) >> 1; |
| 747 int v_pitch = (kWidth + 1) >> 1; | 764 int v_pitch = (kWidth + 1) >> 1; |
| 748 int block_size = 3; | 765 int block_size = 3; |
| 749 // Generate a fake input image. | 766 // Generate a fake input image. |
| 750 rtc::scoped_ptr<uint8[]> yuv_input( | 767 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
| 751 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 768 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
| 752 libyuv::kJpegYuv420, | 769 v_pointer)); |
| 753 y_pointer, u_pointer, v_pointer)); | |
| 754 // As the comparison standard, we convert a grayscale image (by setting both | 770 // As the comparison standard, we convert a grayscale image (by setting both |
| 755 // U and V channels to be 128) using an I420 converter. | 771 // U and V channels to be 128) using an I420 converter. |
| 756 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 772 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
| 757 | 773 |
| 758 rtc::scoped_ptr<uint8[]> uv(new uint8[uv_size + kAlignment]); | 774 rtc::scoped_ptr<uint8_t[]> uv(new uint8_t[uv_size + kAlignment]); |
| 759 u_pointer = v_pointer = ALIGNP(uv.get(), kAlignment); | 775 u_pointer = v_pointer = ALIGNP(uv.get(), kAlignment); |
| 760 memset(u_pointer, 128, uv_size); | 776 memset(u_pointer, 128, uv_size); |
| 761 | 777 |
| 762 // Allocate space for the output image and generate the expected output. | 778 // Allocate space for the output image and generate the expected output. |
| 763 rtc::scoped_ptr<uint8[]> argb_expected( | 779 rtc::scoped_ptr<uint8_t[]> argb_expected( |
| 764 new uint8[kHeight * kWidth * 4 + kAlignment]); | 780 new uint8_t[kHeight * kWidth * 4 + kAlignment]); |
| 765 rtc::scoped_ptr<uint8[]> argb_output( | 781 rtc::scoped_ptr<uint8_t[]> argb_output( |
| 766 new uint8[kHeight * kWidth * 4 + kAlignment]); | 782 new uint8_t[kHeight * kWidth * 4 + kAlignment]); |
| 767 uint8 *argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); | 783 uint8_t* argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); |
| 768 uint8 *argb_pointer = ALIGNP(argb_output.get(), kAlignment); | 784 uint8_t* argb_pointer = ALIGNP(argb_output.get(), kAlignment); |
| 769 | 785 |
| 770 libyuv::I420ToARGB(y_pointer, y_pitch, | 786 libyuv::I420ToARGB(y_pointer, y_pitch, |
| 771 u_pointer, u_pitch, | 787 u_pointer, u_pitch, |
| 772 v_pointer, v_pitch, | 788 v_pointer, v_pitch, |
| 773 argb_expected_pointer, kWidth * 4, | 789 argb_expected_pointer, kWidth * 4, |
| 774 kWidth, kHeight); | 790 kWidth, kHeight); |
| 775 for (int i = 0; i < repeat_; ++i) { | 791 for (int i = 0; i < repeat_; ++i) { |
| 776 libyuv::I400ToARGB_Reference(y_pointer, y_pitch, | 792 libyuv::I400ToARGB_Reference(y_pointer, y_pitch, |
| 777 argb_pointer, kWidth * 4, | 793 argb_pointer, kWidth * 4, |
| 778 kWidth, kHeight); | 794 kWidth, kHeight); |
| 779 } | 795 } |
| 780 | 796 |
| 781 // Note: I420ToARGB and I400ToARGB_Reference should produce identical results. | 797 // Note: I420ToARGB and I400ToARGB_Reference should produce identical results. |
| 782 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, | 798 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, |
| 783 kHeight * kWidth * 4, 2.)); | 799 kHeight * kWidth * 4, 2.)); |
| 784 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } | 800 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } |
| 785 } | 801 } |
| 786 | 802 |
| 787 TEST_P(PlanarFunctionsTest, I400ToARGB) { | 803 TEST_P(PlanarFunctionsTest, I400ToARGB) { |
| 788 // Get the unalignment offset | 804 // Get the unalignment offset |
| 789 int unalignment = GetParam(); | 805 int unalignment = GetParam(); |
| 790 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 806 uint8_t* y_pointer = NULL, * u_pointer = NULL, * v_pointer = NULL; |
|
tlegrand-webrtc
2015/10/05 13:49:01
Here
pbos-webrtc
2015/10/06 09:14:59
Done.
| |
| 791 int y_pitch = kWidth; | 807 int y_pitch = kWidth; |
| 792 int u_pitch = (kWidth + 1) >> 1; | 808 int u_pitch = (kWidth + 1) >> 1; |
| 793 int v_pitch = (kWidth + 1) >> 1; | 809 int v_pitch = (kWidth + 1) >> 1; |
| 794 int block_size = 3; | 810 int block_size = 3; |
| 795 // Generate a fake input image. | 811 // Generate a fake input image. |
| 796 rtc::scoped_ptr<uint8[]> yuv_input( | 812 rtc::scoped_ptr<uint8_t[]> yuv_input(CreateFakeYuvTestingImage( |
| 797 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 813 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
| 798 libyuv::kJpegYuv420, | 814 v_pointer)); |
| 799 y_pointer, u_pointer, v_pointer)); | |
| 800 // As the comparison standard, we convert a grayscale image (by setting both | 815 // As the comparison standard, we convert a grayscale image (by setting both |
| 801 // U and V channels to be 128) using an I420 converter. | 816 // U and V channels to be 128) using an I420 converter. |
| 802 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); | 817 int uv_size = ((kHeight + 1) >> 1) * ((kWidth + 1) >> 1); |
| 803 | 818 |
| 804 // 1 byte extra if in the unaligned mode. | 819 // 1 byte extra if in the unaligned mode. |
| 805 rtc::scoped_ptr<uint8[]> uv(new uint8[uv_size * 2 + kAlignment]); | 820 rtc::scoped_ptr<uint8_t[]> uv(new uint8_t[uv_size * 2 + kAlignment]); |
| 806 u_pointer = ALIGNP(uv.get(), kAlignment); | 821 u_pointer = ALIGNP(uv.get(), kAlignment); |
| 807 v_pointer = u_pointer + uv_size; | 822 v_pointer = u_pointer + uv_size; |
| 808 memset(u_pointer, 128, uv_size); | 823 memset(u_pointer, 128, uv_size); |
| 809 memset(v_pointer, 128, uv_size); | 824 memset(v_pointer, 128, uv_size); |
| 810 | 825 |
| 811 // Allocate space for the output image and generate the expected output. | 826 // Allocate space for the output image and generate the expected output. |
| 812 rtc::scoped_ptr<uint8[]> argb_expected( | 827 rtc::scoped_ptr<uint8_t[]> argb_expected( |
| 813 new uint8[kHeight * kWidth * 4 + kAlignment]); | 828 new uint8_t[kHeight * kWidth * 4 + kAlignment]); |
| 814 // 1 byte extra if in the misalinged mode. | 829 // 1 byte extra if in the misalinged mode. |
| 815 rtc::scoped_ptr<uint8[]> argb_output( | 830 rtc::scoped_ptr<uint8_t[]> argb_output( |
| 816 new uint8[kHeight * kWidth * 4 + kAlignment + unalignment]); | 831 new uint8_t[kHeight * kWidth * 4 + kAlignment + unalignment]); |
| 817 uint8 *argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); | 832 uint8_t* argb_expected_pointer = ALIGNP(argb_expected.get(), kAlignment); |
| 818 uint8 *argb_pointer = ALIGNP(argb_output.get(), kAlignment) + unalignment; | 833 uint8_t* argb_pointer = ALIGNP(argb_output.get(), kAlignment) + unalignment; |
| 819 | 834 |
| 820 libyuv::I420ToARGB(y_pointer, y_pitch, | 835 libyuv::I420ToARGB(y_pointer, y_pitch, |
| 821 u_pointer, u_pitch, | 836 u_pointer, u_pitch, |
| 822 v_pointer, v_pitch, | 837 v_pointer, v_pitch, |
| 823 argb_expected_pointer, kWidth * 4, | 838 argb_expected_pointer, kWidth * 4, |
| 824 kWidth, kHeight); | 839 kWidth, kHeight); |
| 825 for (int i = 0; i < repeat_; ++i) { | 840 for (int i = 0; i < repeat_; ++i) { |
| 826 libyuv::I400ToARGB(y_pointer, y_pitch, | 841 libyuv::I400ToARGB(y_pointer, y_pitch, |
| 827 argb_pointer, kWidth * 4, | 842 argb_pointer, kWidth * 4, |
| 828 kWidth, kHeight); | 843 kWidth, kHeight); |
| 829 } | 844 } |
| 830 | 845 |
| 831 // Note: current I400ToARGB uses an approximate method, | 846 // Note: current I400ToARGB uses an approximate method, |
| 832 // so the error tolerance is larger here. | 847 // so the error tolerance is larger here. |
| 833 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, | 848 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, |
| 834 kHeight * kWidth * 4, 64.0)); | 849 kHeight * kWidth * 4, 64.0)); |
| 835 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } | 850 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } |
| 836 } | 851 } |
| 837 | 852 |
| 838 TEST_P(PlanarFunctionsTest, ARGBToI400) { | 853 TEST_P(PlanarFunctionsTest, ARGBToI400) { |
| 839 // Get the unalignment offset | 854 // Get the unalignment offset |
| 840 int unalignment = GetParam(); | 855 int unalignment = GetParam(); |
| 841 // Create a fake ARGB input image. | 856 // Create a fake ARGB input image. |
| 842 uint8 *y_pointer = NULL, *u_pointer = NULL, *v_pointer = NULL; | 857 uint8_t* y_pointer = NULL, * u_pointer = NULL, * v_pointer = NULL; |
| 843 uint8 *argb_pointer = NULL; | 858 uint8_t* argb_pointer = NULL; |
| 844 int block_size = 3; | 859 int block_size = 3; |
| 845 // Generate a fake input image. | 860 // Generate a fake input image. |
| 846 rtc::scoped_ptr<uint8[]> argb_input( | 861 rtc::scoped_ptr<uint8_t[]> argb_input(CreateFakeArgbTestingImage( |
| 847 CreateFakeArgbTestingImage(kHeight, kWidth, block_size, | 862 kHeight, kWidth, block_size, argb_pointer, FOURCC_ARGB)); |
| 848 argb_pointer, FOURCC_ARGB)); | |
| 849 // Generate the expected output. Only Y channel is used | 863 // Generate the expected output. Only Y channel is used |
| 850 rtc::scoped_ptr<uint8[]> yuv_expected( | 864 rtc::scoped_ptr<uint8_t[]> yuv_expected(CreateFakeYuvTestingImage( |
| 851 CreateFakeYuvTestingImage(kHeight, kWidth, block_size, | 865 kHeight, kWidth, block_size, libyuv::kJpegYuv420, y_pointer, u_pointer, |
| 852 libyuv::kJpegYuv420, | 866 v_pointer)); |
| 853 y_pointer, u_pointer, v_pointer)); | |
| 854 // Allocate space for the Y output. | 867 // Allocate space for the Y output. |
| 855 rtc::scoped_ptr<uint8[]> y_output( | 868 rtc::scoped_ptr<uint8_t[]> y_output( |
| 856 new uint8[kHeight * kWidth + kAlignment + unalignment]); | 869 new uint8_t[kHeight * kWidth + kAlignment + unalignment]); |
| 857 uint8 *y_output_pointer = ALIGNP(y_output.get(), kAlignment) + unalignment; | 870 uint8_t* y_output_pointer = ALIGNP(y_output.get(), kAlignment) + unalignment; |
| 858 | 871 |
| 859 for (int i = 0; i < repeat_; ++i) { | 872 for (int i = 0; i < repeat_; ++i) { |
| 860 libyuv::ARGBToI400(argb_pointer, kWidth * 4, y_output_pointer, kWidth, | 873 libyuv::ARGBToI400(argb_pointer, kWidth * 4, y_output_pointer, kWidth, |
| 861 kWidth, kHeight); | 874 kWidth, kHeight); |
| 862 } | 875 } |
| 863 // Check if the output matches the input Y channel. | 876 // Check if the output matches the input Y channel. |
| 864 // Note: an empirical MSE tolerance 2.0 is used here for the probable | 877 // Note: an empirical MSE tolerance 2.0 is used here for the probable |
| 865 // error from float-to-uint8 type conversion. | 878 // error from float-to-uint8_t type conversion. |
| 866 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, | 879 EXPECT_TRUE(IsMemoryEqual(y_output_pointer, y_pointer, |
| 867 kHeight * kWidth, 2.)); | 880 kHeight * kWidth, 2.)); |
| 868 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } | 881 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } |
| 869 } | 882 } |
| 870 | 883 |
| 871 // A common macro for testing converting RAW, BG24, BGRA, and ABGR | 884 // A common macro for testing converting RAW, BG24, BGRA, and ABGR |
| 872 // to ARGB. | 885 // to ARGB. |
| 873 #define TEST_ARGB(SRC_NAME, FC_ID, BPP, BLOCK_SIZE) \ | 886 #define TEST_ARGB(SRC_NAME, FC_ID, BPP, BLOCK_SIZE) \ |
| 874 TEST_P(PlanarFunctionsTest, SRC_NAME##ToARGB) { \ | 887 TEST_P(PlanarFunctionsTest, SRC_NAME##ToARGB) { \ |
| 875 int unalignment = GetParam(); /* Get the unalignment offset.*/ \ | 888 int unalignment = GetParam(); /* Get the unalignment offset.*/ \ |
| 876 uint8 *argb_expected_pointer = NULL, *src_pointer = NULL; \ | 889 uint8_t* argb_expected_pointer = NULL, * src_pointer = NULL; \ |
| 877 /* Generate a fake input image.*/ \ | 890 /* Generate a fake input image.*/ \ |
| 878 rtc::scoped_ptr<uint8[]> src_input( \ | 891 rtc::scoped_ptr<uint8_t[]> src_input(CreateFakeArgbTestingImage( \ |
| 879 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 892 kHeight, kWidth, BLOCK_SIZE, src_pointer, FOURCC_##FC_ID)); \ |
| 880 src_pointer, FOURCC_##FC_ID)); \ | 893 /* Generate the expected output.*/ \ |
| 881 /* Generate the expected output.*/ \ | 894 rtc::scoped_ptr<uint8_t[]> argb_expected(CreateFakeArgbTestingImage( \ |
| 882 rtc::scoped_ptr<uint8[]> argb_expected( \ | 895 kHeight, kWidth, BLOCK_SIZE, argb_expected_pointer, FOURCC_ARGB)); \ |
| 883 CreateFakeArgbTestingImage(kHeight, kWidth, BLOCK_SIZE, \ | 896 /* Allocate space for the output; 1 byte extra if in the unaligned mode.*/ \ |
| 884 argb_expected_pointer, FOURCC_ARGB)); \ | 897 rtc::scoped_ptr<uint8_t[]> argb_output( \ |
| 885 /* Allocate space for the output; 1 byte extra if in the unaligned mode.*/ \ | 898 new uint8_t[kHeight * kWidth * 4 + kAlignment + unalignment]); \ |
| 886 rtc::scoped_ptr<uint8[]> argb_output( \ | 899 uint8_t* argb_pointer = \ |
| 887 new uint8[kHeight * kWidth * 4 + kAlignment + unalignment]); \ | 900 ALIGNP(argb_output.get(), kAlignment) + unalignment; \ |
| 888 uint8 *argb_pointer = ALIGNP(argb_output.get(), kAlignment) + unalignment; \ | 901 for (int i = 0; i < repeat_; ++i) { \ |
| 889 for (int i = 0; i < repeat_; ++i) { \ | 902 libyuv::SRC_NAME##ToARGB(src_pointer, kWidth*(BPP), argb_pointer, \ |
| 890 libyuv:: SRC_NAME##ToARGB(src_pointer, kWidth * (BPP), argb_pointer, \ | 903 kWidth * 4, kWidth, kHeight); \ |
| 891 kWidth * 4, kWidth, kHeight); \ | 904 } \ |
| 892 } \ | 905 /* Compare the result; expect identical.*/ \ |
| 893 /* Compare the result; expect identical.*/ \ | 906 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ |
| 894 EXPECT_TRUE(IsMemoryEqual(argb_expected_pointer, argb_pointer, \ | 907 kHeight* kWidth * 4, 1.e-6)); \ |
| 895 kHeight * kWidth * 4, 1.e-6)); \ | 908 if (dump_) { \ |
| 896 if (dump_) { DumpArgbImage(argb_pointer, kWidth, kHeight); } \ | 909 DumpArgbImage(argb_pointer, kWidth, kHeight); \ |
| 897 } | 910 } \ |
| 911 } | |
| 898 | 912 |
| 899 TEST_ARGB(RAW, RAW, 3, 3); // TEST_P(PlanarFunctionsTest, RAWToARGB) | 913 TEST_ARGB(RAW, RAW, 3, 3); // TEST_P(PlanarFunctionsTest, RAWToARGB) |
| 900 TEST_ARGB(BG24, 24BG, 3, 3); // TEST_P(PlanarFunctionsTest, BG24ToARGB) | 914 TEST_ARGB(BG24, 24BG, 3, 3); // TEST_P(PlanarFunctionsTest, BG24ToARGB) |
| 901 TEST_ARGB(ABGR, ABGR, 4, 3); // TEST_P(PlanarFunctionsTest, ABGRToARGB) | 915 TEST_ARGB(ABGR, ABGR, 4, 3); // TEST_P(PlanarFunctionsTest, ABGRToARGB) |
| 902 TEST_ARGB(BGRA, BGRA, 4, 3); // TEST_P(PlanarFunctionsTest, BGRAToARGB) | 916 TEST_ARGB(BGRA, BGRA, 4, 3); // TEST_P(PlanarFunctionsTest, BGRAToARGB) |
| 903 | 917 |
| 904 // Parameter Test: The parameter is the unalignment offset. | 918 // Parameter Test: The parameter is the unalignment offset. |
| 905 // Aligned data for testing assembly versions. | 919 // Aligned data for testing assembly versions. |
| 906 INSTANTIATE_TEST_CASE_P(PlanarFunctionsAligned, PlanarFunctionsTest, | 920 INSTANTIATE_TEST_CASE_P(PlanarFunctionsAligned, PlanarFunctionsTest, |
| 907 ::testing::Values(0)); | 921 ::testing::Values(0)); |
| 908 | 922 |
| 909 // Purposely unalign the output argb pointer to test slow path (C version). | 923 // Purposely unalign the output argb pointer to test slow path (C version). |
| 910 INSTANTIATE_TEST_CASE_P(PlanarFunctionsMisaligned, PlanarFunctionsTest, | 924 INSTANTIATE_TEST_CASE_P(PlanarFunctionsMisaligned, PlanarFunctionsTest, |
| 911 ::testing::Values(1)); | 925 ::testing::Values(1)); |
| 912 | 926 |
| 913 } // namespace cricket | 927 } // namespace cricket |
| OLD | NEW |